Merge "Add support for dynamically setting the virtual display surface." into klp-modular-dev
This commit is contained in:
@@ -10950,7 +10950,9 @@ package android.hardware.display {
|
|||||||
|
|
||||||
public final class VirtualDisplay {
|
public final class VirtualDisplay {
|
||||||
method public android.view.Display getDisplay();
|
method public android.view.Display getDisplay();
|
||||||
|
method public android.view.Surface getSurface();
|
||||||
method public void release();
|
method public void release();
|
||||||
|
method public void setSurface(android.view.Surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,6 +437,14 @@ public final class DisplayManager {
|
|||||||
* The behavior of the virtual display depends on the flags that are provided
|
* The behavior of the virtual display depends on the flags that are provided
|
||||||
* to this method. By default, virtual displays are created to be private,
|
* to this method. By default, virtual displays are created to be private,
|
||||||
* non-presentation and unsecure. Permissions may be required to use certain flags.
|
* non-presentation and unsecure. Permissions may be required to use certain flags.
|
||||||
|
* </p><p>
|
||||||
|
* As of {@link android.os.Build.VERSION_CODES#KITKAT_WATCH}, the surface may
|
||||||
|
* be attached or detached dynamically using {@link VirtualDisplay#setSurface}.
|
||||||
|
* Previously, the surface had to be non-null when {@link #createVirtualDisplay}
|
||||||
|
* was called and could not be changed for the lifetime of the display.
|
||||||
|
* </p><p>
|
||||||
|
* Detaching the surface that backs a virtual display has a similar effect to
|
||||||
|
* turning off the screen.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param name The name of the virtual display, must be non-empty.
|
* @param name The name of the virtual display, must be non-empty.
|
||||||
@@ -444,7 +452,7 @@ public final class DisplayManager {
|
|||||||
* @param height The height 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 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
|
* @param surface The surface to which the content of the virtual display should
|
||||||
* be rendered, must be non-null.
|
* be rendered, or null if there is none initially.
|
||||||
* @param flags A combination of virtual display flags:
|
* @param flags A combination of virtual display flags:
|
||||||
* {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
|
* {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
|
||||||
* {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, or {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
|
* {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, or {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
|
||||||
|
|||||||
@@ -377,9 +377,6 @@ public final class DisplayManagerGlobal {
|
|||||||
throw new IllegalArgumentException("width, height, and densityDpi must be "
|
throw new IllegalArgumentException("width, height, and densityDpi must be "
|
||||||
+ "greater than 0");
|
+ "greater than 0");
|
||||||
}
|
}
|
||||||
if (surface == null) {
|
|
||||||
throw new IllegalArgumentException("surface must not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Binder token = new Binder();
|
Binder token = new Binder();
|
||||||
int displayId;
|
int displayId;
|
||||||
@@ -404,7 +401,15 @@ public final class DisplayManagerGlobal {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new VirtualDisplay(this, display, token);
|
return new VirtualDisplay(this, display, token, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVirtualDisplaySurface(IBinder token, Surface surface) {
|
||||||
|
try {
|
||||||
|
mDm.setVirtualDisplaySurface(token, surface);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
Log.w(TAG, "Failed to set virtual display surface.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void releaseVirtualDisplay(IBinder token) {
|
public void releaseVirtualDisplay(IBinder token) {
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ interface IDisplayManager {
|
|||||||
int createVirtualDisplay(IBinder token, String packageName,
|
int createVirtualDisplay(IBinder token, String packageName,
|
||||||
String name, int width, int height, int densityDpi, in Surface surface, int flags);
|
String name, int width, int height, int densityDpi, in Surface surface, int flags);
|
||||||
|
|
||||||
|
// No permissions required but must be same Uid as the creator.
|
||||||
|
void setVirtualDisplaySurface(in IBinder token, in Surface surface);
|
||||||
|
|
||||||
// No permissions required but must be same Uid as the creator.
|
// No permissions required but must be same Uid as the creator.
|
||||||
void releaseVirtualDisplay(in IBinder token);
|
void releaseVirtualDisplay(in IBinder token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,15 +17,18 @@ package android.hardware.display;
|
|||||||
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
|
import android.view.Surface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a virtual display. The content of a virtual display is rendered to a
|
* Represents a virtual display. The content of a virtual display is rendered to a
|
||||||
* {@link android.view.Surface} that you must provide to {@link DisplayManager#createVirtualDisplay
|
* {@link android.view.Surface} that you must provide to {@link DisplayManager#createVirtualDisplay
|
||||||
* createVirtualDisplay()}.
|
* createVirtualDisplay()}.
|
||||||
* <p>Because a virtual display renders to a surface provided by the application, it will be
|
* <p>
|
||||||
|
* Because a virtual display renders to a surface provided by the application, it will be
|
||||||
* released automatically when the process terminates and all remaining windows on it will
|
* released automatically when the process terminates and all remaining windows on it will
|
||||||
* be forcibly removed. However, you should also explicitly call {@link #release} when you're
|
* be forcibly removed. However, you should also explicitly call {@link #release} when
|
||||||
* done with it.
|
* you're done with it.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @see DisplayManager#createVirtualDisplay
|
* @see DisplayManager#createVirtualDisplay
|
||||||
*/
|
*/
|
||||||
@@ -33,11 +36,14 @@ public final class VirtualDisplay {
|
|||||||
private final DisplayManagerGlobal mGlobal;
|
private final DisplayManagerGlobal mGlobal;
|
||||||
private final Display mDisplay;
|
private final Display mDisplay;
|
||||||
private IBinder mToken;
|
private IBinder mToken;
|
||||||
|
private Surface mSurface;
|
||||||
|
|
||||||
VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token) {
|
VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token,
|
||||||
|
Surface surface) {
|
||||||
mGlobal = global;
|
mGlobal = global;
|
||||||
mDisplay = display;
|
mDisplay = display;
|
||||||
mToken = token;
|
mToken = token;
|
||||||
|
mSurface = surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,6 +53,32 @@ public final class VirtualDisplay {
|
|||||||
return mDisplay;
|
return mDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the surface that backs the virtual display.
|
||||||
|
*/
|
||||||
|
public Surface getSurface() {
|
||||||
|
return mSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the surface that backs the virtual display.
|
||||||
|
* <p>
|
||||||
|
* Detaching the surface that backs a virtual display has a similar effect to
|
||||||
|
* turning off the screen.
|
||||||
|
* </p><p>
|
||||||
|
* It is still the caller's responsibility to destroy the surface after it has
|
||||||
|
* been detached.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param surface The surface to set, or null to detach the surface from the virtual display.
|
||||||
|
*/
|
||||||
|
public void setSurface(Surface surface) {
|
||||||
|
if (mSurface != surface) {
|
||||||
|
mGlobal.setVirtualDisplaySurface(mToken, surface);
|
||||||
|
mSurface = surface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases the virtual display and destroys its underlying surface.
|
* Releases the virtual display and destroys its underlying surface.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -63,6 +95,7 @@ public final class VirtualDisplay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken + "}";
|
return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken
|
||||||
|
+ ", surface=" + mSurface + "}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -517,6 +517,16 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
|
||||||
|
synchronized (mSyncRoot) {
|
||||||
|
if (mVirtualDisplayAdapter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void releaseVirtualDisplayInternal(IBinder appToken) {
|
private void releaseVirtualDisplayInternal(IBinder appToken) {
|
||||||
synchronized (mSyncRoot) {
|
synchronized (mSyncRoot) {
|
||||||
if (mVirtualDisplayAdapter == null) {
|
if (mVirtualDisplayAdapter == null) {
|
||||||
@@ -1221,9 +1231,6 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
throw new IllegalArgumentException("width, height, and densityDpi must be "
|
throw new IllegalArgumentException("width, height, and densityDpi must be "
|
||||||
+ "greater than 0");
|
+ "greater than 0");
|
||||||
}
|
}
|
||||||
if (surface == null) {
|
|
||||||
throw new IllegalArgumentException("surface must not be null");
|
|
||||||
}
|
|
||||||
if (callingUid != Process.SYSTEM_UID &&
|
if (callingUid != Process.SYSTEM_UID &&
|
||||||
(flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
|
(flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
|
||||||
if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
|
if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
|
||||||
@@ -1254,6 +1261,16 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // Binder call
|
||||||
|
public void setVirtualDisplaySurface(IBinder appToken, Surface surface) {
|
||||||
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
setVirtualDisplaySurfaceInternal(appToken, surface);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override // Binder call
|
@Override // Binder call
|
||||||
public void releaseVirtualDisplay(IBinder appToken) {
|
public void releaseVirtualDisplay(IBinder appToken) {
|
||||||
final long token = Binder.clearCallingIdentity();
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVirtualDisplaySurfaceLocked(IBinder appToken, Surface surface) {
|
||||||
|
VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
|
||||||
|
if (device != null) {
|
||||||
|
device.setSurfaceLocked(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
|
public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
|
||||||
VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
|
VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
@@ -144,6 +151,17 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSurfaceLocked(Surface surface) {
|
||||||
|
if (mSurface != surface) {
|
||||||
|
if ((mSurface != null) != (surface != null)) {
|
||||||
|
sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
|
||||||
|
}
|
||||||
|
sendTraversalRequestLocked();
|
||||||
|
mSurface = surface;
|
||||||
|
mInfo = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
|
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
|
||||||
if (mInfo == null) {
|
if (mInfo == null) {
|
||||||
@@ -171,6 +189,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
mInfo.type = Display.TYPE_VIRTUAL;
|
mInfo.type = Display.TYPE_VIRTUAL;
|
||||||
mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
|
mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
|
||||||
|
mInfo.state = mSurface != null ? Display.STATE_ON : Display.STATE_OFF;
|
||||||
mInfo.ownerUid = mOwnerUid;
|
mInfo.ownerUid = mOwnerUid;
|
||||||
mInfo.ownerPackageName = mOwnerPackageName;
|
mInfo.ownerPackageName = mOwnerPackageName;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user