Loading core/java/android/app/ActivityManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -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); } services/core/java/com/android/server/am/ActivityManagerService.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); Loading Loading @@ -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 { services/core/java/com/android/server/am/ActivityStackSupervisor.java +64 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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) { Loading Loading @@ -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) { Loading services/core/java/com/android/server/am/ActivityStartInterceptor.java +10 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -76,6 +77,7 @@ class ActivityStartInterceptor { ActivityInfo mAInfo; String mResolvedType; TaskRecord mInTask; ActivityOptions mActivityOptions; ActivityStartInterceptor(ActivityManagerService service, ActivityStackSupervisor supervisor) { mService = service; Loading @@ -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; Loading @@ -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. Loading Loading @@ -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); Loading services/core/java/com/android/server/am/ActivityStarter.java +52 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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, Loading Loading @@ -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 Loading
core/java/android/app/ActivityManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -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); }
services/core/java/com/android/server/am/ActivityManagerService.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); Loading Loading @@ -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 {
services/core/java/com/android/server/am/ActivityStackSupervisor.java +64 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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) { Loading Loading @@ -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) { Loading
services/core/java/com/android/server/am/ActivityStartInterceptor.java +10 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -76,6 +77,7 @@ class ActivityStartInterceptor { ActivityInfo mAInfo; String mResolvedType; TaskRecord mInTask; ActivityOptions mActivityOptions; ActivityStartInterceptor(ActivityManagerService service, ActivityStackSupervisor supervisor) { mService = service; Loading @@ -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; Loading @@ -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. Loading Loading @@ -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); Loading
services/core/java/com/android/server/am/ActivityStarter.java +52 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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, Loading Loading @@ -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