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/java/android/view | |
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/java/android/view')
-rw-r--r-- | core/java/android/view/Surface.java | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index e0786f7..409db84 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -36,7 +36,7 @@ public class Surface implements Parcelable { throws OutOfResourcesException; private static native int nativeCreateFromSurfaceControl(int surfaceControlNativeObject); - private static native void nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty) + private static native int nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty) throws OutOfResourcesException; private static native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas); @@ -72,6 +72,7 @@ public class Surface implements Parcelable { final Object mLock = new Object(); // protects the native state private String mName; int mNativeObject; // package scope only for SurfaceControl access + private int mLockedObject; private int mGenerationId; // incremented each time mNativeObject changes private final Canvas mCanvas = new CompatibleCanvas(); @@ -233,7 +234,14 @@ public class Surface implements Parcelable { throws OutOfResourcesException, IllegalArgumentException { synchronized (mLock) { checkNotReleasedLocked(); - nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); + if (mLockedObject != 0) { + // Ideally, nativeLockCanvas() would throw in this situation and prevent the + // double-lock, but that won't happen if mNativeObject was updated. We can't + // abandon the old mLockedObject because it might still be in use, so instead + // we just refuse to re-lock the Surface. + throw new RuntimeException("Surface was already locked"); + } + mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); return mCanvas; } } @@ -252,11 +260,21 @@ public class Surface implements Parcelable { synchronized (mLock) { checkNotReleasedLocked(); - nativeUnlockCanvasAndPost(mNativeObject, canvas); + if (mNativeObject != mLockedObject) { + Log.w(TAG, "WARNING: Surface's mNativeObject (0x" + + Integer.toHexString(mNativeObject) + ") != mLockedObject (0x" + + Integer.toHexString(mLockedObject) +")"); + } + if (mLockedObject == 0) { + throw new RuntimeException("Surface was not locked"); + } + nativeUnlockCanvasAndPost(mLockedObject, canvas); + nativeRelease(mLockedObject); + mLockedObject = 0; } } - /** + /** * @deprecated This API has been removed and is not supported. Do not use. */ @Deprecated @@ -343,6 +361,10 @@ public class Surface implements Parcelable { } synchronized (mLock) { + // nativeReadFromParcel() will either return mNativeObject, or + // create a new native Surface and return it after reducing + // the reference count on mNativeObject. Either way, it is + // not necessary to call nativeRelease() here. mName = source.readString(); setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); } @@ -365,7 +387,8 @@ public class Surface implements Parcelable { @Override public String toString() { synchronized (mLock) { - return "Surface(name=" + mName + ")"; + return "Surface(name=" + mName + ")/@0x" + + Integer.toHexString(System.identityHashCode(this)); } } @@ -463,7 +486,7 @@ public class Surface implements Parcelable { public void getMatrix(Matrix m) { super.getMatrix(m); if (mOrigMatrix == null) { - mOrigMatrix = new Matrix(); + mOrigMatrix = new Matrix(); } mOrigMatrix.set(m); } |