• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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