Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +4 −4 Original line number Diff line number Diff line Loading @@ -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); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java +2 −3 Original line number Diff line number Diff line Loading @@ -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; Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java +151 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading @@ -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 = Loading @@ -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) Loading Loading @@ -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); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +4 −4 Original line number Diff line number Diff line Loading @@ -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); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java +2 −3 Original line number Diff line number Diff line Loading @@ -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; Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java +151 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading @@ -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 = Loading @@ -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) Loading Loading @@ -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); Loading