1 /* 2 * Copyright (C) 2024 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.InsetsSource.createId; 20 import static android.view.WindowInsets.Type.displayCutout; 21 22 import android.annotation.NonNull; 23 import android.graphics.Rect; 24 import android.view.DisplayCutout; 25 import android.view.DisplayInfo; 26 import android.view.DisplayShape; 27 import android.view.InsetsState; 28 import android.view.PrivacyIndicatorBounds; 29 import android.view.RoundedCorners; 30 31 // Copied/adapted from frameworks/base/services/core/java/com/android/server/wm/DisplayFrames.java 32 public class DisplayFrames { 33 34 private static final int ID_DISPLAY_CUTOUT_LEFT = createId(null, 0, displayCutout()); 35 private static final int ID_DISPLAY_CUTOUT_TOP = createId(null, 1, displayCutout()); 36 private static final int ID_DISPLAY_CUTOUT_RIGHT = createId(null, 2, displayCutout()); 37 private static final int ID_DISPLAY_CUTOUT_BOTTOM = createId(null, 3, displayCutout()); 38 39 private final InsetsState mInsetsState; 40 private final Rect mUnrestricted = new Rect(); 41 private final Rect mDisplayCutoutSafe = new Rect(); 42 private int mWidth; 43 private int mHeight; 44 private int mRotation; 45 DisplayFrames(InsetsState insetsState, DisplayInfo info, DisplayCutout cutout, RoundedCorners roundedCorners, PrivacyIndicatorBounds indicatorBounds, DisplayShape displayShape)46 public DisplayFrames(InsetsState insetsState, DisplayInfo info, DisplayCutout cutout, 47 RoundedCorners roundedCorners, PrivacyIndicatorBounds indicatorBounds, 48 DisplayShape displayShape) { 49 mInsetsState = insetsState; 50 update(info.rotation, info.logicalWidth, info.logicalHeight, cutout, roundedCorners, 51 indicatorBounds, displayShape); 52 } 53 update(int rotation, int w, int h, @NonNull DisplayCutout displayCutout, @NonNull RoundedCorners roundedCorners, @NonNull PrivacyIndicatorBounds indicatorBounds, @NonNull DisplayShape displayShape)54 public boolean update(int rotation, int w, int h, @NonNull DisplayCutout displayCutout, 55 @NonNull RoundedCorners roundedCorners, 56 @NonNull PrivacyIndicatorBounds indicatorBounds, 57 @NonNull DisplayShape displayShape) { 58 final InsetsState state = mInsetsState; 59 final Rect safe = mDisplayCutoutSafe; 60 if (mRotation == rotation && mWidth == w && mHeight == h 61 && mInsetsState.getDisplayCutout().equals(displayCutout) 62 && state.getRoundedCorners().equals(roundedCorners) 63 && state.getPrivacyIndicatorBounds().equals(indicatorBounds)) { 64 return false; 65 } 66 mRotation = rotation; 67 mWidth = w; 68 mHeight = h; 69 final Rect u = mUnrestricted; 70 u.set(0, 0, w, h); 71 state.setDisplayFrame(u); 72 state.setDisplayCutout(displayCutout); 73 state.setRoundedCorners(roundedCorners); 74 state.setPrivacyIndicatorBounds(indicatorBounds); 75 state.setDisplayShape(displayShape); 76 state.getDisplayCutoutSafe(safe); 77 if (safe.left > u.left) { 78 state.getOrCreateSource(ID_DISPLAY_CUTOUT_LEFT, displayCutout()) 79 .setFrame(u.left, u.top, safe.left, u.bottom) 80 .updateSideHint(u); 81 } else { 82 state.removeSource(ID_DISPLAY_CUTOUT_LEFT); 83 } 84 if (safe.top > u.top) { 85 state.getOrCreateSource(ID_DISPLAY_CUTOUT_TOP, displayCutout()) 86 .setFrame(u.left, u.top, u.right, safe.top) 87 .updateSideHint(u); 88 } else { 89 state.removeSource(ID_DISPLAY_CUTOUT_TOP); 90 } 91 if (safe.right < u.right) { 92 state.getOrCreateSource(ID_DISPLAY_CUTOUT_RIGHT, displayCutout()) 93 .setFrame(safe.right, u.top, u.right, u.bottom) 94 .updateSideHint(u); 95 } else { 96 state.removeSource(ID_DISPLAY_CUTOUT_RIGHT); 97 } 98 if (safe.bottom < u.bottom) { 99 state.getOrCreateSource(ID_DISPLAY_CUTOUT_BOTTOM, displayCutout()) 100 .setFrame(u.left, safe.bottom, u.right, u.bottom) 101 .updateSideHint(u); 102 } else { 103 state.removeSource(ID_DISPLAY_CUTOUT_BOTTOM); 104 } 105 return true; 106 } 107 }