blob: dd908a6ffb106bcb1c59c0d89bc93e95ac0de19f [file] [log] [blame]
package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N;
import static android.os.Build.VERSION_CODES.N_MR1;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
import android.Manifest.permission;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowUserManager.UserState;
@RunWith(AndroidJUnit4.class)
public class ShadowUserManagerTest {
private UserManager userManager;
private Context context;
private static final int TEST_USER_HANDLE = 0;
private static final int PROFILE_USER_HANDLE = 2;
private static final String PROFILE_USER_NAME = "profile";
private static final int PROFILE_USER_FLAGS = 0;
@Before
public void setUp() {
context = ApplicationProvider.getApplicationContext();
userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
@Test
@Config(minSdk = LOLLIPOP)
public void shouldGetUserProfiles() {
assertThat(userManager.getUserProfiles()).contains(Process.myUserHandle());
UserHandle anotherProfile = newUserHandle(2);
shadowOf(userManager).addUserProfile(anotherProfile);
assertThat(userManager.getUserProfiles()).containsExactly(Process.myUserHandle(), anotherProfile);
}
@Test
@Config(minSdk = JELLY_BEAN_MR2)
public void testGetApplicationRestrictions() {
String packageName = context.getPackageName();
assertThat(userManager.getApplicationRestrictions(packageName).size()).isEqualTo(0);
Bundle restrictions = new Bundle();
restrictions.putCharSequence("test_key", "test_value");
shadowOf(userManager).setApplicationRestrictions(packageName, restrictions);
assertThat(
userManager
.getApplicationRestrictions(packageName)
.getCharSequence("test_key")
.toString())
.isEqualTo("test_value");
}
@Test
@Config(minSdk = N)
public void isUserUnlocked() {
assertThat(userManager.isUserUnlocked()).isTrue();
shadowOf(userManager).setUserUnlocked(false);
assertThat(userManager.isUserUnlocked()).isFalse();
}
@Test
@Config(minSdk = LOLLIPOP)
public void hasUserRestriction() {
assertThat(userManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS)).isFalse();
UserHandle userHandle = Process.myUserHandle();
shadowOf(userManager).setUserRestriction(userHandle, UserManager.ENSURE_VERIFY_APPS, true);
assertThat(userManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS)).isTrue();
}
@Test
@Config(minSdk = JELLY_BEAN_MR2)
public void getUserRestrictions() {
assertThat(userManager.getUserRestrictions().size()).isEqualTo(0);
UserHandle userHandle = Process.myUserHandle();
shadowOf(userManager).setUserRestriction(userHandle, UserManager.ENSURE_VERIFY_APPS, true);
Bundle restrictions = userManager.getUserRestrictions();
assertThat(restrictions.size()).isEqualTo(1);
assertThat(restrictions.getBoolean(UserManager.ENSURE_VERIFY_APPS)).isTrue();
// make sure that the bundle is not an internal state
restrictions.putBoolean("something", true);
restrictions = userManager.getUserRestrictions();
assertThat(restrictions.size()).isEqualTo(1);
shadowOf(userManager).setUserRestriction(newUserHandle(10), UserManager.DISALLOW_CAMERA, true);
assertThat(userManager.hasUserRestriction(UserManager.DISALLOW_CAMERA)).isFalse();
}
@Test
@Config(minSdk = JELLY_BEAN_MR2)
public void clearUserRestrictions() {
assertThat(userManager.getUserRestrictions().size()).isEqualTo(0);
shadowOf(userManager)
.setUserRestriction(Process.myUserHandle(), UserManager.ENSURE_VERIFY_APPS, true);
assertThat(userManager.getUserRestrictions().size()).isEqualTo(1);
shadowOf(userManager).clearUserRestrictions(Process.myUserHandle());
assertThat(userManager.getUserRestrictions().size()).isEqualTo(0);
}
@Test
@Config(minSdk = LOLLIPOP)
public void isManagedProfile() {
assertThat(userManager.isManagedProfile()).isFalse();
shadowOf(userManager).setManagedProfile(true);
assertThat(userManager.isManagedProfile()).isTrue();
}
@Test
@Config(minSdk = LOLLIPOP)
public void enforcePermissionChecks() throws Exception {
shadowOf(userManager).enforcePermissionChecks(true);
try {
userManager.isManagedProfile();
fail("Expected exception");
} catch (SecurityException expected) {}
Application context = ApplicationProvider.getApplicationContext();
PackageInfo packageInfo =
shadowOf(context.getPackageManager())
.getInternalMutablePackageInfo(context.getPackageName());
packageInfo.requestedPermissions = new String[] {permission.MANAGE_USERS};
shadowOf(userManager).setManagedProfile(true);
assertThat(userManager.isManagedProfile()).isTrue();
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void shouldGetSerialNumberForUser() {
long serialNumberInvalid = -1L;
UserHandle userHandle = newUserHandle(10);
assertThat(userManager.getSerialNumberForUser(userHandle)).isEqualTo(serialNumberInvalid);
shadowOf(userManager).addUserProfile(userHandle);
assertThat(userManager.getSerialNumberForUser(userHandle)).isNotEqualTo(serialNumberInvalid);
}
@Test
@Config(minSdk = N_MR1)
public void isDemoUser() {
// All methods are based on the current user, so no need to pass a UserHandle.
assertThat(userManager.isDemoUser()).isFalse();
shadowOf(userManager).setIsDemoUser(true);
assertThat(userManager.isDemoUser()).isTrue();
shadowOf(userManager).setIsDemoUser(false);
assertThat(userManager.isDemoUser()).isFalse();
}
@Test
@Config(minSdk = M)
public void isSystemUser() {
assertThat(userManager.isSystemUser()).isTrue();
shadowOf(userManager).setIsSystemUser(false);
assertThat(userManager.isSystemUser()).isFalse();
shadowOf(userManager).setIsSystemUser(true);
assertThat(userManager.isSystemUser()).isTrue();
}
@Test
@Config(minSdk = N)
public void isPrimaryUser() {
assertThat(userManager.isPrimaryUser()).isTrue();
shadowOf(userManager).setIsPrimaryUser(false);
assertThat(userManager.isPrimaryUser()).isFalse();
shadowOf(userManager).setIsPrimaryUser(true);
assertThat(userManager.isPrimaryUser()).isTrue();
}
@Test
@Config(minSdk = JELLY_BEAN_MR2)
public void isLinkedUser() {
assertThat(userManager.isLinkedUser()).isFalse();
shadowOf(userManager).setIsLinkedUser(true);
assertThat(userManager.isLinkedUser()).isTrue();
shadowOf(userManager).setIsLinkedUser(false);
assertThat(userManager.isLinkedUser()).isFalse();
}
@Test
@Config(minSdk = KITKAT_WATCH)
public void isGuestUser() {
assertThat(userManager.isGuestUser()).isFalse();
shadowOf(userManager).setIsGuestUser(true);
assertThat(userManager.isGuestUser()).isTrue();
shadowOf(userManager).setIsGuestUser(false);
assertThat(userManager.isGuestUser()).isFalse();
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void isUserRunning() {
UserHandle userHandle = newUserHandle(0);
assertThat(userManager.isUserRunning(userHandle)).isFalse();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKED);
assertThat(userManager.isUserRunning(userHandle)).isTrue();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_LOCKED);
assertThat(userManager.isUserRunning(userHandle)).isTrue();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKING);
assertThat(userManager.isUserRunning(userHandle)).isTrue();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_STOPPING);
assertThat(userManager.isUserRunning(userHandle)).isFalse();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_BOOTING);
assertThat(userManager.isUserRunning(userHandle)).isFalse();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_SHUTDOWN);
assertThat(userManager.isUserRunning(userHandle)).isFalse();
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void isUserRunningOrStopping() {
UserHandle userHandle = newUserHandle(0);
assertThat(userManager.isUserRunningOrStopping(userHandle)).isFalse();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKED);
assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_LOCKED);
assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_RUNNING_UNLOCKING);
assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_STOPPING);
assertThat(userManager.isUserRunningOrStopping(userHandle)).isTrue();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_BOOTING);
assertThat(userManager.isUserRunningOrStopping(userHandle)).isFalse();
shadowOf(userManager).setUserState(userHandle, UserState.STATE_SHUTDOWN);
assertThat(userManager.isUserRunningOrStopping(userHandle)).isFalse();
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void addSecondaryUser() {
assertThat(userManager.getUserCount()).isEqualTo(1);
shadowOf(userManager).addUser(10, "secondary_user", 0);
assertThat(userManager.getUserCount()).isEqualTo(2);
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void removeSecondaryUser() {
shadowOf(userManager).addUser(10, "secondary_user", 0);
assertThat(shadowOf(userManager).removeUser(10)).isTrue();
assertThat(userManager.getUserCount()).isEqualTo(1);
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void switchToSecondaryUser() {
shadowOf(userManager).addUser(10, "secondary_user", 0);
shadowOf(userManager).switchUser(10);
assertThat(UserHandle.myUserId()).isEqualTo(10);
}
@Test
@Config(minSdk = N)
public void canSwitchUser() {
assertThat(shadowOf(userManager).canSwitchUsers()).isFalse();
shadowOf(userManager).setCanSwitchUser(true);
assertThat(shadowOf(userManager).canSwitchUsers()).isTrue();
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void getUsers() {
assertThat(userManager.getUsers()).hasSize(1);
shadowOf(userManager).addUser(10, "secondary_user", 0);
assertThat(userManager.getUsers()).hasSize(2);
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void getUserInfo() {
shadowOf(userManager).addUser(10, "secondary_user", 0);
assertThat(userManager.getUserInfo(10)).isNotNull();
assertThat(userManager.getUserInfo(10).name).isEqualTo("secondary_user");
}
@Test
@Config(minSdk = N)
public void switchToUserNotAddedShouldThrowException() {
try {
shadowOf(userManager).switchUser(10);
fail("Switching to the user that was never added should throw UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
assertThat(e).hasMessageThat().isEqualTo("Must add user before switching to it");
}
}
@Test
@Config(minSdk = LOLLIPOP)
public void getProfiles_addedProfile_containsProfile() {
shadowOf(userManager).addProfile(
TEST_USER_HANDLE, PROFILE_USER_HANDLE, PROFILE_USER_NAME, PROFILE_USER_FLAGS);
assertThat(userManager.getProfiles(TEST_USER_HANDLE).get(0).id).isEqualTo(PROFILE_USER_HANDLE);
}
// Create user handle from parcel since UserHandle.of() was only added in later APIs.
private static UserHandle newUserHandle(int uid) {
Parcel userParcel = Parcel.obtain();
userParcel.writeInt(uid);
userParcel.setDataPosition(0);
return new UserHandle(userParcel);
}
}