1 /*
2  * Copyright 2023 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.microdroid.test.preparer;
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.invoker.TestInformation;
24 import com.android.tradefed.log.LogUtil.CLog;
25 import com.android.tradefed.targetprep.BaseTargetPreparer;
26 import com.android.tradefed.targetprep.BuildError;
27 import com.android.tradefed.targetprep.TargetSetupError;
28 
29 /**
30  * Target preparer that disables microdroid's device policy for future VMs. This requires adb root
31  * for configuring the relevant sysprop.
32  *
33  * <p>Will restore back to original value on tear down. adb will be also unrooted if it wasn't root.
34  */
35 @OptionClass(alias = "disable-microdroid-debug-policy-preparer")
36 public final class DisableMicrodroidDebugPolicyPreparer extends BaseTargetPreparer {
37     private static final String SYSPROP_CUSTOM_DEBUG_POLICY_PATH =
38             "hypervisor.virtualizationmanager.debug_policy.path";
39 
40     private boolean mWasRoot = false;
41     private String mOldDebugPolicyPath;
42 
43     @Option(
44             name = "debug-policy-path",
45             description = "Debug policy path for sysprop " + SYSPROP_CUSTOM_DEBUG_POLICY_PATH)
46     private String mDebugPolicyPath = "/data/local/tmp/virt/stub_debug_policy.dts";
47 
48     @Override
setUp(TestInformation testInfo)49     public void setUp(TestInformation testInfo)
50             throws TargetSetupError, BuildError, DeviceNotAvailableException {
51         ITestDevice device = testInfo.getDevice();
52         mWasRoot = device.isAdbRoot();
53         if (!mWasRoot && !device.enableAdbRoot()) {
54             throw new TargetSetupError("Failed to adb root device", device.getDeviceDescriptor());
55         }
56 
57         try {
58             CLog.d("Bypassing micrdroid debug policy");
59             mOldDebugPolicyPath = device.getProperty(SYSPROP_CUSTOM_DEBUG_POLICY_PATH);
60             boolean result = device.setProperty(SYSPROP_CUSTOM_DEBUG_POLICY_PATH, mDebugPolicyPath);
61             if (!result) {
62                 throw new TargetSetupError(
63                         "Bypassing microdroid debug policy failed", device.getDeviceDescriptor());
64             }
65         } finally {
66             if (!mWasRoot) {
67                 device.disableAdbRoot();
68             }
69         }
70     }
71 
72     @Override
tearDown(TestInformation testInfo, Throwable e)73     public void tearDown(TestInformation testInfo, Throwable e) throws DeviceNotAvailableException {
74         ITestDevice device = testInfo.getDevice();
75         if (e instanceof DeviceNotAvailableException) {
76             CLog.d("device not available: skipping teardown");
77             return;
78         }
79 
80         if (!mWasRoot) {
81             device.enableAdbRoot();
82         }
83 
84         CLog.d("Resetting microdroid debug policy");
85         device.setProperty(
86                 SYSPROP_CUSTOM_DEBUG_POLICY_PATH,
87                 mOldDebugPolicyPath == null ? "" : mOldDebugPolicyPath);
88 
89         if (!mWasRoot) {
90             device.disableAdbRoot();
91         }
92     }
93 }
94