1 /* 2 * Copyright (C) 2011 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 18 package com.android.tradefed.targetprep; 19 20 import com.android.tradefed.build.IDeviceBuildInfo; 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.CommandStatus; 25 26 import java.io.File; 27 import java.util.ArrayList; 28 import java.util.Arrays; 29 import java.util.Collection; 30 import java.util.List; 31 32 /** 33 * A {@link IDeviceFlasher} that relies on the system updater to install a 34 * system image bundled in a OTA update package. In particular, this 35 * implementation doesn't rely on fastboot. 36 */ 37 public class SystemUpdaterDeviceFlasher implements IDeviceFlasher { 38 39 private ITestsZipInstaller mTestsZipInstaller = new DefaultTestsZipInstaller(); 40 41 private UserDataFlashOption mFlashOption = UserDataFlashOption.TESTS_ZIP; 42 43 private boolean mForceSystemFlash; 44 45 private Collection<String> mDataWipeSkipList = new ArrayList<String>(); 46 47 /** 48 * {@inheritDoc} 49 */ 50 @Override setFlashingResourcesRetriever(IFlashingResourcesRetriever retriever)51 public void setFlashingResourcesRetriever(IFlashingResourcesRetriever retriever) { 52 // ignore 53 } 54 55 /** 56 * {@inheritDoc} 57 * <p> 58 * This implementation assumes the device image file returned by 59 * {@link IDeviceBuildInfo#getDeviceImageFile()} is an OTA update zip. It's 60 * not safe to use this updater in a context where this interpretation 61 * doesn't hold. 62 * 63 * @throws DeviceNotAvailableException 64 * @throws TargetSetupError 65 */ 66 @Override flash(ITestDevice device, IDeviceBuildInfo deviceBuild)67 public void flash(ITestDevice device, IDeviceBuildInfo deviceBuild) 68 throws DeviceNotAvailableException, TargetSetupError { 69 CLog.i("Flashing device %s with build %s", device.getSerialNumber(), 70 deviceBuild.getDeviceBuildId()); 71 72 // TODO could add a check for bootloader versions and install 73 // the one produced by the build server @ the current build if the one 74 // on the target is different 75 76 if (installUpdate(device, deviceBuild)) { 77 if (mFlashOption == UserDataFlashOption.TESTS_ZIP) { 78 mTestsZipInstaller.pushTestsZipOntoData(device, deviceBuild); 79 CLog.d("rebooting after installing tests"); 80 device.reboot(); 81 } 82 } 83 } 84 installUpdate(ITestDevice device, IDeviceBuildInfo deviceBuild)85 private boolean installUpdate(ITestDevice device, IDeviceBuildInfo deviceBuild) 86 throws DeviceNotAvailableException, TargetSetupError { 87 // FIXME same high level logic as in 88 // FastbootDeviceFlasher#checkAndFlashSystem, could be de-duped 89 if (!mForceSystemFlash && deviceBuild.getDeviceBuildId().equals(device.getBuildId())) { 90 CLog.i("System is already version %s, skipping install" , device.getBuildId()); 91 // reboot 92 return false; 93 } 94 CLog.i("Flashing system %s on device %s", deviceBuild.getDeviceBuildId(), 95 device.getSerialNumber()); 96 File otaPackageFile = deviceBuild.getOtaPackageFile(); 97 if (otaPackageFile == null) { 98 throw new TargetSetupError("No OTA package file present for build " 99 + deviceBuild.getDeviceBuildId(), device.getDeviceDescriptor()); 100 } 101 if (!device.pushFile(otaPackageFile, "/cache/update.zip")) { 102 throw new TargetSetupError("Could not push OTA file to the target.", 103 device.getDeviceDescriptor()); 104 } 105 String commands = 106 "echo --update_package > /cache/recovery/command &&" + 107 // FIXME would need to be "CACHE:" instead of "/cache/" for 108 // eclair devices 109 "echo /cache/update.zip >> /cache/recovery/command"; 110 device.executeShellCommand(commands); 111 device.rebootIntoRecovery(); 112 device.waitForDeviceAvailable(); 113 return true; 114 } 115 116 // friendly visibility for mock during testing setTestsZipInstaller(ITestsZipInstaller testsZipInstaller)117 void setTestsZipInstaller(ITestsZipInstaller testsZipInstaller) { 118 mTestsZipInstaller = testsZipInstaller; 119 } 120 121 /** 122 * {@inheritDoc} 123 */ 124 @Override overrideDeviceOptions(ITestDevice device)125 public void overrideDeviceOptions(ITestDevice device) { 126 // ignore 127 } 128 129 /** 130 * {@inheritDoc} 131 * <p> 132 * This implementation only supports {@link IDeviceFlasher.UserDataFlashOption#TESTS_ZIP} 133 * and {@link IDeviceFlasher.UserDataFlashOption#RETAIN} as a valid options 134 */ 135 @Override setUserDataFlashOption(UserDataFlashOption flashOption)136 public void setUserDataFlashOption(UserDataFlashOption flashOption) { 137 List<UserDataFlashOption> supported = Arrays.asList( 138 UserDataFlashOption.TESTS_ZIP, UserDataFlashOption.RETAIN); 139 if (!supported.contains(flashOption)) { 140 throw new IllegalArgumentException(flashOption 141 + " not supported. This implementation only supports flashing " 142 + supported.toString()); 143 } 144 mFlashOption = flashOption; 145 } 146 147 /** 148 * {@inheritDoc} 149 */ 150 @Override getUserDataFlashOption()151 public UserDataFlashOption getUserDataFlashOption() { 152 return mFlashOption; 153 } 154 155 /** 156 * {@inheritDoc} 157 */ 158 @Override setForceSystemFlash(boolean forceSystemFlash)159 public void setForceSystemFlash(boolean forceSystemFlash) { 160 mForceSystemFlash = forceSystemFlash; 161 } 162 163 /** 164 * {@inheritDoc} 165 */ 166 @Override setDataWipeSkipList(Collection<String> dataWipeSkipList)167 public void setDataWipeSkipList(Collection<String> dataWipeSkipList) { 168 if (dataWipeSkipList != null) { 169 mDataWipeSkipList = dataWipeSkipList; 170 } 171 if (mTestsZipInstaller != null) { 172 mTestsZipInstaller.setDataWipeSkipList(mDataWipeSkipList); 173 } 174 } 175 176 /** 177 * {@inheritDoc} 178 */ 179 @Override setWipeTimeout(long timeout)180 public void setWipeTimeout(long timeout) { 181 // ignore 182 } 183 184 /** 185 * {@inheritDoc} 186 */ 187 @Override getSystemFlashingStatus()188 public CommandStatus getSystemFlashingStatus() { 189 // system partition flashing status is not applicable to this flasher 190 return null; 191 } 192 } 193