Add v2 onCaptureStartedCallback: adds frame number to callback.

Bug: 214261327

Test: camera CTS native tests
Test: ACameraNdkVendorTest

Change-Id: I1b249a9b16cc9256a1604aacde6baa25b3b01fcb
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/camera/ndk/NdkCameraCaptureSession.cpp b/camera/ndk/NdkCameraCaptureSession.cpp
index 1ac8482..9c98778 100644
--- a/camera/ndk/NdkCameraCaptureSession.cpp
+++ b/camera/ndk/NdkCameraCaptureSession.cpp
@@ -29,6 +29,7 @@
 #include "impl/ACameraCaptureSession.h"
 
 #include "impl/ACameraCaptureSession.inc"
+#include "NdkCameraCaptureSession.inc"
 
 using namespace android;
 
@@ -72,22 +73,16 @@
         int numRequests, ACaptureRequest** requests,
         /*optional*/int* captureSequenceId) {
     ATRACE_CALL();
-    if (session == nullptr || requests == nullptr || numRequests < 1) {
-        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
-                __FUNCTION__, session, numRequests, requests);
-        return ACAMERA_ERROR_INVALID_PARAMETER;
-    }
+    return captureTemplate(session, cbs, numRequests, requests, captureSequenceId);
+}
 
-    if (session->isClosed()) {
-        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
-        if (captureSequenceId != nullptr) {
-            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
-        }
-        return ACAMERA_ERROR_SESSION_CLOSED;
-    }
-
-    return session->capture(
-            cbs, numRequests, requests, captureSequenceId);
+EXPORT
+camera_status_t ACameraCaptureSession_captureV2(
+        ACameraCaptureSession* session, /*optional*/ACameraCaptureSession_captureCallbacksV2* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    return captureTemplate(session, cbs, numRequests, requests, captureSequenceId);
 }
 
 EXPORT
@@ -97,22 +92,26 @@
         int numRequests, ACaptureRequest** requests,
         /*optional*/int* captureSequenceId) {
     ATRACE_CALL();
-    if (session == nullptr || requests == nullptr || numRequests < 1) {
-        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
-                __FUNCTION__, session, numRequests, requests);
-        return ACAMERA_ERROR_INVALID_PARAMETER;
-    }
+    return captureTemplate(session, lcbs, numRequests, requests, captureSequenceId);
+}
 
-    if (session->isClosed()) {
-        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
-        if (captureSequenceId) {
-            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
-        }
-        return ACAMERA_ERROR_SESSION_CLOSED;
-    }
+EXPORT
+camera_status_t ACameraCaptureSession_logicalCamera_captureV2(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    return captureTemplate(session, lcbs, numRequests, requests, captureSequenceId);
+}
 
-    return session->capture(
-            lcbs, numRequests, requests, captureSequenceId);
+EXPORT
+camera_status_t ACameraCaptureSession_setRepeatingRequestV2(
+        ACameraCaptureSession* session, /*optional*/ACameraCaptureSession_captureCallbacksV2* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    return setRepeatingRequestTemplate(session, cbs, numRequests, requests, captureSequenceId);
 }
 
 EXPORT
@@ -121,23 +120,10 @@
         int numRequests, ACaptureRequest** requests,
         /*optional*/int* captureSequenceId) {
     ATRACE_CALL();
-    if (session == nullptr || requests == nullptr || numRequests < 1) {
-        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
-                __FUNCTION__, session, numRequests, requests);
-        return ACAMERA_ERROR_INVALID_PARAMETER;
-    }
-
-    if (session->isClosed()) {
-        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
-        if (captureSequenceId) {
-            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
-        }
-        return ACAMERA_ERROR_SESSION_CLOSED;
-    }
-
-    return session->setRepeatingRequest(cbs, numRequests, requests, captureSequenceId);
+    return setRepeatingRequestTemplate(session, cbs, numRequests, requests, captureSequenceId);
 }
 
+
 EXPORT
 camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequest(
         ACameraCaptureSession* session,
@@ -145,21 +131,18 @@
         int numRequests, ACaptureRequest** requests,
         /*optional*/int* captureSequenceId) {
     ATRACE_CALL();
-    if (session == nullptr || requests == nullptr || numRequests < 1) {
-        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
-                __FUNCTION__, session, numRequests, requests);
-        return ACAMERA_ERROR_INVALID_PARAMETER;
-    }
+    return setRepeatingRequestTemplate(session, lcbs, numRequests, requests, captureSequenceId);
+}
 
-    if (session->isClosed()) {
-        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
-        if (captureSequenceId) {
-            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
-        }
-        return ACAMERA_ERROR_SESSION_CLOSED;
-    }
 
