Merge "Fix a few issues in WindowDecor" into tm-qpr-dev am: 639a4a914a

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

Change-Id: Id43ae8bf42066f94dd3721add519866111226359
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Garfield Tan
2022-10-21 15:22:40 +00:00
committed by Automerger Merge Worker
4 changed files with 100 additions and 73 deletions

View File

@@ -101,9 +101,9 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
final int shadowRadiusID = taskInfo.isFocused final int shadowRadiusID = taskInfo.isFocused
? R.dimen.freeform_decor_shadow_focused_thickness ? R.dimen.freeform_decor_shadow_focused_thickness
: R.dimen.freeform_decor_shadow_unfocused_thickness; : R.dimen.freeform_decor_shadow_unfocused_thickness;
final boolean isFreeform = mTaskInfo.configuration.windowConfiguration.getWindowingMode() final boolean isFreeform =
== WindowConfiguration.WINDOWING_MODE_FREEFORM; taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
final boolean isDragResizeable = isFreeform && mTaskInfo.isResizeable; final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
WindowDecorLinearLayout oldRootView = mResult.mRootView; WindowDecorLinearLayout oldRootView = mResult.mRootView;
final SurfaceControl oldDecorationSurface = mDecorationContainerSurface; final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
@@ -114,6 +114,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
int outsetRightId = R.dimen.freeform_resize_handle; int outsetRightId = R.dimen.freeform_resize_handle;
int outsetBottomId = R.dimen.freeform_resize_handle; int outsetBottomId = R.dimen.freeform_resize_handle;
mRelayoutParams.reset();
mRelayoutParams.mRunningTaskInfo = taskInfo; mRelayoutParams.mRunningTaskInfo = taskInfo;
mRelayoutParams.mLayoutResId = R.layout.caption_window_decoration; mRelayoutParams.mLayoutResId = R.layout.caption_window_decoration;
mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height; mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;

View File

