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

Commit 6eec4185 authored by Avichal Rakesh's avatar Avichal Rakesh Committed by Android (Google) Code Review
Browse files

Merge "Revert "Prevent onImageAvailable from being called on stale listeners""

parents ac9e0ba2 ea4dbac4
Loading
Loading
Loading
Loading
+20 −42
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@ import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.StampedLock;

/**
 * <p>The ImageReader class allows direct application access to image data
@@ -676,8 +675,7 @@ public class ImageReader implements AutoCloseable {
     *            If no handler specified and the calling thread has no looper.
     */
    public void setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
        long writeStamp = mListenerLock.writeLock();
        try {
        synchronized (mListenerLock) {
            if (listener != null) {
                Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
                if (looper == null) {
@@ -693,8 +691,6 @@ public class ImageReader implements AutoCloseable {
                mListenerExecutor = null;
            }
            mListener = listener;
        } finally {
            mListenerLock.unlockWrite(writeStamp);
        }
    }

@@ -717,12 +713,9 @@ public class ImageReader implements AutoCloseable {
            throw new IllegalArgumentException("executor must not be null");
        }

        long writeStamp = mListenerLock.writeLock();
        try {
        synchronized (mListenerLock) {
            mListenerExecutor = executor;
            mListener = listener;
        } finally {
            mListenerLock.unlockWrite(writeStamp);
        }
    }

@@ -738,8 +731,6 @@ public class ImageReader implements AutoCloseable {
        /**
         * Callback that is called when a new image is available from ImageReader.
         *
         * This callback must not modify or close the passed {@code reader}.
         *
         * @param reader the ImageReader the callback is associated with.
         * @see ImageReader
         * @see Image
@@ -898,42 +889,29 @@ public class ImageReader implements AutoCloseable {
            return;
        }

        synchronized (ir.mCloseLock) {
            if (!ir.mIsReaderValid) {
                // It's dangerous to fire onImageAvailable() callback when the ImageReader
                // is being closed, as application could acquire next image in the
                // onImageAvailable() callback.
                return;
            }
        }

        final Executor executor;
        final long readStamp = ir.mListenerLock.readLock();
        try {
        final OnImageAvailableListener listener;
        synchronized (ir.mListenerLock) {
            executor = ir.mListenerExecutor;
            if (executor == null) {
                return;
            listener = ir.mListener;
        }
        } finally {
            ir.mListenerLock.unlockRead(readStamp);
        final boolean isReaderValid;
        synchronized (ir.mCloseLock) {
            isReaderValid = ir.mIsReaderValid;
        }

        executor.execute(() -> {
            // Acquire readlock to ensure that the ImageReader does not change its
            // state while a listener is actively processing.
            final long rStamp = ir.mListenerLock.readLock();
            try {
                // Fire onImageAvailable of the latest non-null listener
                // This ensures that if the listener changes while messages are in queue, the
                // in-flight messages will call onImageAvailable of the new listener instead
                if (ir.mListener != null) {
                    ir.mListener.onImageAvailable(ir);
                }
            } finally {
                ir.mListenerLock.unlockRead(rStamp);
        // It's dangerous to fire onImageAvailable() callback when the ImageReader
        // is being closed, as application could acquire next image in the
        // onImageAvailable() callback.
        if (executor != null && listener != null && isReaderValid) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    listener.onImageAvailable(ir);
                }
            });
        }
    }

    /**
     * Builder class for {@link ImageReader} objects.
@@ -1092,7 +1070,7 @@ public class ImageReader implements AutoCloseable {
    private Surface mSurface;
    private int mEstimatedNativeAllocBytes;

    private final StampedLock mListenerLock = new StampedLock();
    private final Object mListenerLock = new Object();
    private final Object mCloseLock = new Object();
    private boolean mIsReaderValid = false;
    private OnImageAvailableListener mListener;