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.util.DisplayMetrics.DENSITY_DEFAULT; 20 import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM; 21 import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT; 22 import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT; 23 import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; 24 import static android.view.Surface.ROTATION_0; 25 import static android.view.Surface.ROTATION_180; 26 import static android.view.Surface.ROTATION_270; 27 import static android.view.Surface.ROTATION_90; 28 29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 30 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; 31 import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates; 32 33 import static org.junit.Assert.assertEquals; 34 35 import android.content.Context; 36 import android.content.ContextWrapper; 37 import android.content.pm.PackageManager; 38 import android.content.res.Resources; 39 import android.graphics.Matrix; 40 import android.graphics.RectF; 41 import android.os.Binder; 42 import android.os.IBinder; 43 import android.testing.TestableResources; 44 import android.util.Pair; 45 import android.view.DisplayCutout; 46 import android.view.DisplayInfo; 47 import android.view.Gravity; 48 import android.view.View; 49 import android.view.WindowManagerGlobal; 50 51 import com.android.internal.R; 52 import com.android.server.wm.utils.WmDisplayCutout; 53 54 import org.junit.Before; 55 56 public class DisplayPolicyTestsBase extends WindowTestsBase { 57 58 static final int DISPLAY_WIDTH = 500; 59 static final int DISPLAY_HEIGHT = 1000; 60 static final int DISPLAY_DENSITY = 320; 61 62 static final int STATUS_BAR_HEIGHT = 10; 63 static final int NAV_BAR_HEIGHT = 15; 64 static final int DISPLAY_CUTOUT_HEIGHT = 8; 65 66 DisplayPolicy mDisplayPolicy; 67 68 @Before setUpDisplayPolicy()69 public void setUpDisplayPolicy() { 70 mDisplayPolicy = spy(mDisplayContent.getDisplayPolicy()); 71 72 final TestContextWrapper context = new TestContextWrapper( 73 mDisplayPolicy.getContext(), mDisplayPolicy.getCurrentUserResources()); 74 final TestableResources resources = context.getResourceMocker(); 75 resources.addOverride(R.dimen.status_bar_height_portrait, STATUS_BAR_HEIGHT); 76 resources.addOverride(R.dimen.status_bar_height_landscape, STATUS_BAR_HEIGHT); 77 resources.addOverride(R.dimen.navigation_bar_height, NAV_BAR_HEIGHT); 78 resources.addOverride(R.dimen.navigation_bar_height_landscape, NAV_BAR_HEIGHT); 79 resources.addOverride(R.dimen.navigation_bar_width, NAV_BAR_HEIGHT); 80 doReturn(resources.getResources()).when(mDisplayPolicy).getCurrentUserResources(); 81 doReturn(true).when(mDisplayPolicy).hasNavigationBar(); 82 doReturn(true).when(mDisplayPolicy).hasStatusBar(); 83 84 final int shortSizeDp = 85 Math.min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * DENSITY_DEFAULT / DISPLAY_DENSITY; 86 final int longSizeDp = 87 Math.min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * DENSITY_DEFAULT / DISPLAY_DENSITY; 88 mDisplayContent.getDisplayRotation().configure( 89 DISPLAY_WIDTH, DISPLAY_HEIGHT, shortSizeDp, longSizeDp); 90 mDisplayPolicy.onConfigurationChanged(); 91 92 mStatusBarWindow.mAttrs.gravity = Gravity.TOP; 93 addWindow(mStatusBarWindow); 94 mDisplayPolicy.mLastSystemUiFlags |= View.STATUS_BAR_TRANSPARENT; 95 96 mNavBarWindow.mAttrs.gravity = Gravity.BOTTOM; 97 addWindow(mNavBarWindow); 98 mDisplayPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT; 99 } 100 addWindow(WindowState win)101 void addWindow(WindowState win) { 102 mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(), 103 Binder.getCallingUid()); 104 assertEquals(WindowManagerGlobal.ADD_OKAY, 105 mDisplayPolicy.prepareAddWindowLw(win, win.mAttrs)); 106 win.mHasSurface = true; 107 } 108 displayInfoAndCutoutForRotation(int rotation, boolean withDisplayCutout)109 static Pair<DisplayInfo, WmDisplayCutout> displayInfoAndCutoutForRotation(int rotation, 110 boolean withDisplayCutout) { 111 final DisplayInfo info = new DisplayInfo(); 112 WmDisplayCutout cutout = null; 113 114 final boolean flippedDimensions = rotation == ROTATION_90 || rotation == ROTATION_270; 115 info.logicalWidth = flippedDimensions ? DISPLAY_HEIGHT : DISPLAY_WIDTH; 116 info.logicalHeight = flippedDimensions ? DISPLAY_WIDTH : DISPLAY_HEIGHT; 117 info.rotation = rotation; 118 if (withDisplayCutout) { 119 cutout = WmDisplayCutout.computeSafeInsets( 120 displayCutoutForRotation(rotation), info.logicalWidth, 121 info.logicalHeight); 122 info.displayCutout = cutout.getDisplayCutout(); 123 } else { 124 info.displayCutout = null; 125 } 126 return Pair.create(info, cutout); 127 } 128 displayCutoutForRotation(int rotation)129 private static DisplayCutout displayCutoutForRotation(int rotation) { 130 final RectF rectF = 131 new RectF(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT); 132 133 final Matrix m = new Matrix(); 134 transformPhysicalToLogicalCoordinates(rotation, DISPLAY_WIDTH, DISPLAY_HEIGHT, m); 135 m.mapRect(rectF); 136 137 int pos = -1; 138 switch (rotation) { 139 case ROTATION_0: 140 pos = BOUNDS_POSITION_TOP; 141 break; 142 case ROTATION_90: 143 pos = BOUNDS_POSITION_LEFT; 144 break; 145 case ROTATION_180: 146 pos = BOUNDS_POSITION_BOTTOM; 147 break; 148 case ROTATION_270: 149 pos = BOUNDS_POSITION_RIGHT; 150 break; 151 } 152 153 return DisplayCutout.fromBoundingRect((int) rectF.left, (int) rectF.top, 154 (int) rectF.right, (int) rectF.bottom, pos); 155 } 156 157 static class TestContextWrapper extends ContextWrapper { 158 private final TestableResources mResourceMocker; 159 TestContextWrapper(Context targetContext, Resources targetResources)160 TestContextWrapper(Context targetContext, Resources targetResources) { 161 super(targetContext); 162 mResourceMocker = new TestableResources(targetResources); 163 } 164 165 @Override checkPermission(String permission, int pid, int uid)166 public int checkPermission(String permission, int pid, int uid) { 167 return PackageManager.PERMISSION_GRANTED; 168 } 169 170 @Override checkPermission(String permission, int pid, int uid, IBinder callerToken)171 public int checkPermission(String permission, int pid, int uid, IBinder callerToken) { 172 return PackageManager.PERMISSION_GRANTED; 173 } 174 175 @Override getResources()176 public Resources getResources() { 177 return mResourceMocker.getResources(); 178 } 179 getResourceMocker()180 TestableResources getResourceMocker() { 181 return mResourceMocker; 182 } 183 } 184 185 } 186