Merge "Add VDM.createVirtualDisplay"
This commit is contained in:
committed by
Android (Google) Code Review
commit
0f44e20e0b
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user