Merge "Revert^2 "Use same display for activities in same process.""
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
// =====================================
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user