1 /*
2  * Copyright (C) 2017 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 package com.android.tradefed.targetprep;
17 
18 import com.android.tradefed.command.remote.DeviceDescriptor;
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.device.StubDevice;
24 import com.android.tradefed.invoker.TestInformation;
25 import com.android.tradefed.log.LogUtil.CLog;
26 import com.android.tradefed.result.error.DeviceErrorIdentifier;
27 
28 /**
29  * Target preparer that performs "adb root" or "adb unroot" based on option "force-root".
30  *
31  * <p>Will restore back to original root state on tear down.
32  */
33 @OptionClass(alias = "root-preparer")
34 public final class RootTargetPreparer extends BaseTargetPreparer {
35 
36     private boolean mWasRoot = false;
37 
38     @Option(
39             name = "force-root",
40             description =
41                     "Force the preparer to enable adb root if set to true. Otherwise, disable adb "
42                             + "root during setup.")
43     private boolean mForceRoot = true;
44 
45     @Option(
46             name = "throw-on-error",
47             description = "Throws TargetSetupError if adb root/unroot fails")
48     private boolean mThrowOnError = true;
49 
50     @Override
setUp(TestInformation testInfo)51     public void setUp(TestInformation testInfo)
52             throws TargetSetupError, BuildError, DeviceNotAvailableException {
53         ITestDevice device = testInfo.getDevice();
54         // Ignore setUp if it's a stub device, since there is no real device to set up.
55         if (device.getIDevice() instanceof StubDevice) {
56             return;
57         }
58         mWasRoot = device.isAdbRoot();
59         if (!mWasRoot && mForceRoot && !device.enableAdbRoot()) {
60             throwOrLog("Failed to adb root device", device.getDeviceDescriptor());
61         } else if (mWasRoot && !mForceRoot && !device.disableAdbRoot()) {
62             throwOrLog("Failed to adb unroot device", device.getDeviceDescriptor());
63         }
64     }
65 
66     @Override
tearDown(TestInformation testInfo, Throwable e)67     public void tearDown(TestInformation testInfo, Throwable e) throws DeviceNotAvailableException {
68         ITestDevice device = testInfo.getDevice();
69         // Ignore tearDown if it's a stub device, since there is no real device to clean.
70         if (device.getIDevice() instanceof StubDevice) {
71             return;
72         }
73         if (!mWasRoot && mForceRoot) {
74             device.disableAdbRoot();
75         } else if (mWasRoot && !mForceRoot) {
76             device.enableAdbRoot();
77         }
78     }
79 
throwOrLog(String message, DeviceDescriptor deviceDescriptor)80     private void throwOrLog(String message, DeviceDescriptor deviceDescriptor)
81             throws TargetSetupError {
82         if (mThrowOnError) {
83             throw new TargetSetupError(
84                     message, deviceDescriptor, DeviceErrorIdentifier.DEVICE_UNEXPECTED_RESPONSE);
85         } else {
86             CLog.w(message + " " + deviceDescriptor);
87         }
88     }
89 }
90