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 
17 package com.android.compatibility.common.tradefed.targetprep;
18 
19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
20 import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
21 import com.android.compatibility.common.tradefed.util.CollectorUtil;
22 import com.android.compatibility.common.util.DevicePropertyInfo;
23 import com.android.tradefed.build.IBuildInfo;
24 import com.android.tradefed.config.Option;
25 import com.android.tradefed.device.DeviceNotAvailableException;
26 import com.android.tradefed.device.ITestDevice;
27 import com.android.tradefed.log.LogUtil.CLog;
28 import com.android.tradefed.targetprep.BuildError;
29 import com.android.tradefed.targetprep.TargetSetupError;
30 import com.android.tradefed.util.FileUtil;
31 
32 import java.io.File;
33 import java.io.FileNotFoundException;
34 import java.util.Map.Entry;
35 
36 /**
37  * An {@link ApkInstrumentationPreparer} that collects device info.
38  */
39 public class DeviceInfoCollector extends ApkInstrumentationPreparer {
40 
41     private static final String ABI = "ro.product.cpu.abi";
42     private static final String ABI2 = "ro.product.cpu.abi2";
43     private static final String ABIS = "ro.product.cpu.abilist";
44     private static final String ABIS_32 = "ro.product.cpu.abilist32";
45     private static final String ABIS_64 = "ro.product.cpu.abilist64";
46     private static final String BOARD = "ro.product.board";
47     private static final String BRAND = "ro.product.brand";
48     private static final String DEVICE = "ro.product.device";
49     private static final String FINGERPRINT = "ro.build.fingerprint";
50     private static final String ID = "ro.build.id";
51     private static final String MANUFACTURER = "ro.product.manufacturer";
52     private static final String MODEL = "ro.product.model";
53     private static final String PRODUCT = "ro.product.name";
54     private static final String REFERENCE_FINGERPRINT = "ro.build.reference.fingerprint";
55     private static final String SERIAL = "ro.serialno";
56     private static final String TAGS = "ro.build.tags";
57     private static final String TYPE = "ro.build.type";
58     private static final String VERSION_BASE_OS = "ro.build.version.base_os";
59     private static final String VERSION_RELEASE = "ro.build.version.release";
60     private static final String VERSION_SDK = "ro.build.version.sdk";
61     private static final String VERSION_SECURITY_PATCH = "ro.build.version.security_patch";
62     private static final String VERSION_INCREMENTAL = "ro.build.version.incremental";
63 
64     private static final String PREFIX_TAG = "cts:build_";
65 
66     @Option(name = CompatibilityTest.SKIP_DEVICE_INFO_OPTION,
67             shortName = 'd',
68             description = "Whether device info collection should be skipped")
69     private boolean mSkipDeviceInfo = false;
70 
71     @Option(name= "src-dir", description = "The directory to copy to the results dir")
72     private String mSrcDir;
73 
74     @Option(name = "dest-dir", description = "The directory under the result to store the files")
75     private String mDestDir;
76 
77     @Option(name = "temp-dir", description = "The directory containing host-side device info files")
78     private String mTempDir;
79 
80     // Temp directory for host-side device info files.
81     private File mHostDir;
82 
83     // Destination result directory for all device info files.
84     private File mResultDir;
85 
DeviceInfoCollector()86     public DeviceInfoCollector() {
87         mWhen = When.BOTH;
88     }
89 
90     @Override
setUp(ITestDevice device, IBuildInfo buildInfo)91     public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
92             BuildError, DeviceNotAvailableException {
93         DevicePropertyInfo devicePropertyInfo = new DevicePropertyInfo(ABI, ABI2, ABIS, ABIS_32,
94                 ABIS_64, BOARD, BRAND, DEVICE, FINGERPRINT, ID, MANUFACTURER, MODEL, PRODUCT,
95                 REFERENCE_FINGERPRINT, SERIAL, TAGS, TYPE, VERSION_BASE_OS, VERSION_RELEASE,
96                 VERSION_SDK, VERSION_SECURITY_PATCH, VERSION_INCREMENTAL);
97 
98         // add device properties to the result with a prefix tag for each key
99         for (Entry<String, String> entry :
100                 devicePropertyInfo.getPropertytMapWithPrefix(PREFIX_TAG).entrySet()) {
101             buildInfo.addBuildAttribute(
102                     entry.getKey(), nullToEmpty(device.getProperty(entry.getValue())));
103         }
104         if (mSkipDeviceInfo) {
105             return;
106         }
107 
108         createTempHostDir();
109         createResultDir(buildInfo);
110         run(device, buildInfo);
111         getDeviceInfoFiles(device);
112     }
113 
114     @Override
tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)115     public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e) {
116         if (mSkipDeviceInfo) {
117             return;
118         }
119         if (mHostDir != null && mHostDir.isDirectory() &&
120                 mResultDir != null && mResultDir.isDirectory()) {
121             CollectorUtil.pullFromHost(mHostDir, mResultDir);
122         }
123     }
124 
createTempHostDir()125     private void createTempHostDir() {
126         try {
127             mHostDir = FileUtil.createNamedTempDir(mTempDir);
128             if (!mHostDir.isDirectory()) {
129                 CLog.e("%s is not a directory", mHostDir.getAbsolutePath());
130                 return;
131             }
132         } catch (Exception e) {
133             e.printStackTrace();
134         }
135     }
136 
createResultDir(IBuildInfo buildInfo)137     private void createResultDir(IBuildInfo buildInfo) {
138         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
139         try {
140             mResultDir = buildHelper.getResultDir();
141             if (mDestDir != null) {
142                 mResultDir = new File(mResultDir, mDestDir);
143             }
144             mResultDir.mkdirs();
145             if (!mResultDir.isDirectory()) {
146                 CLog.e("%s is not a directory", mResultDir.getAbsolutePath());
147                 return;
148             }
149         } catch (FileNotFoundException fnfe) {
150             fnfe.printStackTrace();
151         }
152     }
153 
getDeviceInfoFiles(ITestDevice device)154     private void getDeviceInfoFiles(ITestDevice device) {
155         if (mResultDir != null && mResultDir.isDirectory()) {
156             String mResultPath = mResultDir.getAbsolutePath();
157             CollectorUtil.pullFromDevice(device, mSrcDir, mResultPath);
158         }
159     }
160 
nullToEmpty(String value)161     private static String nullToEmpty(String value) {
162         return value == null ? "" : value;
163     }
164 }
165