Fix windowing mode for non-resizable tasks

This contains 4 connected fixes for making the Dream activity
non-resizable and fullscreen:

1.  Non-resizable tasks should not be allowed to be in a multi-window
mode.

2. Task#mForceResizableActivities should only be applied to "standard"
activities (eg, Home and Dream should not be forced resizable).

3. Dreams should be set to non-resizable to ensure the activity behind
is not visible, as asserted by the DreamManagerServiceTests CTS test.

4. To ensure the non-resizable dream activity is launched fullscreen,
always create a new one-level task for the Dream - avoid creating an
additional child task as it is not needed, there is only ever one
DreamActivity.

Bug: 168775742
Test: atest CtsWindowManagerDeviceTestCases:DreamManagerServiceTests
Change-Id: Iffe57061cac2044699da78d84d64df0dddfb3a26
This commit is contained in:
Matthew Duggan
2020-10-16 17:27:22 +09:00
parent 7c2008c67d
commit e1fb953f85
4 changed files with 26 additions and 3 deletions

View File

@@ -796,6 +796,9 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
/**
* Returns {@code true} if the windowingMode represents a window in multi-window mode.
* I.e. sharing the screen with another activity.
*
* TODO(b/171672645): This API could be misleading - in 'undefined' mode it's determined by the
* parent's mode
* @hide
*/
public static boolean inMultiWindowMode(int windowingMode) {

View File

@@ -39,6 +39,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
@@ -1294,6 +1295,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
a.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
a.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
a.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
a.resizeMode = RESIZE_MODE_UNRESIZEABLE;
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchActivityType(ACTIVITY_TYPE_DREAM);

View File

@@ -4997,6 +4997,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|| windowingMode == WINDOWING_MODE_MULTI_WINDOW);
}
static boolean canReuseExistingTask(int windowingMode, int activityType) {
// Existing Tasks can be reused if a new stack will be created anyway, or for the Dream -
// because there can only ever be one DreamActivity.
return alwaysCreateStack(windowingMode, activityType)
|| activityType == ACTIVITY_TYPE_DREAM;
}
@Nullable
Task getFocusedStack() {
return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedStack);

View File

@@ -2813,16 +2813,25 @@ class Task extends WindowContainer<WindowContainer> {
int windowingMode =
getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode();
final int parentWindowingMode = newParentConfig.windowConfiguration.getWindowingMode();
// Resolve override windowing mode to fullscreen for home task (even on freeform
// display), or split-screen if in split-screen mode.
if (getActivityType() == ACTIVITY_TYPE_HOME && windowingMode == WINDOWING_MODE_UNDEFINED) {
final int parentWindowingMode = newParentConfig.windowConfiguration.getWindowingMode();
windowingMode = WindowConfiguration.isSplitScreenWindowingMode(parentWindowingMode)
? parentWindowingMode : WINDOWING_MODE_FULLSCREEN;
getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode);
}
// Do not allow non-resizable non-pinned tasks to be in a multi-window mode - they should
// use their parent's windowing mode, or fullscreen.
if (!isResizeable() && windowingMode != WINDOWING_MODE_PINNED
&& WindowConfiguration.inMultiWindowMode(windowingMode)) {
windowingMode = WindowConfiguration.inMultiWindowMode(parentWindowingMode)
? WINDOWING_MODE_FULLSCREEN : parentWindowingMode;
getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode);
}
if (isLeafTask()) {
resolveLeafOnlyOverrideConfigs(newParentConfig, mTmpBounds /* previousBounds */);
}
@@ -3312,7 +3321,9 @@ class Task extends WindowContainer<WindowContainer> {
}
boolean isResizeable(boolean checkSupportsPip) {
return (mAtmService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
final boolean forceResizable = mAtmService.mForceResizableActivities
&& getActivityType() == ACTIVITY_TYPE_STANDARD;
return (forceResizable || ActivityInfo.isResizeableMode(mResizeMode)
|| (checkSupportsPip && mSupportsPictureInPicture));
}
@@ -7174,7 +7185,7 @@ class Task extends WindowContainer<WindowContainer> {
ActivityRecord source, ActivityOptions options) {
Task task;
if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) {
if (DisplayContent.canReuseExistingTask(getWindowingMode(), getActivityType())) {
// This stack will only contain one task, so just return itself since all stacks ara now
// tasks and all tasks are now stacks.
task = reuseAsLeafTask(voiceSession, voiceInteractor, intent, info, activity);