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

Commit dfe920d3 authored by Chien-Yu Chen's avatar Chien-Yu Chen Committed by Android (Google) Code Review
Browse files

Merge "Camera2: Stop repeating request for abandoned output" into nyc-dev

parents 793f8591 2da496f1
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -921,7 +921,16 @@ public class CameraDeviceImpl extends CameraDevice
                int requestId = mRepeatingRequestId;
                mRepeatingRequestId = REQUEST_ID_NONE;

                long lastFrameNumber = mRemoteDevice.cancelRequest(requestId);
                long lastFrameNumber;
                try {
                    lastFrameNumber = mRemoteDevice.cancelRequest(requestId);
                } catch (IllegalArgumentException e) {
                    if (DEBUG) {
                        Log.v(TAG, "Repeating request was already stopped for request " + requestId);
                    }
                    // Repeating request was already stopped. Nothing more to do.
                    return;
                }

                checkEarlyTriggerSequenceComplete(requestId, lastFrameNumber);
            }
@@ -1685,6 +1694,24 @@ public class CameraDeviceImpl extends CameraDevice
            }
        }

        @Override
        public void onRepeatingRequestError(long lastFrameNumber) {
            if (DEBUG) {
                Log.d(TAG, "Repeating request error received. Last frame number is " +
                        lastFrameNumber);
            }

            synchronized(mInterfaceLock) {
                // Camera is already closed or no repeating request is present.
                if (mRemoteDevice == null || mRepeatingRequestId == REQUEST_ID_NONE) {
                    return; // Camera already closed
                }

                checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber);
                mRepeatingRequestId = REQUEST_ID_NONE;
            }
        }

        @Override
        public void onDeviceIdle() {
            if (DEBUG) {
+17 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ public class CameraDeviceState {
        void onBusy();
        void onCaptureStarted(RequestHolder holder, long timestamp);
        void onCaptureResult(CameraMetadataNative result, RequestHolder holder);
        void onRepeatingRequestError(long lastFrameNumber);
    }

    /**
@@ -200,6 +201,22 @@ public class CameraDeviceState {
        return setCaptureResult(request, result, NO_CAPTURE_ERROR, /*errorArg*/null);
    }

    /**
     * Set repeating request error.
     *
     * <p>Repeating request has been stopped due to an error such as abandoned output surfaces.</p>
     *
     * @param lastFrameNumber Frame number of the last repeating request before it is stopped.
     */
    public synchronized void setRepeatingRequestError(final long lastFrameNumber) {
        mCurrentHandler.post(new Runnable() {
            @Override
            public void run() {
                mCurrentListener.onRepeatingRequestError(lastFrameNumber);
            }
        });
    }

    /**
     * Set the listener for state transition callbacks.
     *
+16 −0
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
        private static final int CAPTURE_STARTED = 2;
        private static final int RESULT_RECEIVED = 3;
        private static final int PREPARED = 4;
        private static final int REPEATING_REQUEST_ERROR = 5;

        private final HandlerThread mHandlerThread;
        private Handler mHandler;
@@ -261,6 +262,15 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
            getHandler().sendMessage(msg);
        }


        @Override
        public void onRepeatingRequestError(long lastFrameNumber) {
            Message msg = getHandler().obtainMessage(REPEATING_REQUEST_ERROR,
                    /*arg1*/ (int) (lastFrameNumber & 0xFFFFFFFFL),
                    /*arg2*/ (int) ( (lastFrameNumber >> 32) & 0xFFFFFFFFL));
            getHandler().sendMessage(msg);
        }

        @Override
        public IBinder asBinder() {
            // This is solely intended to be used for in-process binding.
@@ -311,6 +321,12 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
                            mCallbacks.onPrepared(streamId);
                            break;
                        }
                        case REPEATING_REQUEST_ERROR: {
                            long lastFrameNumber = msg.arg2 & 0xFFFFFFFFL;
                            lastFrameNumber = (lastFrameNumber << 32) | (msg.arg1 & 0xFFFFFFFFL);
                            mCallbacks.onRepeatingRequestError(lastFrameNumber);
                            break;
                        }
                        default:
                            throw new IllegalArgumentException(
                                "Unknown callback message " + msg.what);
