1 /* 2 * Copyright (C) 2020 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 android.car.hiddenapitest; 17 18 import static com.android.compatibility.common.util.ShellUtils.runShellCommand; 19 import static com.android.compatibility.common.util.SystemUtil.eventually; 20 21 import static com.google.common.truth.Truth.assertWithMessage; 22 23 import android.annotation.NonNull; 24 import android.app.KeyguardManager; 25 import android.app.admin.DevicePolicyManager; 26 import android.car.Car; 27 import android.car.admin.CarDevicePolicyManager; 28 import android.car.admin.CreateUserResult; 29 import android.car.admin.RemoveUserResult; 30 import android.car.admin.StartUserInBackgroundResult; 31 import android.car.admin.StopUserResult; 32 import android.content.Context; 33 import android.content.pm.UserInfo; 34 import android.os.PowerManager; 35 import android.os.UserHandle; 36 import android.os.UserManager; 37 import android.util.Log; 38 39 import androidx.test.filters.FlakyTest; 40 41 import org.junit.Before; 42 import org.junit.Test; 43 44 public final class CarDevicePolicyManagerTest extends CarMultiUserTestBase { 45 46 private static final String TAG = CarDevicePolicyManagerTest.class.getSimpleName(); 47 48 private static final int TIMEOUT_MS = 5_000; // 5 seconds 49 50 private CarDevicePolicyManager mCarDpm; 51 private DevicePolicyManager mDpm; 52 private KeyguardManager mKeyguardManager; 53 private PowerManager mPowerManager; 54 55 @Before setManager()56 public void setManager() throws Exception { 57 mCarDpm = getCarService(Car.CAR_DEVICE_POLICY_SERVICE); 58 Context context = getContext(); 59 mDpm = context.getSystemService(DevicePolicyManager.class); 60 mKeyguardManager = context.getSystemService(KeyguardManager.class); 61 mPowerManager = context.getSystemService(PowerManager.class); 62 } 63 64 @Test testRemoveUser()65 public void testRemoveUser() throws Exception { 66 assertInitialUserIsAdmin(); 67 68 UserInfo user = createUser(); 69 Log.d(TAG, "removing user " + user.toFullString()); 70 RemoveUserResult result = mCarDpm.removeUser(user.getUserHandle()); 71 Log.d(TAG, "result: " + result); 72 73 assertWithMessage("Result of removeUser %s: %s", user.toFullString(), result) 74 .that(result.isSuccess()).isTrue(); 75 } 76 77 @Test testRemoveUser_whenDisallowed()78 public void testRemoveUser_whenDisallowed() throws Exception { 79 try { 80 testRemoveUser(); 81 } finally { 82 mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, false, 83 UserHandle.SYSTEM); 84 } 85 } 86 87 @Test testRemoveUser_currentUserSetEphemeral()88 public void testRemoveUser_currentUserSetEphemeral() throws Exception { 89 assertInitialUserIsAdmin(); 90 int initialUserId = getCurrentUserId(); 91 92 UserInfo user = createUser(); 93 Log.d(TAG, "switching to user " + user.toFullString()); 94 switchUser(user.id); 95 96 Log.d(TAG, "removing user " + user.toFullString()); 97 RemoveUserResult result = mCarDpm.removeUser(user.getUserHandle()); 98 99 assertWithMessage("status of remove user %s (%s)", user.toFullString(), result) 100 .that(result.getStatus()) 101 .isEqualTo(RemoveUserResult.STATUS_SUCCESS_SET_EPHEMERAL); 102 103 assertWithMessage("User %s still exist", user).that(hasUser(user.id)).isTrue(); 104 assertWithMessage("User %s set as ephemeral", user) 105 .that(getUser(user.id).isEphemeral()) 106 .isTrue(); 107 108 // Switch back to the starting user. 109 Log.d(TAG, "switching to user " + initialUserId); 110 switchUser(initialUserId); 111 112 // User is removed once switch is complete 113 Log.d(TAG, "waiting for user to be removed: " + user); 114 waitForUserRemoval(user.id); 115 waitUntil("User " + user + " exists after switch (should be removed)", 116 TIMEOUT_MS, () -> !hasUser(user.id)); 117 } 118 119 @Test testCreateUser()120 public void testCreateUser() throws Exception { 121 assertCanAddUser(); 122 123 String name = "CarDevicePolicyManagerTest.testCreateUser"; 124 int type = CarDevicePolicyManager.USER_TYPE_REGULAR; 125 Log.d(TAG, "creating new user with name " + name + " and type " + type); 126 CreateUserResult result = mCarDpm.createUser(name, type); 127 Log.d(TAG, "result: " + result); 128 UserHandle user = result.getUserHandle(); 129 130 try { 131 assertWithMessage("Created user named %s and type %s: %s", name, type, 132 result).that(result.isSuccess()).isTrue(); 133 assertWithMessage("%s is not an admin user", user).that( 134 mUserManager.isUserAdmin(user.getIdentifier())).isFalse(); 135 assertWithMessage("Create user with name %s", name).that( 136 mUserManager.getUserInfo(user.getIdentifier()).name).isEqualTo(name); 137 } finally { 138 if (user != null) { 139 removeUser(user.getIdentifier()); 140 } 141 } 142 } 143 144 @Test testCreateAdminUser()145 public void testCreateAdminUser() throws Exception { 146 assertCanAddUser(); 147 148 String name = "CarDevicePolicyManagerTest.testCreateUser"; 149 int type = CarDevicePolicyManager.USER_TYPE_ADMIN; 150 Log.d(TAG, "creating new user with name " + name + " and type " + type); 151 CreateUserResult result = mCarDpm.createUser(name, type); 152 Log.d(TAG, "result: " + result); 153 UserHandle user = result.getUserHandle(); 154 155 try { 156 assertWithMessage("Created user named %s and type %s: %s", name, type, 157 result).that(result.isSuccess()).isTrue(); 158 assertWithMessage("%s is an admin user", user).that( 159 mUserManager.isUserAdmin(user.getIdentifier())).isTrue(); 160 assertWithMessage("Create user with name %s", name).that( 161 mUserManager.getUserInfo(user.getIdentifier()).name).isEqualTo(name); 162 163 } finally { 164 if (user != null) { 165 removeUser(user.getIdentifier()); 166 } 167 } 168 } 169 170 @Test testCreateGuestUser()171 public void testCreateGuestUser() throws Exception { 172 assertCanAddUser(); 173 174 String name = "CarDevicePolicyManagerTest.testCreateUser"; 175 int type = CarDevicePolicyManager.USER_TYPE_GUEST; 176 Log.d(TAG, "creating new user with name " + name + " and type " + type); 177 CreateUserResult result = mCarDpm.createUser(name, type); 178 Log.d(TAG, "result: " + result); 179 UserHandle user = result.getUserHandle(); 180 181 try { 182 assertWithMessage("Created user named %s and type %s: %s", name, type, 183 result).that(result.isSuccess()).isTrue(); 184 assertWithMessage("%s is a guest user", user).that( 185 mUserManager.isGuestUser(user.getIdentifier())).isTrue(); 186 assertWithMessage("%s is not an admin user", user).that( 187 mUserManager.isUserAdmin(user.getIdentifier())).isFalse(); 188 assertWithMessage("Create user with name %s", name).that( 189 mUserManager.getUserInfo(user.getIdentifier()).name).isEqualTo(name); 190 191 } finally { 192 if (user != null) { 193 removeUser(user.getIdentifier()); 194 } 195 } 196 } 197 198 @Test testStartUserInBackground()199 public void testStartUserInBackground() throws Exception { 200 assertInitialUserIsAdmin(); 201 202 UserInfo user = createUser(); 203 Log.d(TAG, "starting user in background " + user.toFullString()); 204 StartUserInBackgroundResult result = mCarDpm.startUserInBackground(user.getUserHandle()); 205 Log.d(TAG, "result: " + result); 206 207 assertWithMessage("Result of startUserInBackground %s: %s", user.toFullString(), result) 208 .that(result.isSuccess()).isTrue(); 209 } 210 211 @Test testStopUser()212 public void testStopUser() throws Exception { 213 assertInitialUserIsAdmin(); 214 215 UserInfo user = createUser(); 216 Log.d(TAG, "stopping user in background " + user.toFullString()); 217 StopUserResult result = mCarDpm.stopUser(user.getUserHandle()); 218 Log.d(TAG, "result: " + result); 219 220 assertWithMessage("Result of stopUser %s: %s", user.toFullString(), result) 221 .that(result.isSuccess()).isTrue(); 222 } 223 224 @Test 225 @FlakyTest(bugId = 396445755) testLockNow_safe()226 public void testLockNow_safe() throws Exception { 227 lockNowTest(/* safe= */ true); 228 } 229 230 @Test 231 @FlakyTest(bugId = 396445755) testLockNow_unsafe()232 public void testLockNow_unsafe() throws Exception { 233 lockNowTest(/* safe= */ false); 234 } 235 236 // lockNow() is safe regardless of the UXR state lockNowTest(boolean safe)237 private void lockNowTest(boolean safe) throws Exception { 238 239 assertScreenOn(); 240 241 runSecureDeviceTest(()-> { 242 setDpmSafety(safe); 243 244 try { 245 mDpm.lockNow(); 246 247 assertLockedEventually(); 248 assertScreenOn(); 249 } finally { 250 setDpmSafety(/* safe= */ true); 251 } 252 }); 253 } 254 runSecureDeviceTest(@onNull Runnable test)255 private void runSecureDeviceTest(@NonNull Runnable test) { 256 unlockDevice(); 257 setUserPin(1234); 258 259 try { 260 test.run(); 261 } finally { 262 resetUserPin(1234); 263 unlockDevice(); 264 } 265 } 266 unlockDevice()267 private void unlockDevice() { 268 runShellCommand("input keyevent KEYCODE_POWER"); 269 runShellCommand("input keyevent KEYCODE_WAKEUP"); 270 runShellCommand("wm dismiss-keyguard"); 271 assertUnLockedEventually(); 272 } 273 setUserPin(int pin)274 private void setUserPin(int pin) { 275 runShellCommand("locksettings set-pin %d", pin); 276 } 277 resetUserPin(int oldPin)278 private void resetUserPin(int oldPin) { 279 runShellCommand("locksettings clear --old %d", oldPin); 280 } 281 assertUnlocked()282 private void assertUnlocked() { 283 assertWithMessage("device is locked").that(mKeyguardManager.isDeviceLocked()).isFalse(); 284 assertWithMessage("keyguard is locked").that(mKeyguardManager.isKeyguardLocked()).isFalse(); 285 } 286 assertUnLockedEventually()287 private void assertUnLockedEventually() { 288 eventually(() -> assertUnlocked()); 289 } 290 assertLocked()291 private void assertLocked() { 292 assertDeviceSecure(); 293 assertWithMessage("device is unlocked").that(mKeyguardManager.isDeviceLocked()) 294 .isTrue(); 295 assertWithMessage("keyguard is unlocked").that(mKeyguardManager.isKeyguardLocked()) 296 .isTrue(); 297 } 298 assertLockedEventually()299 private void assertLockedEventually() { 300 eventually(() -> assertLocked()); 301 } 302 assertDeviceSecure()303 private void assertDeviceSecure() { 304 assertWithMessage("device is secure").that(mKeyguardManager.isDeviceSecure()).isTrue(); 305 } 306 assertScreenOn()307 private void assertScreenOn() { 308 assertWithMessage("screen is off").that(mPowerManager.isInteractive()).isTrue(); 309 } 310 setDpmSafety(boolean safe)311 private void setDpmSafety(boolean safe) { 312 requireNonUserBuild(); 313 String state = safe ? "park" : "drive"; 314 runShellCommand("cmd car_service emulate-driving-state %s", state); 315 } 316 } 317