-    return session->setRepeatingRequest(lcbs, numRequests, requests, captureSequenceId);
+EXPORT
+camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequestV2(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    return setRepeatingRequestTemplate(session, lcbs, numRequests, requests, captureSequenceId);
 }
 
 EXPORT
diff --git a/camera/ndk/NdkCameraCaptureSession.inc b/camera/ndk/NdkCameraCaptureSession.inc
new file mode 100644
index 0000000..258e20d
--- /dev/null
+++ b/camera/ndk/NdkCameraCaptureSession.inc
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "impl/ACameraCaptureSession.h"
+
+#include <camera/NdkCameraCaptureSession.h>
+
+using namespace android;
+
+template <class CallbackType>
+camera_status_t captureTemplate(
+        ACameraCaptureSession* session,
+        /*optional*/CallbackType* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    if (session == nullptr || requests == nullptr || numRequests < 1) {
+        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
+                __FUNCTION__, session, numRequests, requests);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    if (session->isClosed()) {
+        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+        if (captureSequenceId) {
+            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        }
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+
+    return session->capture(
+            cbs, numRequests, requests, captureSequenceId);
+}
+
+template <class CallbackType>
+camera_status_t setRepeatingRequestTemplate(
+        ACameraCaptureSession* session,
+        /*optional*/CallbackType* cbs,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) {
+    ATRACE_CALL();
+    if (session == nullptr || requests == nullptr || numRequests < 1) {
+        ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
+                __FUNCTION__, session, numRequests, requests);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+
+    if (session->isClosed()) {
+        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+        if (captureSequenceId) {
+            *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+        }
+        return ACAMERA_ERROR_SESSION_CLOSED;
+    }
+
+    return session->setRepeatingRequest(cbs, numRequests, requests, captureSequenceId);
+}
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index dd652c7..7997768 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -26,8 +26,6 @@
 #include "ACaptureRequest.h"
 #include "ACameraCaptureSession.h"
 
-#include "ACameraCaptureSession.inc"
-
 ACameraDevice::~ACameraDevice() {
     mDevice->stopLooperAndDisconnect();
 }
@@ -913,6 +911,7 @@
         case kWhatOnError:
         case kWhatSessionStateCb:
         case kWhatCaptureStart:
+        case kWhatCaptureStart2:
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
@@ -985,6 +984,7 @@
         }
         case kWhatSessionStateCb:
         case kWhatCaptureStart:
+        case kWhatCaptureStart2:
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
@@ -1004,6 +1004,7 @@
             sp<CaptureRequest> requestSp = nullptr;
             switch (msg->what()) {
                 case kWhatCaptureStart:
+                case kWhatCaptureStart2:
                 case kWhatCaptureResult:
                 case kWhatLogicalCaptureResult:
                 case kWhatCaptureFail:
@@ -1055,6 +1056,35 @@
                     freeACaptureRequest(request);
                     break;
                 }
+                case kWhatCaptureStart2:
+                {
+                    ACameraCaptureSession_captureCallback_startV2 onStart2;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onStart2 == nullptr) {
+                        return;
+                    }
+                    int64_t timestamp;
+                    found = msg->findInt64(kTimeStampKey, &timestamp);
+                    if (!found) {
+                        ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
+                        return;
+                    }
+                    int64_t frameNumber;
+                    found = msg->findInt64(kFrameNumberKey, &frameNumber);
+                    if (!found) {
+                        ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+                        return;
+                    }
+
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
+                    (*onStart2)(context, session.get(), request, timestamp, frameNumber);
+                    freeACaptureRequest(request);
+                    break;
+                }
                 case kWhatCaptureResult:
                 {
                     ACameraCaptureSession_captureCallback_result onResult;
@@ -1285,7 +1315,8 @@
         ACameraCaptureSession_captureCallbacks* cbs) :
         mSession(session), mRequests(requests),
         mIsRepeating(isRepeating),