+45 −7
Original line number Diff line number Diff line
@@ -242,6 +242,25 @@ public class LegacyCameraDevice implements AutoCloseable {
                }
            });
        }

        @Override
        public void onRepeatingRequestError(final long lastFrameNumber) {
            mResultHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (DEBUG) {
                        Log.d(TAG, "doing onRepeatingRequestError callback.");
                    }
                    try {
                        mDeviceCallbacks.onRepeatingRequestError(lastFrameNumber);
                    } catch (RemoteException e) {
                        throw new IllegalStateException(
                                "Received remote exception during onRepeatingRequestError " +
                                "callback: ", e);
                    }
                }
            });
        }
    };

    private final RequestThreadManager mRequestThreadManager;
@@ -397,8 +416,15 @@ public class LegacyCameraDevice implements AutoCloseable {
                    "submitRequestList - Empty/null requests are not allowed");
        }

        List<Long> surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() :
        List<Long> surfaceIds;

        try {
            surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() :
                    getSurfaceIds(mConfiguredSurfaces);
        } catch (BufferQueueAbandonedException e) {
            throw new ServiceSpecificException(BAD_VALUE,
                    "submitRequestList - configured surface is abandoned.");
        }

        // Make sure that there all requests have at least 1 surface; all surfaces are non-null
        for (CaptureRequest request : requestList) {
@@ -674,12 +700,17 @@ public class LegacyCameraDevice implements AutoCloseable {
        LegacyExceptionUtils.throwOnError(nativeSetSurfaceDimens(surface, width, height));
    }

    static long getSurfaceId(Surface surface) {
    static long getSurfaceId(Surface surface) throws BufferQueueAbandonedException {
        checkNotNull(surface);
        try {
            return nativeGetSurfaceId(surface);
        } catch (IllegalArgumentException e) {
            throw new BufferQueueAbandonedException();
        }
    }

    static List<Long> getSurfaceIds(SparseArray<Surface> surfaces) {
    static List<Long> getSurfaceIds(SparseArray<Surface> surfaces)
            throws BufferQueueAbandonedException {
        if (surfaces == null) {
            throw new NullPointerException("Null argument surfaces");
        }
@@ -696,7 +727,8 @@ public class LegacyCameraDevice implements AutoCloseable {
        return surfaceIds;
    }

    static List<Long> getSurfaceIds(Collection<Surface> surfaces) {
    static List<Long> getSurfaceIds(Collection<Surface> surfaces)
            throws BufferQueueAbandonedException {
        if (surfaces == null) {
            throw new NullPointerException("Null argument surfaces");
        }
@@ -713,7 +745,13 @@ public class LegacyCameraDevice implements AutoCloseable {
    }

    static boolean containsSurfaceId(Surface s, Collection<Long> ids) {
        long id = getSurfaceId(s);
        long id = 0;
        try {
            id = getSurfaceId(s);
        } catch (BufferQueueAbandonedException e) {
            // If surface is abandoned, return false.
            return false;
        }
        return ids.contains(id);
    }

+14 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ public class RequestHolder {
    private final int mNumJpegTargets;
    private final int mNumPreviewTargets;
    private volatile boolean mFailed = false;
    private boolean mOutputAbandoned = false;

    private final Collection<Long> mJpegSurfaceIds;

@@ -266,4 +267,17 @@ public class RequestHolder {
        return mFailed;
    }

    /**
     * Mark at least one of this request's output surfaces is abandoned.
     */
    public void setOutputAbandoned() {
        mOutputAbandoned = true;
    }

    /**
     * Return if any of this request's output surface is abandoned.
     */
    public boolean isOutputAbandoned() {
        return mOutputAbandoned;
    }
}
Loading