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.util.AtomicFile;
35 
36 import androidx.test.InstrumentationRegistry;
37 import androidx.test.runner.AndroidJUnit4;
38 import androidx.test.uiautomator.UiDevice;
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         restrictionsFile = new File(mContext.getCacheDir(), "restrictions.xml");
77         restrictionsFile.delete();
78     }
79 
80     @After
teardown()81     public void teardown() throws Exception {
82         restrictionsFile.delete();
83         if (tempUserId != UserHandle.USER_NULL) {
84             UserManager.get(mContext).removeUser(tempUserId);
85         }
86     }
87 
88     @Test
testWriteReadApplicationRestrictions()89     public void testWriteReadApplicationRestrictions() throws IOException {
90         AtomicFile atomicFile = new AtomicFile(restrictionsFile);
91         Bundle bundle = createBundle();
92         UserManagerService.writeApplicationRestrictionsLAr(bundle, atomicFile);
93         assertThat(atomicFile.getBaseFile().exists()).isTrue();
94         String s = FileUtils.readTextFile(restrictionsFile, 10000, "");
95         System.out.println("restrictionsFile: " + s);
96         bundle = UserManagerService.readApplicationRestrictionsLAr(atomicFile);
97         System.out.println("readApplicationRestrictionsLocked bundle: " + bundle);
98         assertBundle(bundle);
99     }
100 
101     @Test
testAddUserWithAccount()102     public void testAddUserWithAccount() {
103         UserManager um = UserManager.get(mContext);
104         UserInfo user = um.createUser("Test User", 0);
105         assertThat(user).isNotNull();
106         tempUserId = user.id;
107         String accountName = "Test Account";
108         um.setUserAccount(tempUserId, accountName);
109         assertThat(um.getUserAccount(tempUserId)).isEqualTo(accountName);
110     }
111 
112     @Test
testUserSystemPackageWhitelist()113     public void testUserSystemPackageWhitelist() throws Exception {
114         String cmd = "cmd user report-system-user-package-whitelist-problems --critical-only";
115         final String result = runShellCommand(cmd);
116         assertThat(result).isEmpty();
117     }
118 
createBundle()119     private Bundle createBundle() {
120         Bundle result = new Bundle();
121         // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]
122         result.putBoolean("boolean_0", false);
123         result.putBoolean("boolean_1", true);
124         result.putInt("integer", 100);
125         result.putString("empty", "");
126         result.putString("string", "text");
127         result.putStringArray("string[]", STRING_ARRAY);
128 
129         Bundle bundle = new Bundle();
130         bundle.putString("bundle_string", "bundle_string");
131         bundle.putInt("bundle_int", 1);
132         result.putBundle("bundle", bundle);
133 
134         Bundle[] bundleArray = new Bundle[2];
135         bundleArray[0] = new Bundle();
136         bundleArray[0].putString("bundle_array_string", "bundle_array_string");
137         bundleArray[0].putBundle("bundle_array_bundle", bundle);
138         bundleArray[1] = new Bundle();
139         bundleArray[1].putString("bundle_array_string2", "bundle_array_string2");
140         result.putParcelableArray("bundle_array", bundleArray);
141         return result;
142     }
143 
assertBundle(Bundle bundle)144     private void assertBundle(Bundle bundle) {
145         assertThat(bundle.getBoolean("boolean_0")).isFalse();
146         assertThat(bundle.getBoolean("boolean_1")).isTrue();
147         assertThat(bundle.getInt("integer")).isEqualTo(100);
148         assertThat(bundle.getString("empty")).isEqualTo("");
149         assertThat(bundle.getString("string")).isEqualTo("text");
150         assertThat(Arrays.asList(bundle.getStringArray("string[]")))
151                 .isEqualTo(Arrays.asList(STRING_ARRAY));
152         Parcelable[] bundle_array = bundle.getParcelableArray("bundle_array");
153         assertThat(bundle_array.length).isEqualTo(2);
154         Bundle bundle1 = (Bundle) bundle_array[0];
155         assertThat(bundle1.getString("bundle_array_string"))
156                 .isEqualTo("bundle_array_string");
157         assertThat(bundle1.getBundle("bundle_array_bundle")).isNotNull();
158         Bundle bundle2 = (Bundle) bundle_array[1];
159         assertThat(bundle2.getString("bundle_array_string2"))
160                 .isEqualTo("bundle_array_string2");
161         Bundle childBundle = bundle.getBundle("bundle");
162         assertThat(childBundle.getString("bundle_string"))
163                 .isEqualTo("bundle_string");
164         assertThat(childBundle.getInt("bundle_int")).isEqualTo(1);
165     }
166 
167     @Test
assertHasUserRestriction()168     public void assertHasUserRestriction() throws Exception {
169         int userId = ActivityManager.getCurrentUser();
170 
171         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, true, userId);
172         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, userId)).isTrue();
173 
174         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, false, userId);
175         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, userId)).isFalse();
176     }
177 
178     @Test
testHasUserRestriction_NonExistentUserReturnsFalse()179     public void testHasUserRestriction_NonExistentUserReturnsFalse() {
180         int nonExistentUserId = UserHandle.USER_NULL;
181         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, nonExistentUserId))
182                 .isFalse();
183     }
184 
185     @Test
testIsUserInitialized_NonExistentUserReturnsFalse()186     public void testIsUserInitialized_NonExistentUserReturnsFalse() {
187         int nonExistentUserId = UserHandle.USER_NULL;
188         assertThat(mUserManagerService.isUserInitialized(nonExistentUserId))
189                 .isFalse();
190     }
191 
192     @Test
testSetUserRestrictionWithIncorrectID()193     public void testSetUserRestrictionWithIncorrectID() throws Exception {
194         int incorrectId = 1;
195         while (mUserManagerService.userExists(incorrectId)) {
196             incorrectId++;
197         }
198         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, incorrectId))
199                 .isFalse();
200         mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, true, incorrectId);
201         assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, incorrectId))
202                 .isFalse();
203     }
204 
runShellCommand(String cmd)205     private static String runShellCommand(String cmd) throws Exception {
206         return UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
207                 .executeShellCommand(cmd);
208     }
209 }
210