-        mIsLogicalCameraCallback(false) {
+        mIsLogicalCameraCallback(false),
+        mIs2Callback(false) {
     initCaptureCallbacks(cbs);
 
     if (cbs != nullptr) {
@@ -1301,7 +1332,8 @@
         ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
         mSession(session), mRequests(requests),
         mIsRepeating(isRepeating),
-        mIsLogicalCameraCallback(true) {
+        mIsLogicalCameraCallback(true),
+        mIs2Callback(false) {
     initCaptureCallbacks(lcbs);
 
     if (lcbs != nullptr) {
@@ -1310,6 +1342,40 @@
     }
 }
 
+CameraDevice::CallbackHolder::CallbackHolder(
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_captureCallbacksV2* cbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIsLogicalCameraCallback(false),
+        mIs2Callback(true) {
+    initCaptureCallbacksV2(cbs);
+
+    if (cbs != nullptr) {
+        mOnCaptureCompleted = cbs->onCaptureCompleted;
+        mOnCaptureFailed = cbs->onCaptureFailed;
+    }
+}
+
+CameraDevice::CallbackHolder::CallbackHolder(
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIsLogicalCameraCallback(true),
+        mIs2Callback(true) {
+    initCaptureCallbacksV2(lcbs);
+
+    if (lcbs != nullptr) {
+        mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+        mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
+    }
+}
+
 void
 CameraDevice::checkRepeatingSequenceCompleteLocked(
     const int sequenceId, const int64_t lastFrameNumber) {
@@ -1536,7 +1602,6 @@
         const CaptureResultExtras& resultExtras,
         int64_t timestamp) {
     binder::Status ret = binder::Status::ok();
-
     sp<CameraDevice> dev = mDevice.promote();
     if (dev == nullptr) {
         return ret; // device has been closed
@@ -1551,11 +1616,14 @@
 
     int sequenceId = resultExtras.requestId;
     int32_t burstId = resultExtras.burstId;
+    int64_t frameNumber = resultExtras.frameNumber;
 
     auto it = dev->mSequenceCallbackMap.find(sequenceId);
     if (it != dev->mSequenceCallbackMap.end()) {
         CallbackHolder cbh = (*it).second;
+        bool v2Callback = cbh.mIs2Callback;
         ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
+        ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
         sp<ACameraCaptureSession> session = cbh.mSession;
         if ((size_t) burstId >= cbh.mRequests.size()) {
             ALOGE("%s: Error: request index %d out of bound (size %zu)",
@@ -1563,12 +1631,19 @@
             dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
         }
         sp<CaptureRequest> request = cbh.mRequests[burstId];
-        sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+        sp<AMessage> msg = nullptr;
+        if (v2Callback) {
+            msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
+            msg->setPointer(kCallbackFpKey, (void*) onStart2);
+        } else {
+            msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+            msg->setPointer(kCallbackFpKey, (void *)onStart);
+        }
         msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, session);
-        msg->setPointer(kCallbackFpKey, (void*) onStart);
         msg->setObject(kCaptureRequestKey, request);
         msg->setInt64(kTimeStampKey, timestamp);
+        msg->setInt64(kFrameNumberKey, frameNumber);
         dev->postSessionMsgAndCleanup(msg);
     }
     return ret;
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 344d964..17988fe 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -215,6 +215,7 @@
         kWhatSessionStateCb,   // onReady, onActive
         // Capture callbacks
         kWhatCaptureStart,     // onCaptureStarted
+        kWhatCaptureStart2,     // onCaptureStarted
         kWhatCaptureResult,    // onCaptureProgressed, onCaptureCompleted
         kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
         kWhatCaptureFail,      // onCaptureFailed
@@ -294,11 +295,18 @@
                        const Vector<sp<CaptureRequest> >& requests,
                        bool                               isRepeating,
                        ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs);
-
-        template <class T>
-        void initCaptureCallbacks(T* cbs) {
+        CallbackHolder(sp<ACameraCaptureSession>          session,
+                       const Vector<sp<CaptureRequest> >& requests,
+                       bool                               isRepeating,
+                       ACameraCaptureSession_captureCallbacksV2* cbs);
+        CallbackHolder(sp<ACameraCaptureSession>          session,
+                       const Vector<sp<CaptureRequest> >& requests,
+                       bool                               isRepeating,
+                       ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs);
+        void clearCallbacks() {
             mContext = nullptr;
             mOnCaptureStarted = nullptr;
+            mOnCaptureStarted2 = nullptr;
             mOnCaptureProgressed = nullptr;
             mOnCaptureCompleted = nullptr;
             mOnLogicalCameraCaptureCompleted = nullptr;
@@ -307,6 +315,24 @@
             mOnCaptureSequenceCompleted = nullptr;
             mOnCaptureSequenceAborted = nullptr;
             mOnCaptureBufferLost = nullptr;
+        }
+
+        template <class T>
+        void initCaptureCallbacksV2(T* cbs) {
+            clearCallbacks();
+            if (cbs != nullptr) {
+                mContext = cbs->context;
+                mOnCaptureStarted2 = cbs->onCaptureStarted;
+                mOnCaptureProgressed = cbs->onCaptureProgressed;
+                mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
+                mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
+                mOnCaptureBufferLost = cbs->onCaptureBufferLost;
+            }
+        }
+
+        template <class T>
+        void initCaptureCallbacks(T* cbs) {
+            clearCallbacks();
             if (cbs != nullptr) {
                 mContext = cbs->context;
                 mOnCaptureStarted = cbs->onCaptureStarted;
@@ -320,9 +346,11 @@
         Vector<sp<CaptureRequest> > mRequests;
         const bool                  mIsRepeating;
         const bool                  mIsLogicalCameraCallback;
+        const bool                  mIs2Callback;
 
         void*                       mContext;
         ACameraCaptureSession_captureCallback_start mOnCaptureStarted;
+        ACameraCaptureSession_captureCallback_startV2 mOnCaptureStarted2;
         ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
         ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
         ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
diff --git a/camera/ndk/include/camera/NdkCameraCaptureSession.h b/camera/ndk/include/camera/NdkCameraCaptureSession.h
index 2b7f040..b0fd00c 100644
--- a/camera/ndk/include/camera/NdkCameraCaptureSession.h
+++ b/camera/ndk/include/camera/NdkCameraCaptureSession.h
@@ -811,6 +811,184 @@
         int numRequests, ACaptureRequest** requests,
         /*optional*/int* captureSequenceId) __INTRODUCED_IN(29);
 
+/**
+ * The definition of camera capture start callback. The same as
+ * {@link ACameraCaptureSession_captureCallbacks#onCaptureStarted}, except that
+ * it has the frame number of the capture as well.
+ *
+ * @param context The optional application context provided by user in
+ *                {@link ACameraCaptureSession_captureCallbacks}.
+ * @param session The camera capture session of interest.
+ * @param request The capture request that is starting. Note that this pointer points to a copy of
+ *                capture request sent by application, so the address is different to what
+ *                application sent but the content will match. This request will be freed by
+ *                framework immediately after this callback returns.
+ * @param timestamp The timestamp when the capture is started. This timestamp will match
+ *                  {@link ACAMERA_SENSOR_TIMESTAMP} of the {@link ACameraMetadata} in
+ *                  {@link ACameraCaptureSession_captureCallbacks#onCaptureCompleted} callback.
+ * @param frameNumber the frame number of the capture started
+ */
+typedef void (*ACameraCaptureSession_captureCallback_startV2)(
+        void* context, ACameraCaptureSession* session,
+        const ACaptureRequest* request, int64_t timestamp, int64_t frameNumber);
+/**
+ * This has the same functionality as ACameraCaptureSession_captureCallbacks,
+ * with the exception that captureCallback_startV2 callback is
+ * used, instead of captureCallback_start, to support retrieving the frame number.
+ */
+typedef struct ACameraCaptureSession_captureCallbacksV2 {
+    /**
+     * Same as ACameraCaptureSession_captureCallbacks
+     */
+    void*                                               context;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureStarted},
+     * except that it has the frame number of the capture added in the parameter
+     * list.
+     */
+    ACameraCaptureSession_captureCallback_startV2         onCaptureStarted;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureProgressed}.
+     */
+    ACameraCaptureSession_captureCallback_result        onCaptureProgressed;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureCompleted}.
+     */
+    ACameraCaptureSession_captureCallback_result        onCaptureCompleted;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureFailed}.
+     */
+    ACameraCaptureSession_captureCallback_failed        onCaptureFailed;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceCompleted}.
+     */
+    ACameraCaptureSession_captureCallback_sequenceEnd   onCaptureSequenceCompleted;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceAborted}.
+     */
+    ACameraCaptureSession_captureCallback_sequenceAbort onCaptureSequenceAborted;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureBufferLost}.
+     */
+    ACameraCaptureSession_captureCallback_bufferLost    onCaptureBufferLost;
+
+
+} ACameraCaptureSession_captureCallbacksV2;
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logicalCamera_captureCallbacks,
+ * with the exception that an captureCallback_startV2 callback is
+ * used, instead of captureCallback_start, to support retrieving frame number.
+ */
+typedef struct ACameraCaptureSession_logicalCamera_captureCallbacksV2 {
+    /**
+     * Same as ACameraCaptureSession_captureCallbacks
+     */
+    void*                                               context;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureStarted},
+     * except that it has the frame number of the capture added in the parameter
+     * list.
+     */
+    ACameraCaptureSession_captureCallback_startV2         onCaptureStarted;
+
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureProgressed}.
+     */
+    ACameraCaptureSession_captureCallback_result        onCaptureProgressed;
+
+    /**
+     * Same as
+     * {@link ACameraCaptureSession_logicalCamera_captureCallbacks#onLogicalCaptureCompleted}.
+     */
+    ACameraCaptureSession_logicalCamera_captureCallback_result onLogicalCameraCaptureCompleted;
+
+    /**
+     * This callback is called instead of {@link onLogicalCameraCaptureCompleted} when the
+     * camera device failed to produce a capture result for the
+     * request.
+     *
+     * <p>Other requests are unaffected, and some or all image buffers from
+     * the capture may have been pushed to their respective output
+     * streams.</p>
+     *
+     * <p>Note that the ACaptureRequest pointer in the callback will not match what application has
+     * submitted, but the contents the ACaptureRequest will match what application submitted.</p>
+     *
+     * @see ALogicalCameraCaptureFailure
+     */
+    ACameraCaptureSession_logicalCamera_captureCallback_failed onLogicalCameraCaptureFailed;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceCompleted}.
+     */
+    ACameraCaptureSession_captureCallback_sequenceEnd   onCaptureSequenceCompleted;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceAborted}.
+     */
+    ACameraCaptureSession_captureCallback_sequenceAbort onCaptureSequenceAborted;
+
+    /**
+     * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureBufferLost}.
+     */
+    ACameraCaptureSession_captureCallback_bufferLost    onCaptureBufferLost;
+
+} ACameraCaptureSession_logicalCamera_captureCallbacksV2;
+
+/**
+ * This has the same functionality as ACameraCaptureSession_capture, with added
+ * support for v2 of camera callbacks, where the onCaptureStarted callback
+ * adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_captureV2(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_captureCallbacksV2* callbacks,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logical_setRepeatingRequest, with added
+ * support for v2 of logical multi-camera callbacks where the onCaptureStarted
+ * callback adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_setRepeatingRequestV2(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_captureCallbacksV2* callbacks,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logical_capture, with added
+ * support for v2 of logical multi-camera  callbacks where the onCaptureStarted callback
+ * adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_logicalCamera_captureV2(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* callbacks,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logical_setRepeatingRequest, with added
+ * support for v2 of logical multi-camera callbacks where the onCaptureStarted
+ * callback adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequestV2(
+        ACameraCaptureSession* session,
+        /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* callbacks,
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
 __END_DECLS
 
 #endif /* _NDK_CAMERA_CAPTURE_SESSION_H */
