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 visible size of the screen; really; (ir)regardless of whether the status bar can 43 * be hidden but not extending into the overscan area. 44 */ 45 public final Rect mUnrestricted = new Rect(); 46 47 /** 48 * The current size of the screen; these may be different than (0,0)-(dw,dh) if the status bar 49 * can't be hidden; in that case it effectively carves out that area of the display from all 50 * other windows. 51 */ 52 public final Rect mRestricted = new Rect(); 53 54 /** 55 * During layout, the current screen borders accounting for any currently visible system UI 56 * elements. 57 */ 58 public final Rect mSystem = new Rect(); 59 60 /** For applications requesting stable content insets, these are them. */ 61 public final Rect mStable = new Rect(); 62 63 /** 64 * For applications requesting stable content insets but have also set the fullscreen window 65 * flag, these are the stable dimensions without the status bar. 66 */ 67 public final Rect mStableFullscreen = new Rect(); 68 69 /** 70 * During layout, the current screen borders with all outer decoration (status bar, input method 71 * dock) accounted for. 72 */ 73 public final Rect mCurrent = new Rect(); 74 75 /** 76 * During layout, the frame in which content should be displayed to the user, accounting for all 77 * screen decoration except for any space they deem as available for other content. This is 78 * usually the same as mCurrent*, but may be larger if the screen decor has supplied content 79 * insets. 80 */ 81 public final Rect mContent = new Rect(); 82 83 /** 84 * During layout, the frame in which voice content should be displayed to the user, accounting 85 * for all screen decoration except for any space they deem as available for other content. 86 */ 87 public final Rect mVoiceContent = new Rect(); 88 89 /** During layout, the current screen borders along which input method windows are placed. */ 90 public final Rect mDock = new Rect(); 91 92 /** The display cutout used for layout (after rotation) */ 93 @NonNull public WmDisplayCutout mDisplayCutout = WmDisplayCutout.NO_CUTOUT; 94 95 /** The cutout as supplied by display info */ 96 @NonNull public WmDisplayCutout mDisplayInfoCutout = WmDisplayCutout.NO_CUTOUT; 97 98 /** 99 * During layout, the frame that is display-cutout safe, i.e. that does not intersect with it. 100 */ 101 public final Rect mDisplayCutoutSafe = new Rect(); 102 103 public int mDisplayWidth; 104 public int mDisplayHeight; 105 106 public int mRotation; 107 DisplayFrames(int displayId, DisplayInfo info, WmDisplayCutout displayCutout)108 public DisplayFrames(int displayId, DisplayInfo info, WmDisplayCutout displayCutout) { 109 mDisplayId = displayId; 110 onDisplayInfoUpdated(info, displayCutout); 111 } 112 onDisplayInfoUpdated(DisplayInfo info, WmDisplayCutout displayCutout)113 public void onDisplayInfoUpdated(DisplayInfo info, WmDisplayCutout displayCutout) { 114 mDisplayWidth = info.logicalWidth; 115 mDisplayHeight = info.logicalHeight; 116 mRotation = info.rotation; 117 mDisplayInfoCutout = displayCutout != null ? displayCutout : WmDisplayCutout.NO_CUTOUT; 118 } 119 onBeginLayout()120 public void onBeginLayout() { 121 mUnrestricted.set(0, 0, mDisplayWidth, mDisplayHeight); 122 mRestricted.set(mUnrestricted); 123 mSystem.set(mUnrestricted); 124 mDock.set(mUnrestricted); 125 mContent.set(mUnrestricted); 126 mVoiceContent.set(mUnrestricted); 127 mStable.set(mUnrestricted); 128 mStableFullscreen.set(mUnrestricted); 129 mCurrent.set(mUnrestricted); 130 131 mDisplayCutout = mDisplayInfoCutout; 132 mDisplayCutoutSafe.set(Integer.MIN_VALUE, Integer.MIN_VALUE, 133 Integer.MAX_VALUE, Integer.MAX_VALUE); 134 if (!mDisplayCutout.getDisplayCutout().isEmpty()) { 135 final DisplayCutout c = mDisplayCutout.getDisplayCutout(); 136 if (c.getSafeInsetLeft() > 0) { 137 mDisplayCutoutSafe.left = mUnrestricted.left + c.getSafeInsetLeft(); 138 } 139 if (c.getSafeInsetTop() > 0) { 140 mDisplayCutoutSafe.top = mUnrestricted.top + c.getSafeInsetTop(); 141 } 142 if (c.getSafeInsetRight() > 0) { 143 mDisplayCutoutSafe.right = mUnrestricted.right - c.getSafeInsetRight(); 144 } 145 if (c.getSafeInsetBottom() > 0) { 146 mDisplayCutoutSafe.bottom = mUnrestricted.bottom - c.getSafeInsetBottom(); 147 } 148 } 149 } 150 getInputMethodWindowVisibleHeight()151 public int getInputMethodWindowVisibleHeight() { 152 return mDock.bottom - mCurrent.bottom; 153 } 154 dumpDebug(ProtoOutputStream proto, long fieldId)155 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 156 final long token = proto.start(fieldId); 157 mStable.dumpDebug(proto, STABLE_BOUNDS); 158 proto.end(token); 159 } 160 dump(String prefix, PrintWriter pw)161 public void dump(String prefix, PrintWriter pw) { 162 pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight 163 + " r=" + mRotation); 164 final String myPrefix = prefix + " "; 165 dumpFrame(mStable, "mStable", myPrefix, pw); 166 dumpFrame(mStableFullscreen, "mStableFullscreen", myPrefix, pw); 167 dumpFrame(mDock, "mDock", myPrefix, pw); 168 dumpFrame(mCurrent, "mCurrent", myPrefix, pw); 169 dumpFrame(mSystem, "mSystem", myPrefix, pw); 170 dumpFrame(mContent, "mContent", myPrefix, pw); 171 dumpFrame(mVoiceContent, "mVoiceContent", myPrefix, pw); 172 dumpFrame(mRestricted, "mRestricted", myPrefix, pw); 173 dumpFrame(mUnrestricted, "mUnrestricted", myPrefix, pw); 174 pw.println(myPrefix + "mDisplayCutout=" + mDisplayCutout); 175 } 176 dumpFrame(Rect frame, String name, String prefix, PrintWriter pw)177 private void dumpFrame(Rect frame, String name, String prefix, PrintWriter pw) { 178 pw.print(prefix + name + "="); frame.printShortString(pw); pw.println(); 179 } 180 } 181