1 /* 2 * Copyright (C) 2017 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_180; 20 import static android.view.Surface.ROTATION_270; 21 import static android.view.Surface.ROTATION_90; 22 import static com.android.server.wm.DisplayFramesProto.STABLE_BOUNDS; 23 24 import android.annotation.NonNull; 25 import android.graphics.Rect; 26 import android.util.proto.ProtoOutputStream; 27 import android.view.DisplayCutout; 28 import android.view.DisplayInfo; 29 30 import com.android.server.wm.utils.WmDisplayCutout; 31 32 import java.io.PrintWriter; 33 34 /** 35 * Container class for all the display frames that affect how we do window layout on a display. 36 * @hide 37 */ 38 public class DisplayFrames { 39 public final int mDisplayId; 40 41 /** 42 * The current size of the screen; really; extends into the overscan area of the screen and 43 * doesn't account for any system elements like the status bar. 44 */ 45 public final Rect mOverscan = new Rect(); 46 47 /** 48 * The current visible size of the screen; really; (ir)regardless of whether the status bar can 49 * be hidden but not extending into the overscan area. 50 */ 51 public final Rect mUnrestricted = new Rect(); 52 53 /** Like mOverscan*, but allowed to move into the overscan region where appropriate. */ 54 public final Rect mRestrictedOverscan = new Rect(); 55 56 /** 57 * The current size of the screen; these may be different than (0,0)-(dw,dh) if the status bar 58 * can't be hidden; in that case it effectively carves out that area of the display from all 59 * other windows. 60 */ 61 public final Rect mRestricted = new Rect(); 62 63 /** 64 * During layout, the current screen borders accounting for any currently visible system UI 65 * elements. 66 */ 67 public final Rect mSystem = new Rect(); 68 69 /** For applications requesting stable content insets, these are them. */ 70 public final Rect mStable = new Rect(); 71 72 /** 73 * For applications requesting stable content insets but have also set the fullscreen window 74 * flag, these are the stable dimensions without the status bar. 75 */ 76 public final Rect mStableFullscreen = new Rect(); 77 78 /** 79 * During layout, the current screen borders with all outer decoration (status bar, input method 80 * dock) accounted for. 81 */ 82 public final Rect mCurrent = new Rect(); 83 84 /** 85 * During layout, the frame in which content should be displayed to the user, accounting for all 86 * screen decoration except for any space they deem as available for other content. This is 87 * usually the same as mCurrent*, but may be larger if the screen decor has supplied content 88 * insets. 89 */ 90 public final Rect mContent = new Rect(); 91 92 /** 93 * During layout, the frame in which voice content should be displayed to the user, accounting 94 * for all screen decoration except for any space they deem as available for other content. 95 */ 96 public final Rect mVoiceContent = new Rect(); 97 98 /** During layout, the current screen borders along which input method windows are placed. */ 99 public final Rect mDock = new Rect(); 100 101 /** The display cutout used for layout (after rotation) */ 102 @NonNull public WmDisplayCutout mDisplayCutout = WmDisplayCutout.NO_CUTOUT; 103 104 /** The cutout as supplied by display info */ 105 @NonNull public WmDisplayCutout mDisplayInfoCutout = WmDisplayCutout.NO_CUTOUT; 106 107 /** 108 * During layout, the frame that is display-cutout safe, i.e. that does not intersect with it. 109 */ 110 public final Rect mDisplayCutoutSafe = new Rect(); 111 112 private final Rect mDisplayInfoOverscan = new Rect(); 113 private final Rect mRotatedDisplayInfoOverscan = new Rect(); 114 public int mDisplayWidth; 115 public int mDisplayHeight; 116 117 public int mRotation; 118 DisplayFrames(int displayId, DisplayInfo info, WmDisplayCutout displayCutout)119 public DisplayFrames(int displayId, DisplayInfo info, WmDisplayCutout displayCutout) { 120 mDisplayId = displayId; 121 onDisplayInfoUpdated(info, displayCutout); 122 } 123 onDisplayInfoUpdated(DisplayInfo info, WmDisplayCutout displayCutout)124 public void onDisplayInfoUpdated(DisplayInfo info, WmDisplayCutout displayCutout) { 125 mDisplayWidth = info.logicalWidth; 126 mDisplayHeight = info.logicalHeight; 127 mRotation = info.rotation; 128 mDisplayInfoOverscan.set( 129 info.overscanLeft, info.overscanTop, info.overscanRight, info.overscanBottom); 130 mDisplayInfoCutout = displayCutout != null ? displayCutout : WmDisplayCutout.NO_CUTOUT; 131 } 132 onBeginLayout()133 public void onBeginLayout() { 134 switch (mRotation) { 135 case ROTATION_90: 136 mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.top; 137 mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.right; 138 mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.bottom; 139 mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.left; 140 break; 141 case ROTATION_180: 142 mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.right; 143 mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.bottom; 144 mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.left; 145 mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.top; 146 break; 147 case ROTATION_270: 148 mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.bottom; 149 mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.left; 150 mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.top; 151 mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.right; 152 break; 153 default: 154 mRotatedDisplayInfoOverscan.set(mDisplayInfoOverscan); 155 break; 156 } 157 158 mRestrictedOverscan.set(0, 0, mDisplayWidth, mDisplayHeight); 159 mOverscan.set(mRestrictedOverscan); 160 mSystem.set(mRestrictedOverscan); 161 mUnrestricted.set(mRotatedDisplayInfoOverscan); 162 mUnrestricted.right = mDisplayWidth - mUnrestricted.right; 163 mUnrestricted.bottom = mDisplayHeight - mUnrestricted.bottom; 164 mRestricted.set(mUnrestricted); 165 mDock.set(mUnrestricted); 166 mContent.set(mUnrestricted); 167 mVoiceContent.set(mUnrestricted); 168 mStable.set(mUnrestricted); 169 mStableFullscreen.set(mUnrestricted); 170 mCurrent.set(mUnrestricted); 171 172 mDisplayCutout = mDisplayInfoCutout; 173 mDisplayCutoutSafe.set(Integer.MIN_VALUE, Integer.MIN_VALUE, 174 Integer.MAX_VALUE, Integer.MAX_VALUE); 175 if (!mDisplayCutout.getDisplayCutout().isEmpty()) { 176 final DisplayCutout c = mDisplayCutout.getDisplayCutout(); 177 if (c.getSafeInsetLeft() > 0) { 178 mDisplayCutoutSafe.left = mRestrictedOverscan.left + c.getSafeInsetLeft(); 179 } 180 if (c.getSafeInsetTop() > 0) { 181 mDisplayCutoutSafe.top = mRestrictedOverscan.top + c.getSafeInsetTop(); 182 } 183 if (c.getSafeInsetRight() > 0) { 184 mDisplayCutoutSafe.right = mRestrictedOverscan.right - c.getSafeInsetRight(); 185 } 186 if (c.getSafeInsetBottom() > 0) { 187 mDisplayCutoutSafe.bottom = mRestrictedOverscan.bottom - c.getSafeInsetBottom(); 188 } 189 } 190 } 191 getInputMethodWindowVisibleHeight()192 public int getInputMethodWindowVisibleHeight() { 193 return mDock.bottom - mCurrent.bottom; 194 } 195 writeToProto(ProtoOutputStream proto, long fieldId)196 public void writeToProto(ProtoOutputStream proto, long fieldId) { 197 final long token = proto.start(fieldId); 198 mStable.writeToProto(proto, STABLE_BOUNDS); 199 proto.end(token); 200 } 201 dump(String prefix, PrintWriter pw)202 public void dump(String prefix, PrintWriter pw) { 203 pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight 204 + " r=" + mRotation); 205 final String myPrefix = prefix + " "; 206 dumpFrame(mStable, "mStable", myPrefix, pw); 207 dumpFrame(mStableFullscreen, "mStableFullscreen", myPrefix, pw); 208 dumpFrame(mDock, "mDock", myPrefix, pw); 209 dumpFrame(mCurrent, "mCurrent", myPrefix, pw); 210 dumpFrame(mSystem, "mSystem", myPrefix, pw); 211 dumpFrame(mContent, "mContent", myPrefix, pw); 212 dumpFrame(mVoiceContent, "mVoiceContent", myPrefix, pw); 213 dumpFrame(mOverscan, "mOverscan", myPrefix, pw); 214 dumpFrame(mRestrictedOverscan, "mRestrictedOverscan", myPrefix, pw); 215 dumpFrame(mRestricted, "mRestricted", myPrefix, pw); 216 dumpFrame(mUnrestricted, "mUnrestricted", myPrefix, pw); 217 dumpFrame(mDisplayInfoOverscan, "mDisplayInfoOverscan", myPrefix, pw); 218 dumpFrame(mRotatedDisplayInfoOverscan, "mRotatedDisplayInfoOverscan", myPrefix, pw); 219 pw.println(myPrefix + "mDisplayCutout=" + mDisplayCutout); 220 } 221 dumpFrame(Rect frame, String name, String prefix, PrintWriter pw)222 private void dumpFrame(Rect frame, String name, String prefix, PrintWriter pw) { 223 pw.print(prefix + name + "="); frame.printShortString(pw); pw.println(); 224 } 225 } 226