Loading services/core/java/com/android/server/wm/ActivityStartInterceptor.java +48 −4 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; Loading @@ -64,7 +65,7 @@ import com.android.server.am.ActivityManagerService; import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; /** * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked} * A class that contains activity intercepting logic for {@link ActivityStarter#execute()} * It's initialized via setStates and interception occurs via the intercept method. * * Note that this class is instantiated when {@link ActivityManagerService} gets created so there Loading Loading @@ -104,6 +105,7 @@ class ActivityStartInterceptor { ActivityInfo mAInfo; String mResolvedType; Task mInTask; TaskFragment mInTaskFragment; ActivityOptions mActivityOptions; ActivityStartInterceptor( Loading Loading @@ -135,15 +137,46 @@ class ActivityStartInterceptor { } private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) { Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary(); Bundle bOptions = deferCrossProfileAppsAnimationIfNecessary(); final TaskFragment taskFragment = getLaunchTaskFragment(); // If the original intent is going to be embedded, try to forward the embedding TaskFragment // and its task id to embed back the original intent. if (taskFragment != null) { ActivityOptions activityOptions = bOptions != null ? ActivityOptions.fromBundle(bOptions) : ActivityOptions.makeBasic(); activityOptions.setLaunchTaskFragmentToken(taskFragment.getFragmentToken()); bOptions = activityOptions.toBundle(); } final IIntentSender target = mService.getIntentSenderLocked( INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingFeatureId, callingUid, mUserId, null /*token*/, null /*resultCode*/, 0 /*requestCode*/, new Intent[] { mIntent }, new String[] { mResolvedType }, flags, activityOptions); flags, bOptions); return new IntentSender(target); } /** * A helper function to obtain the targeted {@link TaskFragment} during * {@link #intercept(Intent, ResolveInfo, ActivityInfo, String, Task, TaskFragment, int, int, * ActivityOptions)} if any. */ @Nullable private TaskFragment getLaunchTaskFragment() { if (mInTaskFragment != null) { return mInTaskFragment; } if (mActivityOptions == null) { return null; } final IBinder taskFragToken = mActivityOptions.getLaunchTaskFragmentToken(); if (taskFragToken == null) { return null; } return TaskFragment.fromTaskFragmentToken(taskFragToken, mService); } /** * Intercept the launch intent based on various signals. If an interception happened the * internal variables get assigned and need to be read explicitly by the caller. Loading @@ -151,7 +184,8 @@ class ActivityStartInterceptor { * @return true if an interception occurred */ boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { Task inTask, TaskFragment inTaskFragment, int callingPid, int callingUid, ActivityOptions activityOptions) { mUserManager = UserManager.get(mServiceContext); mIntent = intent; Loading @@ -161,6 +195,7 @@ class ActivityStartInterceptor { mAInfo = aInfo; mResolvedType = resolvedType; mInTask = inTask; mInTaskFragment = inTaskFragment; mActivityOptions = activityOptions; if (interceptQuietProfileIfNeeded()) { Loading Loading @@ -332,12 +367,21 @@ class ActivityStartInterceptor { mCallingPid = mRealCallingPid; mCallingUid = mRealCallingUid; mResolvedType = null; final TaskFragment taskFragment = getLaunchTaskFragment(); // 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 (mInTask != null) { mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId); mInTask = null; } else if (taskFragment != null) { // If the original intent is started to an embedded TaskFragment, append its parent task // id to extra. It is to embed back the original intent to the TaskFragment with the // same task. final Task parentTask = taskFragment.getTask(); if (parentTask != null) { mIntent.putExtra(EXTRA_TASK_ID, parentTask.mTaskId); } } if (mActivityOptions == null) { mActivityOptions = ActivityOptions.makeBasic(); Loading services/core/java/com/android/server/wm/ActivityStarter.java +2 −2 Original line number Diff line number Diff line Loading @@ -1060,8 +1060,8 @@ class ActivityStarter { mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, callingFeatureId); if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, checkedOptions)) { if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment, callingPid, callingUid, checkedOptions)) { // activity start was intercepted, e.g. because the target user is currently in quiet // mode (turn off work) or the target application is suspended intent = mInterceptor.mIntent; Loading services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +11 −11 Original line number Diff line number Diff line Loading @@ -192,7 +192,7 @@ public class ActivityStartInterceptorTest { .thenReturn(PLATFORM_PACKAGE_NAME); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the admin support intent assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent); Loading @@ -203,7 +203,7 @@ public class ActivityStartInterceptorTest { final String suspendingPackage = "com.test.suspending.package"; final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // Check intent parameters assertEquals(dialogInfo, Loading Loading @@ -234,7 +234,7 @@ public class ActivityStartInterceptorTest { TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)) .thenReturn(false); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertTrue(BlockedAppActivity.createIntent(TEST_USER_ID, TEST_PACKAGE_NAME) .filterEquals(mInterceptor.mIntent)); Loading @@ -246,7 +246,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) Loading @@ -260,7 +260,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) Loading @@ -273,7 +273,7 @@ public class ActivityStartInterceptorTest { when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true); // THEN calling intercept returns true mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null); mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null); // THEN the returned intent is the quiet mode intent assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent)); Loading @@ -286,7 +286,7 @@ public class ActivityStartInterceptorTest { .thenReturn("This app is bad"); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the harmful app warning intent assertEquals(HarmfulAppWarningActivity.class.getName(), Loading @@ -298,7 +298,7 @@ public class ActivityStartInterceptorTest { // GIVEN that none of the interception conditions are met // THEN calling intercept returns false assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } public void addMockInterceptorCallback( Loading @@ -323,7 +323,7 @@ public class ActivityStartInterceptorTest { new Intent("android.test.foo"), ActivityOptions.makeBasic().setLaunchDisplayId(3)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); } Loading @@ -332,7 +332,7 @@ public class ActivityStartInterceptorTest { public void testInterceptionCallback_singleCallbackReturnsNull() { addMockInterceptorCallback(null, null); assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } @Test Loading @@ -340,7 +340,7 @@ public class ActivityStartInterceptorTest { addMockInterceptorCallback(null, null); addMockInterceptorCallback(new Intent("android.test.second"), null); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.second", mInterceptor.mIntent.getAction()); } Loading Loading
services/core/java/com/android/server/wm/ActivityStartInterceptor.java +48 −4 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; Loading @@ -64,7 +65,7 @@ import com.android.server.am.ActivityManagerService; import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; /** * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked} * A class that contains activity intercepting logic for {@link ActivityStarter#execute()} * It's initialized via setStates and interception occurs via the intercept method. * * Note that this class is instantiated when {@link ActivityManagerService} gets created so there Loading Loading @@ -104,6 +105,7 @@ class ActivityStartInterceptor { ActivityInfo mAInfo; String mResolvedType; Task mInTask; TaskFragment mInTaskFragment; ActivityOptions mActivityOptions; ActivityStartInterceptor( Loading Loading @@ -135,15 +137,46 @@ class ActivityStartInterceptor { } private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) { Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary(); Bundle bOptions = deferCrossProfileAppsAnimationIfNecessary(); final TaskFragment taskFragment = getLaunchTaskFragment(); // If the original intent is going to be embedded, try to forward the embedding TaskFragment // and its task id to embed back the original intent. if (taskFragment != null) { ActivityOptions activityOptions = bOptions != null ? ActivityOptions.fromBundle(bOptions) : ActivityOptions.makeBasic(); activityOptions.setLaunchTaskFragmentToken(taskFragment.getFragmentToken()); bOptions = activityOptions.toBundle(); } final IIntentSender target = mService.getIntentSenderLocked( INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingFeatureId, callingUid, mUserId, null /*token*/, null /*resultCode*/, 0 /*requestCode*/, new Intent[] { mIntent }, new String[] { mResolvedType }, flags, activityOptions); flags, bOptions); return new IntentSender(target); } /** * A helper function to obtain the targeted {@link TaskFragment} during * {@link #intercept(Intent, ResolveInfo, ActivityInfo, String, Task, TaskFragment, int, int, * ActivityOptions)} if any. */ @Nullable private TaskFragment getLaunchTaskFragment() { if (mInTaskFragment != null) { return mInTaskFragment; } if (mActivityOptions == null) { return null; } final IBinder taskFragToken = mActivityOptions.getLaunchTaskFragmentToken(); if (taskFragToken == null) { return null; } return TaskFragment.fromTaskFragmentToken(taskFragToken, mService); } /** * Intercept the launch intent based on various signals. If an interception happened the * internal variables get assigned and need to be read explicitly by the caller. Loading @@ -151,7 +184,8 @@ class ActivityStartInterceptor { * @return true if an interception occurred */ boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { Task inTask, TaskFragment inTaskFragment, int callingPid, int callingUid, ActivityOptions activityOptions) { mUserManager = UserManager.get(mServiceContext); mIntent = intent; Loading @@ -161,6 +195,7 @@ class ActivityStartInterceptor { mAInfo = aInfo; mResolvedType = resolvedType; mInTask = inTask; mInTaskFragment = inTaskFragment; mActivityOptions = activityOptions; if (interceptQuietProfileIfNeeded()) { Loading Loading @@ -332,12 +367,21 @@ class ActivityStartInterceptor { mCallingPid = mRealCallingPid; mCallingUid = mRealCallingUid; mResolvedType = null; final TaskFragment taskFragment = getLaunchTaskFragment(); // 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 (mInTask != null) { mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId); mInTask = null; } else if (taskFragment != null) { // If the original intent is started to an embedded TaskFragment, append its parent task // id to extra. It is to embed back the original intent to the TaskFragment with the // same task. final Task parentTask = taskFragment.getTask(); if (parentTask != null) { mIntent.putExtra(EXTRA_TASK_ID, parentTask.mTaskId); } } if (mActivityOptions == null) { mActivityOptions = ActivityOptions.makeBasic(); Loading
services/core/java/com/android/server/wm/ActivityStarter.java +2 −2 Original line number Diff line number Diff line Loading @@ -1060,8 +1060,8 @@ class ActivityStarter { mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, callingFeatureId); if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, checkedOptions)) { if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment, callingPid, callingUid, checkedOptions)) { // activity start was intercepted, e.g. because the target user is currently in quiet // mode (turn off work) or the target application is suspended intent = mInterceptor.mIntent; Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +11 −11 Original line number Diff line number Diff line Loading @@ -192,7 +192,7 @@ public class ActivityStartInterceptorTest { .thenReturn(PLATFORM_PACKAGE_NAME); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the admin support intent assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent); Loading @@ -203,7 +203,7 @@ public class ActivityStartInterceptorTest { final String suspendingPackage = "com.test.suspending.package"; final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // Check intent parameters assertEquals(dialogInfo, Loading Loading @@ -234,7 +234,7 @@ public class ActivityStartInterceptorTest { TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)) .thenReturn(false); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertTrue(BlockedAppActivity.createIntent(TEST_USER_ID, TEST_PACKAGE_NAME) .filterEquals(mInterceptor.mIntent)); Loading @@ -246,7 +246,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) Loading @@ -260,7 +260,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) Loading @@ -273,7 +273,7 @@ public class ActivityStartInterceptorTest { when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true); // THEN calling intercept returns true mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null); mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null); // THEN the returned intent is the quiet mode intent assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent)); Loading @@ -286,7 +286,7 @@ public class ActivityStartInterceptorTest { .thenReturn("This app is bad"); // THEN calling intercept returns true assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the harmful app warning intent assertEquals(HarmfulAppWarningActivity.class.getName(), Loading @@ -298,7 +298,7 @@ public class ActivityStartInterceptorTest { // GIVEN that none of the interception conditions are met // THEN calling intercept returns false assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } public void addMockInterceptorCallback( Loading @@ -323,7 +323,7 @@ public class ActivityStartInterceptorTest { new Intent("android.test.foo"), ActivityOptions.makeBasic().setLaunchDisplayId(3)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); } Loading @@ -332,7 +332,7 @@ public class ActivityStartInterceptorTest { public void testInterceptionCallback_singleCallbackReturnsNull() { addMockInterceptorCallback(null, null); assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } @Test Loading @@ -340,7 +340,7 @@ public class ActivityStartInterceptorTest { addMockInterceptorCallback(null, null); addMockInterceptorCallback(new Intent("android.test.second"), null); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.second", mInterceptor.mIntent.getAction()); } Loading