Merge "Create a launch params modifier for desktop mode" into tm-qpr-dev am: a746afaa4e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20167859

Change-Id: I8ad50681839f1d05994c5911d4d7d4dd8777e8ef
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Ats Jenk
2022-10-12 23:12:06 +00:00
committed by Automerger Merge Worker
3 changed files with 277 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.os.SystemProperties;
import android.util.Slog;
import com.android.server.wm.LaunchParamsController.LaunchParamsModifier;
/**
* The class that defines default launch params for tasks in desktop mode
*/
public class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
private static final String TAG =
TAG_WITH_CLASS_NAME ? "DesktopModeLaunchParamsModifier" : TAG_ATM;
private static final boolean DEBUG = false;
// Desktop mode feature flag.
static final boolean DESKTOP_MODE_SUPPORTED = SystemProperties.getBoolean(
"persist.wm.debug.desktop_mode", false);
// Override default freeform task width when desktop mode is enabled. In dips.
private static final int DESKTOP_MODE_DEFAULT_WIDTH_DP = SystemProperties.getInt(
"persist.wm.debug.desktop_mode.default_width", 840);
// Override default freeform task height when desktop mode is enabled. In dips.
private static final int DESKTOP_MODE_DEFAULT_HEIGHT_DP = SystemProperties.getInt(
"persist.wm.debug.desktop_mode.default_height", 630);
private StringBuilder mLogBuilder;
@Override
public int onCalculate(@Nullable Task task, @Nullable ActivityInfo.WindowLayout layout,
@Nullable ActivityRecord activity, @Nullable ActivityRecord source,
@Nullable ActivityOptions options, @Nullable ActivityStarter.Request request, int phase,
LaunchParamsController.LaunchParams currentParams,
LaunchParamsController.LaunchParams outParams) {
initLogBuilder(task, activity);
int result = calculate(task, layout, activity, source, options, request, phase,
currentParams, outParams);
outputLog();
return result;
}
private int calculate(@Nullable Task task, @Nullable ActivityInfo.WindowLayout layout,
@Nullable ActivityRecord activity, @Nullable ActivityRecord source,
@Nullable ActivityOptions options, @Nullable ActivityStarter.Request request, int phase,
LaunchParamsController.LaunchParams currentParams,
LaunchParamsController.LaunchParams outParams) {
if (task == null) {
appendLog("task null, skipping");
return RESULT_SKIP;
}
if (phase != PHASE_BOUNDS) {
appendLog("not in bounds phase, skipping");
return RESULT_SKIP;
}
if (!task.inFreeformWindowingMode()) {
appendLog("not a freeform task, skipping");
return RESULT_SKIP;
}
if (!currentParams.mBounds.isEmpty()) {
appendLog("currentParams has bounds set, not overriding");
return RESULT_SKIP;
}
// Copy over any values
outParams.set(currentParams);
// Update width and height with default desktop mode values
float density = (float) task.getConfiguration().densityDpi / DENSITY_DEFAULT;
final int width = (int) (DESKTOP_MODE_DEFAULT_WIDTH_DP * density + 0.5f);
final int height = (int) (DESKTOP_MODE_DEFAULT_HEIGHT_DP * density + 0.5f);
outParams.mBounds.right = width;
outParams.mBounds.bottom = height;
// Center the task in window bounds
Rect windowBounds = task.getWindowConfiguration().getBounds();
outParams.mBounds.offset(windowBounds.centerX() - outParams.mBounds.centerX(),
windowBounds.centerY() - outParams.mBounds.centerY());
appendLog("setting desktop mode task bounds to %s", outParams.mBounds);
return RESULT_DONE;
}
private void initLogBuilder(Task task, ActivityRecord activity) {
if (DEBUG) {
mLogBuilder = new StringBuilder(
"DesktopModeLaunchParamsModifier: task=" + task + " activity=" + activity);
}
}
private void appendLog(String format, Object... args) {
if (DEBUG) mLogBuilder.append(" ").append(String.format(format, args));
}
private void outputLog() {
if (DEBUG) Slog.d(TAG, mLogBuilder.toString());
}
}

View File

