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

Commit 9de43a35 authored by Jigar Thakkar's avatar Jigar Thakkar
Browse files

Fix device restarts for private profiles with separate challenge

We have a bug for private profiles with separate challenge enabled
wherein the apps become unresponsive after the device restarts. This is
because the profile user is stuck in RUNNING_LOCKED state with the
storage still encrypted, as we haven't yet entered the LSKF
corresponding to the profile. This is already solved for managed
profiles with a separate challenge through the method
ActivityStartInterceptor.interceptWithConfirmCredentialsIfNeeded() and a
special case handling inside ActivityStarter.resolveStartActivity(). The
method inside ActivityStartInterceptor is written in a generic manner
and already allows all profiles that have a separate challenge enabled
to show the confirm credentials screen when the activity is started.
However, the ActivityStarter.resolveStartActivity has managed profile
specific checks that prevent the logic to be re-used by private profiles
causing the bug.

Please note that additionally the resolveStartActivity method is also
used to resolve activity for the scenario when the profile is in quiet
mode. This applies to both profiles with unified/separate challenge
mode. This is further used to launch the popup to unlock/unpause the
profile through
ActivityStarterInterceptor.interceptQuietProfileIfNeeded().

This CL adds the change to extend this check to all profiles, instead
of just the managed profiles to fix this issue. The logic is extended
to all profiles since the quiet mode feature (powered through
UserManagerService.requestQuietMode()/isQuietModeEnabled()) is available
for all profiles today.

Test: Tested by locally flashing the changes on a device with private
space with separate challenge enabled and restarting the devic to check
for the issue.
Bug: 304934183

Change-Id: I86e4193ced3dbdaec369a67c26a0cd2d08921c90
parent 6627a307
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -537,8 +537,8 @@ public abstract class ActivityManagerInternal {

    /**
     * Returns whether the given user requires credential entry at this time. This is used to
     * intercept activity launches for locked work apps due to work challenge being triggered or
     * when the profile user is yet to be unlocked.
     * intercept activity launches for apps corresponding to locked profiles due to separate
     * challenge being triggered or when the profile user is yet to be unlocked.
     */
    public abstract boolean shouldConfirmCredentials(@UserIdInt int userId);

+2 −2
Original line number Diff line number Diff line
@@ -3050,8 +3050,8 @@ class UserController implements Handler.Callback {

    /**
     * Returns whether the given user requires credential entry at this time. This is used to
     * intercept activity launches for locked work apps due to work challenge being triggered
     * or when the profile user is yet to be unlocked.
     * intercept activity launches for apps corresponding to locked profiles due to separate
     * challenge being triggered or when the profile user is yet to be unlocked.
     */
    protected boolean shouldConfirmCredentials(@UserIdInt int userId) {
        if (getStartedUserState(userId) == null) {
+2 −2
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ class ActivityStartInterceptor {
            // before issuing the work challenge.
            return true;
        }
        if (interceptLockedManagedProfileIfNeeded()) {
        if (interceptLockedProfileIfNeeded()) {
            return true;
        }
        if (interceptHomeIfNeeded()) {
@@ -377,7 +377,7 @@ class ActivityStartInterceptor {
        return true;
    }

    private boolean interceptLockedManagedProfileIfNeeded() {
    private boolean interceptLockedProfileIfNeeded() {
        final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(mAInfo, mUserId);
        if (interceptingIntent == null) {
            return false;
+35 −24
Original line number Diff line number Diff line
@@ -556,11 +556,33 @@ class ActivityStarter {
                    computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid),
                    realCallingPid);
            if (resolveInfo == null) {
                // Special case for profiles: If attempting to launch non-crypto aware app in a
                // locked profile or launch an app in a profile that is stopped by quiet mode from
                // an unlocked parent, allow it to resolve as user will be sent via confirm
                // credentials to unlock the profile.
                resolveInfo = resolveIntentForLockedOrStoppedProfiles(supervisor);
            }

            // Collect information about the target of the Intent.
            activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
                    profilerInfo);

            // Carefully collect grants without holding lock
            if (activityInfo != null) {
                intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent(
                        intent, resolvedCallingUid, activityInfo.applicationInfo.packageName,
                        UserHandle.getUserId(activityInfo.applicationInfo.uid));
            }
        }

        /**
         * Resolve intent for locked or stopped profiles if the parent profile is unlocking or
         * unlocked.
         */
        ResolveInfo resolveIntentForLockedOrStoppedProfiles(
                ActivityTaskSupervisor supervisor) {
            final UserInfo userInfo = supervisor.getUserInfo(userId);
                if (userInfo != null && userInfo.isManagedProfile()) {
                    // Special case for managed profiles, if attempting to launch non-cryto aware
                    // app in a locked managed profile from an unlocked parent allow it to resolve
                    // as user will be sent via confirm credentials to unlock the profile.
            if (userInfo != null && userInfo.isProfile()) {
                final UserManager userManager = UserManager.get(supervisor.mService.mContext);
                boolean profileLockedAndParentUnlockingOrUnlocked = false;
                final long token = Binder.clearCallingIdentity();
@@ -573,25 +595,14 @@ class ActivityStarter {
                    Binder.restoreCallingIdentity(token);
                }
                if (profileLockedAndParentUnlockingOrUnlocked) {
                        resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
                    return supervisor.resolveIntent(intent, resolvedType, userId,
                            PackageManager.MATCH_DIRECT_BOOT_AWARE
                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                            computeResolveFilterUid(callingUid, realCallingUid,
                                    filterCallingUid), realCallingPid);
                }
            }
            }

            // Collect information about the target of the Intent.
            activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
                    profilerInfo);

            // Carefully collect grants without holding lock
            if (activityInfo != null) {
                intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent(
                        intent, resolvedCallingUid, activityInfo.applicationInfo.packageName,
                        UserHandle.getUserId(activityInfo.applicationInfo.uid));
            }
            return null;
        }
    }