Merge "Added Private profile user type"

This commit is contained in:
Saumya Pathak
2023-06-30 13:46:44 +00:00
committed by Android (Google) Code Review
6 changed files with 129 additions and 0 deletions

View File

@@ -1061,6 +1061,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();

View File

@@ -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;

View File

@@ -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
@@ -2857,6 +2864,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()}
@@ -3145,6 +3162,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.
*

View File

@@ -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);
}
}

View File

@@ -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.

View File

@@ -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 {