diff --git a/camera/ndk/libcamera2ndk.map.txt b/camera/ndk/libcamera2ndk.map.txt
index 2b630db..b3977ff 100644
--- a/camera/ndk/libcamera2ndk.map.txt
+++ b/camera/ndk/libcamera2ndk.map.txt
@@ -2,11 +2,15 @@
   global:
     ACameraCaptureSession_abortCaptures;
     ACameraCaptureSession_capture;
+    ACameraCaptureSession_captureV2; # introduced=33
     ACameraCaptureSession_logicalCamera_capture; # introduced=29
+    ACameraCaptureSession_logicalCamera_captureV2; # introduced=33
     ACameraCaptureSession_close;
     ACameraCaptureSession_getDevice;
     ACameraCaptureSession_setRepeatingRequest;
+    ACameraCaptureSession_setRepeatingRequestV2; # introduced=33
     ACameraCaptureSession_logicalCamera_setRepeatingRequest; # introduced=29
+    ACameraCaptureSession_logicalCamera_setRepeatingRequestV2; # introduced=33
     ACameraCaptureSession_stopRepeating;
     ACameraCaptureSession_updateSharedOutput; # introduced=28
     ACameraDevice_close;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 9f63099..4cc1292 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -29,8 +29,6 @@
 #include "ACaptureRequest.h"
 #include "utils.h"
 
