diff options
author | Andy McFadden <fadden@android.com> | 2013-08-20 10:05:51 -0700 |
---|---|---|
committer | Andy McFadden <fadden@android.com> | 2013-08-20 11:23:17 -0700 |
commit | ed55c8db1c0d47492423fc54f4b0dd5cd585e593 (patch) | |
tree | bdb2642fabb49dafe2e7102629a9a45b46fa8c3f /core/jni/android_view_Surface.cpp | |
parent | 58514937628dfcf3b2949e4cbc45d5526ecb8019 (diff) | |
download | frameworks_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.cpp | 15 |
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 }, |