Added Private profile user type
adb root adb shell pm create-user --profileOf 0 --user-type android.os.usertype.profile.PRIVATE saumyap ^ This will return the user number of the new user (usually, 10). Start that user: am start-user 10 Bug: 287976799 Test: atest com.android.server.pm.UserManagerTest#testPrivateProfile, also created private profile manually via adb Change-Id: Ibcdb14f33fc4d95c9d8d1cc6ffd10767b8352229
This commit is contained in:
@@ -1060,6 +1060,7 @@ package android.content.pm {
|
||||
method public boolean isMain();
|
||||
method public boolean isManagedProfile();
|
||||
method @Deprecated public boolean isPrimary();
|
||||
method public boolean isPrivateProfile();
|
||||
method public boolean isProfile();
|
||||
method public boolean isQuietModeEnabled();
|
||||
method public boolean isRestricted();
|
||||
|
||||
@@ -390,6 +390,10 @@ public class UserInfo implements Parcelable {
|
||||
return UserManager.isUserTypeCommunalProfile(userType);
|
||||
}
|
||||
|
||||
public boolean isPrivateProfile() {
|
||||
return UserManager.isUserTypePrivateProfile(userType);
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public boolean isEnabled() {
|
||||
return (flags & FLAG_DISABLED) != FLAG_DISABLED;
|
||||
|
||||
@@ -159,6 +159,13 @@ public class UserManager {
|
||||
@SystemApi
|
||||
public static final String USER_TYPE_PROFILE_CLONE = "android.os.usertype.profile.CLONE";
|
||||
|
||||
|
||||
/**
|
||||
* User type representing a private profile.
|
||||
* @hide
|
||||
*/
|
||||
public static final String USER_TYPE_PROFILE_PRIVATE = "android.os.usertype.profile.PRIVATE";
|
||||
|
||||
/**
|
||||
* User type representing a generic profile for testing purposes. Only on debuggable builds.
|
||||
* @hide
|
||||
@@ -2848,6 +2855,16 @@ public class UserManager {
|
||||
return USER_TYPE_PROFILE_COMMUNAL.equals(userType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user type is a
|
||||
* {@link UserManager#USER_TYPE_PROFILE_PRIVATE private profile}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isUserTypePrivateProfile(@Nullable String userType) {
|
||||
return USER_TYPE_PROFILE_PRIVATE.equals(userType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @deprecated Use {@link #isRestrictedProfile()}
|
||||
@@ -3136,6 +3153,24 @@ public class UserManager {
|
||||
return isUserTypeCloneProfile(getProfileType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the context user is a private profile.
|
||||
*
|
||||
* @return whether the context user is a private profile.
|
||||
*
|
||||
* @see android.os.UserManager#USER_TYPE_PROFILE_PRIVATE
|
||||
* @hide
|
||||
*/
|
||||
@UserHandleAware(
|
||||
requiresAnyOfPermissionsIfNotCallerProfileGroup = {
|
||||
android.Manifest.permission.MANAGE_USERS,
|
||||
android.Manifest.permission.QUERY_USERS,
|
||||
android.Manifest.permission.INTERACT_ACROSS_USERS})
|
||||
@SuppressAutoDoc
|
||||
public boolean isPrivateProfile() {
|
||||
return isUserTypePrivateProfile(getProfileType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the context user is an ephemeral user.
|
||||
*
|
||||
|
||||
@@ -633,4 +633,12 @@ public final class UserTypeDetails {
|
||||
public boolean isCommunalProfile() {
|
||||
return UserManager.isUserTypeCommunalProfile(mName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user type is a private profile
|
||||
* (i.e. {@link UserManager#USER_TYPE_PROFILE_PRIVATE}).
|
||||
*/
|
||||
public boolean isPrivateProfile() {
|
||||
return UserManager.isUserTypePrivateProfile(mName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
|
||||
import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
|
||||
import static android.os.UserManager.USER_TYPE_PROFILE_COMMUNAL;
|
||||
import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
|
||||
import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE;
|
||||
import static android.os.UserManager.USER_TYPE_PROFILE_TEST;
|
||||
import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
|
||||
|
||||
@@ -108,6 +109,7 @@ public final class UserTypeFactory {
|
||||
builders.put(USER_TYPE_SYSTEM_HEADLESS, getDefaultTypeSystemHeadless());
|
||||
builders.put(USER_TYPE_PROFILE_CLONE, getDefaultTypeProfileClone());
|
||||
builders.put(USER_TYPE_PROFILE_COMMUNAL, getDefaultTypeProfileCommunal());
|
||||
builders.put(USER_TYPE_PROFILE_PRIVATE, getDefaultTypeProfilePrivate());
|
||||
if (Build.IS_DEBUGGABLE) {
|
||||
builders.put(USER_TYPE_PROFILE_TEST, getDefaultTypeProfileTest());
|
||||
}
|
||||
@@ -263,6 +265,39 @@ public final class UserTypeFactory {
|
||||
.setAlwaysVisible(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Builder for the default {@link UserManager#USER_TYPE_PROFILE_PRIVATE}
|
||||
* configuration.
|
||||
*/
|
||||
private static UserTypeDetails.Builder getDefaultTypeProfilePrivate() {
|
||||
return new UserTypeDetails.Builder()
|
||||
.setName(USER_TYPE_PROFILE_PRIVATE)
|
||||
.setBaseType(FLAG_PROFILE)
|
||||
.setMaxAllowedPerParent(1)
|
||||
.setLabel(0)
|
||||
.setIconBadge(com.android.internal.R.drawable.ic_test_icon_badge_experiment)
|
||||
.setBadgePlain(com.android.internal.R.drawable.ic_test_badge_experiment)
|
||||
.setBadgeNoBackground(com.android.internal.R.drawable.ic_test_badge_no_background)
|
||||
.setStatusBarIcon(com.android.internal.R.drawable.ic_test_badge_experiment)
|
||||
.setBadgeLabels(
|
||||
com.android.internal.R.string.managed_profile_label_badge,
|
||||
com.android.internal.R.string.managed_profile_label_badge_2,
|
||||
com.android.internal.R.string.managed_profile_label_badge_3)
|
||||
.setBadgeColors(
|
||||
com.android.internal.R.color.profile_badge_2)
|
||||
.setDarkThemeBadgeColors(
|
||||
com.android.internal.R.color.profile_badge_2_dark)
|
||||
.setDefaultRestrictions(getDefaultProfileRestrictions())
|
||||
.setDefaultSecureSettings(getDefaultNonManagedProfileSecureSettings())
|
||||
.setDefaultUserProperties(new UserProperties.Builder()
|
||||
.setStartWithParent(true)
|
||||
.setCredentialShareableWithParent(false)
|
||||
.setMediaSharedWithParent(false)
|
||||
.setShowInLauncher(UserProperties.SHOW_IN_LAUNCHER_SEPARATE)
|
||||
.setCrossProfileIntentFilterAccessControl(
|
||||
UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Builder for the default {@link UserManager#USER_TYPE_FULL_SECONDARY}
|
||||
* configuration.
|
||||
|
||||
@@ -265,6 +265,52 @@ public final class UserManagerTest {
|
||||
assertWithMessage("Communal profile not visible").that(umCommunal.isUserVisible()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateProfile() throws Exception {
|
||||
UserHandle mainUser = mUserManager.getMainUser();
|
||||
assumeTrue("Main user is null", mainUser != null);
|
||||
// Get the default properties for private profile user type.
|
||||
final UserTypeDetails userTypeDetails =
|
||||
UserTypeFactory.getUserTypes().get(UserManager.USER_TYPE_PROFILE_PRIVATE);
|
||||
assertWithMessage("No %s type on device", UserManager.USER_TYPE_PROFILE_PRIVATE)
|
||||
.that(userTypeDetails).isNotNull();
|
||||
final UserProperties typeProps = userTypeDetails.getDefaultUserPropertiesReference();
|
||||
|
||||
// Test that only one private profile can be created
|
||||
final int mainUserId = mainUser.getIdentifier();
|
||||
UserInfo userInfo = createProfileForUser("Private profile1",
|
||||
UserManager.USER_TYPE_PROFILE_PRIVATE,
|
||||
mainUserId);
|
||||
assertThat(userInfo).isNotNull();
|
||||
UserInfo userInfo2 = createProfileForUser("Private profile2",
|
||||
UserManager.USER_TYPE_PROFILE_PRIVATE,
|
||||
mainUserId);
|
||||
assertThat(userInfo2).isNull();
|
||||
|
||||
// Check that the new private profile has the expected properties (relative to the defaults)
|
||||
// provided that the test caller has the necessary permissions.
|
||||
UserProperties privateProfileUserProperties =
|
||||
mUserManager.getUserProperties(UserHandle.of(userInfo.id));
|
||||
assertThat(typeProps.getShowInLauncher())
|
||||
.isEqualTo(privateProfileUserProperties.getShowInLauncher());
|
||||
assertThrows(SecurityException.class, privateProfileUserProperties::getStartWithParent);
|
||||
assertThrows(SecurityException.class,
|
||||
privateProfileUserProperties::getCrossProfileIntentFilterAccessControl);
|
||||
assertThat(typeProps.isMediaSharedWithParent())
|
||||
.isEqualTo(privateProfileUserProperties.isMediaSharedWithParent());
|
||||
assertThat(typeProps.isCredentialShareableWithParent())
|
||||
.isEqualTo(privateProfileUserProperties.isCredentialShareableWithParent());
|
||||
assertThrows(SecurityException.class, privateProfileUserProperties::getDeleteAppWithParent);
|
||||
|
||||
// Verify private profile parent
|
||||
assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
|
||||
UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
|
||||
assertThat(parentProfileInfo).isNotNull();
|
||||
assertThat(mainUserId).isEqualTo(parentProfileInfo.id);
|
||||
removeUser(userInfo.id);
|
||||
assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@Test
|
||||
public void testAdd2Users() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user