-#include "ACameraCaptureSession.inc"
-
 #define CHECK_TRANSACTION_AND_RET(remoteRet, status, callName) \
     if (!remoteRet.isOk()) { \
         ALOGE("%s: Transaction error during %s call %s", __FUNCTION__, callName, \
@@ -910,6 +908,7 @@
         case kWhatOnError:
         case kWhatSessionStateCb:
         case kWhatCaptureStart:
+        case kWhatCaptureStart2:
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
@@ -982,6 +981,7 @@
         }
         case kWhatSessionStateCb:
         case kWhatCaptureStart:
+        case kWhatCaptureStart2:
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
@@ -1002,6 +1002,7 @@
             const char *id_cstr = mId.c_str();
             switch (msg->what()) {
                 case kWhatCaptureStart:
+                case kWhatCaptureStart2:
                 case kWhatCaptureResult:
                 case kWhatLogicalCaptureResult:
                 case kWhatCaptureFail:
@@ -1053,6 +1054,35 @@
                     freeACaptureRequest(request);
                     break;
                 }
+                case kWhatCaptureStart2:
+                {
+                    ACameraCaptureSession_captureCallback_startV2 onStart2;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onStart2 == nullptr) {
+                        return;
+                    }
+                    int64_t timestamp;
+                    found = msg->findInt64(kTimeStampKey, &timestamp);
+                    if (!found) {
+                        ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
+                        return;
+                    }
+                    int64_t frameNumber;
+                    found = msg->findInt64(kFrameNumberKey, &frameNumber);
+                    if (!found) {
+                        ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+                        return;
+                    }
+
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+                    (*onStart2)(context, session.get(), request, timestamp, frameNumber);
+                    freeACaptureRequest(request);
+                    break;
+                }
                 case kWhatCaptureResult:
                 {
                     ACameraCaptureSession_captureCallback_result onResult;
@@ -1281,6 +1311,7 @@
         ACameraCaptureSession_captureCallbacks* cbs) :
         mSession(session), mRequests(requests),
         mIsRepeating(isRepeating),
