Merge "Add unit tests for layout of window decoration" into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-07-27 04:30:41 +00:00
committed by Android (Google) Code Review
3 changed files with 157 additions and 10 deletions

View File

@@ -222,10 +222,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
float shadowRadius = outResult.mDensity * shadowRadiusDp;
int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor();
mTmpColor[0] = Color.red(backgroundColorInt);
mTmpColor[1] = Color.green(backgroundColorInt);
mTmpColor[2] = Color.blue(backgroundColorInt);
t.setCrop(mTaskBackgroundSurface, taskBounds)
mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
t.setWindowCrop(mTaskBackgroundSurface, taskBounds.width(), taskBounds.height())
.setShadowRadius(mTaskBackgroundSurface, shadowRadius)
.setColor(mTaskBackgroundSurface, mTmpColor);

View File

@@ -34,13 +34,12 @@ public class MockSurfaceControlHelper {
* given {@link SurfaceControl} when calling {@link SurfaceControl.Builder#build()}.
*
* @param mockSurfaceControl the first {@link SurfaceControl} to return
* @param mockSurfaceControls following {@link SurfaceControl} to return
* @return the mock of {@link SurfaceControl.Builder}
*/
public static SurfaceControl.Builder createMockSurfaceControlBuilder(
SurfaceControl mockSurfaceControl, SurfaceControl... mockSurfaceControls) {
SurfaceControl mockSurfaceControl) {
final SurfaceControl.Builder mockBuilder = mock(SurfaceControl.Builder.class, RETURNS_SELF);
doReturn(mockSurfaceControl, (Object[]) mockSurfaceControls)
doReturn(mockSurfaceControl)
.when(mockBuilder)
.build();
return mockBuilder;

View File

@@ -21,23 +21,32 @@ import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceCon
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.same;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.InsetsState;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.WindowManager.LayoutParams;
import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
@@ -53,6 +62,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
/**
@@ -66,6 +77,8 @@ import java.util.function.Supplier;
public class WindowDecorationTests extends ShellTestCase {
private static final int CAPTION_HEIGHT_DP = 32;
private static final int SHADOW_RADIUS_DP = 5;
private static final Rect TASK_BOUNDS = new Rect(100, 300, 400, 400);
private static final Point TASK_POSITION_IN_PARENT = new Point(40, 60);
private final Rect mOutsetsDp = new Rect();
private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
@@ -84,18 +97,139 @@ public class WindowDecorationTests extends ShellTestCase {
@Mock
private WindowContainerTransaction mMockWindowContainerTransaction;
private SurfaceControl.Builder mMockSurfaceControlBuilder;
private final List<SurfaceControl.Builder> mMockSurfaceControlBuilders = new ArrayList<>();
private SurfaceControl.Transaction mMockSurfaceControlTransaction;
@Before
public void setUp() {
mMockSurfaceControlBuilder = createMockSurfaceControlBuilder(mock(SurfaceControl.class));
mMockSurfaceControlTransaction = createMockSurfaceControlTransaction();
doReturn(mMockSurfaceControlViewHost).when(mMockSurfaceControlViewHostFactory)
.create(any(), any(), any(), anyBoolean());
}
@Test
public void testLayoutResultCalculation_invisibleTask() {
final Display defaultDisplay = mock(Display.class);
doReturn(defaultDisplay).when(mMockDisplayController)
.getDisplay(Display.DEFAULT_DISPLAY);
final SurfaceControl decorContainerSurface = mock(SurfaceControl.class);
final SurfaceControl.Builder decorContainerSurfaceBuilder =
createMockSurfaceControlBuilder(decorContainerSurface);
mMockSurfaceControlBuilders.add(decorContainerSurfaceBuilder);
final SurfaceControl taskBackgroundSurface = mock(SurfaceControl.class);
final SurfaceControl.Builder taskBackgroundSurfaceBuilder =
createMockSurfaceControlBuilder(taskBackgroundSurface);
mMockSurfaceControlBuilders.add(taskBackgroundSurfaceBuilder);
final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
new ActivityManager.TaskDescription.Builder()
.setBackgroundColor(Color.YELLOW);
final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
.setDisplayId(Display.DEFAULT_DISPLAY)
.setTaskDescriptionBuilder(taskDescriptionBuilder)
.setBounds(TASK_BOUNDS)
.setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
.setVisible(false)
.build();
taskInfo.isFocused = false;
// Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
// 64px.
taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
mOutsetsDp.set(10, 20, 30, 40);
final SurfaceControl taskSurface = mock(SurfaceControl.class);
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
windowDecor.relayout(taskInfo);
verify(decorContainerSurfaceBuilder, never()).build();
verify(taskBackgroundSurfaceBuilder, never()).build();
verify(mMockSurfaceControlViewHostFactory, never())
.create(any(), any(), any(), anyBoolean());
verify(mMockSurfaceControlTransaction).hide(taskSurface);
assertNull(mRelayoutResult.mRootView);
}
@Test
public void testLayoutResultCalculation_visibleFocusedTask() {
final Display defaultDisplay = mock(Display.class);
doReturn(defaultDisplay).when(mMockDisplayController)
.getDisplay(Display.DEFAULT_DISPLAY);
final SurfaceControl decorContainerSurface = mock(SurfaceControl.class);
final SurfaceControl.Builder decorContainerSurfaceBuilder =
createMockSurfaceControlBuilder(decorContainerSurface);
mMockSurfaceControlBuilders.add(decorContainerSurfaceBuilder);
final SurfaceControl taskBackgroundSurface = mock(SurfaceControl.class);
final SurfaceControl.Builder taskBackgroundSurfaceBuilder =
createMockSurfaceControlBuilder(taskBackgroundSurface);
mMockSurfaceControlBuilders.add(taskBackgroundSurfaceBuilder);
final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
new ActivityManager.TaskDescription.Builder()
.setBackgroundColor(Color.YELLOW);
final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
.setDisplayId(Display.DEFAULT_DISPLAY)
.setTaskDescriptionBuilder(taskDescriptionBuilder)
.setBounds(TASK_BOUNDS)
.setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
.setVisible(true)
.build();
taskInfo.isFocused = true;
// Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
// 64px.
taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
mOutsetsDp.set(10, 20, 30, 40);
final SurfaceControl taskSurface = mock(SurfaceControl.class);
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
windowDecor.relayout(taskInfo);
verify(decorContainerSurfaceBuilder).setParent(taskSurface);
verify(decorContainerSurfaceBuilder).setContainerLayer();
verify(mMockSurfaceControlTransaction).setTrustedOverlay(decorContainerSurface, true);
verify(mMockSurfaceControlTransaction).setPosition(decorContainerSurface, -20, -40);
verify(mMockSurfaceControlTransaction).setWindowCrop(decorContainerSurface, 380, 220);
verify(taskBackgroundSurfaceBuilder).setParent(taskSurface);
verify(taskBackgroundSurfaceBuilder).setEffectLayer();
verify(mMockSurfaceControlTransaction).setWindowCrop(taskBackgroundSurface, 300, 100);
verify(mMockSurfaceControlTransaction)
.setColor(taskBackgroundSurface, new float[] {1.f, 1.f, 0.f});
verify(mMockSurfaceControlTransaction).setShadowRadius(taskBackgroundSurface, 10);
verify(mMockSurfaceControlViewHostFactory)
.create(any(), eq(defaultDisplay), any(), anyBoolean());
verify(mMockSurfaceControlViewHost)
.setView(same(mMockView),
argThat(lp -> lp.height == 64
&& lp.width == 300
&& (lp.flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0));
if (ViewRootImpl.CAPTION_ON_SHELL) {
verify(mMockView).setTaskFocusState(true);
verify(mMockWindowContainerTransaction)
.addRectInsetsProvider(taskInfo.token,
new Rect(100, 300, 400, 364),
new int[] { InsetsState.ITYPE_CAPTION_BAR });
}
verify(mMockSurfaceControlTransaction)
.setPosition(taskSurface, TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y);
verify(mMockSurfaceControlTransaction)
.setCrop(taskSurface, new Rect(-20, -40, 360, 180));
verify(mMockSurfaceControlTransaction)
.show(taskSurface);
assertEquals(380, mRelayoutResult.mWidth);
assertEquals(220, mRelayoutResult.mHeight);
assertEquals(2, mRelayoutResult.mDensity, 0.f);
}
@Test
public void testNotCrashWhenDisplayAppearsAfterTask() {
doReturn(mock(Display.class)).when(mMockDisplayController)
@@ -145,10 +279,24 @@ public class WindowDecorationTests extends ShellTestCase {
private TestWindowDecoration createWindowDecoration(
ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) {
return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
taskInfo, testSurface, () -> mMockSurfaceControlBuilder,
taskInfo, testSurface, new MockSurfaceControlBuilderSupplier(),
mMockSurfaceControlViewHostFactory);
}
private class MockSurfaceControlBuilderSupplier implements Supplier<SurfaceControl.Builder> {
private int mNumOfCalls = 0;
@Override
public SurfaceControl.Builder get() {
final SurfaceControl.Builder builder =
mNumOfCalls < mMockSurfaceControlBuilders.size()
? mMockSurfaceControlBuilders.get(mNumOfCalls)
: createMockSurfaceControlBuilder(mock(SurfaceControl.class));
++mNumOfCalls;
return builder;
}
}
private static class TestView extends View implements TaskFocusStateConsumer {
private TestView(Context context) {
super(context);