Merge "Add VDM.createVirtualDisplay"

This commit is contained in:
TreeHugger Robot
2021-12-20 19:30:42 +00:00
committed by Android (Google) Code Review
2 changed files with 109 additions and 0 deletions

View File

@@ -16,21 +16,32 @@
package android.companion.virtual;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.companion.AssociationInfo;
import android.content.Context;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.hardware.display.VirtualDisplayConfig;
import android.hardware.input.VirtualKeyboard;
import android.hardware.input.VirtualMouse;
import android.hardware.input.VirtualTouchscreen;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.Surface;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* System level service for managing virtual devices.
@@ -44,6 +55,31 @@ public final class VirtualDeviceManager {
private static final boolean DEBUG = false;
private static final String LOG_TAG = "VirtualDeviceManager";
/** @hide */
@IntDef(prefix = "DISPLAY_FLAG_",
flag = true,
value = {DISPLAY_FLAG_TRUSTED})
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
public @interface DisplayFlags {}
/**
* Indicates that the display is trusted to show system decorations and receive inputs without
* users' touch.
*
* @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
* @hide // TODO(b/194949534): Unhide this API
*/
public static final int DISPLAY_FLAG_TRUSTED = 1;
private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS =
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
| DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT
| DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
| DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL
| DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH
| DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
private final IVirtualDeviceManager mService;
private final Context mContext;
@@ -92,6 +128,56 @@ public final class VirtualDeviceManager {
mVirtualDevice = virtualDevice;
}
/**
* Creates a virtual display for this virtual device. All displays created on the same
* device belongs to the same display group.
*
* @param width The width of the virtual display in pixels, must be greater than 0.
* @param height The height of the virtual display in pixels, must be greater than 0.
* @param densityDpi The density of the virtual display in dpi, must be greater than 0.
* @param surface The surface to which the content of the virtual display should
* be rendered, or null if there is none initially. The surface can also be set later using
* {@link VirtualDisplay#setSurface(Surface)}.
* @param flags Either 0, or {@link #DISPLAY_FLAG_TRUSTED}.
* @param callback Callback to call when the state of the {@link VirtualDisplay} changes
* @param handler The handler on which the listener should be invoked, or null
* if the listener should be invoked on the calling thread's looper.
* @return The newly created virtual display, or {@code null} if the application could
* not create the virtual display.
*
* @see DisplayManager#createVirtualDisplay
* @hide
*/
// TODO(b/194949534): Unhide this API
// Suppress "ExecutorRegistration" because DisplayManager.createVirtualDisplay takes a
// handler
@SuppressLint("ExecutorRegistration")
@Nullable
public VirtualDisplay createVirtualDisplay(
int width,
int height,
int densityDpi,
@Nullable Surface surface,
@DisplayFlags int flags,
@Nullable Handler handler,
@Nullable VirtualDisplay.Callback callback) {
// TODO(b/205343547): Handle display groups properly instead of creating a new display
// group for every new virtual display created using this API.
// belongs to the same display group.
DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
// DisplayManager will call into VirtualDeviceManagerInternal to register the
// created displays.
return displayManager.createVirtualDisplay(
mVirtualDevice,
new VirtualDisplayConfig.Builder(
getVirtualDisplayName(), width, height, densityDpi)
.setSurface(surface)
.setFlags(getVirtualDisplayFlags(flags))
.build(),
callback,
handler);
}
/**
* Closes the virtual device, stopping and tearing down any virtual displays,
* audio policies, and event injection that's currently in progress.
@@ -186,5 +272,25 @@ public final class VirtualDeviceManager {
throw e.rethrowFromSystemServer();
}
}
private int getVirtualDisplayFlags(@DisplayFlags int flags) {
int virtualDisplayFlags = DEFAULT_VIRTUAL_DISPLAY_FLAGS;
if ((flags & DISPLAY_FLAG_TRUSTED) != 0) {
virtualDisplayFlags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
}
return virtualDisplayFlags;
}
private String getVirtualDisplayName() {
try {
// Currently this just use the association ID, which means all of the virtual
// displays created using the same virtual device will have the same name. The name
// should only be used for informational purposes, and not for identifying the
// display in code.
return "VirtualDevice_" + mVirtualDevice.getAssociationId();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}

View File

@@ -55,6 +55,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
@VisibleForTesting
final List<Integer> mVirtualDisplayIds = new ArrayList<>();
private final OnDeviceCloseListener mListener;
private final IBinder mAppToken;
/**
* A mapping from the virtual display ID to its corresponding
@@ -74,6 +75,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
mContext = context;
mAssociationInfo = associationInfo;
mOwnerUid = ownerUid;
mAppToken = token;
if (inputController == null) {
mInputController = new InputController(mVirtualDeviceLock);
} else {
@@ -95,6 +97,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
@Override // Binder call
public void close() {
mListener.onClose(mAssociationInfo.getId());
mAppToken.unlinkToDeath(this, 0);
mInputController.close();
}