1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm; 18 19 import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM; 20 import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT; 21 import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT; 22 import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; 23 import static android.view.Surface.ROTATION_0; 24 import static android.view.Surface.ROTATION_180; 25 import static android.view.Surface.ROTATION_270; 26 import static android.view.Surface.ROTATION_90; 27 28 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 30 import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates; 31 32 import static org.junit.Assert.assertEquals; 33 34 import android.graphics.Matrix; 35 import android.graphics.RectF; 36 import android.os.Binder; 37 import android.view.DisplayCutout; 38 import android.view.DisplayInfo; 39 import android.view.WindowManagerGlobal; 40 41 import org.junit.Before; 42 43 public class DisplayPolicyTestsBase extends WindowTestsBase { 44 45 static final int DISPLAY_WIDTH = 500; 46 static final int DISPLAY_HEIGHT = 1000; 47 48 static final int DISPLAY_CUTOUT_HEIGHT = 8; 49 static final int IME_HEIGHT = 415; 50 51 DisplayPolicy mDisplayPolicy; 52 53 @Before setUpDisplayPolicy()54 public void setUpDisplayPolicy() { 55 // Disable surface placement because it has no direct relation to layout policy and it also 56 // avoids some noises such as the display info is modified, screen frozen, config change. 57 mWm.mWindowPlacerLocked.deferLayout(); 58 59 mDisplayPolicy = mDisplayContent.getDisplayPolicy(); 60 spyOn(mDisplayPolicy); 61 doReturn(true).when(mDisplayPolicy).hasNavigationBar(); 62 doReturn(true).when(mDisplayPolicy).hasStatusBar(); 63 addWindow(mStatusBarWindow); 64 addWindow(mNavBarWindow); 65 66 // Update source frame and visibility of insets providers. 67 mDisplayContent.getInsetsStateController().onPostLayout(); 68 } 69 addWindow(WindowState win)70 void addWindow(WindowState win) { 71 mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs); 72 assertEquals(WindowManagerGlobal.ADD_OKAY, mDisplayPolicy.validateAddingWindowLw( 73 win.mAttrs, Binder.getCallingPid(), Binder.getCallingUid())); 74 mDisplayPolicy.addWindowLw(win, win.mAttrs); 75 win.mHasSurface = true; 76 } 77 displayInfoAndCutoutForRotation(int rotation, boolean withDisplayCutout, boolean isLongEdgeCutout)78 DisplayInfo displayInfoAndCutoutForRotation(int rotation, boolean withDisplayCutout, 79 boolean isLongEdgeCutout) { 80 final DisplayInfo info = mDisplayContent.getDisplayInfo(); 81 final boolean flippedDimensions = rotation == ROTATION_90 || rotation == ROTATION_270; 82 info.logicalWidth = flippedDimensions ? DISPLAY_HEIGHT : DISPLAY_WIDTH; 83 info.logicalHeight = flippedDimensions ? DISPLAY_WIDTH : DISPLAY_HEIGHT; 84 info.rotation = rotation; 85 mDisplayContent.mInitialDisplayCutout = withDisplayCutout 86 ? displayCutoutForRotation(ROTATION_0, isLongEdgeCutout) 87 : DisplayCutout.NO_CUTOUT; 88 info.displayCutout = mDisplayContent.calculateDisplayCutoutForRotation(rotation); 89 mDisplayContent.updateBaseDisplayMetrics(DISPLAY_WIDTH, DISPLAY_HEIGHT, 90 info.logicalDensityDpi, info.physicalXDpi, info.physicalYDpi); 91 return info; 92 } 93 displayCutoutForRotation(int rotation, boolean isLongEdgeCutout)94 private static DisplayCutout displayCutoutForRotation(int rotation, boolean isLongEdgeCutout) { 95 RectF rectF = new RectF(); 96 if (isLongEdgeCutout) { 97 rectF.set(0, DISPLAY_HEIGHT / 4, DISPLAY_CUTOUT_HEIGHT, DISPLAY_HEIGHT * 3 / 4); 98 } else { 99 rectF.set(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT); 100 } 101 102 final Matrix m = new Matrix(); 103 transformPhysicalToLogicalCoordinates(rotation, DISPLAY_WIDTH, DISPLAY_HEIGHT, m); 104 m.mapRect(rectF); 105 106 int pos = -1; 107 switch (rotation) { 108 case ROTATION_0: 109 pos = isLongEdgeCutout ? BOUNDS_POSITION_LEFT : BOUNDS_POSITION_TOP; 110 break; 111 case ROTATION_90: 112 pos = isLongEdgeCutout ? BOUNDS_POSITION_BOTTOM : BOUNDS_POSITION_LEFT; 113 break; 114 case ROTATION_180: 115 pos = isLongEdgeCutout ? BOUNDS_POSITION_RIGHT : BOUNDS_POSITION_BOTTOM; 116 break; 117 case ROTATION_270: 118 pos = isLongEdgeCutout ? BOUNDS_POSITION_TOP : BOUNDS_POSITION_RIGHT; 119 break; 120 } 121 122 return DisplayCutout.fromBoundingRect((int) rectF.left, (int) rectF.top, 123 (int) rectF.right, (int) rectF.bottom, pos); 124 } 125 } 126