DO NOT MERGE Use realCallerId to check launch display for Bubbles

am: af0629a53a

Change-Id: Ibf73e916e439fd8746b46339953c2bcda2d1536c
This commit is contained in:
lumark
2019-09-17 17:53:43 -07:00
committed by android-build-merger
5 changed files with 99 additions and 10 deletions

View File

@@ -2700,7 +2700,8 @@ class ActivityStarter {
|| mPreferredDisplayId != DEFAULT_DISPLAY) { || mPreferredDisplayId != DEFAULT_DISPLAY) {
final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront(); final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
final ActivityStack stack = final ActivityStack stack =
mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams); mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
mRequest.realCallingPid, mRequest.realCallingUid);
return stack; return stack;
} }
// Otherwise handle adjacent launch. // Otherwise handle adjacent launch.
@@ -2818,11 +2819,24 @@ class ActivityStarter {
return this; 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) { ActivityStarter setCallingPid(int pid) {
mRequest.callingPid = pid; mRequest.callingPid = pid;
return this; return this;
} }
/**
* Sets the uid of the caller who originally started the activity.
*
* @see #setCallingPid
*/
ActivityStarter setCallingUid(int uid) { ActivityStarter setCallingUid(int uid) {
mRequest.callingUid = uid; mRequest.callingUid = uid;
return this; return this;
@@ -2833,11 +2847,25 @@ class ActivityStarter {
return this; 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) { ActivityStarter setRealCallingPid(int pid) {
mRequest.realCallingPid = pid; mRequest.realCallingPid = pid;
return this; return this;
} }
/**
* Sets the uid of the caller who requested to launch the activity.
*
* @see #setRealCallingPid
*/
ActivityStarter setRealCallingUid(int uid) { ActivityStarter setRealCallingUid(int uid) {
mRequest.realCallingUid = uid; mRequest.realCallingUid = uid;
return this; return this;

View File

@@ -1667,7 +1667,8 @@ class RootActivityContainer extends ConfigurationContainer
<T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) { @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 */);
} }
/** /**
@@ -1676,13 +1677,16 @@ class RootActivityContainer extends ConfigurationContainer
* @param r The activity we are trying to launch. Can be null. * @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 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. * @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. * @return The stack to use for the launch or INVALID_STACK_ID.
*/ */
<T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop, @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 taskId = INVALID_TASK_ID;
int displayId = INVALID_DISPLAY; int displayId = INVALID_DISPLAY;
//Rect bounds = null; //Rect bounds = null;
@@ -1713,7 +1717,14 @@ class RootActivityContainer extends ConfigurationContainer
if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) { if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
displayId = launchParams.mPreferredDisplayId; 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) { if (r != null) {
stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options, stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
launchParams); launchParams);

View File

@@ -341,7 +341,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
doReturn(stack).when(mRootActivityContainer) doReturn(stack).when(mRootActivityContainer)
.getLaunchStack(any(), any(), any(), anyBoolean()); .getLaunchStack(any(), any(), any(), anyBoolean());
doReturn(stack).when(mRootActivityContainer) 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 // Set up mock package manager internal and make sure no unmocked methods are called

View File

@@ -208,6 +208,8 @@ class ActivityTestsBase {
private ActivityStack mStack; private ActivityStack mStack;
private int mActivityFlags; private int mActivityFlags;
private int mLaunchMode; private int mLaunchMode;
private int mLaunchedFromPid;
private int mLaunchedFromUid;
ActivityBuilder(ActivityTaskManagerService service) { ActivityBuilder(ActivityTaskManagerService service) {
mService = service; mService = service;
@@ -258,6 +260,16 @@ class ActivityTestsBase {
return this; return this;
} }
ActivityBuilder setLaunchedFromPid(int pid) {
mLaunchedFromPid = pid;
return this;
}
ActivityBuilder setLaunchedFromUid(int uid) {
mLaunchedFromUid = uid;
return this;
}
ActivityRecord build() { ActivityRecord build() {
if (mComponent == null) { if (mComponent == null) {
final int id = sCurrentActivityId++; final int id = sCurrentActivityId++;
@@ -285,10 +297,11 @@ class ActivityTestsBase {
aInfo.launchMode = mLaunchMode; aInfo.launchMode = mLaunchMode;
final ActivityRecord activity = new ActivityRecord(mService, null /* caller */, final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
0 /* launchedFromPid */, 0, null, intent, null, mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */,
aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */,
0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/,
mService.mStackSupervisor, null /* options */, null /* sourceRecord */); false /* rootVoiceInteraction */, mService.mStackSupervisor,
null /* options */, null /* sourceRecord */);
spyOn(activity); spyOn(activity);
activity.mAppWindowToken = mock(AppWindowToken.class); activity.mAppWindowToken = mock(AppWindowToken.class);
doCallRealMethod().when(activity.mAppWindowToken).getOrientationIgnoreVisibility(); doCallRealMethod().when(activity.mAppWindowToken).getOrientationIgnoreVisibility();

View File

@@ -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.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.view.Display.DEFAULT_DISPLAY; 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.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -61,6 +62,7 @@ import android.content.res.Resources;
import android.graphics.Rect; import android.graphics.Rect;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.util.Pair; import android.util.Pair;
import android.view.DisplayInfo;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
@@ -816,6 +818,41 @@ public class RootActivityContainerTests extends ActivityTestsBase {
assertEquals(infoFake1.activityInfo.name, resolvedInfo.first.name); 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 * Mock {@link RootActivityContainerTests#resolveHomeActivity} for returning consistent activity
* info for test cases (the original implementation will resolve from the real package manager). * info for test cases (the original implementation will resolve from the real package manager).