blob: 6111c23f252cc2d6e29c0da3cc1a78e8f7529fbb [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;
20import static android.hardware.display.DisplayManager
21 .VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
22import 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_SECURE;
Santos Cordonee8931e2017-04-05 10:31:15 -070025import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -040026import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
rongliu1e90fc32017-10-04 17:30:30 -070027import static android.hardware.display.DisplayManager
28 .VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
Andrii Kulian7211d2e2017-01-27 15:58:05 -080029
Jeff Browna506a6e2013-06-04 00:02:38 -070030import android.content.Context;
Michael Wright75ee9fc2014-09-01 19:55:22 -070031import android.hardware.display.IVirtualDisplayCallback;
Michael Wrightc39d47a2014-07-08 18:07:36 -070032import android.media.projection.IMediaProjection;
33import android.media.projection.IMediaProjectionCallback;
Jeff Browna506a6e2013-06-04 00:02:38 -070034import android.os.Handler;
35import android.os.IBinder;
Chong Zhangae6119ff2014-11-11 18:54:39 -080036import android.os.SystemProperties;
Jeff Browna506a6e2013-06-04 00:02:38 -070037import android.os.IBinder.DeathRecipient;
Michael Wrightc39d47a2014-07-08 18:07:36 -070038import android.os.Message;
Jeff Browna506a6e2013-06-04 00:02:38 -070039import android.os.RemoteException;
40import android.util.ArrayMap;
41import android.util.Slog;
42import android.view.Display;
43import android.view.Surface;
44import android.view.SurfaceControl;
45
Santos Cordonee8931e2017-04-05 10:31:15 -070046import com.android.internal.annotations.VisibleForTesting;
47
Michael Wrightc39d47a2014-07-08 18:07:36 -070048import java.io.PrintWriter;
Wale Ogunwale361ca212014-11-20 11:42:38 -080049import java.util.Iterator;
Michael Wrightc39d47a2014-07-08 18:07:36 -070050
Jeff Browna506a6e2013-06-04 00:02:38 -070051/**
52 * A display adapter that provides virtual displays on behalf of applications.
53 * <p>
54 * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
55 * </p>
56 */
Santos Cordonee8931e2017-04-05 10:31:15 -070057@VisibleForTesting
58public class VirtualDisplayAdapter extends DisplayAdapter {
Jeff Browna506a6e2013-06-04 00:02:38 -070059 static final String TAG = "VirtualDisplayAdapter";
60 static final boolean DEBUG = false;
61
Wale Ogunwale361ca212014-11-20 11:42:38 -080062 // Unique id prefix for virtual displays
63 private static final String UNIQUE_ID_PREFIX = "virtual:";
64
Jeff Browna506a6e2013-06-04 00:02:38 -070065 private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices =
66 new ArrayMap<IBinder, VirtualDisplayDevice>();
Santos Cordonee8931e2017-04-05 10:31:15 -070067 private final Handler mHandler;
68 private final SurfaceControlDisplayFactory mSurfaceControlDisplayFactory;
Jeff Browna506a6e2013-06-04 00:02:38 -070069
70 // Called with SyncRoot lock held.
71 public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
72 Context context, Handler handler, Listener listener) {
Santos Cordonee8931e2017-04-05 10:31:15 -070073 this(syncRoot, context, handler, listener,
74 (String name, boolean secure) -> SurfaceControl.createDisplay(name, secure));
75 }
76
77 @VisibleForTesting
78 VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
79 Context context, Handler handler, Listener listener,
80 SurfaceControlDisplayFactory surfaceControlDisplayFactory) {
Jeff Browna506a6e2013-06-04 00:02:38 -070081 super(syncRoot, context, handler, listener, TAG);
Michael Wrightc39d47a2014-07-08 18:07:36 -070082 mHandler = handler;
Santos Cordonee8931e2017-04-05 10:31:15 -070083 mSurfaceControlDisplayFactory = surfaceControlDisplayFactory;
Jeff Browna506a6e2013-06-04 00:02:38 -070084 }
85
Michael Wright75ee9fc2014-09-01 19:55:22 -070086 public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallback callback,
Santos Cordonee8931e2017-04-05 10:31:15 -070087 IMediaProjection projection, int ownerUid, String ownerPackageName, String name,
88 int width, int height, int densityDpi, Surface surface, int flags, String uniqueId) {
Andrii Kulian7211d2e2017-01-27 15:58:05 -080089 boolean secure = (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
Michael Wright75ee9fc2014-09-01 19:55:22 -070090 IBinder appToken = callback.asBinder();
Santos Cordonee8931e2017-04-05 10:31:15 -070091 IBinder displayToken = mSurfaceControlDisplayFactory.createDisplay(name, secure);
Wale Ogunwale361ca212014-11-20 11:42:38 -080092 final String baseUniqueId =
93 UNIQUE_ID_PREFIX + ownerPackageName + "," + ownerUid + "," + name + ",";
94 final int uniqueIndex = getNextUniqueIndex(baseUniqueId);
Santos Cordonee8931e2017-04-05 10:31:15 -070095 if (uniqueId == null) {
96 uniqueId = baseUniqueId + uniqueIndex;
97 } else {
98 uniqueId = UNIQUE_ID_PREFIX + ownerPackageName + ":" + uniqueId;
99 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700100 VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700101 ownerUid, ownerPackageName, name, width, height, densityDpi, surface, flags,
Santos Cordonee8931e2017-04-05 10:31:15 -0700102 new Callback(callback, mHandler), uniqueId, uniqueIndex);
Michael Wrightc39d47a2014-07-08 18:07:36 -0700103
104 mVirtualDisplayDevices.put(appToken, device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700105
106 try {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700107 if (projection != null) {
Michael Wrightcde5bb42014-09-08 13:26:34 -0700108 projection.registerCallback(new MediaProjectionCallback(appToken));
Michael Wrightc39d47a2014-07-08 18:07:36 -0700109 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700110 appToken.linkToDeath(device, 0);
111 } catch (RemoteException ex) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700112 mVirtualDisplayDevices.remove(appToken);
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100113 device.destroyLocked(false);
Jeff Browna506a6e2013-06-04 00:02:38 -0700114 return null;
115 }
116
Jeff Browna506a6e2013-06-04 00:02:38 -0700117 // Return the display device without actually sending the event indicating
118 // that it was added. The caller will handle it.
119 return device;
120 }
121
Michael Wright01e840f2014-06-26 16:03:25 -0700122 public void resizeVirtualDisplayLocked(IBinder appToken,
123 int width, int height, int densityDpi) {
124 VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
125 if (device != null) {
126 device.resizeLocked(width, height, densityDpi);
127 }
128 }
129
130
Jeff Brown92207df2014-04-16 13:16:07 -0700131 public void setVirtualDisplaySurfaceLocked(IBinder appToken, Surface surface) {
132 VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
133 if (device != null) {
134 device.setSurfaceLocked(surface);
135 }
136 }
137
Jeff Browna506a6e2013-06-04 00:02:38 -0700138 public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
139 VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
140 if (device != null) {
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100141 device.destroyLocked(true);
Jeff Browna506a6e2013-06-04 00:02:38 -0700142 appToken.unlinkToDeath(device, 0);
143 }
144
145 // Return the display device that was removed without actually sending the
146 // event indicating that it was removed. The caller will handle it.
147 return device;
148 }
149
Wale Ogunwale361ca212014-11-20 11:42:38 -0800150 /**
151 * Returns the next unique index for the uniqueIdPrefix
152 */
153 private int getNextUniqueIndex(String uniqueIdPrefix) {
154 if (mVirtualDisplayDevices.isEmpty()) {
155 return 0;
156 }
157
158 int nextUniqueIndex = 0;
159 Iterator<VirtualDisplayDevice> it = mVirtualDisplayDevices.values().iterator();
160 while (it.hasNext()) {
161 VirtualDisplayDevice device = it.next();
162 if (device.getUniqueId().startsWith(uniqueIdPrefix)
163 && device.mUniqueIndex >= nextUniqueIndex) {
164 // Increment the next unique index to be greater than ones we have already ran
165 // across for displays that have the same unique Id prefix.
166 nextUniqueIndex = device.mUniqueIndex + 1;
167 }
168 }
169
170 return nextUniqueIndex;
171 }
172
Jeff Browna506a6e2013-06-04 00:02:38 -0700173 private void handleBinderDiedLocked(IBinder appToken) {
Bryce Leea3320fe2017-02-15 17:47:25 -0800174 mVirtualDisplayDevices.remove(appToken);
Jeff Browna506a6e2013-06-04 00:02:38 -0700175 }
176
Michael Wrightc39d47a2014-07-08 18:07:36 -0700177 private void handleMediaProjectionStoppedLocked(IBinder appToken) {
178 VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
179 if (device != null) {
180 Slog.i(TAG, "Virtual display device released because media projection stopped: "
181 + device.mName);
182 device.stopLocked();
183 }
184 }
185
186 private final class VirtualDisplayDevice extends DisplayDevice implements DeathRecipient {
Michael Wright01e840f2014-06-26 16:03:25 -0700187 private static final int PENDING_SURFACE_CHANGE = 0x01;
188 private static final int PENDING_RESIZE = 0x02;
189
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700190 private static final float REFRESH_RATE = 60.0f;
191
Jeff Browna506a6e2013-06-04 00:02:38 -0700192 private final IBinder mAppToken;
193 private final int mOwnerUid;
194 final String mOwnerPackageName;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700195 final String mName;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700196 private final int mFlags;
Michael Wright75ee9fc2014-09-01 19:55:22 -0700197 private final Callback mCallback;
Jeff Browna506a6e2013-06-04 00:02:38 -0700198
Michael Wright01e840f2014-06-26 16:03:25 -0700199 private int mWidth;
200 private int mHeight;
201 private int mDensityDpi;
Jeff Browna506a6e2013-06-04 00:02:38 -0700202 private Surface mSurface;
203 private DisplayDeviceInfo mInfo;
Michael Wright01e840f2014-06-26 16:03:25 -0700204 private int mDisplayState;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700205 private boolean mStopped;
Michael Wright01e840f2014-06-26 16:03:25 -0700206 private int mPendingChanges;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800207 private int mUniqueIndex;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700208 private Display.Mode mMode;
Jeff Browna506a6e2013-06-04 00:02:38 -0700209
Michael Wrightc39d47a2014-07-08 18:07:36 -0700210 public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
211 int ownerUid, String ownerPackageName,
212 String name, int width, int height, int densityDpi, Surface surface, int flags,
Wale Ogunwale361ca212014-11-20 11:42:38 -0800213 Callback callback, String uniqueId, int uniqueIndex) {
214 super(VirtualDisplayAdapter.this, displayToken, uniqueId);
Jeff Browna506a6e2013-06-04 00:02:38 -0700215 mAppToken = appToken;
216 mOwnerUid = ownerUid;
217 mOwnerPackageName = ownerPackageName;
218 mName = name;
219 mWidth = width;
220 mHeight = height;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700221 mMode = createMode(width, height, REFRESH_RATE);
Jeff Browna506a6e2013-06-04 00:02:38 -0700222 mDensityDpi = densityDpi;
223 mSurface = surface;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700224 mFlags = flags;
Michael Wright75ee9fc2014-09-01 19:55:22 -0700225 mCallback = callback;
Michael Wright01e840f2014-06-26 16:03:25 -0700226 mDisplayState = Display.STATE_UNKNOWN;
227 mPendingChanges |= PENDING_SURFACE_CHANGE;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800228 mUniqueIndex = uniqueIndex;
Jeff Browna506a6e2013-06-04 00:02:38 -0700229 }
230
231 @Override
232 public void binderDied() {
233 synchronized (getSyncRoot()) {
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100234 handleBinderDiedLocked(mAppToken);
Bryce Leea3320fe2017-02-15 17:47:25 -0800235 Slog.i(TAG, "Virtual display device released because application token died: "
236 + mOwnerPackageName);
237 destroyLocked(false);
238 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_REMOVED);
Jeff Browna506a6e2013-06-04 00:02:38 -0700239 }
240 }
241
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100242 public void destroyLocked(boolean binderAlive) {
Jesse Hall6a6bc212013-08-08 12:15:03 -0700243 if (mSurface != null) {
244 mSurface.release();
245 mSurface = null;
246 }
247 SurfaceControl.destroyDisplay(getDisplayTokenLocked());
Michael Wrightd1a5fae2015-05-05 14:16:35 +0100248 if (binderAlive) {
249 mCallback.dispatchDisplayStopped();
250 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700251 }
252
253 @Override
Michael Wright1c9977b2016-07-12 13:30:10 -0700254 public boolean hasStableUniqueId() {
255 return false;
256 }
257
258 @Override
Jeff Brown5d6443b2015-04-10 20:15:01 -0700259 public Runnable requestDisplayStateLocked(int state, int brightness) {
Michael Wright01e840f2014-06-26 16:03:25 -0700260 if (state != mDisplayState) {
261 mDisplayState = state;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700262 if (state == Display.STATE_OFF) {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700263 mCallback.dispatchDisplayPaused();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700264 } else {
Michael Wright75ee9fc2014-09-01 19:55:22 -0700265 mCallback.dispatchDisplayResumed();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700266 }
267 }
Jeff Browne75926d2014-09-18 15:24:49 -0700268 return null;
Jeff Browna506a6e2013-06-04 00:02:38 -0700269 }
270
271 @Override
Robert Carrae606b42018-02-15 15:36:23 -0800272 public void performTraversalLocked(SurfaceControl.Transaction t) {
Michael Wright01e840f2014-06-26 16:03:25 -0700273 if ((mPendingChanges & PENDING_RESIZE) != 0) {
Robert Carrae606b42018-02-15 15:36:23 -0800274 t.setDisplaySize(getDisplayTokenLocked(), mWidth, mHeight);
Michael Wright01e840f2014-06-26 16:03:25 -0700275 }
276 if ((mPendingChanges & PENDING_SURFACE_CHANGE) != 0) {
Robert Carrae606b42018-02-15 15:36:23 -0800277 setSurfaceLocked(t, mSurface);
Michael Wright01e840f2014-06-26 16:03:25 -0700278 }
279 mPendingChanges = 0;
Jeff Browna506a6e2013-06-04 00:02:38 -0700280 }
281
Jeff Brown92207df2014-04-16 13:16:07 -0700282 public void setSurfaceLocked(Surface surface) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700283 if (!mStopped && mSurface != surface) {
Jeff Brown92207df2014-04-16 13:16:07 -0700284 if ((mSurface != null) != (surface != null)) {
285 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
286 }
287 sendTraversalRequestLocked();
288 mSurface = surface;
289 mInfo = null;
Michael Wright01e840f2014-06-26 16:03:25 -0700290 mPendingChanges |= PENDING_SURFACE_CHANGE;
291 }
292 }
293
294 public void resizeLocked(int width, int height, int densityDpi) {
295 if (mWidth != width || mHeight != height || mDensityDpi != densityDpi) {
296 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
297 sendTraversalRequestLocked();
298 mWidth = width;
299 mHeight = height;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700300 mMode = createMode(width, height, REFRESH_RATE);
Michael Wright01e840f2014-06-26 16:03:25 -0700301 mDensityDpi = densityDpi;
302 mInfo = null;
303 mPendingChanges |= PENDING_RESIZE;
Jeff Brown92207df2014-04-16 13:16:07 -0700304 }
305 }
306
Michael Wrightc39d47a2014-07-08 18:07:36 -0700307 public void stopLocked() {
308 setSurfaceLocked(null);
309 mStopped = true;
310 }
311
312 @Override
313 public void dumpLocked(PrintWriter pw) {
314 super.dumpLocked(pw);
315 pw.println("mFlags=" + mFlags);
Michael Wright01e840f2014-06-26 16:03:25 -0700316 pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
Michael Wrightc39d47a2014-07-08 18:07:36 -0700317 pw.println("mStopped=" + mStopped);
318 }
319
320
Jeff Browna506a6e2013-06-04 00:02:38 -0700321 @Override
322 public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
323 if (mInfo == null) {
324 mInfo = new DisplayDeviceInfo();
325 mInfo.name = mName;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800326 mInfo.uniqueId = getUniqueId();
Jeff Browna506a6e2013-06-04 00:02:38 -0700327 mInfo.width = mWidth;
328 mInfo.height = mHeight;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700329 mInfo.modeId = mMode.getModeId();
330 mInfo.defaultModeId = mMode.getModeId();
331 mInfo.supportedModes = new Display.Mode[] { mMode };
Jeff Browna506a6e2013-06-04 00:02:38 -0700332 mInfo.densityDpi = mDensityDpi;
333 mInfo.xDpi = mDensityDpi;
334 mInfo.yDpi = mDensityDpi;
P.Y. Laligand5c7773d2015-05-04 13:30:58 -0700335 mInfo.presentationDeadlineNanos = 1000000000L / (int) REFRESH_RATE; // 1 frame
Jeff Brown7d00aff2013-08-02 19:03:49 -0700336 mInfo.flags = 0;
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800337 if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
Michael Wright6720be42014-07-29 19:14:16 -0700338 mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
339 | DisplayDeviceInfo.FLAG_NEVER_BLANK;
340 }
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800341 if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
Michael Wright6720be42014-07-29 19:14:16 -0700342 mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK;
343 } else {
Jeff Brownd14c8c92014-01-07 18:13:09 -0800344 mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700345 }
Michael Wright6720be42014-07-29 19:14:16 -0700346
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800347 if ((mFlags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
Jeff Brown7d00aff2013-08-02 19:03:49 -0700348 mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
349 }
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800350 if ((mFlags & VIRTUAL_DISPLAY_FLAG_PRESENTATION) != 0) {
Jeff Brown7d00aff2013-08-02 19:03:49 -0700351 mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
Chong Zhangae6119ff2014-11-11 18:54:39 -0800352
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800353 if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
Chong Zhangae6119ff2014-11-11 18:54:39 -0800354 // For demonstration purposes, allow rotation of the external display.
355 // In the future we might allow the user to configure this directly.
356 if ("portrait".equals(SystemProperties.get(
357 "persist.demo.remoterotation"))) {
358 mInfo.rotation = Surface.ROTATION_270;
359 }
360 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700361 }
Andrii Kulian7211d2e2017-01-27 15:58:05 -0800362 if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
363 mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -0800364 }
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -0400365 if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) {
366 mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
367 }
rongliu1e90fc32017-10-04 17:30:30 -0700368 if ((mFlags & VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) {
369 mInfo.flags |= DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL;
370 }
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -0400371
Jeff Browna506a6e2013-06-04 00:02:38 -0700372 mInfo.type = Display.TYPE_VIRTUAL;
Santos Cordonee8931e2017-04-05 10:31:15 -0700373 mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
374 DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL;
Jeff Brown92207df2014-04-16 13:16:07 -0700375 mInfo.state = mSurface != null ? Display.STATE_ON : Display.STATE_OFF;
Jeff Browna506a6e2013-06-04 00:02:38 -0700376 mInfo.ownerUid = mOwnerUid;
377 mInfo.ownerPackageName = mOwnerPackageName;
378 }
379 return mInfo;
380 }
381 }
Michael Wrightc39d47a2014-07-08 18:07:36 -0700382
Michael Wright75ee9fc2014-09-01 19:55:22 -0700383 private static class Callback extends Handler {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700384 private static final int MSG_ON_DISPLAY_PAUSED = 0;
385 private static final int MSG_ON_DISPLAY_RESUMED = 1;
386 private static final int MSG_ON_DISPLAY_STOPPED = 2;
387
Michael Wright75ee9fc2014-09-01 19:55:22 -0700388 private final IVirtualDisplayCallback mCallback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700389
Michael Wright75ee9fc2014-09-01 19:55:22 -0700390 public Callback(IVirtualDisplayCallback callback, Handler handler) {
Michael Wrightc39d47a2014-07-08 18:07:36 -0700391 super(handler.getLooper());
Michael Wright75ee9fc2014-09-01 19:55:22 -0700392 mCallback = callback;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700393 }
394
395 @Override
396 public void handleMessage(Message msg) {
397 try {
398 switch (msg.what) {
399 case MSG_ON_DISPLAY_PAUSED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700400 mCallback.onPaused();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700401 break;
402 case MSG_ON_DISPLAY_RESUMED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700403 mCallback.onResumed();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700404 break;
405 case MSG_ON_DISPLAY_STOPPED:
Michael Wright75ee9fc2014-09-01 19:55:22 -0700406 mCallback.onStopped();
Michael Wrightc39d47a2014-07-08 18:07:36 -0700407 break;
408 }
409 } catch (RemoteException e) {
410 Slog.w(TAG, "Failed to notify listener of virtual display event.", e);
411 }
412 }
413
414 public void dispatchDisplayPaused() {
415 sendEmptyMessage(MSG_ON_DISPLAY_PAUSED);
416 }
417
418 public void dispatchDisplayResumed() {
419 sendEmptyMessage(MSG_ON_DISPLAY_RESUMED);
420 }
421
422 public void dispatchDisplayStopped() {
423 sendEmptyMessage(MSG_ON_DISPLAY_STOPPED);
424 }
425 }
426
427 private final class MediaProjectionCallback extends IMediaProjectionCallback.Stub {
428 private IBinder mAppToken;
429 public MediaProjectionCallback(IBinder appToken) {
430 mAppToken = appToken;
431 }
432
433 @Override
434 public void onStop() {
435 synchronized (getSyncRoot()) {
436 handleMediaProjectionStoppedLocked(mAppToken);
437 }
438 }
439 }
Santos Cordonee8931e2017-04-05 10:31:15 -0700440
441 @VisibleForTesting
442 public interface SurfaceControlDisplayFactory {
443 public IBinder createDisplay(String name, boolean secure);
444 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700445}