Home | History | Annotate | Download | only in wm
      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.StateLogger.logAlways;
     24 import static android.view.Display.DEFAULT_DISPLAY;
     25 
     26 import static androidx.test.InstrumentationRegistry.getInstrumentation;
     27 
     28 import static org.junit.Assert.fail;
     29 
     30 import android.graphics.PixelFormat;
     31 import android.hardware.display.DisplayManager;
     32 import android.hardware.display.VirtualDisplay;
     33 import android.media.ImageReader;
     34 import android.os.SystemClock;
     35 
     36 import com.android.compatibility.common.util.SystemUtil;
     37 
     38 import java.util.function.Predicate;
     39 
     40 /**
     41  * Helper class to create virtual display.
     42  */
     43 class VirtualDisplayHelper {
     44 
     45     private boolean mPublicDisplay = false;
     46     private boolean mCanShowWithInsecureKeyguard = false;
     47     private boolean mShowSystemDecorations = false;
     48 
     49     private static final String VIRTUAL_DISPLAY_NAME = "CtsVirtualDisplay";
     50     /** See {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD}. */
     51     private static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
     52     /** See {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS}. */
     53     private static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
     54 
     55     private static final int DENSITY = 160;
     56     static final int HEIGHT = 480;
     57     static final int WIDTH = 800;
     58 
     59     private ImageReader mReader;
     60     private VirtualDisplay mVirtualDisplay;
     61     private boolean mCreated;
     62 
     63     VirtualDisplayHelper setPublicDisplay(boolean publicDisplay) {
     64         mPublicDisplay = publicDisplay;
     65         return this;
     66     }
     67 
     68     VirtualDisplayHelper setCanShowWithInsecureKeyguard(boolean canShowWithInsecureKeyguard) {
     69         mCanShowWithInsecureKeyguard = canShowWithInsecureKeyguard;
     70         return this;
     71     }
     72 
     73     VirtualDisplayHelper setShowSystemDecorations(boolean showSystemDecorations) {
     74         mShowSystemDecorations = showSystemDecorations;
     75         return this;
     76     }
     77 
     78     int createAndWaitForDisplay() {
     79         SystemUtil.runWithShellPermissionIdentity(() -> {
     80             createVirtualDisplay();
     81             waitForDisplayState(mVirtualDisplay.getDisplay().getDisplayId() /* default */,
     82                     true /* on */);
     83             mCreated = true;
     84         });
     85         return mVirtualDisplay.getDisplay().getDisplayId();
     86     }
     87 
     88     void turnDisplayOff() {
     89         SystemUtil.runWithShellPermissionIdentity(() -> {
     90             mVirtualDisplay.setSurface(null);
     91             waitForDisplayState(mVirtualDisplay.getDisplay().getDisplayId() /* displayId */,
     92                     false /* on */);
     93         });
     94     }
     95 
     96     void turnDisplayOn() {
     97         SystemUtil.runWithShellPermissionIdentity(() -> {
     98             mVirtualDisplay.setSurface(mReader.getSurface());
     99             waitForDisplayState(mVirtualDisplay.getDisplay().getDisplayId() /* displayId */,
    100                     true /* on */);
    101         });
    102     }
    103 
    104     void releaseDisplay() {
    105         SystemUtil.runWithShellPermissionIdentity(() -> {
    106             if (mCreated) {
    107                 mVirtualDisplay.release();
    108                 mReader.close();
    109                 waitForDisplayCondition(mVirtualDisplay.getDisplay().getDisplayId() /* displayId */,
    110                         onState -> onState != null && onState == false,
    111                         "Waiting for virtual display destroy");
    112             }
    113             mCreated = false;
    114         });
    115     }
    116 
    117     private void createVirtualDisplay() {
    118         mReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
    119 
    120         final DisplayManager displayManager = getInstrumentation()
    121                 .getContext().getSystemService(DisplayManager.class);
    122 
    123         int flags = VIRTUAL_DISPLAY_FLAG_PRESENTATION | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
    124 
    125         if (mPublicDisplay) {
    126             flags |= VIRTUAL_DISPLAY_FLAG_PUBLIC;
    127         }
    128         if (mCanShowWithInsecureKeyguard) {
    129             flags |= VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
    130         }
    131         if (mShowSystemDecorations) {
    132             flags |= VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
    133         }
    134 
    135         logAlways("createVirtualDisplay: " + WIDTH + "x" + HEIGHT + ", dpi: " + DENSITY
    136                 + ", publicDisplay=" + mPublicDisplay
    137                 + ", canShowWithInsecureKeyguard=" + mCanShowWithInsecureKeyguard
    138                 + ", showSystemDecorations=" + mShowSystemDecorations);
    139 
    140         mVirtualDisplay = displayManager.createVirtualDisplay(
    141                 VIRTUAL_DISPLAY_NAME, WIDTH, HEIGHT, DENSITY, mReader.getSurface(), flags);
    142     }
    143 
    144     static void waitForDefaultDisplayState(boolean wantOn) {
    145         waitForDisplayState(DEFAULT_DISPLAY /* default */, wantOn);
    146     }
    147 
    148     private static void waitForDisplayState(int displayId, boolean wantOn) {
    149         waitForDisplayCondition(displayId, state -> state != null && state == wantOn,
    150                 "Waiting for " + ((displayId == DEFAULT_DISPLAY) ? "default" : "virtual")
    151                         + " display "
    152                         + (wantOn ? "on" : "off"));
    153     }
    154 
    155     private static void waitForDisplayCondition(int displayId,
    156             Predicate<Boolean> condition, String message) {
    157         for (int retry = 1; retry <= 10; retry++) {
    158             if (condition.test(isDisplayOn(displayId))) {
    159                 return;
    160             }
    161             logAlways(message + "... retry=" + retry);
    162             SystemClock.sleep(500);
    163         }
    164         fail(message + " failed");
    165     }
    166 }
    167