Revert^2 "Use same display for activities in same process."

The error was a bad git merge that removed an import.
The fix was just to redo the commit again so the import is available.

Original Commit Message:

Use same display for activities in same process.

Use WindowProcessController to calculate display to hold activity.
Use the display with the top most activity within the same application.
If no top activity is available use the default display
Add additional parameter to task params modifier to include request.
Handle launching on same display if using PendingIntent.

Bug: 152958720
Test: atest WmTests:WindowProcessControllerTests
      atest WmTests:TaskLauncherParamsModifierTests

Change-Id: If96cdc7207ec9dba6663eb327350e7148605f157
This commit is contained in:
Diego Vela
2020-10-08 17:00:52 +00:00
parent 784374c1e9
commit c32262be8b
9 changed files with 362 additions and 47 deletions

View File

@@ -7584,6 +7584,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
}
String getProcessName() {
return info.applicationInfo.processName;
}
int getUid() {
return info.applicationInfo.uid;
}
@@ -7596,6 +7600,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return app != null ? app.getPid() : 0;
}
int getLaunchedFromPid() {
return launchedFromPid;
}
int getLaunchedFromUid() {
return launchedFromUid;
}
/**
* Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
* {@link ActivityRecord#getTurnScreenOnFlag} is set and checks whether the ActivityRecord

View File

@@ -57,9 +57,6 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
@@ -71,6 +68,9 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
import static com.android.server.wm.Task.ActivityState.RESUMED;
@@ -1870,7 +1870,7 @@ class ActivityStarter {
}
mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams);
sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams, mRequest);
mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
? mLaunchParams.mPreferredTaskDisplayArea
: mRootWindowContainer.getDefaultTaskDisplayArea();
@@ -2254,7 +2254,7 @@ class ActivityStarter {
// Preferred display id is the only state we need for now and it could be updated again
// after we located a reusable task (which might be resided in another display).
mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
sourceRecord, options, PHASE_DISPLAY, mLaunchParams, mRequest);
mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
? mLaunchParams.mPreferredTaskDisplayArea
: mRootWindowContainer.getDefaultTaskDisplayArea();

View File

@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
@@ -73,9 +74,10 @@ class LaunchParamsController {
* @param source The {@link ActivityRecord} from which activity was started from.
* @param options The {@link ActivityOptions} specified for the activity.
* @param result The resulting params.
* @param request The optional request from the activity starter.
*/
void calculate(Task task, WindowLayout layout, ActivityRecord activity,
ActivityRecord source, ActivityOptions options, int phase, LaunchParams result) {
void calculate(Task task, WindowLayout layout, ActivityRecord activity, ActivityRecord source,
ActivityOptions options, int phase, LaunchParams result, @Nullable Request request) {
result.reset();
if (task != null || activity != null) {
@@ -91,7 +93,7 @@ class LaunchParamsController {
final LaunchParamsModifier modifier = mModifiers.get(i);
switch(modifier.onCalculate(task, layout, activity, source, options, phase, mTmpCurrent,
mTmpResult)) {
mTmpResult, request)) {
case RESULT_SKIP:
// Do not apply any results when we are told to skip
continue;
@@ -128,7 +130,8 @@ class LaunchParamsController {
boolean layoutTask(Task task, WindowLayout layout, ActivityRecord activity,
ActivityRecord source, ActivityOptions options) {
calculate(task, layout, activity, source, options, PHASE_BOUNDS, mTmpParams);
calculate(task, layout, activity, source, options, PHASE_BOUNDS, mTmpParams,
null /* request */);
// No changes, return.
if (mTmpParams.isEmpty()) {
@@ -305,15 +308,17 @@ class LaunchParamsController {
* launched should have this be non-null.
* @param source the Activity that launched a new task. Could be {@code null}.
* @param options {@link ActivityOptions} used to start the activity with.
* @param phase the calculation phase, see {@link LaunchParamsModifier.Phase}
* @param phase the calculation phase, see {@link Phase}
* @param currentParams launching params after the process of last {@link
* LaunchParamsModifier}.
* @param outParams the result params to be set.
* @param request Optional data to give more context on the launch
* @return see {@link LaunchParamsModifier.Result}
*/
@Result
int onCalculate(Task task, WindowLayout layout, ActivityRecord activity,
int onCalculate(@Nullable Task task, WindowLayout layout, ActivityRecord activity,
ActivityRecord source, ActivityOptions options, @Phase int phase,
LaunchParams currentParams, LaunchParams outParams);
LaunchParams currentParams, LaunchParams outParams,
@Nullable Request request);
}
}

View File

@@ -35,6 +35,7 @@ import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -99,23 +100,25 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
ActivityRecord source, ActivityOptions options, LaunchParams currentParams,
LaunchParams outParams) {
return onCalculate(task, layout, activity, source, options, PHASE_BOUNDS, currentParams,
outParams);
outParams, null);
}
@Override
public int onCalculate(Task task, ActivityInfo.WindowLayout layout,
ActivityRecord activity, ActivityRecord source, ActivityOptions options,
int phase, LaunchParams currentParams, LaunchParams outParams) {
public int onCalculate(@Nullable Task task, @NonNull ActivityInfo.WindowLayout layout,
@NonNull ActivityRecord activity, @Nullable ActivityRecord source,
ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams,
@Nullable Request request) {
initLogBuilder(task, activity);
final int result = calculate(task, layout, activity, source, options, phase, currentParams,
outParams);
outParams, request);
outputLog();
return result;
}
private int calculate(Task task, ActivityInfo.WindowLayout layout,
ActivityRecord activity, ActivityRecord source, ActivityOptions options, int phase,
LaunchParams currentParams, LaunchParams outParams) {
private int calculate(@Nullable Task task, @NonNull ActivityInfo.WindowLayout layout,
@NonNull ActivityRecord activity, @Nullable ActivityRecord source,
ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams,
@Nullable Request request) {
final ActivityRecord root;
if (task != null) {
root = task.getRootActivity() == null ? activity : task.getRootActivity();
@@ -138,7 +141,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
// STEP 1: Determine the display area to launch the activity/task.
final TaskDisplayArea taskDisplayArea = getPreferredLaunchTaskDisplayArea(task,
options, source, currentParams);
options, source, currentParams, activity, request);
outParams.mPreferredTaskDisplayArea = taskDisplayArea;
// TODO(b/152116619): Update the usages of display to use taskDisplayArea below.
final DisplayContent display = taskDisplayArea.mDisplayContent;
@@ -298,7 +301,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
private TaskDisplayArea getPreferredLaunchTaskDisplayArea(@Nullable Task task,
@Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams) {
@Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams,
@NonNull ActivityRecord activityRecord, @Nullable Request request) {
TaskDisplayArea taskDisplayArea = null;
final WindowContainerToken optionLaunchTaskDisplayAreaToken = options != null
@@ -369,7 +373,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
taskDisplayArea = currentParams.mPreferredTaskDisplayArea;
}
// Fallback to default display if the device didn't declare support for multi-display
// Re-route to default display if the device didn't declare support for multi-display
if (taskDisplayArea != null && !mSupervisor.mService.mSupportsMultiDisplay
&& taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY) {
taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
@@ -377,7 +381,53 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
return (taskDisplayArea != null)
? taskDisplayArea
: mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
: getFallbackDisplayAreaForActivity(activityRecord, request);
}
/**
* Calculates the default {@link TaskDisplayArea} for a task. We attempt to put the activity
* within the same display area if possible. The strategy is to find the display in the
* following order:
*
* <ol>
* <li>The display area of the top activity from the launching process will be used</li>
* <li>The display area of the top activity from the real launching process will be used
* </li>
* <li>Default display area from the associated root window container.</li>
* </ol>
* @param activityRecord the activity being started
* @param request optional {@link Request} made to start the activity record
* @return {@link TaskDisplayArea} to house the task
*/
private TaskDisplayArea getFallbackDisplayAreaForActivity(
@NonNull ActivityRecord activityRecord, @Nullable Request request) {
WindowProcessController controllerFromLaunchingRecord = mSupervisor.mService
.getProcessController(activityRecord.launchedFromPid,
activityRecord.launchedFromUid);
final TaskDisplayArea displayAreaForLaunchingRecord = controllerFromLaunchingRecord == null
? null : controllerFromLaunchingRecord.getTopActivityDisplayArea();
if (displayAreaForLaunchingRecord != null) {
return displayAreaForLaunchingRecord;
}
WindowProcessController controllerFromProcess = mSupervisor.mService.getProcessController(
activityRecord.getProcessName(), activityRecord.getUid());
final TaskDisplayArea displayAreaForRecord = controllerFromProcess == null ? null
: controllerFromProcess.getTopActivityDisplayArea();
if (displayAreaForRecord != null) {
return displayAreaForRecord;
}
WindowProcessController controllerFromRequest = request == null ? null : mSupervisor
.mService.getProcessController(request.realCallingPid, request.realCallingUid);
final TaskDisplayArea displayAreaFromSourceProcess = controllerFromRequest == null ? null
: controllerFromRequest.getTopActivityDisplayArea();
if (displayAreaFromSourceProcess != null) {
return displayAreaFromSourceProcess;
}
return mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
}
private boolean canInheritWindowingModeFromSource(@NonNull DisplayContent display,

View File

@@ -730,6 +730,28 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return mHasActivities || mHasRecentTasks;
}
@Nullable
TaskDisplayArea getTopActivityDisplayArea() {
if (mActivities.isEmpty()) {
return null;
}
final int lastIndex = mActivities.size() - 1;
ActivityRecord topRecord = mActivities.get(lastIndex);
TaskDisplayArea displayArea = topRecord.getDisplayArea();
for (int index = lastIndex - 1; index >= 0; --index) {
ActivityRecord nextRecord = mActivities.get(index);
TaskDisplayArea nextDisplayArea = nextRecord.getDisplayArea();
if (nextRecord.compareTo(topRecord) > 0 && nextDisplayArea != null) {
topRecord = nextRecord;
displayArea = nextDisplayArea;
}
}
return displayArea;
}
private boolean hasActivityInVisibleTask() {
for (int i = mActivities.size() - 1; i >= 0; --i) {
Task task = mActivities.get(i).getTask();

View File

@@ -422,7 +422,7 @@ public class ActivityStarterTests extends WindowTestsBase {
// verify that values are passed to the modifier. Values are passed thrice -- two for
// setting initial state, another when task is created.
verify(modifier, times(3)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options),
anyInt(), any(), any());
anyInt(), any(), any(), any());
}
/**

View File

@@ -33,6 +33,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
@@ -92,11 +93,12 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final ActivityRecord source = new ActivityBuilder(mAtm).build();
final WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0);
final ActivityOptions options = mock(ActivityOptions.class);
final Request request = new Request();
mController.calculate(record.getTask(), layout, record, source, options, PHASE_BOUNDS,
new LaunchParams());
new LaunchParams(), request);
verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record),
eq(source), eq(options), anyInt(), any(), any());
eq(source), eq(options), anyInt(), any(), any(), eq(request));
}
/**
@@ -119,9 +121,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
mPersister.putLaunchParams(userId, name, expected);
mController.calculate(activity.getTask(), null /*layout*/, activity, null /*source*/,
null /*options*/, PHASE_BOUNDS, new LaunchParams());
null /*options*/, PHASE_BOUNDS, new LaunchParams(), null /* request */);
verify(positioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
eq(expected), any());
eq(expected), any(), any());
}
/**
@@ -132,16 +134,17 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final LaunchParamsModifier
ignoredPositioner = mock(LaunchParamsModifier.class);
final LaunchParamsModifier earlyExitPositioner =
(task, layout, activity, source, options, phase, currentParams, outParams)
(task, layout, activity, source, options, phase, currentParams, outParams, request)
-> RESULT_DONE;
mController.registerModifier(ignoredPositioner);
mController.registerModifier(earlyExitPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams());
null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(),
null /* request */);
verify(ignoredPositioner, never()).onCalculate(any(), any(), any(), any(), any(), anyInt(),
any(), any());
any(), any(), any());
}
/**
@@ -157,20 +160,22 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
mController.registerModifier(firstPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams());
null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(),
null /* request */);
verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
any(), any());
any(), any(), any());
final LaunchParamsModifier secondPositioner = spy(earlyExitPositioner);
mController.registerModifier(secondPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams());
null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(),
null /* request */);
verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
any(), any());
any(), any(), any());
verify(secondPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
any(), any());
any(), any(), any());
}
/**
@@ -192,10 +197,10 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
mController.registerModifier(positioner2);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
null /*options*/, PHASE_BOUNDS, new LaunchParams());
null /*options*/, PHASE_BOUNDS, new LaunchParams(), null /* request */);
verify(positioner1, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
eq(positioner2.getLaunchParams()), any());
eq(positioner2.getLaunchParams()), any(), any());
}
/**
@@ -218,7 +223,7 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final LaunchParams result = new LaunchParams();
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
null /*options*/, PHASE_BOUNDS, result);
null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(result, positioner2.getLaunchParams());
}
@@ -237,17 +242,17 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
// VR activities should always land on default display.
mController.calculate(null /*task*/, null /*layout*/, vrActivity /*activity*/,
null /*source*/, null /*options*/, PHASE_BOUNDS, result);
null /*source*/, null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(),
result.mPreferredTaskDisplayArea);
// Otherwise, always lands on VR 2D display.
final ActivityRecord vr2dActivity = new ActivityBuilder(mAtm).build();
mController.calculate(null /*task*/, null /*layout*/, vr2dActivity /*activity*/,
null /*source*/, null /*options*/, PHASE_BOUNDS, result);
null /*source*/, null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
null /*options*/, PHASE_BOUNDS, result);
null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea);
mAtm.mVr2dDisplayId = INVALID_DISPLAY;
@@ -269,9 +274,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final ActivityOptions options = mock(ActivityOptions.class);
mController.calculate(record.getTask(), layout, record, source, options, PHASE_BOUNDS,
new LaunchParams());
new LaunchParams(), null /* request */);
verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record),
eq(source), eq(options), eq(PHASE_BOUNDS), any(), any());
eq(source), eq(options), eq(PHASE_BOUNDS), any(), any(), any());
}
/**
@@ -403,8 +408,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
@Override
public int onCalculate(Task task, WindowLayout layout, ActivityRecord activity,
ActivityRecord source, ActivityOptions options, int phase,
LaunchParams currentParams, LaunchParams outParams) {
ActivityRecord source, ActivityOptions options, int phase,
LaunchParams currentParams, LaunchParams outParams,
Request request) {
outParams.set(mParams);
return mReturnVal;
}

View File

@@ -35,6 +35,7 @@ import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
@@ -42,6 +43,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo;
@@ -265,6 +269,180 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
mResult.mPreferredTaskDisplayArea);
}
@Test
public void testUsesDisplayAreaFromTopMostActivityInApplicationIfAvailable() {
final String processName = "processName";
final int uid = 124214;
final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TaskDisplayArea expectedDisplayArea = secondScreen.getDefaultTaskDisplayArea();
final WindowProcessController controller = mock(WindowProcessController.class);
when(controller.getTopActivityDisplayArea()).thenReturn(expectedDisplayArea);
when(mActivity.getProcessName()).thenReturn(processName);
when(mActivity.getUid()).thenReturn(uid);
doReturn(controller)
.when(mSupervisor.mService)
.getProcessController(processName, uid);
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
null /* task */,
null /* layout */,
mActivity /* activity */,
null /* source */,
null /* options */,
-1 /* phase */,
mCurrent,
mResult,
null /* request */
));
assertEquals(expectedDisplayArea, mResult.mPreferredTaskDisplayArea);
}
@Test
public void testUsesDisplayAreaFromLaunchingActivityIfApplicationLaunching() {
final String processName = "processName";
final int uid = 124214;
final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea();
final WindowProcessController controller = mock(WindowProcessController.class);
when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea);
when(mActivity.getProcessName()).thenReturn(processName);
when(mActivity.getUid()).thenReturn(uid);
doReturn(null)
.when(mSupervisor.mService)
.getProcessController(processName, uid);
doReturn(controller)
.when(mSupervisor.mService)
.getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
null /* task */,
null /* layout */,
mActivity /* activity */,
null /* source */,
null /* options */,
-1 /* phase */,
mCurrent,
mResult,
null /* request */
));
assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
}
@Test
public void testDisplayAreaFromLaunchingActivityTakesPrecedence() {
final String processName = "processName";
final int uid = 124214;
final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TaskDisplayArea firstTaskDisplayArea = firstScreen.getDefaultTaskDisplayArea();
final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea();
final WindowProcessController controllerForLaunching = mock(WindowProcessController.class);
final WindowProcessController controllerForApplication =
mock(WindowProcessController.class);
when(mActivity.getProcessName()).thenReturn(processName);
when(mActivity.getUid()).thenReturn(uid);
when(controllerForApplication.getTopActivityDisplayArea()).thenReturn(firstTaskDisplayArea);
when(controllerForLaunching.getTopActivityDisplayArea())
.thenReturn(expectedTaskDisplayArea);
doReturn(controllerForApplication)
.when(mSupervisor.mService)
.getProcessController(processName, uid);
doReturn(controllerForLaunching)
.when(mSupervisor.mService)
.getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
null /* task */,
null /* layout */,
mActivity /* activity */,
null /* source */,
null /* options */,
-1 /* phase */,
mCurrent,
mResult,
null /* request */
));
assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
}
@Test
public void testUsesDisplayAreaOriginalProcessAsLastResort() {
final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea();
final Request request = new Request();
request.realCallingPid = 12412413;
request.realCallingUid = 235424;
final WindowProcessController controller = mock(WindowProcessController.class);
when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea);
doReturn(null)
.when(mSupervisor.mService)
.getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid);
doReturn(null)
.when(mSupervisor.mService)
.getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
doReturn(controller)
.when(mSupervisor.mService)
.getProcessController(request.realCallingPid, request.realCallingUid);
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
null /* task */,
null /* layout */,
mActivity /* activity */,
null /* source */,
null /* options */,
-1 /* phase */,
mCurrent,
mResult,
request
));
assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
}
@Test
public void testUsesDefaultDisplayAreaIfWindowProcessControllerIsNotPresent() {
doReturn(null)
.when(mSupervisor.mService)
.getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid);
doReturn(null)
.when(mSupervisor.mService)
.getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
null /* task */,
null /* layout */,
mActivity /* activity */,
null /* source */,
null /* options */,
-1 /* phase */,
mCurrent,
mResult,
null /* request */
));
assertEquals(DEFAULT_DISPLAY, mResult.mPreferredTaskDisplayArea.getDisplayId());
}
// =====================================
// Launch Windowing Mode Related Tests
// =====================================