@@ -91,7 +91,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
SurfaceControl mTaskBackgroundSurface; SurfaceControl mTaskBackgroundSurface;
SurfaceControl mCaptionContainerSurface; SurfaceControl mCaptionContainerSurface;
private CaptionWindowManager mCaptionWindowManager; private WindowlessWindowManager mCaptionWindowManager;
private SurfaceControlViewHost mViewHost; private SurfaceControlViewHost mViewHost;
private final Rect mCaptionInsetsRect = new Rect(); private final Rect mCaptionInsetsRect = new Rect();
@@ -199,13 +199,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
} }
final Rect taskBounds = taskConfig.windowConfiguration.getBounds(); final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
final int decorContainerOffsetX = -loadResource(params.mOutsetLeftId); final Resources resources = mDecorWindowContext.getResources();
final int decorContainerOffsetY = -loadResource(params.mOutsetTopId); final int decorContainerOffsetX = -loadDimensionPixelSize(resources, params.mOutsetLeftId);
final int decorContainerOffsetY = -loadDimensionPixelSize(resources, params.mOutsetTopId);
outResult.mWidth = taskBounds.width() outResult.mWidth = taskBounds.width()
+ loadResource(params.mOutsetRightId) + loadDimensionPixelSize(resources, params.mOutsetRightId)
- decorContainerOffsetX; - decorContainerOffsetX;
outResult.mHeight = taskBounds.height() outResult.mHeight = taskBounds.height()
+ loadResource(params.mOutsetBottomId) + loadDimensionPixelSize(resources, params.mOutsetBottomId)
- decorContainerOffsetY; - decorContainerOffsetY;
startT.setPosition( startT.setPosition(
mDecorationContainerSurface, decorContainerOffsetX, decorContainerOffsetY) mDecorationContainerSurface, decorContainerOffsetX, decorContainerOffsetY)
@@ -225,7 +226,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
.build(); .build();
} }
float shadowRadius = loadResource(params.mShadowRadiusId); float shadowRadius = loadDimension(resources, params.mShadowRadiusId);
int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor(); int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor();
mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f; mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f; mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
@@ -248,8 +249,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
.build(); .build();
} }
final int captionHeight = loadResource(params.mCaptionHeightId); final int captionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId);
final int captionWidth = loadResource(params.mCaptionWidthId); final int captionWidth = loadDimensionPixelSize(resources, params.mCaptionWidthId);
//Prevent caption from going offscreen if task is too high up //Prevent caption from going offscreen if task is too high up
final int captionYPos = taskBounds.top <= captionHeight / 2 ? 0 : captionHeight / 2; final int captionYPos = taskBounds.top <= captionHeight / 2 ? 0 : captionHeight / 2;
@@ -264,8 +265,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
if (mCaptionWindowManager == null) { if (mCaptionWindowManager == null) {
// Put caption under a container surface because ViewRootImpl sets the destination frame // Put caption under a container surface because ViewRootImpl sets the destination frame
// of windowless window layers and BLASTBufferQueue#update() doesn't support offset. // of windowless window layers and BLASTBufferQueue#update() doesn't support offset.
mCaptionWindowManager = new CaptionWindowManager( mCaptionWindowManager = new WindowlessWindowManager(
mTaskInfo.getConfiguration(), mCaptionContainerSurface); mTaskInfo.getConfiguration(), mCaptionContainerSurface,
null /* hostInputToken */);
} }
// Caption view // Caption view
@@ -309,13 +311,6 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
.setCrop(mTaskSurface, mTaskSurfaceCrop); .setCrop(mTaskSurface, mTaskSurfaceCrop);
} }
private int loadResource(int resourceId) {
if (resourceId == Resources.ID_NULL) {
return 0;
}
return mDecorWindowContext.getResources().getDimensionPixelSize(resourceId);
}
/** /**
* Obtains the {@link Display} instance for the display ID in {@link #mTaskInfo} if it exists or * Obtains the {@link Display} instance for the display ID in {@link #mTaskInfo} if it exists or
* registers {@link #mOnDisplaysChangedListener} if it doesn't. * registers {@link #mOnDisplaysChangedListener} if it doesn't.
@@ -374,33 +369,18 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
releaseViews(); releaseViews();
} }
static class RelayoutResult<T extends View & TaskFocusStateConsumer> { private static int loadDimensionPixelSize(Resources resources, int resourceId) {
int mWidth; if (resourceId == Resources.ID_NULL) {
int mHeight; return 0;
T mRootView;
void reset() {
mWidth = 0;
mHeight = 0;
mRootView = null;
} }
return resources.getDimensionPixelSize(resourceId);
} }
private static class CaptionWindowManager extends WindowlessWindowManager { private static float loadDimension(Resources resources, int resourceId) {
CaptionWindowManager(Configuration config, SurfaceControl rootSurface) { if (resourceId == Resources.ID_NULL) {
super(config, rootSurface, null /* hostInputToken */); return 0;
}
@Override
public void setConfiguration(Configuration configuration) {
super.setConfiguration(configuration);
}
}
interface SurfaceControlViewHostFactory {
default SurfaceControlViewHost create(Context c, Display d, WindowlessWindowManager wmm) {
return new SurfaceControlViewHost(c, d, wmm);
} }
return resources.getDimension(resourceId);
} }
static class RelayoutParams{ static class RelayoutParams{
@@ -433,6 +413,23 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mOutsetLeftId = Resources.ID_NULL; mOutsetLeftId = Resources.ID_NULL;
mOutsetRightId = Resources.ID_NULL; mOutsetRightId = Resources.ID_NULL;
} }
}
static class RelayoutResult<T extends View & TaskFocusStateConsumer> {
int mWidth;
int mHeight;
T mRootView;
void reset() {
mWidth = 0;
mHeight = 0;
mRootView = null;
}
}
interface SurfaceControlViewHostFactory {
default SurfaceControlViewHost create(Context c, Display d, WindowlessWindowManager wmm) {
return new SurfaceControlViewHost(c, d, wmm);
}
} }
} }

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<resources>
<!-- Resources used in WindowDecorationTests -->
<dimen name="test_freeform_decor_caption_height">32dp</dimen>
<dimen name="test_freeform_decor_caption_width">216dp</dimen>
<dimen name="test_window_decor_left_outset">10dp</dimen>
<dimen name="test_window_decor_top_outset">20dp</dimen>
<dimen name="test_window_decor_right_outset">30dp</dimen>
<dimen name="test_window_decor_bottom_outset">40dp</dimen>
<dimen name="test_window_decor_shadow_radius">5dp</dimen>
<dimen name="test_window_decor_resize_handle">10dp</dimen>
</resources>

View File

