1 /* 2 * Copyright (C) 2013 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.tradefed.build; 18 19 import com.android.tradefed.config.Option; 20 import com.android.tradefed.config.OptionClass; 21 import com.android.tradefed.device.DeviceNotAvailableException; 22 import com.android.tradefed.device.ITestDevice; 23 import com.android.tradefed.log.LogUtil.CLog; 24 import com.android.tradefed.util.FileUtil; 25 26 import java.io.File; 27 import java.io.IOException; 28 29 /** 30 * A {@link IDeviceBuildProvider} that bootstraps build info from the test device 31 * 32 * <p> 33 * This is typically used for devices with an externally supplied build, i.e. not generated by 34 * in-house build system. Certain information, specifically the branch, is not actually available 35 * from the device, therefore it's artificially generated. 36 * 37 * <p>All build meta data info comes from various ro.* property fields on device 38 * 39 * <p>Currently this build provider generates meta data as follows: 40 * <ul> 41 * <li>branch: 42 * $(ro.product.brand)-$(ro.product.name)-$(ro.product.device)-$(ro.build.version.release), 43 * for example: 44 * <ul> 45 * <li>for Google Play edition Samsung S4 running Android 4.2: samsung-jgedlteue-jgedlte-4.2 46 * <li>for Nexus 7 running Android 4.2: google-nakasi-grouper-4.2 47 * </ul> 48 * <li>build flavor: as provided by {@link ITestDevice#getBuildFlavor()} 49 * <li>build alias: as provided by {@link ITestDevice#getBuildAlias()} 50 * <li>build id: as provided by {@link ITestDevice#getBuildId()} 51 */ 52 @OptionClass(alias = "bootstrap-build") 53 public class BootstrapBuildProvider implements IDeviceBuildProvider { 54 55 @Option(name="build-target", description="build target name to supply.") 56 private String mBuildTargetName = "bootstrapped"; 57 58 @Option(name="branch", description="build branch name to supply.") 59 private String mBranch = null; 60 61 @Option(name="shell-available-timeout", 62 description="Time to wait in seconds for device shell to become available. " + 63 "Default to 300 seconds.") 64 private long mShellAvailableTimeout = 5 * 60; 65 66 @Option(name="tests-dir", description="Path to top directory of expanded tests zip") 67 private File mTestsDir = null; 68 69 private boolean mCreatedTestDir = false; 70 71 @Override 72 public IBuildInfo getBuild() throws BuildRetrievalError { 73 throw new UnsupportedOperationException("Call getBuild(ITestDevice)"); 74 } 75 76 @Override 77 public void buildNotTested(IBuildInfo info) { 78 // no op 79 CLog.i("ignoring buildNotTested call, build = %s ", info.getBuildId()); 80 } 81 82 @Override 83 public void cleanUp(IBuildInfo info) { 84 // If we created the tests dir, we delete it. 85 if (mCreatedTestDir) { 86 FileUtil.recursiveDelete(((IDeviceBuildInfo) info).getTestsDir()); 87 } 88 } 89 90 @Override 91 public IBuildInfo getBuild(ITestDevice device) throws BuildRetrievalError, 92 DeviceNotAvailableException { 93 String buildId = device.getBuildId(); 94 IBuildInfo info = new DeviceBuildInfo(buildId, mBuildTargetName); 95 if (!device.waitForDeviceShell(mShellAvailableTimeout * 1000)) { 96 throw new DeviceNotAvailableException( 97 String.format("Shell did not become available in %d seconds", 98 mShellAvailableTimeout), device.getSerialNumber()); 99 } 100 if (mBranch == null) { 101 mBranch = String.format("%s-%s-%s-%s", 102 device.getProperty("ro.product.brand"), 103 device.getProperty("ro.product.name"), 104 device.getProductVariant(), 105 device.getProperty("ro.build.version.release")); 106 } 107 info.setBuildBranch(mBranch); 108 info.setBuildFlavor(device.getBuildFlavor()); 109 info.addBuildAttribute("build_alias", device.getBuildAlias()); 110 if (mTestsDir != null && mTestsDir.isDirectory()) { 111 info.setFile("testsdir", mTestsDir, buildId); 112 } 113 // Avoid tests dir being null, by creating a temporary dir. 114 if (mTestsDir == null) { 115 mCreatedTestDir = true; 116 try { 117 mTestsDir = FileUtil.createTempDir("bootstrap-test-dir"); 118 } catch (IOException e) { 119 throw new BuildRetrievalError(e.getMessage(), e); 120 } 121 ((IDeviceBuildInfo) info).setTestsDir(mTestsDir, "1"); 122 } 123 return info; 124 } 125 } 126