am 8e1e4006: Merge "Add support for dynamically setting the virtual display surface." into klp-modular-dev
* commit '8e1e40066bae030d6a6e8f3f3f8f69ccd6ec1848': Add support for dynamically setting the virtual display surface.
This commit is contained in:
@@ -10950,7 +10950,9 @@ package android.hardware.display {
|
||||
|
||||
public final class VirtualDisplay {
|
||||
method public android.view.Display getDisplay();
|
||||
method public android.view.Surface getSurface();
|
||||
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
|
||||
* to this method. By default, virtual displays are created to be private,
|
||||
* 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>
|
||||
*
|
||||
* @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 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, must be non-null.
|
||||
* be rendered, or null if there is none initially.
|
||||
* @param flags A combination of virtual display flags:
|
||||
* {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
|
||||
* {@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 "
|
||||
+ "greater than 0");
|
||||
}
|
||||
if (surface == null) {
|
||||
throw new IllegalArgumentException("surface must not be null");
|
||||
}
|
||||
|
||||
Binder token = new Binder();
|
||||
int displayId;
|
||||
@@ -404,7 +401,15 @@ public final class DisplayManagerGlobal {
|
||||
}
|
||||
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) {
|
||||
|
||||
@@ -62,6 +62,9 @@ interface IDisplayManager {
|
||||
int createVirtualDisplay(IBinder token, String packageName,
|
||||
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.
|
||||
void releaseVirtualDisplay(in IBinder token);
|
||||
}
|
||||
|
||||
@@ -17,15 +17,18 @@ package android.hardware.display;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
* be forcibly removed. However, you should also explicitly call {@link #release} when you're
|
||||
* done with it.
|
||||
* be forcibly removed. However, you should also explicitly call {@link #release} when
|
||||
* you're done with it.
|
||||
* </p>
|
||||
*
|
||||
* @see DisplayManager#createVirtualDisplay
|
||||
*/
|
||||
@@ -33,11 +36,14 @@ public final class VirtualDisplay {
|
||||
private final DisplayManagerGlobal mGlobal;
|
||||
private final Display mDisplay;
|
||||
private IBinder mToken;
|
||||
private Surface mSurface;
|
||||
|
||||
VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token) {
|
||||
VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token,
|
||||
Surface surface) {
|
||||
mGlobal = global;
|
||||
mDisplay = display;
|
||||
mToken = token;
|
||||
mSurface = surface;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,6 +53,32 @@ public final class VirtualDisplay {
|
||||
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.
|
||||
* <p>
|
||||
@@ -63,6 +95,7 @@ public final class VirtualDisplay {
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
|
||||
synchronized (mSyncRoot) {
|
||||
if (mVirtualDisplayAdapter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseVirtualDisplayInternal(IBinder appToken) {
|
||||
synchronized (mSyncRoot) {
|
||||
if (mVirtualDisplayAdapter == null) {
|
||||
@@ -1221,9 +1231,6 @@ public final class DisplayManagerService extends SystemService {
|
||||
throw new IllegalArgumentException("width, height, and densityDpi must be "
|
||||
+ "greater than 0");
|
||||
}
|
||||
if (surface == null) {
|
||||
throw new IllegalArgumentException("surface must not be null");
|
||||
}
|
||||
if (callingUid != Process.SYSTEM_UID &&
|
||||
(flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
|
||||
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
|
||||
public void releaseVirtualDisplay(IBinder appToken) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
|
||||
@@ -69,6 +69,13 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
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) {
|
||||
VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
|
||||
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
|
||||
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
|
||||
if (mInfo == null) {
|
||||
@@ -171,6 +189,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
mInfo.type = Display.TYPE_VIRTUAL;
|
||||
mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
|
||||
mInfo.state = mSurface != null ? Display.STATE_ON : Display.STATE_OFF;
|
||||
mInfo.ownerUid = mOwnerUid;
|
||||
mInfo.ownerPackageName = mOwnerPackageName;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user