1 /*
2  * Copyright (C) 2014 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 com.android.compatibility.common.util;
18 
19 import android.app.Instrumentation;
20 import android.os.Bundle;
21 import android.os.Environment;
22 import android.util.Log;
23 
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.List;
27 
28 /**
29  * Handles adding results to the report for device side tests.
30  *
31  * NOTE: tests MUST call {@link #submit(Instrumentation)} if and only if the test passes in order to
32  * send the results to the runner.
33  */
34 public class DeviceReportLog extends ReportLog {
35     private static final String TAG = DeviceReportLog.class.getSimpleName();
36     private static final String RESULT = "COMPATIBILITY_TEST_RESULT";
37     private static final int INST_STATUS_ERROR = -1;
38     private static final int INST_STATUS_IN_PROGRESS = 2;
39 
40     private ReportLogDeviceInfoStore store;
41 
DeviceReportLog(String reportLogName, String streamName)42     public DeviceReportLog(String reportLogName, String streamName) {
43         this(reportLogName, streamName,
44                 new File(Environment.getExternalStorageDirectory(), "report-log-files"));
45     }
46 
DeviceReportLog(String reportLogName, String streamName, File logDirectory)47     public DeviceReportLog(String reportLogName, String streamName, File logDirectory) {
48         super(reportLogName, streamName);
49         try {
50             // dir value must match the src-dir value configured in ReportLogCollector target
51             // preparer in cts/harness/tools/cts-tradefed/res/config/cts-preconditions.xml
52             if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
53                 throw new IOException("External storage is not mounted");
54             } else if ((!logDirectory.exists() && !logDirectory.mkdirs())
55                     || (logDirectory.exists() && !logDirectory.isDirectory())) {
56                 throw new IOException("Cannot create directory for device info files");
57             } else {
58                 File jsonFile = new File(logDirectory, mReportLogName + ".reportlog.json");
59                 store = new ReportLogDeviceInfoStore(jsonFile, mStreamName);
60                 store.open();
61             }
62         } catch (Exception e) {
63             Log.e(TAG, "Could not create report log file.", e);
64         }
65     }
66 
67     /**
68      * Adds a double metric to the report.
69      */
70     @Override
addValue(String source, String message, double value, ResultType type, ResultUnit unit)71     public void addValue(String source, String message, double value, ResultType type,
72             ResultUnit unit) {
73         super.addValue(source, message, value, type, unit);
74         try {
75             store.addResult(message, value);
76         } catch (Exception e) {
77             Log.e(TAG, "Could not log metric.", e);
78         }
79     }
80 
81     /**
82      * Adds a double metric to the report.
83      */
84     @Override
addValue(String message, double value, ResultType type, ResultUnit unit)85     public void addValue(String message, double value, ResultType type, ResultUnit unit) {
86         super.addValue(message, value, type, unit);
87         try {
88             store.addResult(message, value);
89         } catch (Exception e) {
90             Log.e(TAG, "Could not log metric.", e);
91         }
92     }
93 
94     /**
95      * Adds a double array of metrics to the report.
96      */
97     @Override
addValues(String source, String message, double[] values, ResultType type, ResultUnit unit)98     public void addValues(String source, String message, double[] values, ResultType type,
99             ResultUnit unit) {
100         super.addValues(source, message, values, type, unit);
101         try {
102             store.addArrayResult(message, values);
103         } catch (Exception e) {
104             Log.e(TAG, "Could not log metric.", e);
105         }
106     }
107 
108     /**
109      * Adds a double array of metrics to the report.
110      */
111     @Override
addValues(String message, double[] values, ResultType type, ResultUnit unit)112     public void addValues(String message, double[] values, ResultType type, ResultUnit unit) {
113         super.addValues(message, values, type, unit);
114         try {
115             store.addArrayResult(message, values);
116         } catch (Exception e) {
117             Log.e(TAG, "Could not log metric.", e);
118         }
119     }
120 
121     /**
122      * Adds an int metric to the report.
123      */
124     @Override
addValue(String message, int value, ResultType type, ResultUnit unit)125     public void addValue(String message, int value, ResultType type, ResultUnit unit) {
126         try {
127             store.addResult(message, value);
128         } catch (Exception e) {
129             Log.e(TAG, "Could not log metric.", e);
130         }
131     }
132 
133     /**
134      * Adds a long metric to the report.
135      */
136     @Override
addValue(String message, long value, ResultType type, ResultUnit unit)137     public void addValue(String message, long value, ResultType type, ResultUnit unit) {
138         try {
139             store.addResult(message, value);
140         } catch (Exception e) {
141             Log.e(TAG, "Could not log metric.", e);
142         }
143     }
144 
145     /**
146      * Adds a float metric to the report.
147      */
148     @Override
addValue(String message, float value, ResultType type, ResultUnit unit)149     public void addValue(String message, float value, ResultType type, ResultUnit unit) {
150         try {
151             store.addResult(message, value);
152         } catch (Exception e) {
153             Log.e(TAG, "Could not log metric.", e);
154         }
155     }
156 
157     /**
158      * Adds a boolean metric to the report.
159      */
160     @Override
addValue(String message, boolean value, ResultType type, ResultUnit unit)161     public void addValue(String message, boolean value, ResultType type, ResultUnit unit) {
162         try {
163             store.addResult(message, value);
164         } catch (Exception e) {
165             Log.e(TAG, "Could not log metric.", e);
166         }
167     }
168 
169     /**
170      * Adds a String metric to the report.
171      */
172     @Override
addValue(String message, String value, ResultType type, ResultUnit unit)173     public void addValue(String message, String value, ResultType type, ResultUnit unit) {
174         try {
175             store.addResult(message, value);
176         } catch (Exception e) {
177             Log.e(TAG, "Could not log metric.", e);
178         }
179     }
180 
181     /**
182      * Adds an int array of metrics to the report.
183      */
184     @Override
addValues(String message, int[] values, ResultType type, ResultUnit unit)185     public void addValues(String message, int[] values, ResultType type, ResultUnit unit) {
186         try {
187             store.addArrayResult(message, values);
188         } catch (Exception e) {
189             Log.e(TAG, "Could not log metric.", e);
190         }
191     }
192 
193     /**
194      * Adds a long array of metrics to the report.
195      */
196     @Override
addValues(String message, long[] values, ResultType type, ResultUnit unit)197     public void addValues(String message, long[] values, ResultType type, ResultUnit unit) {
198         try {
199             store.addArrayResult(message, values);
200         } catch (Exception e) {
201             Log.e(TAG, "Could not log metric.", e);
202         }
203     }
204 
205     /**
206      * Adds a float array of metrics to the report.
207      */
208     @Override
addValues(String message, float[] values, ResultType type, ResultUnit unit)209     public void addValues(String message, float[] values, ResultType type, ResultUnit unit) {
210         try {
211             store.addArrayResult(message, values);
212         } catch (Exception e) {
213             Log.e(TAG, "Could not log metric.", e);
214         }
215     }
216 
217     /**
218      * Adds a boolean array of metrics to the report.
219      */
220     @Override
addValues(String message, boolean[] values, ResultType type, ResultUnit unit)221     public void addValues(String message, boolean[] values, ResultType type, ResultUnit unit) {
222         try {
223             store.addArrayResult(message, values);
224         } catch (Exception e) {
225             Log.e(TAG, "Could not log metric.", e);
226         }
227     }
228 
229     /**
230      * Adds a String List of metrics to the report.
231      */
232     @Override
addValues(String message, List<String> values, ResultType type, ResultUnit unit)233     public void addValues(String message, List<String> values, ResultType type, ResultUnit unit) {
234         try {
235             store.addListResult(message, values);
236         } catch (Exception e) {
237             Log.e(TAG, "Could not log metric.", e);
238         }
239     }
240 
241     /**
242      * Sets the summary double metric of the report.
243      *
244      * NOTE: messages over {@value Metric#MAX_MESSAGE_LENGTH} chars will be trimmed.
245      */
246     @Override
setSummary(String message, double value, ResultType type, ResultUnit unit)247     public void setSummary(String message, double value, ResultType type, ResultUnit unit) {
248         super.setSummary(message, value, type, unit);
249         try {
250             store.addResult(message, value);
251         } catch (Exception e) {
252             Log.e(TAG, "Could not log metric.", e);
253         }
254     }
255 
256     /**
257      * Closes report file and submits report to instrumentation.
258      */
submit(Instrumentation instrumentation)259     public void submit(Instrumentation instrumentation) {
260         try {
261             store.close();
262             Bundle output = new Bundle();
263             output.putString(RESULT, serialize(this));
264             instrumentation.sendStatus(INST_STATUS_IN_PROGRESS, output);
265         } catch (Exception e) {
266             Log.e(TAG, "ReportLog Submit Failed", e);
267             instrumentation.sendStatus(INST_STATUS_ERROR, null);
268         }
269     }
270 
271     /**
272      * Closes report file. Static functions that do not have access to instrumentation can
273      * use this to close report logs. Summary, if present, is not reported to instrumentation, hence
274      * does not appear in the result XML.
275      */
submit()276     public void submit() {
277         try {
278             store.close();
279         } catch (Exception e) {
280             Log.e(TAG, "ReportLog Submit Failed", e);
281         }
282     }
283 }
284