• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.chromium.latency.walt;
18 
19 import android.content.Context;
20 import android.os.Environment;
21 
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.OutputStreamWriter;
26 import java.text.DecimalFormat;
27 import java.util.ArrayList;
28 
29 /**
30  * Used to log events for Android systrace
31  */
32 class TraceLogger {
33 
34     private static final Object LOCK = new Object();
35     private static TraceLogger instance;
36 
37     private ArrayList<TraceEvent> traceEvents;
38 
getInstance()39     public static TraceLogger getInstance() {
40         synchronized (LOCK) {
41             if (instance == null) {
42                 instance = new TraceLogger();
43             }
44             return instance;
45         }
46     }
47 
TraceLogger()48     private TraceLogger() {
49         traceEvents = new ArrayList<>();
50     }
51 
log(long startTimeMicros, long finishTimeMicros, String title, String description)52     public synchronized void log(long startTimeMicros, long finishTimeMicros, String title, String description) {
53         traceEvents.add(new TraceEvent(startTimeMicros, finishTimeMicros, title, description));
54     }
55 
getLogText()56     public String getLogText() {
57         DecimalFormat df = new DecimalFormat(".000000");
58         StringBuilder sb = new StringBuilder();
59         int pid = android.os.Process.myPid();
60         for (TraceEvent e : traceEvents) {
61             sb.append(String.format(
62                     "WALTThread-1234 (%d) [000] ...1 %s: tracing_mark_write: B|%d|%s|description=%s|WALT\n",
63                     pid, df.format(e.startTimeMicros / 1e6), pid, e.title, e.description));
64             sb.append(String.format(
65                     "WALTThread-1234 (%d) [000] ...1 %s: tracing_mark_write: E|%d|%s||WALT\n",
66                     pid, df.format(e.finishTimeMicros / 1e6), pid, e.title));
67         }
68         return sb.toString();
69     }
70 
flush(Context context)71     void flush(Context context) {
72         SimpleLogger logger = SimpleLogger.getInstance(context);
73         if (!isExternalStorageWritable()) {
74             logger.log("ERROR: could not write systrace logs to file");
75             return;
76         }
77         writeSystraceLogs(context);
78         traceEvents.clear();
79     }
80 
writeSystraceLogs(Context context)81     private void writeSystraceLogs(Context context) {
82         File file = new File(context.getExternalFilesDir(null), "trace.txt");
83         SimpleLogger logger = SimpleLogger.getInstance(context);
84         try {
85             OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file, true));
86             writer.write(getLogText());
87             writer.close();
88             logger.log(String.format("TraceLogger wrote %d events to %s",
89                     traceEvents.size(), file.getAbsolutePath()));
90         } catch (IOException e) {
91             logger.log("ERROR: IOException writing to trace.txt");
92             e.printStackTrace();
93         }
94     }
95 
isExternalStorageWritable()96     private boolean isExternalStorageWritable() {
97         String state = Environment.getExternalStorageState();
98         return Environment.MEDIA_MOUNTED.equals(state);
99     }
100 
101     private class TraceEvent {
102         long startTimeMicros;
103         long finishTimeMicros;
104         String title;
105         String description;
TraceEvent(long startTimeMicros, long finishTimeMicros, String title, String description)106         TraceEvent(long startTimeMicros, long finishTimeMicros, String title, String description) {
107             this.startTimeMicros = startTimeMicros;
108             this.finishTimeMicros = finishTimeMicros;
109             this.title = title;
110             this.description = description;
111         }
112     }
113 }
114