• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.cts.appcloning;
18 
19 import com.android.modules.utils.build.testing.DeviceSdkLevel;
20 import com.android.tradefed.device.DeviceNotAvailableException;
21 import com.android.tradefed.device.ITestDevice;
22 import com.android.tradefed.device.NativeDevice;
23 import com.android.tradefed.log.LogUtil.CLog;
24 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
25 import com.android.tradefed.util.CommandResult;
26 import com.android.tradefed.util.CommandStatus;
27 
28 import java.util.function.BooleanSupplier;
29 
30 
31 abstract class BaseHostTestCase extends BaseHostJUnit4Test {
32     private int mCurrentUserId = NativeDevice.INVALID_USER_ID;
33     private static final String ERROR_MESSAGE_TAG = "[ERROR]";
34     protected ITestDevice mDevice = null;
35 
setDevice()36     protected void setDevice() {
37         mDevice = getDevice();
38     }
39 
executeShellCommand(String cmd, Object... args)40     protected String executeShellCommand(String cmd, Object... args) throws Exception {
41         return mDevice.executeShellCommand(String.format(cmd, args));
42     }
43 
executeShellV2Command(String cmd, Object... args)44     protected CommandResult executeShellV2Command(String cmd, Object... args) throws Exception {
45         return mDevice.executeShellV2Command(String.format(cmd, args));
46     }
47 
isPackageInstalled(String packageName, String userId)48     protected boolean isPackageInstalled(String packageName, String userId) throws Exception {
49         return mDevice.isPackageInstalled(packageName, userId);
50     }
51 
52     // TODO (b/174775905) remove after exposing the check from ITestDevice.
isHeadlessSystemUserMode()53     protected boolean isHeadlessSystemUserMode() throws DeviceNotAvailableException {
54         String result = mDevice
55                 .executeShellCommand("getprop ro.fw.mu.headless_system_user").trim();
56         return "true".equalsIgnoreCase(result);
57     }
58 
supportsMultipleUsers()59     protected boolean supportsMultipleUsers() throws DeviceNotAvailableException {
60         return mDevice.getMaxNumberOfUsersSupported() > 1;
61     }
62 
isAtLeastS()63     protected boolean isAtLeastS() throws DeviceNotAvailableException {
64         DeviceSdkLevel deviceSdkLevel = new DeviceSdkLevel(mDevice);
65         return deviceSdkLevel.isDeviceAtLeastS();
66     }
67 
isAtLeastT()68     protected boolean isAtLeastT() throws DeviceNotAvailableException {
69         DeviceSdkLevel deviceSdkLevel = new DeviceSdkLevel(mDevice);
70         return deviceSdkLevel.isDeviceAtLeastT();
71     }
72 
throwExceptionIfTimeout(long start, long timeoutMillis, Throwable e)73     protected static void throwExceptionIfTimeout(long start, long timeoutMillis, Throwable e) {
74         if (System.currentTimeMillis() - start < timeoutMillis) {
75             try {
76                 Thread.sleep(100);
77             } catch (InterruptedException ignored) {
78                 throw new RuntimeException(e);
79             }
80         } else {
81             throw new RuntimeException(e);
82         }
83     }
84 
eventually(ThrowingRunnable r, long timeoutMillis)85     protected static void eventually(ThrowingRunnable r, long timeoutMillis) {
86         long start = System.currentTimeMillis();
87 
88         while (true) {
89             try {
90                 r.run();
91                 return;
92             } catch (Throwable e) {
93                 throwExceptionIfTimeout(start, timeoutMillis, e);
94             }
95         }
96     }
97 
eventually(ThrowingBooleanSupplier booleanSupplier, long timeoutMillis, String failureMessage)98     protected static void eventually(ThrowingBooleanSupplier booleanSupplier,
99             long timeoutMillis, String failureMessage) {
100         long start = System.currentTimeMillis();
101 
102         while (true) {
103             try {
104                 if (booleanSupplier.getAsBoolean()) {
105                     return;
106                 }
107 
108                 throw new RuntimeException(failureMessage);
109             } catch (Throwable e) {
110                 throwExceptionIfTimeout(start, timeoutMillis, e);
111             }
112         }
113     }
114 
getCurrentUserId()115     protected int getCurrentUserId() throws Exception {
116         setCurrentUserId();
117 
118         return mCurrentUserId;
119     }
120 
isSuccessful(CommandResult result)121     protected boolean isSuccessful(CommandResult result) {
122         if (!CommandStatus.SUCCESS.equals(result.getStatus())) {
123             return false;
124         }
125         String stdout = result.getStdout();
126         if (stdout.contains(ERROR_MESSAGE_TAG)) {
127             return false;
128         }
129         String stderr = result.getStderr();
130         return (stderr == null || stderr.trim().isEmpty());
131     }
132 
setCurrentUserId()133     private void setCurrentUserId() throws Exception {
134         if (mCurrentUserId != NativeDevice.INVALID_USER_ID) return;
135 
136         mCurrentUserId = mDevice.getCurrentUser();
137         CLog.i("Current user: %d");
138     }
139 
140     protected interface ThrowingRunnable {
141         /**
142          * Similar to {@link Runnable#run} but has {@code throws Exception}.
143          */
run()144         void run() throws Exception;
145     }
146 
147     protected interface ThrowingBooleanSupplier {
148         /**
149          * Similar to {@link BooleanSupplier#getAsBoolean} but has {@code throws Exception}.
150          */
getAsBoolean()151         boolean getAsBoolean() throws Exception;
152     }
153 }
154