Merge "Handle Surface::lock errors in TextureView Bug #8689535"
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 5c3934d..f0acba1 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -648,13 +648,19 @@
* rectangle. Every pixel within that rectangle must be written; however
* pixels outside the dirty rectangle will be preserved by the next call
* to lockCanvas().
+ *
+ * This method can return null if the underlying surface texture is not
+ * available (see {@link #isAvailable()} or if the surface texture is
+ * already connected to an image producer (for instance: the camera,
+ * OpenGL, a media player, etc.)
*
* @param dirty Area of the surface that will be modified.
* @return A Canvas used to draw into the surface.
*
* @see #lockCanvas()
- * @see #unlockCanvasAndPost(android.graphics.Canvas)
+ * @see #unlockCanvasAndPost(android.graphics.Canvas)
+ * @see #isAvailable()
*/
public Canvas lockCanvas(Rect dirty) {
if (!isAvailable()) return null;
@@ -664,7 +670,9 @@
}
synchronized (mNativeWindowLock) {
- nLockCanvas(mNativeWindow, mCanvas, dirty);
+ if (!nLockCanvas(mNativeWindow, mCanvas, dirty)) {
+ return null;
+ }
}
mSaveCount = mCanvas.save();
@@ -803,6 +811,6 @@
private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture,
int width, int height);
- private static native void nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
+ private static native boolean nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
private static native void nUnlockCanvasAndPost(int nativeWindow, Canvas canvas);
}
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 5baae84..a1985bc 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -134,11 +134,11 @@
SkSafeUnref(previousCanvas);
}
-static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
+static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
jint nativeWindow, jobject canvas, jobject dirtyRect) {
if (!nativeWindow) {
- return;
+ return false;
}
ANativeWindow_Buffer buffer;
@@ -154,7 +154,8 @@
}
sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
- native_window_lock(window.get(), &buffer, &rect);
+ int32_t status = native_window_lock(window.get(), &buffer, &rect);
+ if (status) return false;
ssize_t bytesCount = buffer.stride * bytesPerPixel(buffer.format);
@@ -184,6 +185,8 @@
INVOKEV(dirtyRect, gRectClassInfo.set,
int(rect.left), int(rect.top), int(rect.right), int(rect.bottom));
}
+
+ return true;
}
static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject,
@@ -213,7 +216,7 @@
{ "nDestroyNativeWindow", "()V",
(void*) android_view_TextureView_destroyNativeWindow },
- { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V",
+ { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z",
(void*) android_view_TextureView_lockCanvas },
{ "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
(void*) android_view_TextureView_unlockCanvasAndPost },
@@ -241,7 +244,8 @@
GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");
FIND_CLASS(clazz, "android/graphics/Canvas");
- GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;");
+ GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
+ "Landroid/graphics/Canvas$CanvasFinalizer;");
GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");