1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; 4 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; 5 import static android.os.Build.VERSION_CODES.KITKAT_WATCH; 6 import static android.os.Build.VERSION_CODES.LOLLIPOP; 7 import static android.os.Build.VERSION_CODES.M; 8 import static android.os.Build.VERSION_CODES.N; 9 import static android.os.Build.VERSION_CODES.N_MR1; 10 import static com.google.common.truth.Truth.assertThat; 11 import static org.junit.Assert.fail; 12 import static org.robolectric.Shadows.shadowOf; 13 14 import android.Manifest.permission; 15 import android.app.Application; 16 import android.content.Context; 17 import android.content.pm.PackageInfo; 18 import android.os.Bundle; 19 import android.os.Parcel; 20 import android.os.Process; 21 import android.os.UserHandle; 22 import android.os.UserManager; 23 import androidx.test.core.app.ApplicationProvider; 24 import androidx.test.ext.junit.runners.AndroidJUnit4; 25 import org.junit.Before; 26 import org.junit.Test; 27 import org.junit.runner.RunWith; 28 import org.robolectric.annotation.Config; 29 import org.robolectric.shadows.ShadowUserManager.UserState; 30 31 @RunWith(AndroidJUnit4.class) 32 public class ShadowUserManagerTest { 33 34 private UserManager userManager; 35 private Context context; 36 37 @Before 38 public void setUp() { 39 context = ApplicationProvider.getApplicationContext(); 40 userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 41 } 42 43 @Test 44 @Config(minSdk = LOLLIPOP) 45 public void shouldGetUserProfiles() { 46 assertThat(userManager.getUserProfiles()).contains(Process.myUserHandle()); 47 48 UserHandle anotherProfile = newUserHandle(2); 49 shadowOf(userManager).addUserProfile(anotherProfile); 50 51 assertThat(userManager.getUserProfiles()).containsExactly(Process.myUserHandle(), anotherProfile); 52 } 53 54 @Test 55 @Config(minSdk = JELLY_BEAN_MR2) 56 public void testGetApplicationRestrictions() { 57 String packageName = context.getPackageName(); 58 assertThat(userManager.getApplicationRestrictions(packageName).size()).isEqualTo(0); 59 60 Bundle restrictions = new Bundle(); 61 restrictions.putCharSequence("test_key", "test_value"); 62 shadowOf(userManager).setApplicationRestrictions(packageName, restrictions); 63 64 assertThat( 65 userManager 66 .getApplicationRestrictions(packageName) 67 .getCharSequence("test_key") 68 .toString()) 69 .isEqualTo("test_value"); 70 } 71 72 @Test 73 @Config(minSdk = N) 74 public void isUserUnlocked() { 75 assertThat(userManager.isUserUnlocked()).isTrue(); 76 shadowOf(userManager).setUserUnlocked(false); 77 assertThat(userManager.isUserUnlocked()).isFalse(); 78 } 79 80 @Test 81 @Config(minSdk = LOLLIPOP) 82 public void hasUserRestriction() { 83 assertThat(userManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS)).isFalse(); 84 85 UserHandle userHandle = Process.myUserHandle(); 86 shadowOf(userManager).setUserRestriction(userHandle, UserManager.ENSURE_VERIFY_APPS, true); 87 88 assertThat(userManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS)).isTrue(); 89 } 90 91 @Test 92 @Config(minSdk = JELLY_BEAN_MR2) 93 public void getUserRestrictions() { 94 assertThat(userManager.getUserRestrictions().size()).isEqualTo(0); 95 96 UserHandle userHandle = Process.myUserHandle(); 97 shadowOf(userManager).setUserRestriction(userHandle, UserManager.ENSURE_VERIFY_APPS, true); 98 99 Bundle restrictions = userManager.getUserRestrictions(); 100 assertThat(restrictions.size()).isEqualTo(1); 101 assertThat(restrictions.getBoolean(UserManager.ENSURE_VERIFY_APPS)).isTrue(); 102 103 // make sure that the bundle is not an internal state 104 restrictions.putBoolean("something", true); 105 restrictions = userManager.getUserRestrictions(); 106 assertThat(restrictions.size()).isEqualTo(1); 107 108 shadowOf(userManager).setUserRestriction(newUserHandle(10), UserManager.DISALLOW_CAMERA, true); 109 110 assertThat(userManager.hasUserRestriction(UserManager.DISALLOW_CAMERA)).isFalse(); 111 } 112 113 @Test 114 @Config(minSdk = JELLY_BEAN_MR2) 115 public void clearUserRestrictions() { 116 assertThat(userManager.getUserRestrictions().size()).isEqualTo(0); 117 shadowOf(userManager) 118 .setUserRestriction(Process.myUserHandle(), UserManager.ENSURE_VERIFY_APPS, true); 119 assertThat(userManager.getUserRestrictions().size()).isEqualTo(1); 120 121 shadowOf(userManager).clearUserRestrictions(Process.myUserHandle()); 122 assertThat(userManager.getUserRestrictions().size()).isEqualTo(0); 123 } 124 125 @Test 126 @Config(minSdk = LOLLIPOP) 127 public void isManagedProfile() { 128 assertThat(userManager.isManagedProfile()).isFalse(); 129 shadowOf(userManager).setManagedProfile(true); 130 assertThat(userManager.isManagedProfile()).isTrue(); 131 } 132 133 @Test 134 @Config(minSdk = LOLLIPOP) 135 public void enforcePermissionChecks() throws Exception { 136 shadowOf(userManager).enforcePermissionChecks(true); 137 138 try { 139 userManager.isManagedProfile(); 140 fail("Expected exception"); 141 } catch (SecurityException expected) {} 142 143 Application context = ApplicationProvider.getApplicationContext(); 144 PackageInfo packageInfo = 145 shadowOf(context.getPackageManager()) 146 .getInternalMutablePackageInfo(context.getPackageName()); 147 packageInfo.requestedPermissions = new String[] {permission.MANAGE_USERS}; 148 shadowOf(userManager).setManagedProfile(true); 149 150 assertThat(userManager.isManagedProfile()).isTrue(); 151 } 152 153 @Test 154 @Config(minSdk = JELLY_BEAN_MR1) 155 public void shouldGetSerialNumberForUser() { 156 long serialNumberInvalid = -1L; 157 158 UserHandle userHandle = newUserHandle(10); 159 assertThat(userManager.getSerialNumberForUser(userHandle)).isEqualTo(serialNumberInvalid); 160 161 shadowOf(userManager).addUserProfile(userHandle); 162 163 assertThat(userManager.getSerialNumberForUser(userHandle)).isNotEqualTo(serialNumberInvalid); 164 } 165 166 @Test 167 @Config(minSdk = N_MR1) 168 public void isDemoUser() { 169 // All methods are based on the current user, so no need to pass a UserHandle. 170 assertThat(userManager.isDemoUser()).isFalse(); 171 172 shadowOf(userManager).setIsDemoUser(true); 173 assertThat(userManager.isDemoUser()).isTrue(); 174 175 shadowOf(userManager).setIsDemoUser(false); 176 assertThat(userManager.isDemoUser()).isFalse(); 177 } 178 179 @Test 180 @Config(minSdk = M) 181 public void isSystemUser() { 182 assertThat(userManager.isSystemUser()).isTrue(); 183 184 shadowOf(userManager).setIsSystemUser(false); 185 assertThat(userManager.isSystemUser()).isFalse(); 186 187 shadowOf(userManager).setIsSystemUser(true); 188 assertThat(userManager.isSystemUser()).isTrue(); 189 } 190 191 @Test 192 @Config(minSdk = N) 193 public void isPrimaryUser() { 194 assertThat(userManager.isPrimaryUser()).isTrue(); 195 196 shadowOf(userManager).setIsPrimaryUser(false); 197 assertThat(userManager.isPrimaryUser()).isFalse(); 198 199 shadowOf(userManager).setIsPrimaryUser(true); 200 assertThat(userManager.isPrimaryUser()).isTrue(); 201 } 202 203 @Test 204 @Config(minSdk = JELLY_BEAN_MR2) 205 public void isLinkedUser() { 206 assertThat(userManager.isLinkedUser()).isFalse(); 207 208 shadowOf(userManager).setIsLinkedUser(true); 209 assertThat(userManager.isLinkedUser()).isTrue(); 210 211 shadowOf(userManager).setIsLinkedUser(false); 212 assertThat(userManager.isLinkedUser()).isFalse(); 213 } 214 215 @Test 216 @Config(minSdk = KITKAT_WATCH) 217 public void isGuestUser() { 218 assertThat(userManager.isGuestUser()).isFalse(); 219 220 shadowOf(userManager).setIsGuestUser(true); 221 assertThat(userManager.isGuestUser()).isTrue(); 222 223 shadowOf(userManager).setIsGuestUser(false); 224 assertThat(userManager.isGuestUser()).isFalse(); 225 } 226 227 @Test 228 @Config(minSdk = JELLY_BEAN_MR1) 229 public void isUserRunning() { 230 UserHandle userHandle = newUserHandle(0); 231 232 assertThat(userManager.isUserRunning(userHandle)).isFalse(); 233 234 shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKED); 235 assertThat(userManager.isUserRunning(userHandle)).isTrue(); 236 237 shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_LOCKED); 238 assertThat(userManager.isUserRunning(userHandle)).isTrue(); 239 240 shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKING); 241 assertThat(userManager.isUserRunning(userHandle)).isTrue(); 242 243 shadowOf(userManager).setUserState(userHandle, UserState.STATE_STOPPING); 244 assertThat(userManager.isUserRunning(userHandle)).isFalse(); 245 246 shadowOf(userManager).setUserState(userHandle, UserState.STATE_BOOTING); 247 assertThat(userManager.isUserRunning(userHandle)).isFalse(); 248 249 shadowOf(userManager).setUserState(userHandle, UserState.STATE_SHUTDOWN); 250 assertThat(userManager.isUserRunning(userHandle)).isFalse(); 251 } 252 253 @Test 254 @Config(minSdk = JELLY_BEAN_MR1) 255 public void isUserRunningOrStopping() { 256 UserHandle userHandle = newUserHandle(0); 257 258 assertThat(userManager.isUserRunningOrStopping(userHandle)).isFalse(); 259 260 shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKED); 261 assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue(); 262 263 shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_LOCKED); 264 assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue(); 265 266 shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKING); 267 assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue(); 268 269 shadowOf(userManager).setUserState(userHandle, UserState.STATE_STOPPING); 270 assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue(); 271 272 shadowOf(userManager).setUserState(userHandle, UserState.STATE_BOOTING); 273 assertThat(userManager.isUserRunningOrStopping(userHandle)).isFalse(); 274 275 shadowOf(userManager).setUserState(userHandle, UserState.STATE_SHUTDOWN); 276 assertThat(userManager.isUserRunningOrStopping(userHandle)).isFalse(); 277 } 278 279 @Test 280 @Config(minSdk = JELLY_BEAN_MR1) 281 public void addSecondaryUser() { 282 assertThat(userManager.getUserCount()).isEqualTo(1); 283 shadowOf(userManager).addUser(10, "secondary_user", 0); 284 assertThat(userManager.getUserCount()).isEqualTo(2); 285 } 286 287 @Test 288 @Config(minSdk = JELLY_BEAN_MR1) 289 public void removeSecondaryUser() { 290 shadowOf(userManager).addUser(10, "secondary_user", 0); 291 assertThat(shadowOf(userManager).removeUser(10)).isTrue(); 292 assertThat(userManager.getUserCount()).isEqualTo(1); 293 } 294 295 @Test 296 @Config(minSdk = JELLY_BEAN_MR1) 297 public void switchToSecondaryUser() { 298 shadowOf(userManager).addUser(10, "secondary_user", 0); 299 shadowOf(userManager).switchUser(10); 300 assertThat(UserHandle.myUserId()).isEqualTo(10); 301 } 302 303 @Test 304 @Config(minSdk = N) 305 public void canSwitchUser() { 306 assertThat(shadowOf(userManager).canSwitchUsers()).isFalse(); 307 shadowOf(userManager).setCanSwitchUser(true); 308 assertThat(shadowOf(userManager).canSwitchUsers()).isTrue(); 309 } 310 311 @Test 312 @Config(minSdk = JELLY_BEAN_MR1) 313 public void getUsers() { 314 assertThat(userManager.getUsers()).hasSize(1); 315 shadowOf(userManager).addUser(10, "secondary_user", 0); 316 assertThat(userManager.getUsers()).hasSize(2); 317 } 318 319 @Test 320 @Config(minSdk = JELLY_BEAN_MR1) 321 public void getUserInfo() { 322 shadowOf(userManager).addUser(10, "secondary_user", 0); 323 assertThat(userManager.getUserInfo(10)).isNotNull(); 324 assertThat(userManager.getUserInfo(10).name).isEqualTo("secondary_user"); 325 } 326 327 @Test 328 @Config(minSdk = N) 329 public void switchToUserNotAddedShouldThrowException() { 330 try { 331 shadowOf(userManager).switchUser(10); 332 fail("Switching to the user that was never added should throw UnsupportedOperationException"); 333 } catch (UnsupportedOperationException e) { 334 assertThat(e).hasMessageThat().isEqualTo("Must add user before switching to it"); 335 } 336 } 337 338 // Create user handle from parcel since UserHandle.of() was only added in later APIs. 339 private static UserHandle newUserHandle(int uid) { 340 Parcel userParcel = Parcel.obtain(); 341 userParcel.writeInt(uid); 342 userParcel.setDataPosition(0); 343 return new UserHandle(userParcel); 344 } 345 } 346