+        mIs2Callback(false),
         mIsLogicalCameraCallback(false) {
     initCaptureCallbacks(cbs);
 
@@ -1297,6 +1328,7 @@
         ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
         mSession(session), mRequests(requests),
         mIsRepeating(isRepeating),
+        mIs2Callback(false),
         mIsLogicalCameraCallback(true) {
     initCaptureCallbacks(lcbs);
 
@@ -1306,6 +1338,40 @@
     }
 }
 
+CameraDevice::CallbackHolder::CallbackHolder(
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_captureCallbacksV2* cbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIs2Callback(true),
+        mIsLogicalCameraCallback(false) {
+    initCaptureCallbacksV2(cbs);
+
+    if (cbs != nullptr) {
+        mOnCaptureCompleted = cbs->onCaptureCompleted;
+        mOnCaptureFailed = cbs->onCaptureFailed;
+    }
+}
+
+CameraDevice::CallbackHolder::CallbackHolder(
+        sp<ACameraCaptureSession>          session,
+        const Vector<sp<CaptureRequest> >& requests,
+        bool                               isRepeating,
+        ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
+        mSession(session), mRequests(requests),
+        mIsRepeating(isRepeating),
+        mIs2Callback(true),
+        mIsLogicalCameraCallback(true) {
+    initCaptureCallbacksV2(lcbs);
+
+    if (lcbs != nullptr) {
+        mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+        mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
+    }
+}
+
 void
 CameraDevice::checkRepeatingSequenceCompleteLocked(
     const int sequenceId, const int64_t lastFrameNumber) {
@@ -1542,11 +1608,14 @@
 
     int32_t sequenceId = resultExtras.requestId;
     int32_t burstId = resultExtras.burstId;
+    int64_t frameNumber = resultExtras.frameNumber;
 
     auto it = dev->mSequenceCallbackMap.find(sequenceId);
     if (it != dev->mSequenceCallbackMap.end()) {
         CallbackHolder cbh = (*it).second;
         ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
+        ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
+        bool v2Callback = cbh.mIs2Callback;
         sp<ACameraCaptureSession> session = cbh.mSession;
         if ((size_t) burstId >= cbh.mRequests.size()) {
             ALOGE("%s: Error: request index %d out of bound (size %zu)",
@@ -1554,12 +1623,19 @@
             dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
         }
         sp<CaptureRequest> request = cbh.mRequests[burstId];
-        sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+        sp<AMessage> msg = nullptr;
+        if (v2Callback) {
+            msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
+            msg->setPointer(kCallbackFpKey, (void*) onStart2);
+        } else {
+            msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+            msg->setPointer(kCallbackFpKey, (void*) onStart);
+        }
         msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, session);
-        msg->setPointer(kCallbackFpKey, (void*) onStart);
         msg->setObject(kCaptureRequestKey, request);
         msg->setInt64(kTimeStampKey, timestamp);
+        msg->setInt64(kFrameNumberKey, frameNumber);
         dev->postSessionMsgAndCleanup(msg);
     }
     return ret;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.h b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
index 0b6c7c8..c306206 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
@@ -245,6 +245,7 @@
         kWhatSessionStateCb,   // onReady, onActive
         // Capture callbacks
         kWhatCaptureStart,     // onCaptureStarted
+        kWhatCaptureStart2,     // onCaptureStarted2
         kWhatCaptureResult,    // onCaptureProgressed, onCaptureCompleted
         kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
         kWhatCaptureFail,      // onCaptureFailed
@@ -309,11 +310,18 @@
                        const Vector<sp<CaptureRequest>>&  requests,
                        bool                               isRepeating,
                        ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs);
-
-        template <class T>
-        void initCaptureCallbacks(T* cbs) {
+        CallbackHolder(sp<ACameraCaptureSession>          session,
+                       const Vector<sp<CaptureRequest> >& requests,
+                       bool                               isRepeating,
+                       ACameraCaptureSession_captureCallbacksV2* cbs);
+        CallbackHolder(sp<ACameraCaptureSession>          session,
+                       const Vector<sp<CaptureRequest> >& requests,
+                       bool                               isRepeating,
+                       ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs);
+        void clearCallbacks() {
             mContext = nullptr;
             mOnCaptureStarted = nullptr;
+            mOnCaptureStarted2 = nullptr;
             mOnCaptureProgressed = nullptr;
             mOnCaptureCompleted = nullptr;
             mOnLogicalCameraCaptureCompleted = nullptr;
@@ -322,6 +330,24 @@
             mOnCaptureSequenceCompleted = nullptr;
             mOnCaptureSequenceAborted = nullptr;
             mOnCaptureBufferLost = nullptr;
+        }
+
+        template <class T>
+        void initCaptureCallbacksV2(T* cbs) {
+            clearCallbacks();
+            if (cbs != nullptr) {
+                mContext = cbs->context;
+                mOnCaptureStarted2 = cbs->onCaptureStarted;
+                mOnCaptureProgressed = cbs->onCaptureProgressed;
+                mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
+                mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
+                mOnCaptureBufferLost = cbs->onCaptureBufferLost;
+            }
+        }
+
+        template <class T>
+        void initCaptureCallbacks(T* cbs) {
+            clearCallbacks();
             if (cbs != nullptr) {
                 mContext = cbs->context;
                 mOnCaptureStarted = cbs->onCaptureStarted;
@@ -335,10 +361,12 @@
         sp<ACameraCaptureSession>   mSession;
         Vector<sp<CaptureRequest>>  mRequests;
         const bool                  mIsRepeating;
+        const bool                  mIs2Callback;
         const bool                  mIsLogicalCameraCallback;
 
         void*                       mContext;
         ACameraCaptureSession_captureCallback_start mOnCaptureStarted;
+        ACameraCaptureSession_captureCallback_startV2 mOnCaptureStarted2;
         ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
         ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
         ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index ba14c5c..63cdb76 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -236,6 +236,11 @@
         return ACameraCaptureSession_capture(mSession, &mCaptureCallbacks, 1, &mStillRequest,
                                              &seqId);
     }
+    int takePicture2() {
+        int seqId;
+        return ACameraCaptureSession_captureV2(mSession, &mCaptureCallbacksV2, 1,
+                &mStillRequest, &seqId);
+    }
 
     int takeLogicalCameraPicture() {
         int seqId;
@@ -243,15 +248,31 @@
                 1, &mStillRequest, &seqId);
     }
 
+    int takeLogicalCameraPicture2() {
+        int seqId;
+        return ACameraCaptureSession_logicalCamera_captureV2(mSession,
+                &mLogicalCaptureCallbacksV2, 1, &mStillRequest, &seqId);
+    }
+
     bool checkCallbacks(int pictureCount) {
         std::lock_guard<std::mutex> lock(mMutex);
         if (mCompletedCaptureCallbackCount != pictureCount) {
-            ALOGE("Completed capture callaback count not as expected. expected %d actual %d",
+            ALOGE("Completed capture callback count not as expected. expected %d actual %d",
                   pictureCount, mCompletedCaptureCallbackCount);
             return false;
         }
         return true;
     }
+    bool checkCallbacksV2(int pictureCount) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        if (mCaptureStartedCallbackCount != pictureCount) {
+            ALOGE("Capture started callback count not as expected. expected %d actual %d",
+                  pictureCount, mCaptureStartedCallbackCount);
+            return false;
+        }
+        return true;
+    }
+
 
    private:
     ACameraDevice_StateCallbacks mDeviceCb{this, nullptr, nullptr};
@@ -276,6 +297,7 @@
     const char* mCameraId;
     ACameraManager* mCameraManager;
     int mCompletedCaptureCallbackCount = 0;
+    int mCaptureStartedCallbackCount = 0;
     std::mutex mMutex;
     ACameraCaptureSession_captureCallbacks mCaptureCallbacks = {
         // TODO: Add tests for other callbacks
@@ -293,8 +315,25 @@
         nullptr, // onCaptureSequenceAborted
         nullptr, // onCaptureBufferLost
     };
+    ACameraCaptureSession_captureCallbacksV2 mCaptureCallbacksV2 = {
+        this, // context
+        [](void* ctx , ACameraCaptureSession *,const ACaptureRequest *, int64_t,
+              int64_t frameNumber ) {
+            CameraHelper *ch = static_cast<CameraHelper *>(ctx);
+            ASSERT_TRUE(frameNumber >= 0);
+            std::lock_guard<std::mutex> lock(ch->mMutex);
+            ch->mCaptureStartedCallbackCount++;
+        },
+        nullptr, // onCaptureProgressed
+        nullptr, // onCaptureCompleted
+        nullptr, // onCaptureFailed
+        nullptr, // onCaptureSequenceCompleted
+        nullptr, // onCaptureSequenceAborted
+        nullptr, // onCaptureBufferLost
+    };
 
     std::vector<std::string> mPhysicalCameraIds;
+
     ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCaptureCallbacks = {
         // TODO: Add tests for other callbacks
         this, // context
@@ -336,6 +375,23 @@
         nullptr, // onCaptureSequenceAborted
         nullptr, // onCaptureBufferLost
     };
+    ACameraCaptureSession_logicalCamera_captureCallbacksV2 mLogicalCaptureCallbacksV2 = {
+        this, // context
+        [](void* ctx , ACameraCaptureSession *,const ACaptureRequest *, int64_t,
+                int64_t frameNumber) {
+            CameraHelper *ch = static_cast<CameraHelper *>(ctx);
+            ASSERT_TRUE(frameNumber >= 0);
+            std::lock_guard<std::mutex> lock(ch->mMutex);
+            ch->mCaptureStartedCallbackCount++;
+        },
+        nullptr, // onCaptureProgressed
+        nullptr, //onLogicalCaptureCompleted
+        nullptr, //onLogicalCpatureFailed
+        nullptr, // onCaptureSequenceCompleted
+        nullptr, // onCaptureSequenceAborted
+        nullptr, // onCaptureBufferLost
+    };
+
 };
 
 class ImageReaderTestCase {
@@ -570,7 +626,7 @@
     }
 
     bool takePictures(const char* id, uint64_t readerUsage, int readerMaxImages,
-            bool readerAsync, int pictureCount) {
+            bool readerAsync, int pictureCount, bool v2 = false) {
         int ret = 0;
 
         ImageReaderTestCase testCase(
@@ -600,7 +656,11 @@
         }
 
         for (int i = 0; i < pictureCount; i++) {
-            ret = cameraHelper.takePicture();
+            if (v2) {
+                ret = cameraHelper.takePicture2();
+            } else {
+                ret = cameraHelper.takePicture();
+            }
             if (ret < 0) {
                 ALOGE("Unable to take picture");
                 return false;
@@ -617,7 +677,8 @@
             }
         }
         return testCase.getAcquiredImageCount() == pictureCount &&
-                cameraHelper.checkCallbacks(pictureCount);
+               v2 ? cameraHelper.checkCallbacksV2(pictureCount) :
+                    cameraHelper.checkCallbacks(pictureCount);
     }
 
     bool testTakePicturesNative(const char* id) {
@@ -626,12 +687,14 @@
             for (auto& readerMaxImages : {1, 4, 8}) {
                 for (auto& readerAsync : {true, false}) {
                     for (auto& pictureCount : {1, 4, 8}) {
-                        if (!takePictures(id, readerUsage, readerMaxImages,
-                                readerAsync, pictureCount)) {
-                            ALOGE("Test takePictures failed for test case usage=%" PRIu64
-                                  ", maxImages=%d, async=%d, pictureCount=%d",
-                                  readerUsage, readerMaxImages, readerAsync, pictureCount);
-                            return false;
+                        for ( auto & v2 : {true, false}) {
+                            if (!takePictures(id, readerUsage, readerMaxImages,
+                                    readerAsync, pictureCount, v2)) {
+                                ALOGE("Test takePictures failed for test case usage=%" PRIu64
+                                      ", maxImages=%d, async=%d, pictureCount=%d",
+                                      readerUsage, readerMaxImages, readerAsync, pictureCount);
+                                return false;
+                            }
                         }
                     }
                 }
@@ -725,7 +788,7 @@
         return;
     }
 
-    void testLogicalCameraPhysicalStream(bool usePhysicalSettings) {
+    void testLogicalCameraPhysicalStream(bool usePhysicalSettings, bool v2) {
         const char* cameraId = nullptr;
         ACameraMetadata* staticMetadata = nullptr;
         std::vector<const char*> physicalCameraIds;
@@ -772,7 +835,12 @@
         }
 
         for (int i = 0; i < pictureCount; i++) {
-            ret = cameraHelper.takeLogicalCameraPicture();
+            if (v2) {
+              ret = cameraHelper.takeLogicalCameraPicture2();
+            }
+            else {
+              ret = cameraHelper.takeLogicalCameraPicture();
+            }
             ASSERT_EQ(ret, 0);
         }
 
@@ -793,8 +861,11 @@
             ALOGI("Testing window %p", testCase->getNativeWindow());
             ASSERT_EQ(testCase->getAcquiredImageCount(), pictureCount);
         }
-
-        ASSERT_TRUE(cameraHelper.checkCallbacks(pictureCount));
+        if (v2) {
+            ASSERT_TRUE(cameraHelper.checkCallbacksV2(pictureCount));
+        } else {
+            ASSERT_TRUE(cameraHelper.checkCallbacks(pictureCount));
+        }
 
         ACameraMetadata_free(staticMetadata);
     }
@@ -834,8 +905,10 @@
 }
 
 TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
-    testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/);
-    testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/);
+    for (auto & v2 : {true, false}) {
+        testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/, v2);
+        testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/, v2);
+    }
 }
 
 }  // namespace