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.SetupWindows( 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, 144 int right, int bottom) { 145 mErrorCollector.checkThat("stableInsets", getStableInsets(di), 146 equalTo(new Rect(left, top, right, bottom))); 147 } 148 verifyNonDecorInsets(DisplayInfo di, int left, int top, int right, int bottom)149 private void verifyNonDecorInsets(DisplayInfo di, int left, int top, 150 int right, int bottom) { 151 mErrorCollector.checkThat("nonDecorInsets", 152 getNonDecorInsets(di), equalTo(new Rect(left, top, right, bottom))); 153 } 154 verifyConsistency(DisplayInfo di)155 private void verifyConsistency(DisplayInfo di) { 156 final DisplayPolicy.DecorInsets.Info info = mDisplayPolicy.getDecorInsetsInfo( 157 di.rotation, di.logicalWidth, di.logicalHeight); 158 verifyConsistency("configDisplay", di, info.mConfigInsets, 159 info.mConfigFrame.width(), info.mConfigFrame.height()); 160 verifyConsistency("nonDecorDisplay", di, info.mNonDecorInsets, 161 info.mNonDecorFrame.width(), info.mNonDecorFrame.height()); 162 } 163 verifyConsistency(String what, DisplayInfo di, Rect insets, int width, int height)164 private void verifyConsistency(String what, DisplayInfo di, Rect insets, int width, 165 int height) { 166 mErrorCollector.checkThat(what + ":width", width, 167 equalTo(di.logicalWidth - insets.left - insets.right)); 168 mErrorCollector.checkThat(what + ":height", height, 169 equalTo(di.logicalHeight - insets.top - insets.bottom)); 170 } 171 getStableInsets(DisplayInfo di)172 private Rect getStableInsets(DisplayInfo di) { 173 return mDisplayPolicy.getDecorInsetsInfo( 174 di.rotation, di.logicalWidth, di.logicalHeight).mConfigInsets; 175 } 176 getNonDecorInsets(DisplayInfo di)177 private Rect getNonDecorInsets(DisplayInfo di) { 178 return mDisplayPolicy.getDecorInsetsInfo( 179 di.rotation, di.logicalWidth, di.logicalHeight).mNonDecorInsets; 180 } 181 displayInfoForRotation(int rotation, boolean withDisplayCutout)182 private DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) { 183 return displayInfoAndCutoutForRotation( 184 rotation, withDisplayCutout, false /* isLongEdgeCutout */); 185 } 186 } 187