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.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT; 20 import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT; 21 import static android.view.InsetsState.ITYPE_RIGHT_DISPLAY_CUTOUT; 22 import static android.view.InsetsState.ITYPE_TOP_DISPLAY_CUTOUT; 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 import android.view.InsetsState; 30 import android.view.PrivacyIndicatorBounds; 31 import android.view.RoundedCorners; 32 33 import java.io.PrintWriter; 34 35 /** 36 * Container class for all the display frames that affect how we do window layout on a display. 37 * @hide 38 */ 39 public class DisplayFrames { 40 public final InsetsState mInsetsState; 41 42 /** 43 * The current visible size of the screen; really; (ir)regardless of whether the status bar can 44 * be hidden but not extending into the overscan area. 45 */ 46 public final Rect mUnrestricted = new Rect(); 47 48 /** 49 * During layout, the frame that is display-cutout safe, i.e. that does not intersect with it. 50 */ 51 public final Rect mDisplayCutoutSafe = new Rect(); 52 53 public int mWidth; 54 public int mHeight; 55 56 public int mRotation; 57 DisplayFrames(InsetsState insetsState, DisplayInfo info, DisplayCutout cutout, RoundedCorners roundedCorners, PrivacyIndicatorBounds indicatorBounds)58 public DisplayFrames(InsetsState insetsState, DisplayInfo info, DisplayCutout cutout, 59 RoundedCorners roundedCorners, PrivacyIndicatorBounds indicatorBounds) { 60 mInsetsState = insetsState; 61 update(info.rotation, info.logicalWidth, info.logicalHeight, cutout, roundedCorners, 62 indicatorBounds); 63 } 64 DisplayFrames()65 DisplayFrames() { 66 mInsetsState = new InsetsState(); 67 } 68 69 /** 70 * This is called if the display info may be changed, e.g. rotation, size, insets. 71 * 72 * @return {@code true} if anything has been changed; {@code false} otherwise. 73 */ update(int rotation, int w, int h, @NonNull DisplayCutout displayCutout, @NonNull RoundedCorners roundedCorners, @NonNull PrivacyIndicatorBounds indicatorBounds)74 public boolean update(int rotation, int w, int h, @NonNull DisplayCutout displayCutout, 75 @NonNull RoundedCorners roundedCorners, 76 @NonNull PrivacyIndicatorBounds indicatorBounds) { 77 final InsetsState state = mInsetsState; 78 final Rect safe = mDisplayCutoutSafe; 79 if (mRotation == rotation && mWidth == w && mHeight == h 80 && mInsetsState.getDisplayCutout().equals(displayCutout) 81 && state.getRoundedCorners().equals(roundedCorners) 82 && state.getPrivacyIndicatorBounds().equals(indicatorBounds)) { 83 return false; 84 } 85 mRotation = rotation; 86 mWidth = w; 87 mHeight = h; 88 final Rect unrestricted = mUnrestricted; 89 unrestricted.set(0, 0, w, h); 90 state.setDisplayFrame(unrestricted); 91 state.setDisplayCutout(displayCutout); 92 state.setRoundedCorners(roundedCorners); 93 state.setPrivacyIndicatorBounds(indicatorBounds); 94 state.getDisplayCutoutSafe(safe); 95 if (safe.left > unrestricted.left) { 96 state.getSource(ITYPE_LEFT_DISPLAY_CUTOUT).setFrame( 97 unrestricted.left, unrestricted.top, safe.left, unrestricted.bottom); 98 } else { 99 state.removeSource(ITYPE_LEFT_DISPLAY_CUTOUT); 100 } 101 if (safe.top > unrestricted.top) { 102 state.getSource(ITYPE_TOP_DISPLAY_CUTOUT).setFrame( 103 unrestricted.left, unrestricted.top, unrestricted.right, safe.top); 104 } else { 105 state.removeSource(ITYPE_TOP_DISPLAY_CUTOUT); 106 } 107 if (safe.right < unrestricted.right) { 108 state.getSource(ITYPE_RIGHT_DISPLAY_CUTOUT).setFrame( 109 safe.right, unrestricted.top, unrestricted.right, unrestricted.bottom); 110 } else { 111 state.removeSource(ITYPE_RIGHT_DISPLAY_CUTOUT); 112 } 113 if (safe.bottom < unrestricted.bottom) { 114 state.getSource(ITYPE_BOTTOM_DISPLAY_CUTOUT).setFrame( 115 unrestricted.left, safe.bottom, unrestricted.right, unrestricted.bottom); 116 } else { 117 state.removeSource(ITYPE_BOTTOM_DISPLAY_CUTOUT); 118 } 119 return true; 120 } 121 dumpDebug(ProtoOutputStream proto, long fieldId)122 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 123 final long token = proto.start(fieldId); 124 proto.end(token); 125 } 126 dump(String prefix, PrintWriter pw)127 public void dump(String prefix, PrintWriter pw) { 128 pw.println(prefix + "DisplayFrames w=" + mWidth + " h=" + mHeight + " r=" + mRotation); 129 } 130 } 131