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

Commit 4dc4d3ed authored by Tony Mak's avatar Tony Mak Committed by android-build-merger
Browse files

Show work challenge in if user in docked stack is locked

am: 853304c0

* commit '853304c0':
  Show work challenge in if user in docked stack is locked

Change-Id: I1a5ff10237639fa2f0c20c756594d1d04c16d07d
parents 01e99d1a 853304c0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -133,4 +133,10 @@ public abstract class ActivityManagerInternal {
     * the focused activity.
     */
    public abstract List<IBinder> getTopVisibleActivities();

    /**
     * Callback for window manager to let activity manager know that docked stack changes its
     * minimized state.
     */
    public abstract void notifyDockedStackMinimizedChanged(boolean minimized);
}
+10 −9
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import android.app.IUiAutomationConnection;
import android.app.IUidObserver;
import android.app.IUserSwitchObserver;
import android.app.Instrumentation;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -11471,20 +11472,13 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        synchronized (this) {
            if (mStackSupervisor.isFocusedUserLockedProfile()) {
            if (mStackSupervisor.isUserLockedProfile(userId)) {
                final long ident = Binder.clearCallingIdentity();
                try {
                    final int currentUserId = mUserController.getCurrentUserIdLocked();
                    // Get the focused task before launching launcher.
                    if (mUserController.isLockScreenDisabled(currentUserId)) {
                        // If there is no device lock, we will show the profile's credential page.
                        // startActivityFromRecentsInner is intercepted and will forward user to it.
                        if (mFocusedActivity != null) {
                            mStackSupervisor.startActivityFromRecentsInner(
                                    mFocusedActivity.task.taskId, null);
                        }
                        mActivityStarter.showConfirmDeviceCredential(userId);
                    } else {
                        // Showing launcher to avoid user entering credential twice.
                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
@@ -21006,6 +21000,13 @@ public final class ActivityManagerService extends ActivityManagerNative
                return mStackSupervisor.getTopVisibleActivities();
            }
        }
        @Override
        public void notifyDockedStackMinimizedChanged(boolean minimized) {
            synchronized (ActivityManagerService.this) {
                mStackSupervisor.setDockedStackMinimized(minimized);
            }
        }
    }
    private final class SleepTokenImpl extends SleepToken {
+64 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.am;

import android.Manifest;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
@@ -29,6 +30,8 @@ import android.app.IActivityContainer;
import android.app.IActivityContainerCallback;
import android.app.IActivityManager;
import android.app.IActivityManager.WaitResult;
import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.app.StatusBarManager;
@@ -37,6 +40,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -166,6 +170,7 @@ import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
@@ -432,6 +437,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
     */
    private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>();

    /**
     * Is dock currently minimized.
     */
    boolean mIsDockMinimized;

    /**
     * Description of a request to start a new activity, which has been held
     * due to app switches being disabled.
@@ -716,10 +726,44 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return null;
    }

    boolean isFocusedUserLockedProfile() {
        final int userId = mFocusedStack.topRunningActivityLocked().userId;
        return userId != UserHandle.myUserId()
                && mService.mUserController.shouldConfirmCredentials(userId);
    /**
     * TODO: Handle freefom mode.
     * @return true when credential confirmation is needed for the user and there is any
     *         activity started by the user in any visible stack.
     */
    boolean isUserLockedProfile(@UserIdInt int userId) {
        if (!mService.mUserController.shouldConfirmCredentials(userId)) {
            return false;
        }
        final ActivityStack fullScreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
        final ActivityStack dockedStack = getStack(DOCKED_STACK_ID);
        final ActivityStack[] activityStacks = new ActivityStack[] {fullScreenStack, dockedStack};
        for (final ActivityStack activityStack : activityStacks) {
            if (activityStack == null) {
                continue;
            }
            if (activityStack.topRunningActivityLocked() == null) {
                continue;
            }
            if (activityStack.getStackVisibilityLocked(null) == STACK_INVISIBLE) {
                continue;
            }
            if (activityStack.isDockedStack() && mIsDockMinimized) {
                continue;
            }
            final TaskRecord topTask = activityStack.topTask();
            if (topTask == null) {
                continue;
            }
            // To handle the case that work app is in the task but just is not the top one.
            for (int i = topTask.mActivities.size() - 1; i >= 0; i--) {
                final ActivityRecord activityRecord = topTask.mActivities.get(i);
                if (activityRecord.userId == userId) {
                    return true;
                }
            }
        }
        return false;
    }

    void setNextTaskIdForUserLocked(int taskId, int userId) {
@@ -3590,6 +3634,22 @@ public final class ActivityStackSupervisor implements DisplayListener {
        }
    }

    void setDockedStackMinimized(boolean minimized) {
        mIsDockMinimized = minimized;
        if (minimized) {
            // Docked stack is not visible, no need to confirm credentials for its top activity.
            return;
        }
        final ActivityStack dockedStack = getStack(StackId.DOCKED_STACK_ID);
        if (dockedStack == null) {
            return;
        }
        final ActivityRecord top = dockedStack.topRunningActivityLocked();
        if (top != null && mService.mUserController.shouldConfirmCredentials(top.userId)) {
            mService.mActivityStarter.showConfirmDeviceCredential(top.userId);
        }
    }

    private final class ActivityStackSupervisorHandler extends Handler {

        public ActivityStackSupervisorHandler(Looper looper) {
+10 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;

import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.IIntentSender;
@@ -76,6 +77,7 @@ class ActivityStartInterceptor {
    ActivityInfo mAInfo;
    String mResolvedType;
    TaskRecord mInTask;
    ActivityOptions mActivityOptions;

    ActivityStartInterceptor(ActivityManagerService service, ActivityStackSupervisor supervisor) {
        mService = service;
@@ -92,7 +94,7 @@ class ActivityStartInterceptor {
    }

    void intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType,
            TaskRecord inTask, int callingPid, int callingUid) {
            TaskRecord inTask, int callingPid, int callingUid, ActivityOptions activityOptions) {
        mUserManager = UserManager.get(mService.mContext);
        mIntent = intent;
        mCallingPid = callingPid;
@@ -101,6 +103,7 @@ class ActivityStartInterceptor {
        mAInfo = aInfo;
        mResolvedType = resolvedType;
        mInTask = inTask;
        mActivityOptions = activityOptions;
        if (interceptSuspendPackageIfNeed()) {
            // Skip the rest of interceptions as the package is suspended by device admin so
            // no user action can undo this.
@@ -177,6 +180,12 @@ class ActivityStartInterceptor {
            mIntent.putExtra(EXTRA_TASK_ID, mInTask.taskId);
            mInTask = null;
        }
        if (mActivityOptions == null) {
            mActivityOptions = ActivityOptions.makeBasic();
        }
        // Showing credential confirmation activity in home task to avoid stopping multi-windowed
        // mode after showing the full-screen credential confirmation activity.
        mActivityOptions.setLaunchTaskId(mSupervisor.getHomeActivity().task.taskId);

        final UserInfo parent = mUserManager.getProfileParent(mUserId);
        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+52 −2
Original line number Diff line number Diff line
@@ -82,9 +82,11 @@ import android.app.AppGlobals;
import android.app.IActivityContainer;
import android.app.IActivityManager;
import android.app.IApplicationThread;
import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.ProfilerInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
@@ -380,7 +382,8 @@ class ActivityStarter {
        }

        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
        mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid);
        mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid,
                options);
        intent = mInterceptor.mIntent;
        rInfo = mInterceptor.mRInfo;
        aInfo = mInterceptor.mAInfo;
@@ -388,7 +391,7 @@ class ActivityStarter {
        inTask = mInterceptor.mInTask;
        callingPid = mInterceptor.mCallingPid;
        callingUid = mInterceptor.mCallingUid;

        options = mInterceptor.mActivityOptions;
        if (abort) {
            if (resultRecord != null) {
                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
@@ -589,6 +592,53 @@ class ActivityStarter {
        }
    }

    void showConfirmDeviceCredential(int userId) {
        // First, retrieve the stack that we want to resume after credential is confirmed.
        ActivityStack targetStack;
        ActivityStack fullscreenStack =
                mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID);
        if (fullscreenStack != null &&
                fullscreenStack.getStackVisibilityLocked(null) != ActivityStack.STACK_INVISIBLE) {
            // Single window case and the case that the docked stack is shown with fullscreen stack.
            targetStack = fullscreenStack;
        } else {
            // The case that the docked stack is shown with recent.
            targetStack = mSupervisor.getStack(HOME_STACK_ID);
        }
        if (targetStack == null) {
            return;
        }
        final KeyguardManager km = (KeyguardManager) mService.mContext
                .getSystemService(Context.KEYGUARD_SERVICE);
        final Intent credential =
                km.createConfirmDeviceCredentialIntent(null, null, userId);
        credential.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
                Intent.FLAG_ACTIVITY_TASK_ON_HOME);
        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchTaskId(mSupervisor.getHomeActivity().task.taskId);
        final ActivityRecord activityRecord = targetStack.topRunningActivityLocked();
        if (activityRecord != null) {
            final IIntentSender target = mService.getIntentSenderLocked(
                    ActivityManager.INTENT_SENDER_ACTIVITY,
                    activityRecord.launchedFromPackage,
                    activityRecord.launchedFromUid,
                    activityRecord.userId,
                    null, null, 0,
                    new Intent[] { activityRecord.intent },
                    new String[] { activityRecord.resolvedType },
                    PendingIntent.FLAG_CANCEL_CURRENT |
                            PendingIntent.FLAG_ONE_SHOT |
                            PendingIntent.FLAG_IMMUTABLE,
                    null);
            credential.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
            // Show confirm credentials activity.
            mService.mContext.startActivityAsUser(credential, options.toBundle(),
                    UserHandle.CURRENT);
        }
    }


    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Loading