Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59210de1 authored by Andy McFadden's avatar Andy McFadden Committed by Android (Google) Code Review
Browse files

Merge "Avoid crashing in unlockCanvasAndPost" into klp-dev

parents ec850cd6 ed55c8db
Loading
Loading
Loading
Loading
+29 −6
Original line number Diff line number Diff line
@@ -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,7 +260,17 @@ 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;
        }
    }

@@ -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));
        }
    }

+11 −4
Original line number Diff line number Diff line
@@ -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 },