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.Surface.ROTATION_0; 20 import static android.view.Surface.ROTATION_180; 21 import static android.view.Surface.ROTATION_270; 22 import static android.view.Surface.ROTATION_90; 23 24 import static org.hamcrest.Matchers.equalTo; 25 26 import android.graphics.Rect; 27 import android.platform.test.annotations.Presubmit; 28 import android.view.DisplayInfo; 29 30 import androidx.test.filters.SmallTest; 31 32 import org.junit.Rule; 33 import org.junit.Test; 34 import org.junit.rules.ErrorCollector; 35 import org.junit.runner.RunWith; 36 37 @SmallTest 38 @Presubmit 39 @WindowTestsBase.UseTestDisplay( 40 addWindows = { WindowTestsBase.W_STATUS_BAR, WindowTestsBase.W_NAVIGATION_BAR }) 41 @RunWith(WindowTestRunner.class) 42 public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { 43 44 @Rule 45 public final ErrorCollector mErrorCollector = new ErrorCollector(); 46 47 @Test portrait()48 public void portrait() { 49 final DisplayInfo di = displayInfoForRotation(ROTATION_0, false /* withCutout */); 50 51 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); 52 verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT); 53 verifyConsistency(di); 54 } 55 56 @Test portrait_withCutout()57 public void portrait_withCutout() { 58 final DisplayInfo di = displayInfoForRotation(ROTATION_0, true /* withCutout */); 59 60 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); 61 verifyNonDecorInsets(di, 0, DISPLAY_CUTOUT_HEIGHT, 0, NAV_BAR_HEIGHT); 62 verifyConsistency(di); 63 } 64 65 @Test landscape()66 public void landscape() { 67 final DisplayInfo di = displayInfoForRotation(ROTATION_90, false /* withCutout */); 68 69 if (mDisplayPolicy.navigationBarCanMove()) { 70 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); 71 verifyNonDecorInsets(di, 0, 0, NAV_BAR_HEIGHT, 0); 72 } else { 73 // if the navigation bar cannot move then it is always on the bottom 74 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); 75 verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT); 76 } 77 verifyConsistency(di); 78 } 79 80 @Test landscape_withCutout()81 public void landscape_withCutout() { 82 final DisplayInfo di = displayInfoForRotation(ROTATION_90, true /* withCutout */); 83 84 if (mDisplayPolicy.navigationBarCanMove()) { 85 verifyStableInsets(di, DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); 86 verifyNonDecorInsets(di, DISPLAY_CUTOUT_HEIGHT, 0, NAV_BAR_HEIGHT, 0); 87 } else { 88 // if the navigation bar cannot move then it is always on the bottom 89 verifyStableInsets(di, DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); 90 verifyNonDecorInsets(di, DISPLAY_CUTOUT_HEIGHT, 0, 0, NAV_BAR_HEIGHT); 91 } 92 verifyConsistency(di); 93 } 94 95 @Test seascape()96 public void seascape() { 97 final DisplayInfo di = displayInfoForRotation(ROTATION_270, false /* withCutout */); 98 99 if (mDisplayPolicy.navigationBarCanMove()) { 100 verifyStableInsets(di, NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0); 101 verifyNonDecorInsets(di, NAV_BAR_HEIGHT, 0, 0, 0); 102 } else { 103 // if the navigation bar cannot move then it is always on the bottom 104 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); 105 verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT); 106 } 107 verifyConsistency(di); 108 } 109 110 @Test seascape_withCutout()111 public void seascape_withCutout() { 112 final DisplayInfo di = displayInfoForRotation(ROTATION_270, true /* withCutout */); 113 114 if (mDisplayPolicy.navigationBarCanMove()) { 115 verifyStableInsets(di, NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0); 116 verifyNonDecorInsets(di, NAV_BAR_HEIGHT, 0, DISPLAY_CUTOUT_HEIGHT, 0); 117 } else { 118 // if the navigation bar cannot move then it is always on the bottom 119 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, NAV_BAR_HEIGHT); 120 verifyNonDecorInsets(di, 0, 0, DISPLAY_CUTOUT_HEIGHT, NAV_BAR_HEIGHT); 121 } 122 verifyConsistency(di); 123 } 124 125 @Test upsideDown()126 public void upsideDown() { 127 final DisplayInfo di = displayInfoForRotation(ROTATION_180, false /* withCutout */); 128 129 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); 130 verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT); 131 verifyConsistency(di); 132 } 133 134 @Test upsideDown_withCutout()135 public void upsideDown_withCutout() { 136 final DisplayInfo di = displayInfoForRotation(ROTATION_180, true /* withCutout */); 137 138 verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT + DISPLAY_CUTOUT_HEIGHT); 139 verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT + DISPLAY_CUTOUT_HEIGHT); 140 verifyConsistency(di); 141 } 142 verifyStableInsets(DisplayInfo di, int left, int top, int right, int bottom)143 private void verifyStableInsets(DisplayInfo di, int left, int top, int right, int bottom) { 144 mErrorCollector.checkThat("stableInsets", getStableInsetsLw(di), equalTo(new Rect( 145 left, top, right, bottom))); 146 } 147 verifyNonDecorInsets(DisplayInfo di, int left, int top, int right, int bottom)148 private void verifyNonDecorInsets(DisplayInfo di, int left, int top, int right, int bottom) { 149 mErrorCollector.checkThat("nonDecorInsets", getNonDecorInsetsLw(di), equalTo(new Rect( 150 left, top, right, bottom))); 151 } 152 verifyConsistency(DisplayInfo di)153 private void verifyConsistency(DisplayInfo di) { 154 verifyConsistency("configDisplay", di, getStableInsetsLw(di), 155 getConfigDisplayWidth(di), getConfigDisplayHeight(di)); 156 verifyConsistency("nonDecorDisplay", di, getNonDecorInsetsLw(di), 157 getNonDecorDisplayWidth(di), getNonDecorDisplayHeight(di)); 158 } 159 verifyConsistency(String what, DisplayInfo di, Rect insets, int width, int height)160 private void verifyConsistency(String what, DisplayInfo di, Rect insets, int width, 161 int height) { 162 mErrorCollector.checkThat(what + ":width", width, 163 equalTo(di.logicalWidth - insets.left - insets.right)); 164 mErrorCollector.checkThat(what + ":height", height, 165 equalTo(di.logicalHeight - insets.top - insets.bottom)); 166 } 167 getStableInsetsLw(DisplayInfo di)168 private Rect getStableInsetsLw(DisplayInfo di) { 169 Rect result = new Rect(); 170 mDisplayPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, 171 di.displayCutout, result); 172 return result; 173 } 174 getNonDecorInsetsLw(DisplayInfo di)175 private Rect getNonDecorInsetsLw(DisplayInfo di) { 176 Rect result = new Rect(); 177 mDisplayPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, 178 di.displayCutout, result); 179 return result; 180 } 181 getNonDecorDisplayWidth(DisplayInfo di)182 private int getNonDecorDisplayWidth(DisplayInfo di) { 183 return mDisplayPolicy.getNonDecorDisplayWidth(di.logicalWidth, di.logicalHeight, 184 di.rotation, 0 /* ui */, di.displayCutout); 185 } 186 getNonDecorDisplayHeight(DisplayInfo di)187 private int getNonDecorDisplayHeight(DisplayInfo di) { 188 return mDisplayPolicy.getNonDecorDisplayHeight(di.logicalWidth, di.logicalHeight, 189 di.rotation, 0 /* ui */, di.displayCutout); 190 } 191 getConfigDisplayWidth(DisplayInfo di)192 private int getConfigDisplayWidth(DisplayInfo di) { 193 return mDisplayPolicy.getConfigDisplayWidth(di.logicalWidth, di.logicalHeight, 194 di.rotation, 0 /* ui */, di.displayCutout); 195 } 196 getConfigDisplayHeight(DisplayInfo di)197 private int getConfigDisplayHeight(DisplayInfo di) { 198 return mDisplayPolicy.getConfigDisplayHeight(di.logicalWidth, di.logicalHeight, 199 di.rotation, 0 /* ui */, di.displayCutout); 200 } 201 displayInfoForRotation(int rotation, boolean withDisplayCutout)202 private static DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) { 203 return displayInfoAndCutoutForRotation(rotation, withDisplayCutout, false).first; 204 } 205 } 206