Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12e9595f authored by Adam Bookatz's avatar Adam Bookatz Committed by Android (Google) Code Review
Browse files

Merge "Introduce Communal Profile user type [minimalist]"

parents 295915cd ab75d2ce
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1049,6 +1049,7 @@ package android.content.pm {
    method public android.os.UserHandle getUserHandle();
    method public boolean isAdmin();
    method public boolean isCloneProfile();
    method public boolean isCommunalProfile();
    method public boolean isDemo();
    method public boolean isEnabled();
    method public boolean isEphemeral();
+4 −0
Original line number Diff line number Diff line
@@ -386,6 +386,10 @@ public class UserInfo implements Parcelable {
        return UserManager.isUserTypeCloneProfile(userType);
    }

    public boolean isCommunalProfile() {
        return UserManager.isUserTypeCommunalProfile(userType);
    }

    @UnsupportedAppUsage
    public boolean isEnabled() {
        return (flags & FLAG_DISABLED) != FLAG_DISABLED;
+45 −2
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public final class UserProperties implements Parcelable {
    private static final String ATTR_CREDENTIAL_SHAREABLE_WITH_PARENT =
            "credentialShareableWithParent";
    private static final String ATTR_DELETE_APP_WITH_PARENT = "deleteAppWithParent";
    private static final String ATTR_ALWAYS_VISIBLE = "alwaysVisible";

    /** Index values of each property (to indicate whether they are present in this object). */
    @IntDef(prefix = "INDEX_", value = {
@@ -76,6 +77,7 @@ public final class UserProperties implements Parcelable {
            INDEX_MEDIA_SHARED_WITH_PARENT,
            INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT,
            INDEX_DELETE_APP_WITH_PARENT,
            INDEX_ALWAYS_VISIBLE,
    })
    @Retention(RetentionPolicy.SOURCE)
    private @interface PropertyIndex {
@@ -91,6 +93,7 @@ public final class UserProperties implements Parcelable {
    private static final int INDEX_MEDIA_SHARED_WITH_PARENT = 8;
    private static final int INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT = 9;
    private static final int INDEX_DELETE_APP_WITH_PARENT = 10;
    private static final int INDEX_ALWAYS_VISIBLE = 11;
    /** A bit set, mapping each PropertyIndex to whether it is present (1) or absent (0). */
    private long mPropertiesPresent = 0;

@@ -316,6 +319,7 @@ public final class UserProperties implements Parcelable {
                    orig.getCrossProfileIntentFilterAccessControl());
            setCrossProfileIntentResolutionStrategy(orig.getCrossProfileIntentResolutionStrategy());
            setDeleteAppWithParent(orig.getDeleteAppWithParent());
            setAlwaysVisible(orig.getAlwaysVisible());
        }
        if (hasManagePermission) {
            // Add items that require MANAGE_USERS or stronger.
@@ -439,6 +443,24 @@ public final class UserProperties implements Parcelable {
    }
    private boolean mDeleteAppWithParent;

    /**
     * Returns whether the user should always
     * be {@link android.os.UserManager#isUserVisible() visible}.
     * The intended usage is for the Communal Profile, which is running and accessible at all times.
     * @hide
     */
    public boolean getAlwaysVisible() {
        if (isPresent(INDEX_ALWAYS_VISIBLE)) return mAlwaysVisible;
        if (mDefaultProperties != null) return mDefaultProperties.mAlwaysVisible;
        throw new SecurityException("You don't have permission to query alwaysVisible");
    }
    /** @hide */
    public void setAlwaysVisible(boolean val) {
        this.mAlwaysVisible = val;
        setPresent(INDEX_ALWAYS_VISIBLE);
    }
    private boolean mAlwaysVisible;

    /**
     * Return whether, and how, select user restrictions or device policies should be inherited
     * from other user.
@@ -632,6 +654,7 @@ public final class UserProperties implements Parcelable {
                + ", mMediaSharedWithParent=" + isMediaSharedWithParent()
                + ", mCredentialShareableWithParent=" + isCredentialShareableWithParent()
                + ", mDeleteAppWithParent=" + getDeleteAppWithParent()
                + ", mAlwaysVisible=" + getAlwaysVisible()
                + "}";
    }

@@ -658,6 +681,7 @@ public final class UserProperties implements Parcelable {
        pw.println(prefix + "    mCredentialShareableWithParent="
                + isCredentialShareableWithParent());
        pw.println(prefix + "    mDeleteAppWithParent=" + getDeleteAppWithParent());
        pw.println(prefix + "    mAlwaysVisible=" + getAlwaysVisible());
    }

    /**
@@ -724,6 +748,9 @@ public final class UserProperties implements Parcelable {
                case ATTR_DELETE_APP_WITH_PARENT:
                    setDeleteAppWithParent(parser.getAttributeBoolean(i));
                    break;
                case ATTR_ALWAYS_VISIBLE:
                    setAlwaysVisible(parser.getAttributeBoolean(i));
                    break;
                default:
                    Slog.w(LOG_TAG, "Skipping unknown property " + attributeName);
            }
@@ -783,6 +810,10 @@ public final class UserProperties implements Parcelable {
            serializer.attributeBoolean(null, ATTR_DELETE_APP_WITH_PARENT,
                    mDeleteAppWithParent);
        }
        if (isPresent(INDEX_ALWAYS_VISIBLE)) {
            serializer.attributeBoolean(null, ATTR_ALWAYS_VISIBLE,
                    mAlwaysVisible);
        }
    }

    // For use only with an object that has already had any permission-lacking fields stripped out.
@@ -800,6 +831,7 @@ public final class UserProperties implements Parcelable {
        dest.writeBoolean(mMediaSharedWithParent);
        dest.writeBoolean(mCredentialShareableWithParent);
        dest.writeBoolean(mDeleteAppWithParent);
        dest.writeBoolean(mAlwaysVisible);
    }

    /**
@@ -821,6 +853,7 @@ public final class UserProperties implements Parcelable {
        mMediaSharedWithParent = source.readBoolean();
        mCredentialShareableWithParent = source.readBoolean();
        mDeleteAppWithParent = source.readBoolean();
        mAlwaysVisible = source.readBoolean();
    }

    @Override
@@ -859,6 +892,7 @@ public final class UserProperties implements Parcelable {
        private boolean mMediaSharedWithParent = false;
        private boolean mCredentialShareableWithParent = false;
        private boolean mDeleteAppWithParent = false;
        private boolean mAlwaysVisible = false;

        public Builder setShowInLauncher(@ShowInLauncher int showInLauncher) {
            mShowInLauncher = showInLauncher;
@@ -926,6 +960,12 @@ public final class UserProperties implements Parcelable {
            return this;
        }

        /** Sets the value for {@link #mAlwaysVisible}*/
        public Builder setAlwaysVisible(boolean alwaysVisible) {
            mAlwaysVisible = alwaysVisible;
            return this;
        }

        /** Builds a UserProperties object with *all* values populated. */
        public UserProperties build() {
            return new UserProperties(
@@ -939,7 +979,8 @@ public final class UserProperties implements Parcelable {
                    mCrossProfileIntentResolutionStrategy,
                    mMediaSharedWithParent,
                    mCredentialShareableWithParent,
                    mDeleteAppWithParent);
                    mDeleteAppWithParent,
                    mAlwaysVisible);
        }
    } // end Builder

@@ -954,7 +995,8 @@ public final class UserProperties implements Parcelable {
            @CrossProfileIntentResolutionStrategy int crossProfileIntentResolutionStrategy,
            boolean mediaSharedWithParent,
            boolean credentialShareableWithParent,
            boolean deleteAppWithParent) {
            boolean deleteAppWithParent,
            boolean alwaysVisible) {
        mDefaultProperties = null;
        setShowInLauncher(showInLauncher);
        setStartWithParent(startWithParent);
@@ -967,5 +1009,6 @@ public final class UserProperties implements Parcelable {
        setMediaSharedWithParent(mediaSharedWithParent);
        setCredentialShareableWithParent(credentialShareableWithParent);
        setDeleteAppWithParent(deleteAppWithParent);
        setAlwaysVisible(alwaysVisible);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ interface IUserManager {
    ParcelFileDescriptor getUserIcon(int userId);
    UserInfo getPrimaryUser();
    int getMainUserId();
    int getCommunalProfileId();
    int getPreviousFullUserToEnterForeground();
    List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated);
    List<UserInfo> getProfiles(int userId, boolean enabledOnly);
+58 −0
Original line number Diff line number Diff line
@@ -165,6 +165,12 @@ public class UserManager {
     */
    public static final String USER_TYPE_PROFILE_TEST = "android.os.usertype.profile.TEST";

    /**
     * User type representing a communal profile, which is shared by all users of the device.
     * @hide
     */
    public static final String USER_TYPE_PROFILE_COMMUNAL = "android.os.usertype.profile.COMMUNAL";

    /**
     * User type representing a {@link UserHandle#USER_SYSTEM system} user that is <b>not</b> a
     * human user.
@@ -2383,6 +2389,16 @@ public class UserManager {
                .getBoolean(com.android.internal.R.bool.config_guestUserAllowEphemeralStateChange);
    }

    /**
     * Returns whether the device is configured to support a Communal Profile.
     * @hide
     */
    public static boolean isCommunalProfileEnabled() {
        return SystemProperties.getBoolean("persist.fw.omnipresent_communal_user",
                Resources.getSystem()
                        .getBoolean(com.android.internal.R.bool.config_omnipresentCommunalUser));
    }

    /**
     * Returns whether multiple admins are enabled on the device
     * @hide
@@ -2690,6 +2706,38 @@ public class UserManager {
            throw re.rethrowFromSystemServer();
        }
    }
    /**
     * Returns the designated "communal profile" of the device, or {@code null} if there is none.
     * @hide
     */
    @RequiresPermission(anyOf = {
            Manifest.permission.MANAGE_USERS,
            Manifest.permission.CREATE_USERS,
            Manifest.permission.QUERY_USERS})
    public @Nullable UserHandle getCommunalProfile() {
        try {
            final int userId = mService.getCommunalProfileId();
            if (userId == UserHandle.USER_NULL) {
                return null;
            }
            return UserHandle.of(userId);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Returns {@code true} if the given user is the designated "communal profile" of the device.
     * @hide
     */
    @RequiresPermission(anyOf = {
            Manifest.permission.MANAGE_USERS,
            Manifest.permission.CREATE_USERS,
            Manifest.permission.QUERY_USERS})
    public boolean isCommunalProfile(@UserIdInt int userId) {
        final UserInfo user = getUserInfo(userId);
        return user != null && user.isCommunalProfile();
    }

    /**
     * Used to check if the context user is an admin user. An admin user may be allowed to
@@ -2791,6 +2839,15 @@ public class UserManager {
        return USER_TYPE_PROFILE_CLONE.equals(userType);
    }

    /**
     * Returns whether the user type is a
     * {@link UserManager#USER_TYPE_PROFILE_COMMUNAL communal profile}.
     * @hide
     */
    public static boolean isUserTypeCommunalProfile(@Nullable String userType) {
        return USER_TYPE_PROFILE_COMMUNAL.equals(userType);
    }

    /**
     * @hide
     * @deprecated Use {@link #isRestrictedProfile()}
@@ -3238,6 +3295,7 @@ public class UserManager {
     *   <li>(Running) profiles of the current foreground user.
     *   <li>Background users assigned to secondary displays (for example, passenger users on
     *   automotive builds, using the display associated with their seats).
     *   <li>A communal profile, if present.
     * </ol>
     *
     * @return whether the user is visible at the moment, as defined above.
Loading