[wm] VirtualDisplayConfig to mirror the non-default display
The application can request to mirror default display by using MediaProjection.
However, there is no way to mirror the specific display on multi-display enviroment.
Now, the application can set displayIdToMirror through VirtualDisplayConfig class.
Test: atest FrameworksServicesTests:DisplayManagerServiceTest
Bug : 127687569
Change-Id: I1ef94bfa79e103d0a4a05a10fc8705ed3bbcc0c9
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index a232051..3afbf66 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -57,6 +57,7 @@
import android.hardware.display.IDisplayManager;
import android.hardware.display.IDisplayManagerCallback;
import android.hardware.display.IVirtualDisplayCallback;
+import android.hardware.display.VirtualDisplayConfig;
import android.hardware.display.WifiDisplayStatus;
import android.hardware.input.InputManagerInternal;
import android.media.projection.IMediaProjection;
@@ -794,8 +795,8 @@
}
private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
- IMediaProjection projection, int callingUid, String packageName, String name, int width,
- int height, int densityDpi, Surface surface, int flags, String uniqueId) {
+ IMediaProjection projection, int callingUid, String packageName, Surface surface,
+ int flags, VirtualDisplayConfig virtualDisplayConfig) {
synchronized (mSyncRoot) {
if (mVirtualDisplayAdapter == null) {
Slog.w(TAG, "Rejecting request to create private virtual display "
@@ -804,8 +805,8 @@
}
DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
- callback, projection, callingUid, packageName, name, width, height, densityDpi,
- surface, flags, uniqueId);
+ callback, projection, callingUid, packageName, surface, flags,
+ virtualDisplayConfig);
if (device == null) {
return -1;
}
@@ -1480,8 +1481,8 @@
if (!ownContent) {
if (display != null && !display.hasContentLocked()) {
// If the display does not have any content of its own, then
- // automatically mirror the default logical display contents.
- display = null;
+ // automatically mirror the requested logical display contents if possible.
+ display = mLogicalDisplays.get(device.getDisplayIdToMirrorLocked());
}
if (display == null) {
display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
@@ -1729,6 +1730,28 @@
}
}
+ @VisibleForTesting
+ int getDisplayIdToMirrorInternal(int displayId) {
+ synchronized (mSyncRoot) {
+ LogicalDisplay display = mLogicalDisplays.get(displayId);
+ if (display != null) {
+ DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+ return displayDevice.getDisplayIdToMirrorLocked();
+ }
+ return Display.INVALID_DISPLAY;
+ }
+ }
+
+ @VisibleForTesting
+ Surface getVirtualDisplaySurfaceInternal(IBinder appToken) {
+ synchronized (mSyncRoot) {
+ if (mVirtualDisplayAdapter == null) {
+ return null;
+ }
+ return mVirtualDisplayAdapter.getVirtualDisplaySurfaceLocked(appToken);
+ }
+ }
+
private final class DisplayManagerHandler extends Handler {
public DisplayManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
@@ -2050,10 +2073,8 @@
}
@Override // Binder call
- public int createVirtualDisplay(IVirtualDisplayCallback callback,
- IMediaProjection projection, String packageName, String name,
- int width, int height, int densityDpi, Surface surface, int flags,
- String uniqueId) {
+ public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
+ IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) {
final int callingUid = Binder.getCallingUid();
if (!validatePackageName(callingUid, packageName)) {
throw new SecurityException("packageName must match the calling uid");
@@ -2061,13 +2082,12 @@
if (callback == null) {
throw new IllegalArgumentException("appToken must not be null");
}
- if (TextUtils.isEmpty(name)) {
- throw new IllegalArgumentException("name must be non-null and non-empty");
+ if (virtualDisplayConfig == null) {
+ throw new IllegalArgumentException("virtualDisplayConfig must not be null");
}
- if (width <= 0 || height <= 0 || densityDpi <= 0) {
- throw new IllegalArgumentException("width, height, and densityDpi must be "
- + "greater than 0");
- }
+ final Surface surface = virtualDisplayConfig.getSurface();
+ int flags = virtualDisplayConfig.getFlags();
+
if (surface != null && surface.isSingleBuffered()) {
throw new IllegalArgumentException("Surface can't be single-buffered");
}
@@ -2128,7 +2148,7 @@
final long token = Binder.clearCallingIdentity();
try {
return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
- name, width, height, densityDpi, surface, flags, uniqueId);
+ surface, flags, virtualDisplayConfig);
} finally {
Binder.restoreCallingIdentity(token);
}