summaryrefslogtreecommitdiffstats
path: root/core/jni/android_view_Surface.cpp
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2013-08-20 10:05:51 -0700
committerAndy McFadden <fadden@android.com>2013-08-20 11:23:17 -0700
commited55c8db1c0d47492423fc54f4b0dd5cd585e593 (patch)
treebdb2642fabb49dafe2e7102629a9a45b46fa8c3f /core/jni/android_view_Surface.cpp
parent58514937628dfcf3b2949e4cbc45d5526ecb8019 (diff)
downloadframeworks_base-ed55c8db1c0d47492423fc54f4b0dd5cd585e593.zip
frameworks_base-ed55c8db1c0d47492423fc54f4b0dd5cd585e593.tar.gz
frameworks_base-ed55c8db1c0d47492423fc54f4b0dd5cd585e593.tar.bz2
Avoid crashing in unlockCanvasAndPost
It's possible to update the native surface pointer while the surface is locked (via lockCanvas). This leads to a surprise when the surface is unlocked. Avoid the surprise by tracking the locked surface separately. Bug 10289713 Change-Id: I84346c952be859bbd91ceae7df07b91dabe0948e
Diffstat (limited to 'core/jni/android_view_Surface.cpp')
-rw-r--r--core/jni/android_view_Surface.cpp15
1 files changed, 11 insertions, 4 deletions
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 304514b..3f54fd7 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -196,13 +196,13 @@ static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCa
SkSafeUnref(previousCanvas);
}
-static void nativeLockCanvas(JNIEnv* env, jclass clazz,
+static jint nativeLockCanvas(JNIEnv* env, jclass clazz,
jint nativeObject, jobject canvasObj, jobject dirtyRectObj) {
sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
if (!isSurfaceValid(surface)) {
doThrowIAE(env);
- return;
+ return 0;
}
Rect dirtyRect;
@@ -223,7 +223,7 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz,
OutOfResourcesException :
"java/lang/IllegalArgumentException";
jniThrowException(env, exception, NULL);
- return;
+ return 0;
}
// Associate a SkCanvas object to this surface
@@ -255,6 +255,13 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz,
env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right);
env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom);
}
+
+ // Create another reference to the surface and return it. This reference
+ // should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,
+ // because the latter could be replaced while the surface is locked.
+ sp<Surface> lockedSurface(surface);
+ lockedSurface->incStrong(&sRefBaseOwner);
+ return (int) lockedSurface.get();
}
static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,
@@ -351,7 +358,7 @@ static JNINativeMethod gSurfaceMethods[] = {
(void*)nativeIsValid },
{"nativeIsConsumerRunningBehind", "(I)Z",
(void*)nativeIsConsumerRunningBehind },
- {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V",
+ {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)I",
(void*)nativeLockCanvas },
{"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
(void*)nativeUnlockCanvasAndPost },