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

Commit 731009ed authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Add API for surface offline mode queries

Camera clients of devices that support offline processing
capability must be able to check for offline support of
individual surfaces registered within a give capture session.

Bug: 135142453
Test: Camera CTS
Change-Id: Ia5b6ec31a3540925b92761c9ac1f2407214cbcf7
parent 301abd49
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16953,6 +16953,7 @@ package android.hardware.camera2 {
    method public abstract int setRepeatingRequest(@NonNull android.hardware.camera2.CaptureRequest, @Nullable android.hardware.camera2.CameraCaptureSession.CaptureCallback, @Nullable android.os.Handler) throws android.hardware.camera2.CameraAccessException;
    method public int setSingleRepeatingRequest(@NonNull android.hardware.camera2.CaptureRequest, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.CaptureCallback) throws android.hardware.camera2.CameraAccessException;
    method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
    method public boolean supportsOfflineProcessing(@NonNull android.view.Surface);
    method @Nullable public android.hardware.camera2.CameraOfflineSession switchToOffline(@NonNull java.util.Collection<android.view.Surface>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback) throws android.hardware.camera2.CameraAccessException;
    method public void updateOutputConfiguration(android.hardware.camera2.params.OutputConfiguration) throws android.hardware.camera2.CameraAccessException;
  }
+33 −5
Original line number Diff line number Diff line
@@ -886,12 +886,14 @@ public abstract class CameraCaptureSession implements AutoCloseable {
     * @param offlineSurfaces Client-specified collection of input/output camera registered surfaces
     *                        that need to be switched to offline mode along with their pending
     *                        capture requests. Do note that not all camera registered
     *                        surfaces can be switched to offline mode.
     *                        Shared surfaces {@link OutputConfiguration#enableSurfaceSharing}
     *                        and surfaces as part of a surface group do not support offline
     *                        switches.
     *                        surfaces can be switched to offline mode. Offline processing
     *                        support for individual surfaces can be queried using
     *                        {@link #supportsOfflineProcessing}. Additionally offline mode
     *                        switches are not available for shared surfaces
     *                        {@link OutputConfiguration#enableSurfaceSharing} and surfaces
     *                        as part of a surface group.
     *
     * @param executor the executor which will be used for invoking the offline callback listener.
     * @param executor The executor which will be used for invoking the offline callback listener.
     *
     * @param listener The callback object to notify for offline session events.
     *
@@ -912,6 +914,7 @@ public abstract class CameraCaptureSession implements AutoCloseable {
     *
     * @see CameraOfflineSession
     * @see CameraOfflineSessionCallback
     * @see #supportsOfflineProcessing
     */
    @Nullable
    public CameraOfflineSession switchToOffline(@NonNull Collection<Surface> offlineSurfaces,
@@ -920,6 +923,31 @@ public abstract class CameraCaptureSession implements AutoCloseable {
        throw new UnsupportedOperationException("Subclasses must override this method");
    }

    /**
     * <p>Query whether a given Surface is able to support offline mode. </p>
     *
     * <p>Surfaces that support offline mode can be passed as arguments to {@link #switchToOffline}.
     * </p>
     *
     * @param surface An input/output surface that was used to create this session or the result of
     *                {@link #getInputSurface}.
     *
     * @return {@code true} if the surface can support offline mode and can be passed as argument to
     *         {@link #switchToOffline}. {@code false} otherwise.
     *
     * @throws IllegalArgumentException if an attempt was made to pass a {@link Surface} that was
     *                                  not registered with this capture session.
     * @throws UnsupportedOperationException if an attempt was made to call this method using
     *                                       unsupported camera capture session like
     *                                       {@link CameraConstrainedHighSpeedCaptureSession} or
     *                                       {@link CameraOfflineSession}.
     *
     * @see #switchToOffline
     */
    public boolean supportsOfflineProcessing(@NonNull Surface surface) {
        throw new UnsupportedOperationException("Subclasses must override this method");
    }

    /**
     * Close this capture session asynchronously.
     *
+9 −0
Original line number Diff line number Diff line
@@ -469,6 +469,15 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
        return mDeviceImpl.switchToOffline(offlineOutputs, executor, listener);
    }


    @Override
    public boolean supportsOfflineProcessing(Surface surface) {
        synchronized (mDeviceImpl.mInterfaceLock) {
            checkNotClosed();
        }
        return mDeviceImpl.supportsOfflineProcessing(surface);
    }

    @Override
    public boolean isReprocessable() {
        return mInput != null;
+6 −0
Original line number Diff line number Diff line
@@ -291,6 +291,12 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl
                + " this method");
    }

    @Override
    public boolean supportsOfflineProcessing(Surface surface) {
        throw new UnsupportedOperationException("Constrained high speed session doesn't support" +
                " offline mode");
    }

    @Override
    public void closeWithoutDraining() {
        throw new UnsupportedOperationException("Constrained high speed session doesn't support"
+33 −2
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ public class CameraDeviceImpl extends CameraDevice
    private final SparseArray<OutputConfiguration> mConfiguredOutputs =
            new SparseArray<>();

    // Cache all stream IDs capable of supporting offline mode.
    private final HashSet<Integer> mOfflineSupport = new HashSet<>();

    private final String mCameraId;
    private final CameraCharacteristics mCharacteristics;
    private final int mTotalPartialCount;
@@ -473,10 +476,19 @@ public class CameraDeviceImpl extends CameraDevice
                    }
                }

                int offlineStreamIds[];
                if (sessionParams != null) {
                    mRemoteDevice.endConfigure(operatingMode, sessionParams.getNativeCopy());
                    offlineStreamIds = mRemoteDevice.endConfigure(operatingMode,
                            sessionParams.getNativeCopy());
                } else {
                    mRemoteDevice.endConfigure(operatingMode, null);
                    offlineStreamIds = mRemoteDevice.endConfigure(operatingMode, null);
                }

                mOfflineSupport.clear();
                if ((offlineStreamIds != null) && (offlineStreamIds.length > 0)) {
                    for (int offlineStreamId : offlineStreamIds) {
                        mOfflineSupport.add(offlineStreamId);
                    }
                }

                success = true;
@@ -944,6 +956,25 @@ public class CameraDeviceImpl extends CameraDevice
        return mOfflineSessionImpl;
    }

    public boolean supportsOfflineProcessing(Surface surface) {
        if (surface == null) throw new IllegalArgumentException("Surface is null");

        synchronized(mInterfaceLock) {
            int streamId = -1;
            for (int i = 0; i < mConfiguredOutputs.size(); i++) {
                if (surface == mConfiguredOutputs.valueAt(i).getSurface()) {
                    streamId = mConfiguredOutputs.keyAt(i);
                    break;
                }
            }
            if (streamId == -1) {
                throw new IllegalArgumentException("Surface is not part of this session");
            }

            return mOfflineSupport.contains(streamId);
        }
    }

    public void tearDown(Surface surface) throws CameraAccessException {
        if (surface == null) throw new IllegalArgumentException("Surface is null");

Loading