1 /*
2  * Copyright (C) 2015 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 package com.android.compatibility.common.deviceinfo;
17 
18 import android.app.Activity;
19 import android.content.Context;
20 import android.content.pm.ActivityInfo;
21 import android.content.pm.PackageManager;
22 import android.os.Bundle;
23 import android.os.Environment;
24 import android.test.InstrumentationTestCase;
25 import android.text.TextUtils;
26 import android.util.JsonWriter;
27 import android.util.Log;
28 
29 import com.android.compatibility.common.util.DeviceInfoStore;
30 
31 import java.io.File;
32 import java.io.FileOutputStream;
33 import java.io.OutputStreamWriter;
34 import java.nio.charset.StandardCharsets;
35 import java.util.Arrays;
36 import java.util.HashSet;
37 import java.util.Set;
38 
39 /**
40  * Collect device information on target device and write to a JSON file.
41  */
42 public abstract class DeviceInfo extends InstrumentationTestCase {
43 
44     private enum ResultCode {
45         // Collection started.
46         STARTED,
47         // Collection completed.
48         COMPLETED,
49         // Collection completed with error.
50         ERROR,
51         // Collection failed to complete.
52         FAILED
53     }
54 
55     private static final int MAX_STRING_VALUE_LENGTH = 1000;
56     private static final int MAX_ARRAY_LENGTH = 1000;
57 
58     private static final String LOG_TAG = "ExtendedDeviceInfo";
59 
60     private JsonWriter mJsonWriter = null;
61     private String mResultFilePath = null;
62     private String mErrorMessage = null;
63     private ResultCode mResultCode = ResultCode.STARTED;
64 
65     Set<String> mActivityList = new HashSet<String>();
66 
testCollectDeviceInfo()67     public void testCollectDeviceInfo() throws Exception {
68         if (!mActivityList.contains(getClass().getName())) {
69             return;
70         }
71 
72         final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
73         if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
74             failed("External storage is not mounted");
75         } else if (!dir.mkdirs() && !dir.isDirectory()) {
76             failed("Cannot create directory for device info files");
77         } else {
78             try {
79                 File jsonFile = new File(dir, getClass().getSimpleName() + ".deviceinfo.json");
80                 jsonFile.createNewFile();
81                 mResultFilePath = jsonFile.getAbsolutePath();
82                 DeviceInfoStore store = new DeviceInfoStore(jsonFile);
83                 store.open();
84                 collectDeviceInfo(store);
85                 store.close();
86                 if (mResultCode == ResultCode.STARTED) {
87                     mResultCode = ResultCode.COMPLETED;
88                 }
89             } catch (Exception e) {
90                 failed("Could not collect device info: " + e.getMessage());
91             }
92         }
93 
94         String message = getClass().getSimpleName() + " collection completed.";
95         assertEquals(message, ResultCode.COMPLETED, mResultCode);
96     }
97 
98     @Override
setUp()99     protected void setUp() throws Exception {
100         super.setUp();
101 
102         // Build the list of supported activities that can run collection.
103         ActivityInfo[] activities = null;
104         try {
105             activities = getContext().getPackageManager().getPackageInfo(
106                 getContext().getPackageName(), PackageManager.GET_ACTIVITIES).activities;
107         } catch (Exception e) {
108             Log.e(LOG_TAG, "Exception occurred while getting activities.", e);
109             return;
110         }
111 
112         for (ActivityInfo activityInfo : activities) {
113             mActivityList.add(activityInfo.name);
114         }
115     }
116 
117     /**
118      * Method to collect device information.
119      */
collectDeviceInfo(DeviceInfoStore store)120     protected abstract void collectDeviceInfo(DeviceInfoStore store) throws Exception;
121 
getContext()122     protected Context getContext() {
123         return getInstrumentation().getContext();
124     }
125 
126     /**
127      * Returns the path to the json file if collector completed successfully.
128      */
getResultFilePath()129     String getResultFilePath() {
130         return mResultFilePath;
131     }
132 
error(String message, Throwable exception)133     private void error(String message, Throwable exception) {
134         mResultCode = ResultCode.ERROR;
135         mErrorMessage = message;
136         Log.e(LOG_TAG, message, exception);
137     }
138 
failed(String message)139     private void failed(String message) {
140         mResultCode = ResultCode.FAILED;
141         mErrorMessage = message;
142         Log.e(LOG_TAG, message);
143     }
144 }
145