blob: 210d2979c80724f0c2c246736598ba112a624710 [file] [log] [blame]
Jeff Browna506a6e2013-06-04 00:02:38 -07001/*
2 * Copyright (C) 2013 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
17package com.android.server.display;
18
Andrii Kulian7211d2e2017-01-27 15:58:05 -080019import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
Louis Changbd48dca2018-08-29 17:44:34 +080020import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
21import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010022import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
23import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
24import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
25import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
Louis Changbd48dca2018-08-29 17:44:34 +080026import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010027import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
Charles Chenb28fb722020-05-21 17:19:32 +080028import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
29
30import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
Andrii Kulian7211d2e2017-01-27 15:58:05 -080031
Jeff Browna506a6e2013-06-04 00:02:38 -070032import android.content.Context;
Michael Wright75ee9fc2014-09-01 19:55:22 -070033import android.hardware.display.IVirtualDisplayCallback;
b0202.jung925435c2020-01-08 18:46:59 +090034import android.hardware.display.VirtualDisplayConfig;
Michael Wrightc39d47a2014-07-08 18:07:36 -070035import android.media.projection.IMediaProjection;
36import android.media.projection.IMediaProjectionCallback;
Jeff Browna506a6e2013-06-04 00:02:38 -070037import android.os.Handler;
38import android.os.IBinder;
39import android.os.IBinder.DeathRecipient;
Michael Wrightc39d47a2014-07-08 18:07:36 -070040import android.os.Message;
Jeff Browna506a6e2013-06-04 00:02:38 -070041import android.os.RemoteException;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010042import android.os.SystemProperties;
Jeff Browna506a6e2013-06-04 00:02:38 -070043import android.util.ArrayMap;
44import android.util.Slog;
45import android.view.Display;
46import android.view.Surface;
47import android.view.SurfaceControl;
48
Santos Cordonee8931e2017-04-05 10:31:15 -070049import com.android.internal.annotations.VisibleForTesting;
50
Michael Wrightc39d47a2014-07-08 18:07:36 -070051import java.io.PrintWriter;
Wale Ogunwale361ca212014-11-20 11:42:38 -080052import java.util.Iterator;
Michael Wrightc39d47a2014-07-08 18:07:36 -070053
Jeff Browna506a6e2013-06-04 00:02:38 -070054/**
55 * A display adapter that provides virtual displays on behalf of applications.
56 * <p>
57 * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
58 * </p>
59 */
Santos Cordonee8931e2017-04-05 10:31:15 -070060@VisibleForTesting
61public class VirtualDisplayAdapter extends DisplayAdapter {
Jeff Browna506a6e2013-06-04 00:02:38 -070062 static final String TAG = "VirtualDisplayAdapter";
63 static final boolean DEBUG = false;
64
Wale Ogunwale361ca212014-11-20 11:42:38 -080065 // Unique id prefix for virtual displays
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010066 @VisibleForTesting
67 static final String UNIQUE_ID_PREFIX = "virtual:";
Wale Ogunwale361ca212014-11-20 11:42:38 -080068
Jeff Browna506a6e2013-06-04 00:02:38 -070069 private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices =
70 new ArrayMap<IBinder, VirtualDisplayDevice>();
Santos Cordonee8931e2017-04-05 10:31:15 -070071 private final Handler mHandler;
72 private final SurfaceControlDisplayFactory mSurfaceControlDisplayFactory;
Jeff Browna506a6e2013-06-04 00:02:38 -070073
74 // Called with SyncRoot lock held.
75 public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
76 Context context, Handler handler, Listener listener) {
Santos Cordonee8931e2017-04-05 10:31:15 -070077 this(syncRoot, context, handler, listener,
78 (String name, boolean secure) -> SurfaceControl.createDisplay(name, secure));
79 }
80
81 @VisibleForTesting
82 VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
83 Context context, Handler handler, Listener listener,
84 SurfaceControlDisplayFactory surfaceControlDisplayFactory) {
Jeff Browna506a6e2013-06-04 00:02:38 -070085 super(syncRoot, context, handler, listener, TAG);
Michael Wrightc39d47a2014-07-08 18:07:36 -070086 mHandler = handler;
Santos Cordonee8931e2017-04-05 10:31:15 -070087 mSurfaceControlDisplayFactory = surfaceControlDisplayFactory;
Jeff Browna506a6e2013-06-04 00:02:38 -070088 }
89
Michael Wright75ee9fc2014-09-01 19:55:22 -070090 public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallback callback,
b0202.jung925435c2020-01-08 18:46:59 +090091 IMediaProjection projection, int ownerUid, String ownerPackageName, Surface surface,
92 int flags, VirtualDisplayConfig virtualDisplayConfig) {
93 String name = virtualDisplayConfig.getName();
Andrii Kulian7211d2e2017-01-27 15:58:05 -080094 boolean secure = (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
Michael Wright75ee9fc2014-09-01 19:55:22 -070095 IBinder appToken = callback.asBinder();
Santos Cordonee8931e2017-04-05 10:31:15 -070096 IBinder displayToken = mSurfaceControlDisplayFactory.createDisplay(name, secure);
Wale Ogunwale361ca212014-11-20 11:42:38 -080097 final String baseUniqueId =
98 UNIQUE_ID_PREFIX + ownerPackageName + "," + ownerUid + "," + name + ",";
99 final int uniqueIndex = getNextUniqueIndex(baseUniqueId);
b0202.jung925435c2020-01-08 18:46:59 +0900100 String uniqueId = virtualDisplayConfig.getUniqueId();
Santos Cordonee8931e2017-04-05 10:31:15 -0700101 if (uniqueId == null) {
102 uniqueId = baseUniqueId + uniqueIndex;
103 } else {
104 uniqueId = UNIQUE_ID_PREFIX + ownerPackageName + ":" + uniqueId;
105 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700106 VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
b0202.jung925435c2020-01-08 18:46:59 +0900107 ownerUid, ownerPackageName, surface, flags, new Callback(callback, mHandler),
108 uniqueId, uniqueIndex, virtualDisplayConfig);
Michael Wrightc39d47a2014-07-08 18:07:36 -0700109
110 mVirtualDisplayDevices.put(appToken, device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700111
112 try {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700113 if (projection != null) {
Michael Wrightcde5bb42014-09-08 13:26:34 -0700114 projection.registerCallback(new MediaProjectionCallback(appToken));
Michael Wrightc39d47a2014-07-08 18:07:36 -0700115 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700116 appToken.linkToDeath(device, 0);
117 } catch (RemoteException ex) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700118 mVirtualDisplayDevices.remove(appToken);
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100119 device.destroyLocked(false);
Jeff Browna506a6e2013-06-04 00:02:38 -0700120 return null;
121 }
122
Jeff Browna506a6e2013-06-04 00:02:38 -0700123 // Return the display device without actually sending the event indicating
124 // that it was added. The caller will handle it.
125 return device;
126 }
127
Michael Wright01e840f2014-06-26 16:03:25 -0700128 public void resizeVirtualDisplayLocked(IBinder appToken,
129 int width, int height, int densityDpi) {
130 VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
131 if (device != null) {
132 device.resizeLocked(width, height, densityDpi);
133 }
134 }
135
b0202.jung925435c2020-01-08 18:46:59 +0900136 @VisibleForTesting
137 Surface getVirtualDisplaySurfaceLocked(IBinder appToken) {
138 VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
139 if (device != null) {
140 return device.getSurfaceLocked();
141 }
142 return null;
143 }
Michael Wright01e840f2014-06-26 16:03:25 -0700144
Jeff Brown92207df2014-04-16 13:16:07 -0700145 public void setVirtualDisplaySurfaceLocked(IBinder appToken, Surface surface) {
146 VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
147 if (device != null) {
148 device.setSurfaceLocked(surface);
149 }
150 }
151
Jeff Browna506a6e2013-06-04 00:02:38 -0700152 public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
153 VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
154 if (device != null) {
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100155 device.destroyLocked(true);
Jeff Browna506a6e2013-06-04 00:02:38 -0700156 appToken.unlinkToDeath(device, 0);
157 }
158
159 // Return the display device that was removed without actually sending the
160 // event indicating that it was removed. The caller will handle it.
161 return device;
162 }
163
chaviwda4c6942018-11-07 15:52:56 -0800164 void setVirtualDisplayStateLocked(IBinder appToken, boolean isOn) {
165 VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
166 if (device != null) {
167 device.setDisplayState(isOn);
168 }
169 }
170
Wale Ogunwale361ca212014-11-20 11:42:38 -0800171 /**
172 * Returns the next unique index for the uniqueIdPrefix
173 */
174 private int getNextUniqueIndex(String uniqueIdPrefix) {
175 if (mVirtualDisplayDevices.isEmpty()) {
176 return 0;
177 }
178
179 int nextUniqueIndex = 0;
180 Iterator<VirtualDisplayDevice> it = mVirtualDisplayDevices.values().iterator();
181 while (it.hasNext()) {
182 VirtualDisplayDevice device = it.next();
183 if (device.getUniqueId().startsWith(uniqueIdPrefix)
184 && device.mUniqueIndex >= nextUniqueIndex) {
185 // Increment the next unique index to be greater than ones we have already ran
186 // across for displays that have the same unique Id prefix.
187 nextUniqueIndex = device.mUniqueIndex + 1;
188 }
189 }
190
191 return nextUniqueIndex;
192 }
193
Jeff Browna506a6e2013-06-04 00:02:38 -0700194 private void handleBinderDiedLocked(IBinder appToken) {
Bryce Leea3320fe2017-02-15 17:47:25 -0800195 mVirtualDisplayDevices.remove(appToken);
Jeff Browna506a6e2013-06-04 00:02:38 -0700196 }
197
Michael Wrightc39d47a2014-07-08 18:07:36 -0700198 private void handleMediaProjectionStoppedLocked(IBinder appToken) {
199 VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
200 if (device != null) {
201 Slog.i(TAG, "Virtual display device released because media projection stopped: "
202 + device.mName);
203 device.stopLocked();
204 }
205 }
206
207 private final class VirtualDisplayDevice extends DisplayDevice implements DeathRecipient {
Michael Wright01e840f2014-06-26 16:03:25 -0700208 private static final int PENDING_SURFACE_CHANGE = 0x01;
209 private static final int PENDING_RESIZE = 0x02;
210
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700211 private static final float REFRESH_RATE = 60.0f;
212
Jeff Browna506a6e2013-06-04 00:02:38 -0700213 private final IBinder mAppToken;
214 private final int mOwnerUid;
215 final String mOwnerPackageName;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700216 final String mName;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700217 private final int mFlags;
Michael Wright75ee9fc2014-09-01 19:55:22 -0700218 private final Callback mCallback;
Jeff Browna506a6e2013-06-04 00:02:38 -0700219
Michael Wright01e840f2014-06-26 16:03:25 -0700220 private int mWidth;
221 private int mHeight;
222 private int mDensityDpi;
Jeff Browna506a6e2013-06-04 00:02:38 -0700223 private Surface mSurface;
224 private DisplayDeviceInfo mInfo;
Michael Wright01e840f2014-06-26 16:03:25 -0700225 private int mDisplayState;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700226 private boolean mStopped;
Michael Wright01e840f2014-06-26 16:03:25 -0700227 private int mPendingChanges;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800228 private int mUniqueIndex;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700229 private Display.Mode mMode;
chaviwda4c6942018-11-07 15:52:56 -0800230 private boolean mIsDisplayOn;
b0202.jung925435c2020-01-08 18:46:59 +0900231 private int mDisplayIdToMirror;
Jeff Browna506a6e2013-06-04 00:02:38 -0700232
Michael Wrightc39d47a2014-07-08 18:07:36 -0700233 public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
b0202.jung925435c2020-01-08 18:46:59 +0900234 int ownerUid, String ownerPackageName, Surface surface, int flags,
235 Callback callback, String uniqueId, int uniqueIndex,
236 VirtualDisplayConfig virtualDisplayConfig) {
Wale Ogunwale361ca212014-11-20 11:42:38 -0800237 super(VirtualDisplayAdapter.this, displayToken, uniqueId);
Jeff Browna506a6e2013-06-04 00:02:38 -0700238 mAppToken = appToken;
239 mOwnerUid = ownerUid;
240 mOwnerPackageName = ownerPackageName;
b0202.jung925435c2020-01-08 18:46:59 +0900241 mName = virtualDisplayConfig.getName();
242 mWidth = virtualDisplayConfig.getWidth();
243 mHeight = virtualDisplayConfig.getHeight();
244 mMode = createMode(mWidth, mHeight, REFRESH_RATE);
245 mDensityDpi = virtualDisplayConfig.getDensityDpi();
Jeff Browna506a6e2013-06-04 00:02:38 -0700246 mSurface = surface;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700247 mFlags = flags;
Michael Wright75ee9fc2014-09-01 19:55:22 -0700248 mCallback = callback;
Michael Wright01e840f2014-06-26 16:03:25 -0700249 mDisplayState = Display.STATE_UNKNOWN;
250 mPendingChanges |= PENDING_SURFACE_CHANGE;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800251 mUniqueIndex = uniqueIndex;
chaviwda4c6942018-11-07 15:52:56 -0800252 mIsDisplayOn = surface != null;
b0202.jung925435c2020-01-08 18:46:59 +0900253 mDisplayIdToMirror = virtualDisplayConfig.getDisplayIdToMirror();
Jeff Browna506a6e2013-06-04 00:02:38 -0700254 }
255
256 @Override
257 public void binderDied() {
258 synchronized (getSyncRoot()) {
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100259 handleBinderDiedLocked(mAppToken);
Bryce Leea3320fe2017-02-15 17:47:25 -0800260 Slog.i(TAG, "Virtual display device released because application token died: "
261 + mOwnerPackageName);
262 destroyLocked(false);
263 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_REMOVED);
Jeff Browna506a6e2013-06-04 00:02:38 -0700264 }
265 }
266
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100267 public void destroyLocked(boolean binderAlive) {
Jesse Hall6a6bc212013-08-08 12:15:03 -0700268 if (mSurface != null) {
269 mSurface.release();
270 mSurface = null;
271 }
272 SurfaceControl.destroyDisplay(getDisplayTokenLocked());
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100273 if (binderAlive) {
274 mCallback.dispatchDisplayStopped();
275 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700276 }
277
278 @Override
b0202.jung925435c2020-01-08 18:46:59 +0900279 public int getDisplayIdToMirrorLocked() {
280 return mDisplayIdToMirror;
281 }
282
283 @VisibleForTesting
284 Surface getSurfaceLocked() {
285 return mSurface;
286 }
287
288 @Override
Michael Wright1c9977b2016-07-12 13:30:10 -0700289 public boolean hasStableUniqueId() {
290 return false;
291 }
292
293 @Override
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000294 public Runnable requestDisplayStateLocked(int state, float brightnessState) {
Michael Wright01e840f2014-06-26 16:03:25 -0700295 if (state != mDisplayState) {
296 mDisplayState = state;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700297 if (state == Display.STATE_OFF) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700298 mCallback.dispatchDisplayPaused();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700299 } else {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700300 mCallback.dispatchDisplayResumed();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700301 }
302 }
Jeff Browne75926d2014-09-18 15:24:49 -0700303 return null;
Jeff Browna506a6e2013-06-04 00:02:38 -0700304 }
305
306 @Override
Robert Carrae606b42018-02-15 15:36:23 -0800307 public void performTraversalLocked(SurfaceControl.Transaction t) {
Michael Wright01e840f2014-06-26 16:03:25 -0700308 if ((mPendingChanges & PENDING_RESIZE) != 0) {
Robert Carrae606b42018-02-15 15:36:23 -0800309 t.setDisplaySize(getDisplayTokenLocked(), mWidth, mHeight);
Michael Wright01e840f2014-06-26 16:03:25 -0700310 }
311 if ((mPendingChanges & PENDING_SURFACE_CHANGE) != 0) {
Robert Carrae606b42018-02-15 15:36:23 -0800312 setSurfaceLocked(t, mSurface);
Michael Wright01e840f2014-06-26 16:03:25 -0700313 }
314 mPendingChanges = 0;
Jeff Browna506a6e2013-06-04 00:02:38 -0700315 }
316
Jeff Brown92207df2014-04-16 13:16:07 -0700317 public void setSurfaceLocked(Surface surface) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700318 if (!mStopped && mSurface != surface) {
Jeff Brown92207df2014-04-16 13:16:07 -0700319 if ((mSurface != null) != (surface != null)) {
320 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
321 }
322 sendTraversalRequestLocked();
323 mSurface = surface;
324 mInfo = null;
Michael Wright01e840f2014-06-26 16:03:25 -0700325 mPendingChanges |= PENDING_SURFACE_CHANGE;
326 }
327 }
328
329 public void resizeLocked(int width, int height, int densityDpi) {
330 if (mWidth != width || mHeight != height || mDensityDpi != densityDpi) {
331 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
332 sendTraversalRequestLocked();
333 mWidth = width;
334 mHeight = height;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700335 mMode = createMode(width, height, REFRESH_RATE);
Michael Wright01e840f2014-06-26 16:03:25 -0700336 mDensityDpi = densityDpi;
337 mInfo = null;
338 mPendingChanges |= PENDING_RESIZE;
Jeff Brown92207df2014-04-16 13:16:07 -0700339 }
340 }
341
chaviwda4c6942018-11-07 15:52:56 -0800342 void setDisplayState(boolean isOn) {
343 if (mIsDisplayOn != isOn) {
344 mIsDisplayOn = isOn;
345 mInfo = null;
346 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
347 }
348 }
349
Michael Wrightc39d47a2014-07-08 18:07:36 -0700350 public void stopLocked() {
351 setSurfaceLocked(null);
352 mStopped = true;
353 }
354
355 @Override
356 public void dumpLocked(PrintWriter pw) {
357 super.dumpLocked(pw);
358 pw.println("mFlags=" + mFlags);
Michael Wright01e840f2014-06-26 16:03:25 -0700359 pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
Michael Wrightc39d47a2014-07-08 18:07:36 -0700360 pw.println("mStopped=" + mStopped);
b0202.jung925435c2020-01-08 18:46:59 +0900361 pw.println("mDisplayIdToMirror=" + mDisplayIdToMirror);
Michael Wrightc39d47a2014-07-08 18:07:36 -0700362 }
363
364
Jeff Browna506a6e2013-06-04 00:02:38 -0700365 @Override
366 public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
367 if (mInfo == null) {
368 mInfo = new DisplayDeviceInfo();
369 mInfo.name = mName;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800370 mInfo.uniqueId = getUniqueId();
Jeff Browna506a6e2013-06-04 00:02:38 -0700371 mInfo.width = mWidth;
372 mInfo.height = mHeight;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700373 mInfo.modeId = mMode.getModeId();
374 mInfo.defaultModeId = mMode.getModeId();
375 mInfo.supportedModes = new Display.Mode[] { mMode };
Jeff Browna506a6e2013-06-04 00:02:38 -0700376 mInfo.densityDpi = mDensityDpi;
377 mInfo.xDpi = mDensityDpi;
378 mInfo.yDpi = mDensityDpi;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700379 mInfo.presentationDeadlineNanos = 1000000000L / (int) REFRESH_RATE; // 1 frame
Jeff Brown7d00aff2013-08-02 19:03:49 -0700380 mInfo.flags = 0;
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800381 if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
Michael Wright6720be42014-07-29 19:14:16 -0700382 mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
383 | DisplayDeviceInfo.FLAG_NEVER_BLANK;
384 }
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800385 if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
Michael Wright6720be42014-07-29 19:14:16 -0700386 mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK;
387 } else {
Jeff Brownd14c8c92014-01-07 18:13:09 -0800388 mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700389 }
Michael Wright6720be42014-07-29 19:14:16 -0700390
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800391 if ((mFlags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
Jeff Brown7d00aff2013-08-02 19:03:49 -0700392 mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
393 }
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800394 if ((mFlags & VIRTUAL_DISPLAY_FLAG_PRESENTATION) != 0) {
Jeff Brown7d00aff2013-08-02 19:03:49 -0700395 mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
Chong Zhangae6119ff2014-11-11 18:54:39 -0800396
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800397 if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
Chong Zhangae6119ff2014-11-11 18:54:39 -0800398 // For demonstration purposes, allow rotation of the external display.
399 // In the future we might allow the user to configure this directly.
400 if ("portrait".equals(SystemProperties.get(
401 "persist.demo.remoterotation"))) {
402 mInfo.rotation = Surface.ROTATION_270;
403 }
404 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700405 }
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800406 if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
407 mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -0800408 }
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -0400409 if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) {
410 mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
411 }
rongliu1e90fc32017-10-04 17:30:30 -0700412 if ((mFlags & VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) {
Louis Changbd48dca2018-08-29 17:44:34 +0800413 mInfo.flags |= DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL;
414 }
415 if ((mFlags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
416 mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
rongliu1e90fc32017-10-04 17:30:30 -0700417 }
Charles Chenb28fb722020-05-21 17:19:32 +0800418 if ((mFlags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
419 mInfo.flags |= FLAG_TRUSTED;
420 }
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -0400421
Jeff Browna506a6e2013-06-04 00:02:38 -0700422 mInfo.type = Display.TYPE_VIRTUAL;
Santos Cordonee8931e2017-04-05 10:31:15 -0700423 mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
424 DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL;
chaviwda4c6942018-11-07 15:52:56 -0800425
426 mInfo.state = mIsDisplayOn ? Display.STATE_ON : Display.STATE_OFF;
427
Jeff Browna506a6e2013-06-04 00:02:38 -0700428 mInfo.ownerUid = mOwnerUid;
429 mInfo.ownerPackageName = mOwnerPackageName;
430 }
431 return mInfo;
432 }
433 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700434
Michael Wright75ee9fc2014-09-01 19:55:22 -0700435 private static class Callback extends Handler {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700436 private static final int MSG_ON_DISPLAY_PAUSED = 0;
437 private static final int MSG_ON_DISPLAY_RESUMED = 1;
438 private static final int MSG_ON_DISPLAY_STOPPED = 2;
439
Michael Wright75ee9fc2014-09-01 19:55:22 -0700440 private final IVirtualDisplayCallback mCallback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700441
Michael Wright75ee9fc2014-09-01 19:55:22 -0700442 public Callback(IVirtualDisplayCallback callback, Handler handler) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700443 super(handler.getLooper());
Michael Wright75ee9fc2014-09-01 19:55:22 -0700444 mCallback = callback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700445 }
446
447 @Override
448 public void handleMessage(Message msg) {
449 try {
450 switch (msg.what) {
451 case MSG_ON_DISPLAY_PAUSED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700452 mCallback.onPaused();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700453 break;
454 case MSG_ON_DISPLAY_RESUMED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700455 mCallback.onResumed();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700456 break;
457 case MSG_ON_DISPLAY_STOPPED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700458 mCallback.onStopped();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700459 break;
460 }
461 } catch (RemoteException e) {
462 Slog.w(TAG, "Failed to notify listener of virtual display event.", e);
463 }
464 }
465
466 public void dispatchDisplayPaused() {
467 sendEmptyMessage(MSG_ON_DISPLAY_PAUSED);
468 }
469
470 public void dispatchDisplayResumed() {
471 sendEmptyMessage(MSG_ON_DISPLAY_RESUMED);
472 }
473
474 public void dispatchDisplayStopped() {
475 sendEmptyMessage(MSG_ON_DISPLAY_STOPPED);
476 }
477 }
478
479 private final class MediaProjectionCallback extends IMediaProjectionCallback.Stub {
480 private IBinder mAppToken;
481 public MediaProjectionCallback(IBinder appToken) {
482 mAppToken = appToken;
483 }
484
485 @Override
486 public void onStop() {
487 synchronized (getSyncRoot()) {
488 handleMediaProjectionStoppedLocked(mAppToken);
489 }
490 }
491 }
Santos Cordonee8931e2017-04-05 10:31:15 -0700492
493 @VisibleForTesting
494 public interface SurfaceControlDisplayFactory {
495 public IBinder createDisplay(String name, boolean secure);
496 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700497}