• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
20 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
21 
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
26 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
27 
28 import static org.mockito.ArgumentMatchers.any;
29 
30 import android.content.res.Configuration;
31 import android.graphics.Insets;
32 import android.graphics.Rect;
33 import android.hardware.display.DisplayManagerGlobal;
34 import android.view.Display;
35 import android.view.DisplayCutout;
36 import android.view.DisplayInfo;
37 
38 class TestDisplayContent extends DisplayContent {
39 
40     public static final int DEFAULT_LOGICAL_DISPLAY_DENSITY = 300;
41 
42     /** Please use the {@link Builder} to create, visible for use in test builder overrides only. */
TestDisplayContent(RootWindowContainer rootWindowContainer, Display display)43     TestDisplayContent(RootWindowContainer rootWindowContainer, Display display) {
44         super(display, rootWindowContainer);
45         // Normally this comes from display-properties as exposed by WM. Without that, just
46         // hard-code to FULLSCREEN for tests.
47         setWindowingMode(WINDOWING_MODE_FULLSCREEN);
48         spyOn(this);
49         forAllTaskDisplayAreas(taskDisplayArea -> {
50             spyOn(taskDisplayArea);
51         });
52         final DisplayRotation displayRotation = getDisplayRotation();
53         spyOn(displayRotation);
54         doAnswer(invocation -> {
55             // Bypass all the rotation animation and display freezing stuff for testing and just
56             // set the rotation we want for the display
57             final int oldRotation = displayRotation.getRotation();
58             final int rotation = displayRotation.rotationForOrientation(
59                     displayRotation.getLastOrientation(), oldRotation);
60             if (oldRotation == rotation) {
61                 return false;
62             }
63             setLayoutNeeded();
64             displayRotation.setRotation(rotation);
65             return true;
66         }).when(displayRotation).updateRotationUnchecked(anyBoolean());
67 
68         final InputMonitor inputMonitor = getInputMonitor();
69         spyOn(inputMonitor);
70         doNothing().when(inputMonitor).resumeDispatchingLw(any());
71     }
72 
73     public static class Builder {
74         private final DisplayInfo mInfo;
75         private boolean mCanRotate = true;
76         private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
77         private int mPosition = POSITION_BOTTOM;
78         protected final ActivityTaskManagerService mService;
79         private boolean mSystemDecorations = false;
80 
Builder(ActivityTaskManagerService service, int width, int height)81         Builder(ActivityTaskManagerService service, int width, int height) {
82             mService = service;
83             mInfo = new DisplayInfo();
84             mService.mContext.getDisplay().getDisplayInfo(mInfo);
85             mInfo.logicalWidth = width;
86             mInfo.logicalHeight = height;
87             mInfo.logicalDensityDpi = DEFAULT_LOGICAL_DISPLAY_DENSITY;
88             mInfo.displayCutout = null;
89             // Set unique ID so physical display overrides are not inheritted from
90             // DisplayWindowSettings.
91             mInfo.uniqueId = generateUniqueId();
92         }
Builder(ActivityTaskManagerService service, DisplayInfo info)93         Builder(ActivityTaskManagerService service, DisplayInfo info) {
94             mService = service;
95             mInfo = info;
96             // Set unique ID so physical display overrides are not inheritted from
97             // DisplayWindowSettings.
98             mInfo.uniqueId = generateUniqueId();
99         }
generateUniqueId()100         private String generateUniqueId() {
101             return "TEST_DISPLAY_CONTENT_" + System.currentTimeMillis();
102         }
setSystemDecorations(boolean yes)103         Builder setSystemDecorations(boolean yes) {
104             mSystemDecorations = yes;
105             return this;
106         }
setPosition(int position)107         Builder setPosition(int position) {
108             mPosition = position;
109             return this;
110         }
setUniqueId(String uniqueId)111         Builder setUniqueId(String uniqueId) {
112             mInfo.uniqueId = uniqueId;
113             return this;
114         }
setType(int type)115         Builder setType(int type) {
116             mInfo.type = type;
117             return this;
118         }
setOwnerUid(int ownerUid)119         Builder setOwnerUid(int ownerUid) {
120             mInfo.ownerUid = ownerUid;
121             return this;
122         }
setNotch(int height)123         Builder setNotch(int height) {
124             mInfo.displayCutout = new DisplayCutout(
125                     Insets.of(0, height, 0, 0), null, new Rect(20, 0, 80, height), null, null);
126             return this;
127         }
setCanRotate(boolean canRotate)128         Builder setCanRotate(boolean canRotate) {
129             mCanRotate = canRotate;
130             return this;
131         }
setWindowingMode(int windowingMode)132         Builder setWindowingMode(int windowingMode) {
133             mWindowingMode = windowingMode;
134             return this;
135         }
setDensityDpi(int dpi)136         Builder setDensityDpi(int dpi) {
137             mInfo.logicalDensityDpi = dpi;
138             return this;
139         }
createInternal(Display display)140         TestDisplayContent createInternal(Display display) {
141             return new TestDisplayContent(mService.mRootWindowContainer, display);
142         }
build()143         TestDisplayContent build() {
144             SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
145 
146             final int displayId = SystemServicesTestRule.sNextDisplayId++;
147             final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
148                     mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
149             final TestDisplayContent newDisplay = createInternal(display);
150             // disable the normal system decorations
151             final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy();
152             spyOn(displayPolicy);
153             if (mSystemDecorations) {
154                 doReturn(true).when(newDisplay).supportsSystemDecorations();
155                 doReturn(true).when(displayPolicy).hasNavigationBar();
156             } else {
157                 doReturn(false).when(displayPolicy).hasNavigationBar();
158                 doReturn(false).when(displayPolicy).hasStatusBar();
159                 doReturn(false).when(newDisplay).supportsSystemDecorations();
160             }
161             Configuration c = new Configuration();
162             newDisplay.computeScreenConfiguration(c);
163             c.windowConfiguration.setWindowingMode(mWindowingMode);
164             newDisplay.onRequestedOverrideConfigurationChanged(c);
165             if (!mCanRotate) {
166                 final DisplayRotation displayRotation = newDisplay.getDisplayRotation();
167                 doReturn(true).when(displayRotation).isFixedToUserRotation();
168             }
169             // Please add stubbing before this line. Services will start using this display in other
170             // threads immediately after adding it to hierarchy. Calling doAnswer() type of stubbing
171             // reduces chance of races, but still doesn't eliminate race conditions.
172             mService.mRootWindowContainer.addChild(newDisplay, mPosition);
173 
174             // Set the default focused TDA.
175             newDisplay.onLastFocusedTaskDisplayAreaChanged(newDisplay.getDefaultTaskDisplayArea());
176 
177             return newDisplay;
178         }
179     }
180 }
181