blob: dc99609ec3a5567849302b3368b1ae21e2a6c503 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.compatibility.common.tradefed.targetprep;
import com.android.compatibility.common.util.DeviceInfo;
import com.android.compatibility.common.util.DevicePropertyInfo;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.log.ITestLogger;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.FileInputStreamSource;
import com.android.tradefed.result.ITestLoggerReceiver;
import com.android.tradefed.result.LogDataType;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.TargetSetupError;
import com.android.tradefed.util.FileUtil;
import java.io.File;
import java.io.IOException;
import java.util.Map.Entry;
/** An {@link ApkInstrumentationPreparer} that collects device info. */
@OptionClass(alias = "device-info-collector")
public class DeviceInfoCollector extends ApkInstrumentationPreparer implements ITestLoggerReceiver {
public static final String DEVICE_INFO_DIR = "device_info_dir";
public static final String SKIP_DEVICE_INFO_OPTION = "skip-device-info";
private static final String ABI = "ro.product.cpu.abi";
private static final String ABI2 = "ro.product.cpu.abi2";
private static final String ABIS = "ro.product.cpu.abilist";
private static final String ABIS_32 = "ro.product.cpu.abilist32";
private static final String ABIS_64 = "ro.product.cpu.abilist64";
private static final String BOARD = "ro.product.board";
private static final String BRAND = "ro.product.brand";
private static final String DEVICE = "ro.product.device";
private static final String FINGERPRINT = "ro.build.fingerprint";
private static final String VENDOR_FINGERPRINT = "ro.vendor.build.fingerprint";
private static final String BOOTIMAGE_FINGERPRINT = "ro.bootimage.build.fingerprint";
private static final String ID = "ro.build.id";
private static final String MANUFACTURER = "ro.product.manufacturer";
private static final String MODEL = "ro.product.model";
private static final String PRODUCT = "ro.product.name";
private static final String REFERENCE_FINGERPRINT = "ro.build.reference.fingerprint";
private static final String SERIAL = "ro.serialno";
private static final String TAGS = "ro.build.tags";
private static final String TYPE = "ro.build.type";
private static final String VERSION_BASE_OS = "ro.build.version.base_os";
private static final String VERSION_RELEASE = "ro.build.version.release";
private static final String VERSION_SDK = "ro.build.version.sdk";
private static final String VERSION_SECURITY_PATCH = "ro.build.version.security_patch";
private static final String VERSION_INCREMENTAL = "ro.build.version.incremental";
private static final String PREFIX_TAG = "cts:build_";
@Option(name = SKIP_DEVICE_INFO_OPTION,
shortName = 'd',
description = "Whether device info collection should be skipped")
private boolean mSkipDeviceInfo = false;
@Option(
name = "force-collect-device-info",
description =
"Force device info collection. If set to true, "
+ SKIP_DEVICE_INFO_OPTION
+ " is ignored.")
private boolean mForceCollectDeviceInfo = false;
@Option(name= "src-dir", description = "The directory to copy to the results dir")
private String mSrcDir;
@Option(name = "dest-dir", description = "The directory under the result to store the files")
private String mDestDir = DeviceInfo.RESULT_DIR_NAME;
@Deprecated
@Option(name = "temp-dir", description = "The directory containing host-side device info files")
private String mTempDir;
private ITestLogger mLogger;
private File deviceInfoDir = null;
public DeviceInfoCollector() {
mWhen = When.BEFORE;
}
@Override
public void setUp(TestInformation testInfo)
throws TargetSetupError, BuildError, DeviceNotAvailableException {
if (testInfo.getBuildInfo().getFile(DEVICE_INFO_DIR) != null) {
CLog.i("Device info already collected, skipping DeviceInfoCollector.");
return;
}
if (mSkipDeviceInfo && !mForceCollectDeviceInfo) {
return;
}
ITestDevice device = testInfo.getDevice();
IBuildInfo buildInfo = testInfo.getBuildInfo();
DevicePropertyInfo devicePropertyInfo =
new DevicePropertyInfo(
ABI,
ABI2,
ABIS,
ABIS_32,
ABIS_64,
BOARD,
BRAND,
DEVICE,
FINGERPRINT,
VENDOR_FINGERPRINT,
ID,
MANUFACTURER,
MODEL,
PRODUCT,
REFERENCE_FINGERPRINT,
SERIAL,
TAGS,
TYPE,
VERSION_BASE_OS,
VERSION_RELEASE,
VERSION_SDK,
VERSION_SECURITY_PATCH,
VERSION_INCREMENTAL,
BOOTIMAGE_FINGERPRINT);
// add device properties to the result with a prefix tag for each key
for (Entry<String, String> entry :
devicePropertyInfo.getPropertytMapWithPrefix(PREFIX_TAG).entrySet()) {
String property = nullToEmpty(device.getProperty(entry.getValue()));
buildInfo.addBuildAttribute(entry.getKey(), property);
}
run(testInfo);
try {
deviceInfoDir = FileUtil.createTempDir(DeviceInfo.RESULT_DIR_NAME);
if (device.pullDir(mSrcDir, deviceInfoDir)) {
if (!deviceInfoDir.exists() || deviceInfoDir.listFiles() == null) {
CLog.e(
"Pulled device-info, but local dir '%s' is not valid. "
+ "[exists=%s, isDir=%s].",
deviceInfoDir, deviceInfoDir.exists(), deviceInfoDir.isDirectory());
} else {
for (File deviceInfoFile : deviceInfoDir.listFiles()) {
try (FileInputStreamSource source =
new FileInputStreamSource(deviceInfoFile)) {
mLogger.testLog(deviceInfoFile.getName(), LogDataType.TEXT, source);
}
}
// Some host tests depends on this code. E.g. SELinuxHostTestCases reads device
// info files by querying DEVICE_INFO_DIR against buildInfo. Change this with
// caution.
buildInfo.setFile(
DEVICE_INFO_DIR,
deviceInfoDir,
/** version */
"v1");
}
} else {
CLog.e("Failed to pull device-info files from device %s", device.getSerialNumber());
}
} catch (IOException e) {
CLog.e("Failed to pull device-info files from device %s", device.getSerialNumber());
CLog.e(e);
}
}
@Override
public void tearDown(TestInformation testInfo, Throwable e) throws DeviceNotAvailableException {
FileUtil.recursiveDelete(deviceInfoDir);
super.tearDown(testInfo, e);
}
@Override
public void setTestLogger(ITestLogger testLogger) {
mLogger = testLogger;
}
private static String nullToEmpty(String value) {
return value == null ? "" : value;
}
}