22
33import android .os .Build ;
44
5+ import com .google .common .io .CountingOutputStream ;
6+ import com .google .firebase .perf .metrics .Trace ;
7+
58import org .commcare .AppUtils ;
69import org .commcare .CommCareApplication ;
710import org .commcare .android .javarosa .DeviceReportRecord ;
11+ import org .commcare .google .services .analytics .CCPerfMonitoring ;
812import org .commcare .models .database .SqlStorage ;
913import org .javarosa .core .model .User ;
1014import org .javarosa .core .model .utils .DateUtils ;
1721import java .util .ArrayList ;
1822import java .util .Date ;
1923
24+ import static org .commcare .utils .FileUtil .XML_EXTENSION ;
25+
2026/**
2127 * This class generates and serializes a device report to either a byte array
2228 * or to a file as designated by a log record
@@ -27,18 +33,34 @@ public class DeviceReportWriter {
2733 public static final String XMLNS = "http://code.javarosa.org/devicereport" ;
2834
2935 private final XmlSerializer serializer ;
30- private final OutputStream os ;
36+ private final CountingOutputStream countingOutputStream ;
3137 private final ArrayList <DeviceReportElement > elements = new ArrayList <>();
38+ private final boolean encryptionWithKeystore ;
39+ private final boolean skipPerfTracing ;
3240
3341 public DeviceReportWriter (DeviceReportRecord record ) throws IOException {
34- this (record .openOutputStream ());
42+ this (record .openOutputStream (), record . shouldUseKeystoreKey (), false );
3543 }
3644
37- public DeviceReportWriter (OutputStream outputStream ) throws IOException {
38- os = outputStream ;
45+ /**
46+ * Constructor for in-memory report generation where the output stream is a ByteArrayOutputStream and no file
47+ * encryption occurs. When skipTracing is true, file encryption performance tracing is omitted
48+ */
49+ public DeviceReportWriter (OutputStream outputStream , boolean skipPerfTracing ) throws IOException {
50+ this (outputStream , false , skipPerfTracing );
51+ }
52+
53+ private DeviceReportWriter (
54+ OutputStream outputStream ,
55+ boolean keystoreEncrypted ,
56+ boolean skipPerfTracing
57+ ) throws IOException {
58+ countingOutputStream = new CountingOutputStream (outputStream );
59+ encryptionWithKeystore = keystoreEncrypted ;
60+ this .skipPerfTracing = skipPerfTracing ;
3961
4062 serializer = new KXmlSerializer ();
41- serializer .setOutput (os , "UTF-8" );
63+ serializer .setOutput (countingOutputStream , "UTF-8" );
4264 serializer .setPrefix ("" , XMLNS );
4365
4466 serializer .setFeature ("http://xmlpull.org/v1/doc/features.html#indent-output" , true );
@@ -50,6 +72,10 @@ public void addReportElement(DeviceReportElement element) {
5072 }
5173
5274 public void write () throws IllegalArgumentException , IllegalStateException , IOException {
75+ Trace trace = null ;
76+ if (!skipPerfTracing ) {
77+ trace = CCPerfMonitoring .INSTANCE .startTracing (CCPerfMonitoring .TRACE_FILE_ENCRYPTION_TIME );
78+ }
5379 try {
5480 serializer .startDocument ("UTF-8" , null );
5581 serializer .startTag (XMLNS , "device_report" );
@@ -80,7 +106,13 @@ public void write() throws IllegalArgumentException, IllegalStateException, IOEx
80106 serializer .endDocument ();
81107 } finally {
82108 try {
83- os .close ();
109+ CCPerfMonitoring .INSTANCE .stopFileEncryptionTracing (
110+ trace ,
111+ countingOutputStream .getCount (),
112+ XML_EXTENSION ,
113+ encryptionWithKeystore
114+ );
115+ countingOutputStream .close ();
84116 } catch (IOException e ) {
85117 }
86118 }
0 commit comments