Loading core/java/android/content/Intent.java +9 −0 Original line number Diff line number Diff line Loading @@ -3603,6 +3603,15 @@ public class Intent implements Parcelable, Cloneable { */ public static final String EXTRA_USER_ID = "android.intent.extra.USER_ID"; /** * An int representing the task id to be retrieved. This is used when a launch from recents is * intercepted by another action such as credentials confirmation to remember which task should * be resumed when complete. * * @hide */ public static final String EXTRA_TASK_ID = "android.intent.extra.TASK_ID"; /** * An Intent[] describing additional, alternate choices you would like shown with * {@link #ACTION_CHOOSER}. Loading services/core/java/com/android/server/am/ActivityManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -4407,7 +4407,6 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException("startActivityFromRecentsInner: Task " + taskId + " can't be launch in the home stack."); } task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId); if (task == null) { throw new IllegalArgumentException( Loading @@ -4426,7 +4425,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (task.getRootActivity() != null) { // If the user must confirm credentials (e.g. when first launching a work app and the // Work Challenge is present) let startActivityInPackage handle the intercepting. if (!mUserController.shouldConfirmCredentials(task.userId) && task.getRootActivity() != null) { moveTaskToFrontLocked(task.taskId, 0, bOptions); return ActivityManager.START_TASK_TO_FRONT; } Loading services/core/java/com/android/server/am/ActivityStarter.java +55 −32 Original line number Diff line number Diff line package com.android.server.am; import static android.app.Activity.RESULT_CANCELED; import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY; import static android.app.ActivityManager.START_CLASS_NOT_FOUND; import static android.app.ActivityManager.START_DELIVERED_TO_TOP; import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED; Loading @@ -15,8 +16,16 @@ import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.PendingIntent.FLAG_CANCEL_CURRENT; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.content.Context.KEYGUARD_SERVICE; import static android.content.Intent.EXTRA_INTENT; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.EXTRA_TASK_ID; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_TO_SIDE; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; Loading Loading @@ -66,7 +75,6 @@ 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 @@ -91,7 +99,6 @@ import android.view.Display; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.internal.widget.LockPatternUtils; import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch; import com.android.server.wm.WindowManagerService; Loading Loading @@ -358,38 +365,26 @@ class ActivityStarter { } } UserInfo user = mSupervisor.getUserInfo(userId); KeyguardManager km = (KeyguardManager) mService.mContext .getSystemService(Context.KEYGUARD_SERVICE); if (user.isManagedProfile() && LockPatternUtils.isSeparateWorkChallengeEnabled() && km.isDeviceLocked(userId)) { IIntentSender target = mService.getIntentSenderLocked( ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent }, new String[]{ resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE, null); final int flags = intent.getFlags(); final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, user.id); if (newIntent != null) { intent = newIntent; intent.setFlags(flags | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName); intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target)); resolvedType = null; callingUid = realCallingUid; final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(intent, resolvedType, aInfo, callingPackage, userId); if (interceptingIntent != null) { intent = interceptingIntent; callingPid = realCallingPid; callingUid = realCallingUid; resolvedType = null; // If we are intercepting and there was a task, convert it into an extra for the // ConfirmCredentials intent and unassign it, as otherwise the task will move to // front even if ConfirmCredentials is cancelled. if (inTask != null) { intent.putExtra(EXTRA_TASK_ID, inTask.taskId); inTask = null; } UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId); final UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId); rInfo = mSupervisor.resolveIntent(intent, resolvedType, parent.id); aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/); } } if (abort) { if (resultRecord != null) { Loading Loading @@ -538,6 +533,34 @@ class ActivityStarter { return err; } /** * Creates an intent to intercept the current activity start with Confirm Credentials if needed. * * @return The intercepting intent if needed. */ private Intent interceptWithConfirmCredentialsIfNeeded(Intent intent, String resolvedType, ActivityInfo aInfo, String callingPackage, int userId) { if (!mService.mUserController.shouldConfirmCredentials(userId)) { return null; } final IIntentSender target = mService.getIntentSenderLocked( INTENT_SENDER_ACTIVITY, callingPackage, Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent }, new String[]{ resolvedType }, FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE, null); final int flags = intent.getFlags(); final KeyguardManager km = (KeyguardManager) mService.mContext .getSystemService(KEYGUARD_SERVICE); final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId); if (newIntent == null) { return null; } newIntent.setFlags(flags | FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); newIntent.putExtra(EXTRA_PACKAGE_NAME, aInfo.packageName); newIntent.putExtra(EXTRA_INTENT, new IntentSender(target)); return newIntent; } void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) { mSupervisor.moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason); startActivityLocked(null /*caller*/, intent, null /*ephemeralIntent*/, Loading services/core/java/com/android/server/am/UserController.java +17 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM; import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP; import static android.app.ActivityManager.USER_OP_IS_CURRENT; import static android.app.ActivityManager.USER_OP_SUCCESS; import static android.content.Context.KEYGUARD_SERVICE; import static android.os.Process.SYSTEM_UID; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; Loading @@ -43,6 +44,7 @@ import android.app.AppOpsManager; import android.app.Dialog; import android.app.IStopUserCallback; import android.app.IUserSwitchObserver; import android.app.KeyguardManager; import android.content.Context; import android.content.IIntentReceiver; import android.content.Intent; Loading Loading @@ -73,6 +75,7 @@ import android.util.SparseIntArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import com.android.internal.widget.LockPatternUtils; import com.android.server.pm.UserManagerService; import java.io.PrintWriter; Loading Loading @@ -1286,6 +1289,20 @@ final class UserController { return mCurrentProfileIds; } /** * Returns whether the given user requires credential entry at this time. This is used to * intercept activity launches for work apps when the Work Challenge is present. */ boolean shouldConfirmCredentials(int userId) { final UserInfo user = getUserInfo(userId); if (!user.isManagedProfile() || !LockPatternUtils.isSeparateWorkChallengeEnabled()) { return false; } final KeyguardManager km = (KeyguardManager) mService.mContext .getSystemService(KEYGUARD_SERVICE); return km.isDeviceLocked(user.id); } void dump(PrintWriter pw, boolean dumpAll) { pw.println(" mStartedUsers:"); for (int i = 0; i < mStartedUsers.size(); i++) { Loading Loading
core/java/android/content/Intent.java +9 −0 Original line number Diff line number Diff line Loading @@ -3603,6 +3603,15 @@ public class Intent implements Parcelable, Cloneable { */ public static final String EXTRA_USER_ID = "android.intent.extra.USER_ID"; /** * An int representing the task id to be retrieved. This is used when a launch from recents is * intercepted by another action such as credentials confirmation to remember which task should * be resumed when complete. * * @hide */ public static final String EXTRA_TASK_ID = "android.intent.extra.TASK_ID"; /** * An Intent[] describing additional, alternate choices you would like shown with * {@link #ACTION_CHOOSER}. Loading
services/core/java/com/android/server/am/ActivityManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -4407,7 +4407,6 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException("startActivityFromRecentsInner: Task " + taskId + " can't be launch in the home stack."); } task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId); if (task == null) { throw new IllegalArgumentException( Loading @@ -4426,7 +4425,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (task.getRootActivity() != null) { // If the user must confirm credentials (e.g. when first launching a work app and the // Work Challenge is present) let startActivityInPackage handle the intercepting. if (!mUserController.shouldConfirmCredentials(task.userId) && task.getRootActivity() != null) { moveTaskToFrontLocked(task.taskId, 0, bOptions); return ActivityManager.START_TASK_TO_FRONT; } Loading
services/core/java/com/android/server/am/ActivityStarter.java +55 −32 Original line number Diff line number Diff line package com.android.server.am; import static android.app.Activity.RESULT_CANCELED; import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY; import static android.app.ActivityManager.START_CLASS_NOT_FOUND; import static android.app.ActivityManager.START_DELIVERED_TO_TOP; import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED; Loading @@ -15,8 +16,16 @@ import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.PendingIntent.FLAG_CANCEL_CURRENT; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.content.Context.KEYGUARD_SERVICE; import static android.content.Intent.EXTRA_INTENT; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.EXTRA_TASK_ID; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_TO_SIDE; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; Loading Loading @@ -66,7 +75,6 @@ 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 @@ -91,7 +99,6 @@ import android.view.Display; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.internal.widget.LockPatternUtils; import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch; import com.android.server.wm.WindowManagerService; Loading Loading @@ -358,38 +365,26 @@ class ActivityStarter { } } UserInfo user = mSupervisor.getUserInfo(userId); KeyguardManager km = (KeyguardManager) mService.mContext .getSystemService(Context.KEYGUARD_SERVICE); if (user.isManagedProfile() && LockPatternUtils.isSeparateWorkChallengeEnabled() && km.isDeviceLocked(userId)) { IIntentSender target = mService.getIntentSenderLocked( ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent }, new String[]{ resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE, null); final int flags = intent.getFlags(); final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, user.id); if (newIntent != null) { intent = newIntent; intent.setFlags(flags | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName); intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target)); resolvedType = null; callingUid = realCallingUid; final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(intent, resolvedType, aInfo, callingPackage, userId); if (interceptingIntent != null) { intent = interceptingIntent; callingPid = realCallingPid; callingUid = realCallingUid; resolvedType = null; // If we are intercepting and there was a task, convert it into an extra for the // ConfirmCredentials intent and unassign it, as otherwise the task will move to // front even if ConfirmCredentials is cancelled. if (inTask != null) { intent.putExtra(EXTRA_TASK_ID, inTask.taskId); inTask = null; } UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId); final UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId); rInfo = mSupervisor.resolveIntent(intent, resolvedType, parent.id); aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/); } } if (abort) { if (resultRecord != null) { Loading Loading @@ -538,6 +533,34 @@ class ActivityStarter { return err; } /** * Creates an intent to intercept the current activity start with Confirm Credentials if needed. * * @return The intercepting intent if needed. */ private Intent interceptWithConfirmCredentialsIfNeeded(Intent intent, String resolvedType, ActivityInfo aInfo, String callingPackage, int userId) { if (!mService.mUserController.shouldConfirmCredentials(userId)) { return null; } final IIntentSender target = mService.getIntentSenderLocked( INTENT_SENDER_ACTIVITY, callingPackage, Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent }, new String[]{ resolvedType }, FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE, null); final int flags = intent.getFlags(); final KeyguardManager km = (KeyguardManager) mService.mContext .getSystemService(KEYGUARD_SERVICE); final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId); if (newIntent == null) { return null; } newIntent.setFlags(flags | FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); newIntent.putExtra(EXTRA_PACKAGE_NAME, aInfo.packageName); newIntent.putExtra(EXTRA_INTENT, new IntentSender(target)); return newIntent; } void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) { mSupervisor.moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason); startActivityLocked(null /*caller*/, intent, null /*ephemeralIntent*/, Loading
services/core/java/com/android/server/am/UserController.java +17 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM; import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP; import static android.app.ActivityManager.USER_OP_IS_CURRENT; import static android.app.ActivityManager.USER_OP_SUCCESS; import static android.content.Context.KEYGUARD_SERVICE; import static android.os.Process.SYSTEM_UID; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; Loading @@ -43,6 +44,7 @@ import android.app.AppOpsManager; import android.app.Dialog; import android.app.IStopUserCallback; import android.app.IUserSwitchObserver; import android.app.KeyguardManager; import android.content.Context; import android.content.IIntentReceiver; import android.content.Intent; Loading Loading @@ -73,6 +75,7 @@ import android.util.SparseIntArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import com.android.internal.widget.LockPatternUtils; import com.android.server.pm.UserManagerService; import java.io.PrintWriter; Loading Loading @@ -1286,6 +1289,20 @@ final class UserController { return mCurrentProfileIds; } /** * Returns whether the given user requires credential entry at this time. This is used to * intercept activity launches for work apps when the Work Challenge is present. */ boolean shouldConfirmCredentials(int userId) { final UserInfo user = getUserInfo(userId); if (!user.isManagedProfile() || !LockPatternUtils.isSeparateWorkChallengeEnabled()) { return false; } final KeyguardManager km = (KeyguardManager) mService.mContext .getSystemService(KEYGUARD_SERVICE); return km.isDeviceLocked(user.id); } void dump(PrintWriter pw, boolean dumpAll) { pw.println(" mStartedUsers:"); for (int i = 0; i < mStartedUsers.size(); i++) { Loading