@@ -64,6 +64,10 @@ class LaunchParamsController {
void registerDefaultModifiers(ActivityTaskSupervisor supervisor) { void registerDefaultModifiers(ActivityTaskSupervisor supervisor) {
// {@link TaskLaunchParamsModifier} handles window layout preferences. // {@link TaskLaunchParamsModifier} handles window layout preferences.
registerModifier(new TaskLaunchParamsModifier(supervisor)); registerModifier(new TaskLaunchParamsModifier(supervisor));
if (DesktopModeLaunchParamsModifier.DESKTOP_MODE_SUPPORTED) {
// {@link DesktopModeLaunchParamsModifier} handles default task size changes
registerModifier(new DesktopModeLaunchParamsModifier());
}
} }
/** /**

View File

@@ -0,0 +1,148 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
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.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import com.android.server.wm.LaunchParamsController.LaunchParamsModifier.Result;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Tests for desktop mode task bounds.
*
* Build/Install/Run:
* atest WmTests:DesktopModeLaunchParamsModifierTests
*/
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class DesktopModeLaunchParamsModifierTests extends WindowTestsBase {
private ActivityRecord mActivity;
private DesktopModeLaunchParamsModifier mTarget;
private LaunchParamsController.LaunchParams mCurrent;
private LaunchParamsController.LaunchParams mResult;
@Before
public void setUp() throws Exception {
mActivity = new ActivityBuilder(mAtm).build();
mTarget = new DesktopModeLaunchParamsModifier();
mCurrent = new LaunchParamsController.LaunchParams();
mCurrent.reset();
mResult = new LaunchParamsController.LaunchParams();
mResult.reset();
}
@Test
public void testReturnsSkipIfTaskIsNull() {
assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(null).calculate());
}
@Test
public void testReturnsSkipIfNotBoundsPhase() {
final Task task = new TaskBuilder(mSupervisor).build();
assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).setPhase(
PHASE_DISPLAY).calculate());
}
@Test
public void testReturnsSkipIfTaskNotInFreeform() {
final Task task = new TaskBuilder(mSupervisor).setWindowingMode(
WINDOWING_MODE_FULLSCREEN).build();
assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).calculate());
}
@Test
public void testReturnsSkipIfCurrentParamsHasBounds() {
final Task task = new TaskBuilder(mSupervisor).setWindowingMode(
WINDOWING_MODE_FREEFORM).build();
mCurrent.mBounds.set(/* left */ 0, /* top */ 0, /* right */ 100, /* bottom */ 100);
assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).calculate());
}
@Test
public void testUsesDefaultBounds() {
final Task task = new TaskBuilder(mSupervisor).setWindowingMode(
WINDOWING_MODE_FREEFORM).build();
assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
assertEquals(dpiToPx(task, 840), mResult.mBounds.width());
assertEquals(dpiToPx(task, 630), mResult.mBounds.height());
}
@Test
public void testUsesDisplayAreaAndWindowingModeFromSource() {
final Task task = new TaskBuilder(mSupervisor).setWindowingMode(
WINDOWING_MODE_FREEFORM).build();
TaskDisplayArea mockTaskDisplayArea = mock(TaskDisplayArea.class);
mCurrent.mPreferredTaskDisplayArea = mockTaskDisplayArea;
mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
assertEquals(mockTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
assertEquals(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode);
}
private int dpiToPx(Task task, int dpi) {
float density = (float) task.getConfiguration().densityDpi / DENSITY_DEFAULT;
return (int) (dpi * density + 0.5f);
}
private class CalculateRequestBuilder {
private Task mTask;
private int mPhase = PHASE_BOUNDS;
private final ActivityRecord mActivity =
DesktopModeLaunchParamsModifierTests.this.mActivity;
private final LaunchParamsController.LaunchParams mCurrentParams = mCurrent;
private final LaunchParamsController.LaunchParams mOutParams = mResult;
private CalculateRequestBuilder setTask(Task task) {
mTask = task;
return this;
}
private CalculateRequestBuilder setPhase(int phase) {
mPhase = phase;
return this;
}
@Result
private int calculate() {
return mTarget.onCalculate(mTask, /* layout*/ null, mActivity, /* source */
null, /* options */ null, /* request */ null, mPhase, mCurrentParams,
mOutParams);
}
}
}