Loading services/core/java/com/android/server/wm/ActivityStarter.java +29 −1 Original line number Diff line number Diff line Loading @@ -2700,7 +2700,8 @@ class ActivityStarter { || mPreferredDisplayId != DEFAULT_DISPLAY) { final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront(); final ActivityStack stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams); mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams, mRequest.realCallingPid, mRequest.realCallingUid); return stack; } // Otherwise handle adjacent launch. Loading Loading @@ -2818,11 +2819,24 @@ class ActivityStarter { return this; } /** * Sets the pid of the caller who originally started the activity. * * Normally, the pid/uid would be the calling pid from the binder call. * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid, * which represents the entity who invoked pending intent via {@link PendingIntent#send}. */ ActivityStarter setCallingPid(int pid) { mRequest.callingPid = pid; return this; } /** * Sets the uid of the caller who originally started the activity. * * @see #setCallingPid */ ActivityStarter setCallingUid(int uid) { mRequest.callingUid = uid; return this; Loading @@ -2833,11 +2847,25 @@ class ActivityStarter { return this; } /** * Sets the pid of the caller who requested to launch the activity. * * The pid/uid represents the caller who launches the activity in this request. * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}: * the pid/uid will be the caller who called {@link PendingIntent#send()}. * * @see #setCallingPid */ ActivityStarter setRealCallingPid(int pid) { mRequest.realCallingPid = pid; return this; } /** * Sets the uid of the caller who requested to launch the activity. * * @see #setRealCallingPid */ ActivityStarter setRealCallingUid(int uid) { mRequest.realCallingUid = uid; return this; Loading services/core/java/com/android/server/wm/RootActivityContainer.java +15 −4 Original line number Diff line number Diff line Loading @@ -1667,7 +1667,8 @@ class RootActivityContainer extends ConfigurationContainer <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) { return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */); return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */, -1 /* no realCallingPid */, -1 /* no realCallingUid */); } /** Loading @@ -1676,13 +1677,16 @@ class RootActivityContainer extends ConfigurationContainer * @param r The activity we are trying to launch. Can be null. * @param options The activity options used to the launch. Can be null. * @param candidateTask The possible task the activity might be launched in. Can be null. * @params launchParams The resolved launch params to use. * @param launchParams The resolved launch params to use. * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} * * @return The stack to use for the launch or INVALID_STACK_ID. */ <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop, @Nullable LaunchParamsController.LaunchParams launchParams) { @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, int realCallingUid) { int taskId = INVALID_TASK_ID; int displayId = INVALID_DISPLAY; //Rect bounds = null; Loading Loading @@ -1713,7 +1717,14 @@ class RootActivityContainer extends ConfigurationContainer if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) { displayId = launchParams.mPreferredDisplayId; } if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) { final boolean canLaunchOnDisplayFromStartRequest = realCallingPid != 0 && realCallingUid > 0 && r != null && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid, realCallingUid, r.info); // Checking if the activity's launch caller, or the realCallerId of the activity from // start request (i.e. PendingIntent caller) is allowed to launch on the display. if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId) || canLaunchOnDisplayFromStartRequest)) { if (r != null) { stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options, launchParams); Loading services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -341,7 +341,7 @@ public class ActivityStarterTests extends ActivityTestsBase { doReturn(stack).when(mRootActivityContainer) .getLaunchStack(any(), any(), any(), anyBoolean()); doReturn(stack).when(mRootActivityContainer) .getLaunchStack(any(), any(), any(), anyBoolean(), any()); .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt()); } // Set up mock package manager internal and make sure no unmocked methods are called Loading services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +17 −4 Original line number Diff line number Diff line Loading @@ -208,6 +208,8 @@ class ActivityTestsBase { private ActivityStack mStack; private int mActivityFlags; private int mLaunchMode; private int mLaunchedFromPid; private int mLaunchedFromUid; ActivityBuilder(ActivityTaskManagerService service) { mService = service; Loading Loading @@ -258,6 +260,16 @@ class ActivityTestsBase { return this; } ActivityBuilder setLaunchedFromPid(int pid) { mLaunchedFromPid = pid; return this; } ActivityBuilder setLaunchedFromUid(int uid) { mLaunchedFromUid = uid; return this; } ActivityRecord build() { if (mComponent == null) { final int id = sCurrentActivityId++; Loading Loading @@ -285,10 +297,11 @@ class ActivityTestsBase { aInfo.launchMode = mLaunchMode; final ActivityRecord activity = new ActivityRecord(mService, null /* caller */, 0 /* launchedFromPid */, 0, null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, mService.mStackSupervisor, null /* options */, null /* sourceRecord */); mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */, null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, mService.mStackSupervisor, null /* options */, null /* sourceRecord */); spyOn(activity); activity.mAppWindowToken = mock(AppWindowToken.class); doCallRealMethod().when(activity.mAppWindowToken).getOrientationIgnoreVisibility(); Loading services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +37 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.TYPE_VIRTUAL; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; Loading Loading @@ -61,6 +62,7 @@ import android.content.res.Resources; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.Pair; import android.view.DisplayInfo; import androidx.test.filters.MediumTest; Loading Loading @@ -816,6 +818,41 @@ public class RootActivityContainerTests extends ActivityTestsBase { assertEquals(infoFake1.activityInfo.name, resolvedInfo.first.name); } /** * Test that {@link RootActivityContainer#getLaunchStack} with the real caller id will get the * expected stack when requesting the activity launch on the secondary display. */ @Test public void testGetLaunchStackWithRealCallerId() { // Create a non-system owned virtual display. final DisplayInfo info = new DisplayInfo(); mSupervisor.mService.mContext.getDisplay().getDisplayInfo(info); info.type = TYPE_VIRTUAL; info.ownerUid = 100; final TestActivityDisplay secondaryDisplay = createNewActivityDisplay(info); mRootActivityContainer.addChild(secondaryDisplay, POSITION_TOP); // Create an activity with specify the original launch pid / uid. final ActivityRecord r = new ActivityBuilder(mService).setLaunchedFromPid(200) .setLaunchedFromUid(200).build(); // Simulate ActivityStarter to find a launch stack for requesting the activity to launch // on the secondary display with realCallerId. final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchDisplayId(secondaryDisplay.mDisplayId); options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId, 300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info); final ActivityStack result = mRootActivityContainer.getLaunchStack(r, options, null /* task */, true /* onTop */, null, 300 /* test realCallerPid */, 300 /* test realCallerUid */); // Assert that the stack is returned as expected. assertNotNull(result); assertEquals("The display ID of the stack should same as secondary display ", secondaryDisplay.mDisplayId, result.mDisplayId); } /** * Mock {@link RootActivityContainerTests#resolveHomeActivity} for returning consistent activity * info for test cases (the original implementation will resolve from the real package manager). Loading Loading
services/core/java/com/android/server/wm/ActivityStarter.java +29 −1 Original line number Diff line number Diff line Loading @@ -2700,7 +2700,8 @@ class ActivityStarter { || mPreferredDisplayId != DEFAULT_DISPLAY) { final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront(); final ActivityStack stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams); mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams, mRequest.realCallingPid, mRequest.realCallingUid); return stack; } // Otherwise handle adjacent launch. Loading Loading @@ -2818,11 +2819,24 @@ class ActivityStarter { return this; } /** * Sets the pid of the caller who originally started the activity. * * Normally, the pid/uid would be the calling pid from the binder call. * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid, * which represents the entity who invoked pending intent via {@link PendingIntent#send}. */ ActivityStarter setCallingPid(int pid) { mRequest.callingPid = pid; return this; } /** * Sets the uid of the caller who originally started the activity. * * @see #setCallingPid */ ActivityStarter setCallingUid(int uid) { mRequest.callingUid = uid; return this; Loading @@ -2833,11 +2847,25 @@ class ActivityStarter { return this; } /** * Sets the pid of the caller who requested to launch the activity. * * The pid/uid represents the caller who launches the activity in this request. * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}: * the pid/uid will be the caller who called {@link PendingIntent#send()}. * * @see #setCallingPid */ ActivityStarter setRealCallingPid(int pid) { mRequest.realCallingPid = pid; return this; } /** * Sets the uid of the caller who requested to launch the activity. * * @see #setRealCallingPid */ ActivityStarter setRealCallingUid(int uid) { mRequest.realCallingUid = uid; return this; Loading
services/core/java/com/android/server/wm/RootActivityContainer.java +15 −4 Original line number Diff line number Diff line Loading @@ -1667,7 +1667,8 @@ class RootActivityContainer extends ConfigurationContainer <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) { return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */); return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */, -1 /* no realCallingPid */, -1 /* no realCallingUid */); } /** Loading @@ -1676,13 +1677,16 @@ class RootActivityContainer extends ConfigurationContainer * @param r The activity we are trying to launch. Can be null. * @param options The activity options used to the launch. Can be null. * @param candidateTask The possible task the activity might be launched in. Can be null. * @params launchParams The resolved launch params to use. * @param launchParams The resolved launch params to use. * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} * * @return The stack to use for the launch or INVALID_STACK_ID. */ <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop, @Nullable LaunchParamsController.LaunchParams launchParams) { @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, int realCallingUid) { int taskId = INVALID_TASK_ID; int displayId = INVALID_DISPLAY; //Rect bounds = null; Loading Loading @@ -1713,7 +1717,14 @@ class RootActivityContainer extends ConfigurationContainer if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) { displayId = launchParams.mPreferredDisplayId; } if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) { final boolean canLaunchOnDisplayFromStartRequest = realCallingPid != 0 && realCallingUid > 0 && r != null && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid, realCallingUid, r.info); // Checking if the activity's launch caller, or the realCallerId of the activity from // start request (i.e. PendingIntent caller) is allowed to launch on the display. if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId) || canLaunchOnDisplayFromStartRequest)) { if (r != null) { stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options, launchParams); Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -341,7 +341,7 @@ public class ActivityStarterTests extends ActivityTestsBase { doReturn(stack).when(mRootActivityContainer) .getLaunchStack(any(), any(), any(), anyBoolean()); doReturn(stack).when(mRootActivityContainer) .getLaunchStack(any(), any(), any(), anyBoolean(), any()); .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt()); } // Set up mock package manager internal and make sure no unmocked methods are called Loading
services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +17 −4 Original line number Diff line number Diff line Loading @@ -208,6 +208,8 @@ class ActivityTestsBase { private ActivityStack mStack; private int mActivityFlags; private int mLaunchMode; private int mLaunchedFromPid; private int mLaunchedFromUid; ActivityBuilder(ActivityTaskManagerService service) { mService = service; Loading Loading @@ -258,6 +260,16 @@ class ActivityTestsBase { return this; } ActivityBuilder setLaunchedFromPid(int pid) { mLaunchedFromPid = pid; return this; } ActivityBuilder setLaunchedFromUid(int uid) { mLaunchedFromUid = uid; return this; } ActivityRecord build() { if (mComponent == null) { final int id = sCurrentActivityId++; Loading Loading @@ -285,10 +297,11 @@ class ActivityTestsBase { aInfo.launchMode = mLaunchMode; final ActivityRecord activity = new ActivityRecord(mService, null /* caller */, 0 /* launchedFromPid */, 0, null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, mService.mStackSupervisor, null /* options */, null /* sourceRecord */); mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */, null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, mService.mStackSupervisor, null /* options */, null /* sourceRecord */); spyOn(activity); activity.mAppWindowToken = mock(AppWindowToken.class); doCallRealMethod().when(activity.mAppWindowToken).getOrientationIgnoreVisibility(); Loading
services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +37 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.TYPE_VIRTUAL; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; Loading Loading @@ -61,6 +62,7 @@ import android.content.res.Resources; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.Pair; import android.view.DisplayInfo; import androidx.test.filters.MediumTest; Loading Loading @@ -816,6 +818,41 @@ public class RootActivityContainerTests extends ActivityTestsBase { assertEquals(infoFake1.activityInfo.name, resolvedInfo.first.name); } /** * Test that {@link RootActivityContainer#getLaunchStack} with the real caller id will get the * expected stack when requesting the activity launch on the secondary display. */ @Test public void testGetLaunchStackWithRealCallerId() { // Create a non-system owned virtual display. final DisplayInfo info = new DisplayInfo(); mSupervisor.mService.mContext.getDisplay().getDisplayInfo(info); info.type = TYPE_VIRTUAL; info.ownerUid = 100; final TestActivityDisplay secondaryDisplay = createNewActivityDisplay(info); mRootActivityContainer.addChild(secondaryDisplay, POSITION_TOP); // Create an activity with specify the original launch pid / uid. final ActivityRecord r = new ActivityBuilder(mService).setLaunchedFromPid(200) .setLaunchedFromUid(200).build(); // Simulate ActivityStarter to find a launch stack for requesting the activity to launch // on the secondary display with realCallerId. final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchDisplayId(secondaryDisplay.mDisplayId); options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId, 300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info); final ActivityStack result = mRootActivityContainer.getLaunchStack(r, options, null /* task */, true /* onTop */, null, 300 /* test realCallerPid */, 300 /* test realCallerUid */); // Assert that the stack is returned as expected. assertNotNull(result); assertEquals("The display ID of the stack should same as secondary display ", secondaryDisplay.mDisplayId, result.mDisplayId); } /** * Mock {@link RootActivityContainerTests#resolveHomeActivity} for returning consistent activity * info for test cases (the original implementation will resolve from the real package manager). Loading