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