DO NOT MERGE Use realCallerId to check launch display for Bubbles
am: af0629a53a
Change-Id: Ibf73e916e439fd8746b46339953c2bcda2d1536c
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|||||||
Reference in New Issue
Block a user