Fail createVirtualDisplay with single-buffered Surface
Bug 30106031
Change-Id: I434df329eb3c162dd9ef01245ac5e0da97216e70
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 286e097..dc19d32 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -96,6 +96,8 @@
private HwuiContext mHwuiContext;
+ private boolean mIsSingleBuffered;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({SCALING_MODE_FREEZE, SCALING_MODE_SCALE_TO_WINDOW,
@@ -158,7 +160,7 @@
if (surfaceTexture == null) {
throw new IllegalArgumentException("surfaceTexture must not be null");
}
-
+ mIsSingleBuffered = surfaceTexture.isSingleBuffered();
synchronized (mLock) {
mName = surfaceTexture.toString();
setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
@@ -458,6 +460,7 @@
// the reference count on mNativeObject. Either way, it is
// not necessary to call nativeRelease() here.
mName = source.readString();
+ mIsSingleBuffered = source.readInt() != 0;
setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
}
}
@@ -469,6 +472,7 @@
}
synchronized (mLock) {
dest.writeString(mName);
+ dest.writeInt(mIsSingleBuffered ? 1 : 0);
nativeWriteToParcel(mNativeObject, dest);
}
if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
@@ -531,6 +535,14 @@
}
/**
+ * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture
+ * @hide
+ */
+ public boolean isSingleBuffered() {
+ return mIsSingleBuffered;
+ }
+
+ /**
* Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
* when a SurfaceTexture could not successfully be allocated.
*/
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 0d8a95c..73b3f52 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -371,7 +371,12 @@
if (sur != NULL) {
bufferProducer = sur->getIGraphicBufferProducer();
}
- SurfaceComposerClient::setDisplaySurface(token, bufferProducer);
+ status_t err = SurfaceComposerClient::setDisplaySurface(token,
+ bufferProducer);
+ if (err != NO_ERROR) {
+ doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this"
+ " Surface created with singleBufferMode?");
+ }
}
static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 5c54324..c386108 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -77,6 +77,8 @@
private long mProducer;
private long mFrameAvailableListener;
+ private boolean mIsSingleBuffered;
+
/**
* Callback interface for being notified that a new stream frame is available.
*/
@@ -130,6 +132,7 @@
*/
public SurfaceTexture(int texName, boolean singleBufferMode) {
mCreatorLooper = Looper.myLooper();
+ mIsSingleBuffered = singleBufferMode;
nativeInit(false, texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
}
@@ -157,6 +160,7 @@
*/
public SurfaceTexture(boolean singleBufferMode) {
mCreatorLooper = Looper.myLooper();
+ mIsSingleBuffered = singleBufferMode;
nativeInit(true, 0, singleBufferMode, new WeakReference<SurfaceTexture>(this));
}
@@ -378,6 +382,14 @@
}
}
+ /**
+ * Returns true if the SurfaceTexture is single-buffered
+ * @hide
+ */
+ public boolean isSingleBuffered() {
+ return mIsSingleBuffered;
+ }
+
private native void nativeInit(boolean isDetached, int texName,
boolean singleBufferMode, WeakReference<SurfaceTexture> weakSelf)
throws Surface.OutOfResourcesException;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 0abd2e7..45a9644 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1402,6 +1402,9 @@
throw new IllegalArgumentException("width, height, and densityDpi must be "
+ "greater than 0");
}
+ if (surface.isSingleBuffered()) {
+ throw new IllegalArgumentException("Surface can't be single-buffered");
+ }
if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;