Add resize method for virtual displays

Change-Id: I2632fc56c2d2cba356379e42f5c1a3e283b11d1e
This commit is contained in:
Michael Wright
2014-06-26 16:03:25 -07:00
parent e877138d44
commit 01e840ff94
8 changed files with 111 additions and 9 deletions

View File

@@ -13247,6 +13247,7 @@ package android.hardware.display {
method public android.view.Display getDisplay();
method public android.view.Surface getSurface();
method public void release();
method public void resize(int, int, int);
method public void setSurface(android.view.Surface);
}

View File

@@ -416,6 +416,15 @@ public final class DisplayManagerGlobal {
}
}
public void resizeVirtualDisplay(IVirtualDisplayCallbacks token,
int width, int height, int densityDpi) {
try {
mDm.resizeVirtualDisplay(token, width, height, densityDpi);
} catch (RemoteException ex) {
Log.w(TAG, "Failed to resize virtual display.", ex);
}
}
public void releaseVirtualDisplay(IVirtualDisplayCallbacks token) {
try {
mDm.releaseVirtualDisplay(token);

View File

@@ -65,6 +65,10 @@ interface IDisplayManager {
in IMediaProjection projectionToken, 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 resizeVirtualDisplay(in IVirtualDisplayCallbacks token,
int width, int height, int densityDpi);
// No permissions required but must be same Uid as the creator.
void setVirtualDisplaySurface(in IVirtualDisplayCallbacks token, in Surface surface);

View File

@@ -79,6 +79,18 @@ public final class VirtualDisplay {
}
}
/**
* Asks the virtual display to resize.
*<p>
* This is really just a convenience to allow applications using
* virtual displays to adapt to changing conditions without having
* to tear down and recreate the display.
* </p>
*/
public void resize(int width, int height, int densityDpi) {
mGlobal.resizeVirtualDisplay(mToken, width, height, densityDpi);
}
/**
* Releases the virtual display and destroys its underlying surface.
* <p>

View File

@@ -74,6 +74,7 @@ public class SurfaceControl {
IBinder displayToken, int orientation,
int l, int t, int r, int b,
int L, int T, int R, int B);
private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
IBinder displayToken);
private static native int nativeGetActiveConfig(IBinder displayToken);
@@ -588,6 +589,17 @@ public class SurfaceControl {
}
}
public static void setDisplaySize(IBinder displayToken, int width, int height) {
if (displayToken == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be positive");
}
nativeSetDisplaySize(displayToken, width, height);
}
public static IBinder createDisplay(String name, boolean secure) {
if (name == null) {
throw new IllegalArgumentException("name must not be null");

View File

@@ -369,6 +369,13 @@ static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
}
static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
jobject tokenObj, jint width, jint height) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
if (token == NULL) return;
SurfaceComposerClient::setDisplaySize(token, width, height);
}
static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
jobject tokenObj) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
@@ -620,6 +627,8 @@ static JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetDisplayLayerStack },
{"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V",
(void*)nativeSetDisplayProjection },
{"nativeSetDisplaySize", "(Landroid/os/IBinder;II)V",
(void*)nativeSetDisplaySize },
{"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;",
(void*)nativeGetDisplayConfigs },
{"nativeGetActiveConfig", "(Landroid/os/IBinder;)I",

View File

@@ -523,6 +523,17 @@ public final class DisplayManagerService extends SystemService {
return -1;
}
private void resizeVirtualDisplayInternal(IBinder appToken,
int width, int height, int densityDpi) {
synchronized (mSyncRoot) {
if (mVirtualDisplayAdapter == null) {
return;
}
mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
}
}
private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
synchronized (mSyncRoot) {
if (mVirtualDisplayAdapter == null) {
@@ -1303,6 +1314,17 @@ public final class DisplayManagerService extends SystemService {
}
}
@Override // Binder call
public void resizeVirtualDisplay(IVirtualDisplayCallbacks callbacks,
int width, int height, int densityDpi) {
final long token = Binder.clearCallingIdentity();
try {
resizeVirtualDisplayInternal(callbacks.asBinder(), width, height, densityDpi);
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override // Binder call
public void setVirtualDisplaySurface(IVirtualDisplayCallbacks callbacks, Surface surface) {
final long token = Binder.clearCallingIdentity();

View File

@@ -83,6 +83,15 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
return device;
}
public void resizeVirtualDisplayLocked(IBinder appToken,
int width, int height, int densityDpi) {
VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
if (device != null) {
device.resizeLocked(width, height, densityDpi);
}
}
public void setVirtualDisplaySurfaceLocked(IBinder appToken, Surface surface) {
VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
if (device != null) {
@@ -122,20 +131,24 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
}
private final class VirtualDisplayDevice extends DisplayDevice implements DeathRecipient {
private static final int PENDING_SURFACE_CHANGE = 0x01;
private static final int PENDING_RESIZE = 0x02;
private final IBinder mAppToken;
private final int mOwnerUid;
final String mOwnerPackageName;
final String mName;
private final int mWidth;
private final int mHeight;
private final int mDensityDpi;
private final int mFlags;
private final Callbacks mCallbacks;
private int mWidth;
private int mHeight;
private int mDensityDpi;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
private int mState;
private int mDisplayState;
private boolean mStopped;
private int mPendingChanges;
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
int ownerUid, String ownerPackageName,
@@ -152,7 +165,8 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
mSurface = surface;
mFlags = flags;
mCallbacks = callbacks;
mState = Display.STATE_UNKNOWN;
mDisplayState = Display.STATE_UNKNOWN;
mPendingChanges |= PENDING_SURFACE_CHANGE;
}
@Override
@@ -175,8 +189,8 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
@Override
public void requestDisplayStateLocked(int state) {
if (state != mState) {
mState = state;
if (state != mDisplayState) {
mDisplayState = state;
if (state == Display.STATE_OFF) {
mCallbacks.dispatchDisplayPaused();
} else {
@@ -187,7 +201,13 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
@Override
public void performTraversalInTransactionLocked() {
setSurfaceInTransactionLocked(mSurface);
if ((mPendingChanges & PENDING_RESIZE) != 0) {
SurfaceControl.setDisplaySize(getDisplayTokenLocked(), mWidth, mHeight);
}
if ((mPendingChanges & PENDING_SURFACE_CHANGE) != 0) {
setSurfaceInTransactionLocked(mSurface);
}
mPendingChanges = 0;
}
public void setSurfaceLocked(Surface surface) {
@@ -198,6 +218,19 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
sendTraversalRequestLocked();
mSurface = surface;
mInfo = null;
mPendingChanges |= PENDING_SURFACE_CHANGE;
}
}
public void resizeLocked(int width, int height, int densityDpi) {
if (mWidth != width || mHeight != height || mDensityDpi != densityDpi) {
sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
sendTraversalRequestLocked();
mWidth = width;
mHeight = height;
mDensityDpi = densityDpi;
mInfo = null;
mPendingChanges |= PENDING_RESIZE;
}
}
@@ -210,7 +243,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
pw.println("mFlags=" + mFlags);
pw.println("mState=" + Display.stateToString(mState));
pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
pw.println("mStopped=" + mStopped);
}