1 /*
2  * Copyright (C) 2018 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.flicker;
18 
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.graphics.Point;
22 import android.graphics.Rect;
23 import android.view.Surface;
24 import android.view.WindowManager;
25 
26 import androidx.test.InstrumentationRegistry;
27 
28 /** Helper functions to retrieve system window sizes and positions. */
29 public class WindowUtils {
30 
getDisplayBounds()31     public static Rect getDisplayBounds() {
32         Point display = new Point();
33         WindowManager wm =
34                 (WindowManager)
35                         InstrumentationRegistry.getContext()
36                                 .getSystemService(Context.WINDOW_SERVICE);
37         wm.getDefaultDisplay().getRealSize(display);
38         return new Rect(0, 0, display.x, display.y);
39     }
40 
getCurrentRotation()41     private static int getCurrentRotation() {
42         WindowManager wm =
43                 (WindowManager)
44                         InstrumentationRegistry.getContext()
45                                 .getSystemService(Context.WINDOW_SERVICE);
46         return wm.getDefaultDisplay().getRotation();
47     }
48 
getDisplayBounds(int requestedRotation)49     public static Rect getDisplayBounds(int requestedRotation) {
50         Rect displayBounds = getDisplayBounds();
51         int currentDisplayRotation = getCurrentRotation();
52 
53         boolean displayIsRotated =
54                 (currentDisplayRotation == Surface.ROTATION_90
55                         || currentDisplayRotation == Surface.ROTATION_270);
56 
57         boolean requestedDisplayIsRotated =
58                 requestedRotation == Surface.ROTATION_90
59                         || requestedRotation == Surface.ROTATION_270;
60 
61         // if the current orientation changes with the requested rotation,
62         // flip height and width of display bounds.
63         if (displayIsRotated != requestedDisplayIsRotated) {
64             return new Rect(0, 0, displayBounds.height(), displayBounds.width());
65         }
66 
67         return new Rect(0, 0, displayBounds.width(), displayBounds.height());
68     }
69 
getAppPosition(int requestedRotation)70     public static Rect getAppPosition(int requestedRotation) {
71         Rect displayBounds = getDisplayBounds();
72         int currentDisplayRotation = getCurrentRotation();
73 
74         boolean displayIsRotated =
75                 currentDisplayRotation == Surface.ROTATION_90
76                         || currentDisplayRotation == Surface.ROTATION_270;
77 
78         boolean requestedAppIsRotated =
79                 requestedRotation == Surface.ROTATION_90
80                         || requestedRotation == Surface.ROTATION_270;
81 
82         // display size will change if the display is reflected. Flip height and width of app if the
83         // requested rotation is different from the current rotation.
84         if (displayIsRotated != requestedAppIsRotated) {
85             return new Rect(0, 0, displayBounds.height(), displayBounds.width());
86         }
87 
88         return new Rect(0, 0, displayBounds.width(), displayBounds.height());
89     }
90 
getStatusBarPosition(int requestedRotation)91     public static Rect getStatusBarPosition(int requestedRotation) {
92         Resources resources = InstrumentationRegistry.getContext().getResources();
93         String resourceName;
94         Rect displayBounds = getDisplayBounds();
95         int width;
96         if (requestedRotation == Surface.ROTATION_0 || requestedRotation == Surface.ROTATION_180) {
97             resourceName = "status_bar_height_portrait";
98             width = Math.min(displayBounds.width(), displayBounds.height());
99         } else {
100             resourceName = "status_bar_height_landscape";
101             width = Math.max(displayBounds.width(), displayBounds.height());
102         }
103 
104         int resourceId = resources.getIdentifier(resourceName, "dimen", "android");
105         int height = resources.getDimensionPixelSize(resourceId);
106 
107         return new Rect(0, 0, width, height);
108     }
109 
getNavigationBarPosition(int requestedRotation)110     public static Rect getNavigationBarPosition(int requestedRotation) {
111         Resources resources = InstrumentationRegistry.getContext().getResources();
112         Rect displayBounds = getDisplayBounds();
113         int displayWidth = Math.min(displayBounds.width(), displayBounds.height());
114         int displayHeight = Math.max(displayBounds.width(), displayBounds.height());
115         int resourceId;
116         if (requestedRotation == Surface.ROTATION_0 || requestedRotation == Surface.ROTATION_180) {
117             resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
118             int height = resources.getDimensionPixelSize(resourceId);
119             return new Rect(0, displayHeight - height, displayWidth, displayHeight);
120         } else {
121             resourceId = resources.getIdentifier("navigation_bar_width", "dimen", "android");
122             int width = resources.getDimensionPixelSize(resourceId);
123             // swap display dimensions in landscape or seascape mode
124             int temp = displayHeight;
125             displayHeight = displayWidth;
126             displayWidth = temp;
127             if (requestedRotation == Surface.ROTATION_90) {
128                 return new Rect(0, 0, width, displayHeight);
129             } else {
130                 return new Rect(displayWidth - width, 0, displayWidth, displayHeight);
131             }
132         }
133     }
134 
getNavigationBarHeight()135     public static int getNavigationBarHeight() {
136         Resources resources = InstrumentationRegistry.getContext().getResources();
137         int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
138         return resources.getDimensionPixelSize(resourceId);
139     }
140 
getDockedStackDividerInset()141     public static int getDockedStackDividerInset() {
142         Resources resources = InstrumentationRegistry.getContext().getResources();
143         int resourceId = resources.getIdentifier("docked_stack_divider_insets", "dimen", "android");
144         return resources.getDimensionPixelSize(resourceId);
145     }
146 }
147