1 /** 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 * express or implied. See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 package android.accessibilityservice.cts.utils; 16 17 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; 18 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; 19 import static android.view.Display.DEFAULT_DISPLAY; 20 21 import android.app.Activity; 22 import android.content.Context; 23 import android.graphics.PixelFormat; 24 import android.graphics.Rect; 25 import android.hardware.display.DisplayManager; 26 import android.hardware.display.VirtualDisplay; 27 import android.media.ImageReader; 28 import android.os.Looper; 29 import android.util.DisplayMetrics; 30 import android.view.Display; 31 import android.view.Window; 32 33 import com.android.compatibility.common.util.TestUtils; 34 35 /** 36 * Utilities needed when interacting with the display 37 */ 38 public class DisplayUtils { 39 private static final int DISPLAY_ADDED_TIMEOUT_MS = 5000; 40 getStatusBarHeight(Activity activity)41 public static int getStatusBarHeight(Activity activity) { 42 final Rect rect = new Rect(); 43 Window window = activity.getWindow(); 44 window.getDecorView().getWindowVisibleDisplayFrame(rect); 45 return rect.top; 46 } 47 48 public static class VirtualDisplaySession implements AutoCloseable { 49 private VirtualDisplay mVirtualDisplay; 50 private ImageReader mReader; 51 createDisplay(Context context, int width, int height, int density, boolean isPrivate)52 public Display createDisplay(Context context, int width, int height, int density, 53 boolean isPrivate) { 54 if (mReader != null) { 55 throw new IllegalStateException( 56 "Only one display can be created during this session."); 57 } 58 mReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 59 1 /* maxImages */); 60 int flags = isPrivate ? 0 61 :(VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | VIRTUAL_DISPLAY_FLAG_PUBLIC); 62 mVirtualDisplay = context.getSystemService(DisplayManager.class).createVirtualDisplay( 63 "A11yDisplay", width, height, density, mReader.getSurface(), flags); 64 return mVirtualDisplay.getDisplay(); 65 } 66 67 @Override close()68 public void close() { 69 if (mVirtualDisplay != null) { 70 mVirtualDisplay.release(); 71 } 72 if (mReader != null) { 73 mReader.close(); 74 } 75 } 76 77 /** 78 * Creates a virtual display having same size with default display and waits until it's 79 * in display list. The density of the virtual display is based on 80 * {@link DisplayMetrics#xdpi} so that the threshold of gesture detection is same as 81 * the default display's. 82 * 83 * @param context 84 * @param isPrivate if this display is a private display. 85 * @return virtual display. 86 * 87 * @throws IllegalStateException if called from main thread. 88 */ createDisplayWithDefaultDisplayMetricsAndWait(Context context, boolean isPrivate)89 public Display createDisplayWithDefaultDisplayMetricsAndWait(Context context, 90 boolean isPrivate) { 91 if (Looper.myLooper() == Looper.getMainLooper()) { 92 throw new IllegalStateException("Should not call from main thread"); 93 } 94 95 final Object waitObject = new Object(); 96 final DisplayManager.DisplayListener listener = new DisplayManager.DisplayListener() { 97 @Override 98 public void onDisplayAdded(int i) { 99 synchronized (waitObject) { 100 waitObject.notifyAll(); 101 } 102 } 103 104 @Override 105 public void onDisplayRemoved(int i) { 106 } 107 108 @Override 109 public void onDisplayChanged(int i) { 110 } 111 }; 112 final DisplayManager displayManager = (DisplayManager) context.getSystemService( 113 Context.DISPLAY_SERVICE); 114 displayManager.registerDisplayListener(listener, null); 115 116 final DisplayMetrics metrics = new DisplayMetrics(); 117 displayManager.getDisplay(DEFAULT_DISPLAY).getRealMetrics(metrics); 118 final Display display = createDisplay(context, metrics.widthPixels, 119 metrics.heightPixels, (int) metrics.xdpi, isPrivate); 120 121 try { 122 TestUtils.waitOn(waitObject, 123 () -> displayManager.getDisplay(display.getDisplayId()) != null, 124 DISPLAY_ADDED_TIMEOUT_MS, 125 String.format("wait for virtual display %d adding", display.getDisplayId())); 126 } finally { 127 displayManager.unregisterDisplayListener(listener); 128 } 129 return display; 130 } 131 } 132 } 133