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