1 /*
2  * Copyright (C) 2015 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.server.pm;
18 
19 import static android.os.UserManager.DISALLOW_USER_SWITCH;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import android.app.ActivityManager;
24 import android.app.PropertyInvalidatedCache;
25 import android.content.Context;
26 import android.content.pm.UserInfo;
27 import android.os.Bundle;
28 import android.os.FileUtils;
29 import android.os.Looper;
30 import android.os.Parcelable;
31 import android.os.UserHandle;
32 import android.os.UserManager;
33 import android.platform.test.annotations.Postsubmit;
34 import android.support.test.uiautomator.UiDevice;
35 import android.util.AtomicFile;
36 
37 import androidx.test.InstrumentationRegistry;
38 import androidx.test.runner.AndroidJUnit4;
39 
40 import com.android.server.LocalServices;
41 
42 import org.junit.After;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 
47 import java.io.File;
48 import java.io.IOException;
49 import java.util.Arrays;
50 
51 /** Test {@link UserManagerService} functionality. */
52 @Postsubmit
53 @RunWith(AndroidJUnit4.class)
54 public class UserManagerServiceTest {
55     private static String[] STRING_ARRAY = new String[] {"<tag", "<![CDATA["};
56     private File restrictionsFile;
57     private int tempUserId = UserHandle.USER_NULL;
58     private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
59     private UserManagerService mUserManagerService;
60 
61     @Before
setup()62     public void setup() throws Exception {
63         // Currently UserManagerService cannot be instantiated twice inside a VM without a cleanup
64         // TODO: Remove once UMS supports proper dependency injection
65         if (Looper.myLooper() == null) {
66             Looper.prepare();
67         }
68         // Disable binder caches in this process.
69         PropertyInvalidatedCache.disableForTestMode();
70 
71         LocalServices.removeServiceForTest(UserManagerInternal.class);
72         mUserManagerService = new UserManagerService(InstrumentationRegistry.getContext());
73         // Put the current user to mUsers. UMS can't find userlist.xml, and fallbackToSingleUserLP.
74         mUserManagerService.putUserInfo(
75                 new UserInfo(ActivityManager.getCurrentUser(), "Current User", 0));
76 
77         restrictionsFile = new File(mContext.getCacheDir(), "restrictions.xml");
78         restrictionsFile.delete();
79     }
80 
81     @After
teardown()82     public void teardown() throws Exception {
83         restrictionsFile.delete();
84         if (tempUserId != UserHandle.USER_NULL) {
85             UserManager.get(mContext).removeUser(tempUserId);
86         }
87     }
88 
89     @Test
testWriteReadApplicationRestrictions()90     public void testWriteReadApplicationRestrictions() throws IOException {
91         AtomicFile atomicFile = new AtomicFile(restrictionsFile);
92         Bundle bundle = createBundle();
93         UserManagerService.writeApplicationRestrictionsLAr(bundle, atomicFile);
94         assertThat(atomicFile.getBaseFile().exists()).isTrue();
95         String s = FileUtils.readTextFile(restrictionsFile, 10000, "");
96         System.out.println("restrictionsFile: " + s);
97         bundle = UserManagerService.readApplicationRestrictionsLAr(atomicFile);
98         System.out.println("readApplicationRestrictionsLocked bundle: " + bundle);
99         assertBundle(bundle);
100     }
101 
102     @Test
testAddUserWithAccount()103     public void testAddUserWithAccount() {
104         UserManager um = UserManager.get(mContext);
105         UserInfo user = um.createUser("Test User", 0);
106         assertThat(user).isNotNull();
107         tempUserId = user.id;
108         String accountName = "Test Account";
109         um.setUserAccount(tempUserId, accountName);
110         assertThat(um.getUserAccount(tempUserId)).isEqualTo(accountName);
111     }
112 
113     @Test
testUserSystemPackageWhitelist()114     public void testUserSystemPackageWhitelist() throws Exception {
115         String cmd = "cmd user report-system-user-package-whitelist-problems --critical-only";
116         final String result = runShellCommand(cmd);
117         assertThat(result).isEmpty();
118     }
119 
createBundle()120     private Bundle createBundle() {
121         Bundle result = new Bundle();
122         // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]
123         result.putBoolean("boolean_0", false);
124         result.putBoolean("boolean_1", true);
125         result.putInt("integer", 100);
126         result.putString("empty", "");
127         result.putString("string", "text");
128         result.putStringArray("string[]", STRING_ARRAY);
129 
130         Bundle bundle = new Bundle();
131         bundle.putString("bundle_string", "bundle_string");
132         bundle.putInt("bundle_int", 1);
133         result.putBundle("bundle", bundle);
134 
135         Bundle[] bundleArray = new Bundle[2];
136         bundleArray[0] = new Bundle();
137         bundleArray[0].putString("bundle_array_string", "bundle_array_string");
138         bundleArray[0].putBundle("bundle_array_bundle", bundle);
139         bundleArray[1] = new Bundle();
140         bundleArray[1].putString("bundle_array_string2", "bundle_array_string2");
141         result.putParcelableArray("bundle_array", bundleArray);
142         return result;
143     }
144 
assertBundle(Bundle bundle)145     private void assertBundle(Bundle bundle) {
146         assertThat(bundle.getBoolean("boolean_0")).isFalse();
147         assertThat(bundle.getBoolean("boolean_1")).isTrue();
148         assertThat(bundle.getInt("integer")).isEqualTo(100);
149         assertThat(bundle.getString("empty")).isEqualTo("");
150         assertThat(bundle.getString("string")).isEqualTo("text");
151         assertThat(Arrays.asList(bundle.getStringArray("string[]")))
152                 .isEqualTo(Arrays.asList(STRING_ARRAY));
153         Parcelable[] bundle_array = bundle.getParcelableArray("bundle_array");
154         assertThat(bundle_array.length).isEqualTo(2);
155         Bundle bundle1 = (Bundle) bundle_array[0];
156         assertThat(bundle1.getString("bundle_array_string"))
157                 .isEqualTo("bundle_array_string");
158         assertThat(bundle1.getBundle("bundle_array_bundle")).isNotNull();
159         Bundle bundle2 = (Bundle) bundle_array[1];
160         assertThat(bundle2.getString("bundle_array_string2"))
161                 .isEqualTo("bundle_array_string2");
162         Bundle childBundle = bundle.getBundle("bundle");
163         assertThat(childBundle.getString("bundle_string"))
164                 .isEqualTo("bundle_string");
165         assertThat(childBundle.getInt("bundle_int")).isEqualTo(1);
166     }
167 
168     @Test
assertHasUserRestriction()169     public void assertHasUserRestriction() throws Exception {
170         int userId = ActivityManager.getCurrentUser();
171 
172         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, true, userId);
173         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, userId)).isTrue();
174 
175         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, false, userId);
176         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, userId)).isFalse();
177     }
178 
179     @Test
testHasUserRestriction_NonExistentUserReturnsFalse()180     public void testHasUserRestriction_NonExistentUserReturnsFalse() {
181         int nonExistentUserId = UserHandle.USER_NULL;
182         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, nonExistentUserId))
183                 .isFalse();
184     }
185 
186     @Test
testSetUserRestrictionWithIncorrectID()187     public void testSetUserRestrictionWithIncorrectID() throws Exception {
188         int incorrectId = 1;
189         while (mUserManagerService.userExists(incorrectId)) {
190             incorrectId++;
191         }
192         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, incorrectId))
193                 .isFalse();
194         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, true, incorrectId);
195         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, incorrectId))
196                 .isFalse();
197     }
198 
199     @Test
assertIsUserSwitcherEnabledOnMultiUserSettings()200     public void assertIsUserSwitcherEnabledOnMultiUserSettings() throws Exception {
201         int userId = ActivityManager.getCurrentUser();
202         resetUserSwitcherEnabled();
203 
204         setUserSwitch(false);
205         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isFalse();
206 
207         setUserSwitch(true);
208         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isTrue();
209     }
210 
211     @Test
assertIsUserSwitcherEnabledOnMaxSupportedUsers()212     public void assertIsUserSwitcherEnabledOnMaxSupportedUsers()  throws Exception {
213         int userId = ActivityManager.getCurrentUser();
214         setMaxSupportedUsers(1);
215 
216         assertThat(UserManager.supportsMultipleUsers()).isFalse();
217         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isFalse();
218 
219         setMaxSupportedUsers(8);
220 
221         assertThat(UserManager.supportsMultipleUsers()).isTrue();
222         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isTrue();
223     }
224 
225     @Test
assertIsUserSwitcherEnabled()226     public void assertIsUserSwitcherEnabled()  throws Exception {
227         int userId = ActivityManager.getCurrentUser();
228         setMaxSupportedUsers(8);
229         assertThat(mUserManagerService.isUserSwitcherEnabled(true, userId)).isTrue();
230 
231         setUserSwitch(false);
232         assertThat(mUserManagerService.isUserSwitcherEnabled(true, userId)).isFalse();
233 
234         setUserSwitch(true);
235         assertThat(mUserManagerService.isUserSwitcherEnabled(false, userId)).isTrue();
236 
237         mUserManagerService.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, userId);
238         assertThat(mUserManagerService.isUserSwitcherEnabled(false, userId)).isFalse();
239 
240         mUserManagerService.setUserRestriction(UserManager.DISALLOW_ADD_USER, false, userId);
241         setMaxSupportedUsers(1);
242         assertThat(mUserManagerService.isUserSwitcherEnabled(true, userId)).isFalse();
243     }
244 
245     @Test
assertIsUserSwitcherEnabledOnShowMultiuserUI()246     public void assertIsUserSwitcherEnabledOnShowMultiuserUI()  throws Exception {
247         int userId = ActivityManager.getCurrentUser();
248         setShowMultiuserUI(false);
249 
250         assertThat(UserManager.supportsMultipleUsers()).isFalse();
251         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isFalse();
252 
253         setShowMultiuserUI(true);
254 
255         assertThat(UserManager.supportsMultipleUsers()).isTrue();
256         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isTrue();
257     }
258 
259     @Test
assertIsUserSwitcherEnabledOnUserRestrictions()260     public void assertIsUserSwitcherEnabledOnUserRestrictions() throws Exception {
261         int userId = ActivityManager.getCurrentUser();
262         resetUserSwitcherEnabled();
263 
264         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, true, userId);
265         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isFalse();
266 
267         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, false, userId);
268         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isTrue();
269     }
270 
271     @Test
assertIsUserSwitcherEnabledOnDemoMode()272     public void assertIsUserSwitcherEnabledOnDemoMode()  throws Exception {
273         int userId = ActivityManager.getCurrentUser();
274         resetUserSwitcherEnabled();
275 
276         setDeviceDemoMode(true);
277         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isFalse();
278 
279         setDeviceDemoMode(false);
280         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isTrue();
281     }
282 
resetUserSwitcherEnabled()283     private void resetUserSwitcherEnabled() throws Exception {
284         int userId = ActivityManager.getCurrentUser();
285         setUserSwitch(true);
286         setShowMultiuserUI(true);
287         setDeviceDemoMode(false);
288         setMaxSupportedUsers(8);
289         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, false, userId);
290     }
291 
setUserSwitch(boolean enabled)292     private void setUserSwitch(boolean enabled) {
293         android.provider.Settings.Global.putInt(mContext.getContentResolver(),
294                 android.provider.Settings.Global.USER_SWITCHER_ENABLED, enabled ? 1 : 0);
295     }
296 
setDeviceDemoMode(boolean enabled)297     private void setDeviceDemoMode(boolean enabled) {
298         android.provider.Settings.Global.putInt(mContext.getContentResolver(),
299                 android.provider.Settings.Global.DEVICE_DEMO_MODE, enabled ? 1 : 0);
300     }
301 
302 
runShellCommand(String cmd)303     private static String runShellCommand(String cmd) throws Exception {
304         return UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
305                 .executeShellCommand(cmd);
306     }
307 
setSystemProperty(String name, String value)308     private static String setSystemProperty(String name, String value) throws Exception {
309         final String oldValue = runShellCommand("getprop " + name);
310         assertThat(runShellCommand("setprop " + name + " " + value))
311                 .isEqualTo("");
312         return oldValue;
313     }
314 
setMaxSupportedUsers(int max)315     private static void setMaxSupportedUsers(int max) throws Exception {
316         setSystemProperty("fw.max_users", String.valueOf(max));
317     }
318 
setShowMultiuserUI(boolean show)319     public static void setShowMultiuserUI(boolean show) throws Exception {
320         setSystemProperty("fw.show_multiuserui", String.valueOf(show));
321     }
322 }
323