@@ -50,12 +50,13 @@ import android.view.WindowManager.LayoutParams;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder; import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.tests.R;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -145,8 +146,11 @@ public class WindowDecorationTests extends ShellTestCase {
// Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is // Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
// 64px. // 64px.
taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2; taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
mRelayoutParams.setOutsets(R.dimen.freeform_resize_handle, R.dimen.freeform_resize_handle, mRelayoutParams.setOutsets(
R.dimen.freeform_resize_handle, R.dimen.freeform_resize_handle); R.dimen.test_window_decor_left_outset,
R.dimen.test_window_decor_top_outset,
R.dimen.test_window_decor_right_outset,
R.dimen.test_window_decor_bottom_outset);
final SurfaceControl taskSurface = mock(SurfaceControl.class); final SurfaceControl taskSurface = mock(SurfaceControl.class);
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface); final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
@@ -196,13 +200,11 @@ public class WindowDecorationTests extends ShellTestCase {
// Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is // Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
// 64px. // 64px.
taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2; taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
// int outsetLeftId = R.dimen.split_divider_bar_width; mRelayoutParams.setOutsets(
// int outsetTopId = R.dimen.gestures_onehanded_drag_threshold; R.dimen.test_window_decor_left_outset,
// int outsetRightId = R.dimen.freeform_resize_handle; R.dimen.test_window_decor_top_outset,
// int outsetBottomId = R.dimen.bubble_dismiss_target_padding_x; R.dimen.test_window_decor_right_outset,
// mRelayoutParams.setOutsets(outsetLeftId, outsetTopId, outsetRightId, outsetBottomId); R.dimen.test_window_decor_bottom_outset);
mRelayoutParams.setOutsets(R.dimen.freeform_resize_handle, R.dimen.freeform_resize_handle,
R.dimen.freeform_resize_handle, R.dimen.freeform_resize_handle);
final SurfaceControl taskSurface = mock(SurfaceControl.class); final SurfaceControl taskSurface = mock(SurfaceControl.class);
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface); final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
@@ -211,8 +213,8 @@ public class WindowDecorationTests extends ShellTestCase {
verify(decorContainerSurfaceBuilder).setParent(taskSurface); verify(decorContainerSurfaceBuilder).setParent(taskSurface);
verify(decorContainerSurfaceBuilder).setContainerLayer(); verify(decorContainerSurfaceBuilder).setContainerLayer();
verify(mMockSurfaceControlStartT).setTrustedOverlay(decorContainerSurface, true); verify(mMockSurfaceControlStartT).setTrustedOverlay(decorContainerSurface, true);
verify(mMockSurfaceControlStartT).setPosition(decorContainerSurface, -60, -60); verify(mMockSurfaceControlStartT).setPosition(decorContainerSurface, -20, -40);
verify(mMockSurfaceControlStartT).setWindowCrop(decorContainerSurface, 420, 220); verify(mMockSurfaceControlStartT).setWindowCrop(decorContainerSurface, 380, 220);
verify(taskBackgroundSurfaceBuilder).setParent(taskSurface); verify(taskBackgroundSurfaceBuilder).setParent(taskSurface);
verify(taskBackgroundSurfaceBuilder).setEffectLayer(); verify(taskBackgroundSurfaceBuilder).setEffectLayer();
@@ -225,36 +227,34 @@ public class WindowDecorationTests extends ShellTestCase {
verify(captionContainerSurfaceBuilder).setParent(decorContainerSurface); verify(captionContainerSurfaceBuilder).setParent(decorContainerSurface);
verify(captionContainerSurfaceBuilder).setContainerLayer(); verify(captionContainerSurfaceBuilder).setContainerLayer();
verify(mMockSurfaceControlStartT).setPosition(captionContainerSurface, -6, -156); verify(mMockSurfaceControlStartT).setPosition(captionContainerSurface, -46, 8);
verify(mMockSurfaceControlStartT).setWindowCrop(captionContainerSurface, 300, 432); verify(mMockSurfaceControlStartT).setWindowCrop(captionContainerSurface, 300, 64);
verify(mMockSurfaceControlStartT).show(captionContainerSurface); verify(mMockSurfaceControlStartT).show(captionContainerSurface);
verify(mMockSurfaceControlViewHostFactory).create(any(), eq(defaultDisplay), any()); verify(mMockSurfaceControlViewHostFactory).create(any(), eq(defaultDisplay), any());
verify(mMockSurfaceControlViewHost) verify(mMockSurfaceControlViewHost)
.setView(same(mMockView), .setView(same(mMockView),
argThat(lp -> lp.height == 432 argThat(lp -> lp.height == 64
&& lp.width == 432 && lp.width == 432
&& (lp.flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0)); && (lp.flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0));
if (ViewRootImpl.CAPTION_ON_SHELL) { if (ViewRootImpl.CAPTION_ON_SHELL) {
verify(mMockView).setTaskFocusState(true); verify(mMockView).setTaskFocusState(true);
verify(mMockWindowContainerTransaction) verify(mMockWindowContainerTransaction)
.addRectInsetsProvider(taskInfo.token, .addRectInsetsProvider(taskInfo.token,
new Rect(100, 300, 400, 516), new Rect(100, 300, 400, 332),
new int[] { InsetsState.ITYPE_CAPTION_BAR }); new int[] { InsetsState.ITYPE_CAPTION_BAR });
} }
verify(mMockSurfaceControlFinishT) verify(mMockSurfaceControlFinishT)
.setPosition(taskSurface, TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y); .setPosition(taskSurface, TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y);
verify(mMockSurfaceControlFinishT) verify(mMockSurfaceControlFinishT)
.setCrop(taskSurface, new Rect(-60, -60, 360, 160)); .setCrop(taskSurface, new Rect(-20, -40, 360, 180));
verify(mMockSurfaceControlStartT) verify(mMockSurfaceControlStartT)
.show(taskSurface); .show(taskSurface);
assertEquals(420, mRelayoutResult.mWidth); assertEquals(380, mRelayoutResult.mWidth);
assertEquals(220, mRelayoutResult.mHeight); assertEquals(220, mRelayoutResult.mHeight);
} }
@Test @Test
@@ -293,8 +293,11 @@ public class WindowDecorationTests extends ShellTestCase {
// Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is // Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
// 64px. // 64px.
taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2; taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
mRelayoutParams.setOutsets(R.dimen.freeform_resize_handle, R.dimen.freeform_resize_handle, mRelayoutParams.setOutsets(
R.dimen.freeform_resize_handle, R.dimen.freeform_resize_handle); R.dimen.test_window_decor_left_outset,
R.dimen.test_window_decor_top_outset,
R.dimen.test_window_decor_right_outset,
R.dimen.test_window_decor_bottom_outset);
final SurfaceControl taskSurface = mock(SurfaceControl.class); final SurfaceControl taskSurface = mock(SurfaceControl.class);
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface); final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
@@ -365,7 +368,8 @@ public class WindowDecorationTests extends ShellTestCase {
private TestWindowDecoration createWindowDecoration( private TestWindowDecoration createWindowDecoration(
ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) { ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) {
return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer, return new TestWindowDecoration(InstrumentationRegistry.getInstrumentation().getContext(),
mMockDisplayController, mMockShellTaskOrganizer,
taskInfo, testSurface, taskInfo, testSurface,
new MockObjectSupplier<>(mMockSurfaceControlBuilders, new MockObjectSupplier<>(mMockSurfaceControlBuilders,
() -> createMockSurfaceControlBuilder(mock(SurfaceControl.class))), () -> createMockSurfaceControlBuilder(mock(SurfaceControl.class))),
@@ -417,12 +421,10 @@ public class WindowDecorationTests extends ShellTestCase {
@Override @Override
void relayout(ActivityManager.RunningTaskInfo taskInfo) { void relayout(ActivityManager.RunningTaskInfo taskInfo) {
mRelayoutParams.mLayoutResId = 0; mRelayoutParams.mLayoutResId = 0;
mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_width; mRelayoutParams.mCaptionHeightId = R.dimen.test_freeform_decor_caption_height;
mRelayoutParams.mCaptionWidthId = R.dimen.freeform_decor_caption_width; mRelayoutParams.mCaptionWidthId = R.dimen.test_freeform_decor_caption_width;
mRelayoutParams.mShadowRadiusId = mRelayoutParams.mShadowRadiusId = R.dimen.test_window_decor_shadow_radius;
R.dimen.freeform_decor_shadow_unfocused_thickness;
relayout(mRelayoutParams, mMockSurfaceControlStartT, mMockSurfaceControlFinishT, relayout(mRelayoutParams, mMockSurfaceControlStartT, mMockSurfaceControlFinishT,
mMockWindowContainerTransaction, mMockView, mRelayoutResult); mMockWindowContainerTransaction, mMockView, mRelayoutResult);