Camera: Support querying session config with parameters

Existing isSessionConfigurationSupported doesn't consider session
parameters. However, many features are modeled as a session parameters.

Add a new API to query session configuration support considring session
parameters.

Test: Camera CTS
Bug: 309627704
Change-Id: If64d878cb0052c0f78db277ebe605d36197eb618
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 409a930..8078cea 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -22,6 +22,7 @@
 import android.hardware.camera2.ICameraDeviceCallbacks;
 import android.hardware.camera2.ICameraInjectionCallback;
 import android.hardware.camera2.ICameraInjectionSession;
+import android.hardware.camera2.params.SessionConfiguration;
 import android.hardware.camera2.params.VendorTagDescriptor;
 import android.hardware.camera2.params.VendorTagDescriptorCache;
 import android.hardware.camera2.utils.ConcurrentCameraIdCombination;
@@ -261,4 +262,18 @@
     const int DEVICE_STATE_FOLDED = 4;
     const int DEVICE_STATE_LAST_FRAMEWORK_BIT = 0x80000000; // 1 << 31;
 
+    // Create a CaptureRequest metadata based on template id
+    CameraMetadataNative createDefaultRequest(@utf8InCpp String cameraId, int templateId);
+
+    /**
+      * Check whether a particular session configuration with optional session parameters
+      * has camera device support.
+      *
+      * @param cameraId The camera id to query session configuration on
+      * @param sessionConfiguration Specific session configuration to be verified.
+      * @return true  - in case the stream combination is supported.
+      *         false - in case there is no device support.
+      */
+    boolean isSessionConfigurationWithParametersSupported(@utf8InCpp String cameraId,
+            in SessionConfiguration sessionConfiguration);
 }
diff --git a/camera/camera2/SessionConfiguration.cpp b/camera/camera2/SessionConfiguration.cpp
index 7cf6087..2f1f22d 100644
--- a/camera/camera2/SessionConfiguration.cpp
+++ b/camera/camera2/SessionConfiguration.cpp
@@ -22,10 +22,13 @@
 
 #include <camera/camera2/SessionConfiguration.h>
 #include <camera/camera2/OutputConfiguration.h>
+#include <com_android_internal_camera_flags.h>
 #include <binder/Parcel.h>
 
 namespace android {
 
+namespace flags = com::android::internal::camera::flags;
+
 status_t SessionConfiguration::readFromParcel(const android::Parcel* parcel) {
     status_t err = OK;
     int operatingMode = 0;
@@ -67,6 +70,22 @@
         return err;
     }
 
+    bool hasSessionParameters = false;
+    CameraMetadata settings;
+    if (flags::feature_combination_query()) {
+        if ((err = parcel->readBool(&hasSessionParameters)) != OK) {
+            ALOGE("%s: Failed to read hasSessionParameters flag from parcel", __FUNCTION__);
+            return err;
+        }
+
+        if (hasSessionParameters) {
+            if ((err = settings.readFromParcel(parcel)) != OK) {
+                ALOGE("%s: Failed to read metadata flag from parcel", __FUNCTION__);
+                return err;
+            }
+        }
+    }
+
     mOperatingMode = operatingMode;
     mInputWidth = inputWidth;
     mInputHeight = inputHeight;
@@ -75,7 +94,10 @@
     for (auto& stream : outputStreams) {
         mOutputStreams.push_back(stream);
     }
-
+    if (flags::feature_combination_query()) {
+        mHasSessionParameters = hasSessionParameters;
+        mSessionParameters = std::move(settings);
+    }
 
     return err;
 }
@@ -103,6 +125,16 @@
     err = parcel->writeParcelableVector(mOutputStreams);
     if (err != OK) return err;
 
+    if (flags::feature_combination_query()) {
+        err = parcel->writeBool(mHasSessionParameters);
+        if (err != OK) return err;
+
+        if (mHasSessionParameters) {
+            err = mSessionParameters.writeToParcel(parcel);
+            if (err != OK) return err;
+        }
+    }
+
     return OK;
 }
 
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index f8dfe34..f7deda1 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -13,6 +13,14 @@
      description: "Introduces a new concert mode camera extension type"
      bug: "297083874"
 }
+
+flag {
+     namespace: "camera_platform"
+     name: "feature_combination_query"
+     description: "Query feature combination support and session specific characteristics"
+     bug: "309627704"
+}
+
 flag {
      namespace: "camera_platform"
      name: "log_ultrawide_usage"
diff --git a/camera/include/camera/camera2/SessionConfiguration.h b/camera/include/camera/camera2/SessionConfiguration.h
index 29913f6..120bf9e 100644
--- a/camera/include/camera/camera2/SessionConfiguration.h
+++ b/camera/include/camera/camera2/SessionConfiguration.h
@@ -18,6 +18,7 @@
 #define ANDROID_HARDWARE_CAMERA2_SESSIONCONFIGURATION_H
 
 #include <binder/Parcelable.h>
+#include <camera/CameraMetadata.h>
 
 namespace android {
 
@@ -39,6 +40,8 @@
     int getInputFormat() const { return mInputFormat; }
     int getOperatingMode() const { return mOperatingMode; }
     bool inputIsMultiResolution() const { return mInputIsMultiResolution; }
+    bool hasSessionParameters() const { return mHasSessionParameters; }
+    const CameraMetadata& getSessionParameters() const { return mSessionParameters; }
 
     virtual status_t writeToParcel(android::Parcel* parcel) const override;
     virtual status_t readFromParcel(const android::Parcel* parcel) override;
@@ -111,6 +114,8 @@
     std::vector<OutputConfiguration> mOutputStreams;
     int                              mInputWidth, mInputHeight, mInputFormat, mOperatingMode;
     bool                             mInputIsMultiResolution = false;
+    bool                             mHasSessionParameters = false;
+    CameraMetadata                   mSessionParameters;
 };
 } // namespace params
 } // namespace camera2