1 /*
2  * Copyright (C) 2017 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 android.server.wm;
18 
19 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
20 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
21 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
22 import static android.server.wm.ActivityManagerTestBase.isDisplayOn;
23 import static android.server.wm.ActivityManagerTestBase.waitForOrFail;
24 import static android.server.wm.StateLogger.logAlways;
25 import static android.view.Display.DEFAULT_DISPLAY;
26 
27 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
28 
29 import android.graphics.PixelFormat;
30 import android.hardware.display.DisplayManager;
31 import android.hardware.display.VirtualDisplay;
32 import android.media.ImageReader;
33 
34 import com.android.compatibility.common.util.SystemUtil;
35 
36 /**
37  * Helper class to create virtual display.
38  */
39 class VirtualDisplayHelper {
40 
41     private boolean mPublicDisplay = false;
42     private boolean mCanShowWithInsecureKeyguard = false;
43     private boolean mShowSystemDecorations = false;
44 
45     private static final String VIRTUAL_DISPLAY_NAME = "CtsVirtualDisplay";
46     /** See {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD}. */
47     private static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
48     /** See {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS}. */
49     private static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
50 
51     private static final int DENSITY = 160;
52     static final int HEIGHT = 480;
53     static final int WIDTH = 800;
54 
55     private ImageReader mReader;
56     private VirtualDisplay mVirtualDisplay;
57     private boolean mCreated;
58 
setPublicDisplay(boolean publicDisplay)59     VirtualDisplayHelper setPublicDisplay(boolean publicDisplay) {
60         mPublicDisplay = publicDisplay;
61         return this;
62     }
63 
setCanShowWithInsecureKeyguard(boolean canShowWithInsecureKeyguard)64     VirtualDisplayHelper setCanShowWithInsecureKeyguard(boolean canShowWithInsecureKeyguard) {
65         mCanShowWithInsecureKeyguard = canShowWithInsecureKeyguard;
66         return this;
67     }
68 
setShowSystemDecorations(boolean showSystemDecorations)69     VirtualDisplayHelper setShowSystemDecorations(boolean showSystemDecorations) {
70         mShowSystemDecorations = showSystemDecorations;
71         return this;
72     }
73 
createAndWaitForDisplay()74     int createAndWaitForDisplay() {
75         SystemUtil.runWithShellPermissionIdentity(() -> {
76             createVirtualDisplay();
77             waitForDisplayState(mVirtualDisplay.getDisplay().getDisplayId(), true /* wantOn */);
78             mCreated = true;
79         });
80         return mVirtualDisplay.getDisplay().getDisplayId();
81     }
82 
turnDisplayOff()83     void turnDisplayOff() {
84         mVirtualDisplay.setSurface(null);
85         waitForDisplayState(mVirtualDisplay.getDisplay().getDisplayId(), false /* wantOn */);
86     }
87 
turnDisplayOn()88     void turnDisplayOn() {
89         mVirtualDisplay.setSurface(mReader.getSurface());
90         waitForDisplayState(mVirtualDisplay.getDisplay().getDisplayId(), true /* wantOn */);
91     }
92 
releaseDisplay()93     void releaseDisplay() {
94         if (mCreated) {
95             mVirtualDisplay.release();
96             mReader.close();
97             waitForDisplayState(mVirtualDisplay.getDisplay().getDisplayId(), false /* wantOn */);
98         }
99         mCreated = false;
100     }
101 
createVirtualDisplay()102     private void createVirtualDisplay() {
103         mReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
104 
105         final DisplayManager displayManager = getInstrumentation()
106                 .getContext().getSystemService(DisplayManager.class);
107 
108         int flags = VIRTUAL_DISPLAY_FLAG_PRESENTATION | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
109 
110         if (mPublicDisplay) {
111             flags |= VIRTUAL_DISPLAY_FLAG_PUBLIC;
112         }
113         if (mCanShowWithInsecureKeyguard) {
114             flags |= VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
115         }
116         if (mShowSystemDecorations) {
117             flags |= VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
118         }
119 
120         logAlways("createVirtualDisplay: " + WIDTH + "x" + HEIGHT + ", dpi: " + DENSITY
121                 + ", publicDisplay=" + mPublicDisplay
122                 + ", canShowWithInsecureKeyguard=" + mCanShowWithInsecureKeyguard
123                 + ", showSystemDecorations=" + mShowSystemDecorations);
124 
125         mVirtualDisplay = displayManager.createVirtualDisplay(
126                 VIRTUAL_DISPLAY_NAME, WIDTH, HEIGHT, DENSITY, mReader.getSurface(), flags);
127     }
128 
waitForDefaultDisplayState(boolean wantOn)129     static void waitForDefaultDisplayState(boolean wantOn) {
130         waitForDisplayState(DEFAULT_DISPLAY, wantOn);
131     }
132 
waitForDisplayState(int displayId, boolean wantOn)133     private static void waitForDisplayState(int displayId, boolean wantOn) {
134         final String message = (displayId == DEFAULT_DISPLAY ? "default" : "virtual")
135                 + " display " + (wantOn ? "on" : "off");
136         waitForOrFail(message, () -> isDisplayOn(displayId) == wantOn);
137     }
138 }
139