1 /* 2 * Copyright (C) 2021 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 androidx.window.util; 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 android.app.Activity; 25 import android.graphics.Rect; 26 import android.hardware.display.DisplayManagerGlobal; 27 import android.view.DisplayInfo; 28 import android.view.Surface; 29 30 import androidx.annotation.NonNull; 31 import androidx.annotation.Nullable; 32 33 /** 34 * Util class for both Sidecar and Extensions. 35 */ 36 public final class ExtensionHelper { 37 ExtensionHelper()38 private ExtensionHelper() { 39 // Util class, no instances should be created. 40 } 41 42 /** 43 * Rotates the input rectangle specified in default display orientation to the current display 44 * rotation. 45 */ rotateRectToDisplayRotation(int displayId, Rect inOutRect)46 public static void rotateRectToDisplayRotation(int displayId, Rect inOutRect) { 47 DisplayManagerGlobal dmGlobal = DisplayManagerGlobal.getInstance(); 48 DisplayInfo displayInfo = dmGlobal.getDisplayInfo(displayId); 49 int rotation = displayInfo.rotation; 50 51 boolean isSideRotation = rotation == ROTATION_90 || rotation == ROTATION_270; 52 int displayWidth = isSideRotation ? displayInfo.logicalHeight : displayInfo.logicalWidth; 53 int displayHeight = isSideRotation ? displayInfo.logicalWidth : displayInfo.logicalHeight; 54 55 inOutRect.intersect(0, 0, displayWidth, displayHeight); 56 57 rotateBounds(inOutRect, displayWidth, displayHeight, rotation); 58 } 59 60 /** 61 * Rotates the input rectangle within parent bounds for a given delta. 62 */ rotateBounds(Rect inOutRect, int parentWidth, int parentHeight, @Surface.Rotation int delta)63 private static void rotateBounds(Rect inOutRect, int parentWidth, int parentHeight, 64 @Surface.Rotation int delta) { 65 int origLeft = inOutRect.left; 66 switch (delta) { 67 case ROTATION_0: 68 return; 69 case ROTATION_90: 70 inOutRect.left = inOutRect.top; 71 inOutRect.top = parentWidth - inOutRect.right; 72 inOutRect.right = inOutRect.bottom; 73 inOutRect.bottom = parentWidth - origLeft; 74 return; 75 case ROTATION_180: 76 inOutRect.left = parentWidth - inOutRect.right; 77 inOutRect.right = parentWidth - origLeft; 78 return; 79 case ROTATION_270: 80 inOutRect.left = parentHeight - inOutRect.bottom; 81 inOutRect.bottom = inOutRect.right; 82 inOutRect.right = parentHeight - inOutRect.top; 83 inOutRect.top = origLeft; 84 return; 85 } 86 } 87 88 /** Transforms rectangle from absolute coordinate space to the window coordinate space. */ transformToWindowSpaceRect(Activity activity, Rect inOutRect)89 public static void transformToWindowSpaceRect(Activity activity, Rect inOutRect) { 90 Rect windowRect = getWindowBounds(activity); 91 if (windowRect == null) { 92 inOutRect.setEmpty(); 93 return; 94 } 95 if (!Rect.intersects(inOutRect, windowRect)) { 96 inOutRect.setEmpty(); 97 return; 98 } 99 inOutRect.intersect(windowRect); 100 inOutRect.offset(-windowRect.left, -windowRect.top); 101 } 102 103 /** 104 * Gets the current window bounds in absolute coordinates. 105 */ 106 @Nullable getWindowBounds(@onNull Activity activity)107 private static Rect getWindowBounds(@NonNull Activity activity) { 108 return activity.getWindowManager().getCurrentWindowMetrics().getBounds(); 109 } 110 111 /** 112 * Checks if both dimensions of the given rect are zero at the same time. 113 */ isZero(@onNull Rect rect)114 public static boolean isZero(@NonNull Rect rect) { 115 return rect.height() == 0 && rect.width() == 0; 116 } 117 } 118