View File

@@ -27,10 +27,13 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.IApplicationThread;
@@ -327,6 +330,45 @@ public class WindowProcessControllerTests extends WindowTestsBase {
return new ActivityBuilder(mAtm).setCreateTask(true).setUseProcess(wpc).build();
}
@Test
public void testTopActivityDisplayAreaMatchesTopMostActivity_noActivities() {
assertNull(mWpc.getTopActivityDisplayArea());
}
@Test
public void testTopActivityDisplayAreaMatchesTopMostActivity_singleActivity() {
final ActivityRecord activityRecord = new ActivityBuilder(mSupervisor.mService).build();
final TaskDisplayArea expectedDisplayArea = mock(TaskDisplayArea.class);
when(activityRecord.getDisplayArea())
.thenReturn(expectedDisplayArea);
mWpc.addActivityIfNeeded(activityRecord);
assertEquals(expectedDisplayArea, mWpc.getTopActivityDisplayArea());
}
/**
* Test that top most activity respects z-order.
*/
@Test
public void testTopActivityDisplayAreaMatchesTopMostActivity_multipleActivities() {
final ActivityRecord bottomRecord = new ActivityBuilder(mSupervisor.mService).build();
final TaskDisplayArea bottomDisplayArea = mock(TaskDisplayArea.class);
final ActivityRecord topRecord = new ActivityBuilder(mSupervisor.mService).build();
final TaskDisplayArea topDisplayArea = mock(TaskDisplayArea.class);
when(bottomRecord.getDisplayArea()).thenReturn(bottomDisplayArea);
when(topRecord.getDisplayArea()).thenReturn(topDisplayArea);
doReturn(-1).when(bottomRecord).compareTo(topRecord);
doReturn(1).when(topRecord).compareTo(bottomRecord);
mWpc.addActivityIfNeeded(topRecord);
mWpc.addActivityIfNeeded(bottomRecord);
assertEquals(topDisplayArea, mWpc.getTopActivityDisplayArea());
}
private TestDisplayContent createTestDisplayContentInContainer() {
return new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
}