Merge "Add two missing comparison ops to HAL"
diff --git a/audio/5.0/Android.bp b/audio/5.0/Android.bp
index b7a7138..27c1ef5 100644
--- a/audio/5.0/Android.bp
+++ b/audio/5.0/Android.bp
@@ -3,6 +3,9 @@
 hidl_interface {
     name: "android.hardware.audio@5.0",
     root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
     srcs: [
         "types.hal",
         "IDevice.hal",
diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp
index 054c752..663f847 100644
--- a/audio/common/5.0/Android.bp
+++ b/audio/common/5.0/Android.bp
@@ -3,6 +3,9 @@
 hidl_interface {
     name: "android.hardware.audio.common@5.0",
     root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
     srcs: [
         "types.hal",
     ],
diff --git a/audio/effect/5.0/Android.bp b/audio/effect/5.0/Android.bp
index 1367f8d..d60d94a 100644
--- a/audio/effect/5.0/Android.bp
+++ b/audio/effect/5.0/Android.bp
@@ -3,6 +3,9 @@
 hidl_interface {
     name: "android.hardware.audio.effect@5.0",
     root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
     srcs: [
         "types.hal",
         "IAcousticEchoCancelerEffect.hal",
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 9c2b02b..08354b3 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -452,6 +452,16 @@
     return res;
 }
 
+int CameraModule::isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams) {
+    int res = INVALID_OPERATION;
+    if (mModule->is_stream_combination_supported != NULL) {
+        ATRACE_BEGIN("camera_module->is_stream_combination_supported");
+        res = mModule->is_stream_combination_supported(cameraId, streams);
+        ATRACE_END();
+    }
+    return res;
+}
+
 status_t CameraModule::filterOpenErrorCode(status_t err) {
     switch(err) {
         case NO_ERROR:
diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h
index aee9654..ee75e72 100644
--- a/camera/common/1.0/default/include/CameraModule.h
+++ b/camera/common/1.0/default/include/CameraModule.h
@@ -66,6 +66,7 @@
     // Only used by CameraProvider
     void removeCamera(int cameraId);
     int getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo);
+    int isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams);
 
 private:
     // Derive camera characteristics keys defined after HAL device version
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 4ef5fc9..66b17db 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -2163,7 +2163,8 @@
     }
 }
 
-bool ExternalCameraDeviceSession::isSupported(const Stream& stream) {
+bool ExternalCameraDeviceSession::isSupported(const Stream& stream,
+        const std::vector<SupportedV4L2Format>& supportedFormats) {
     int32_t ds = static_cast<int32_t>(stream.dataSpace);
     PixelFormat fmt = stream.format;
     uint32_t width = stream.width;
@@ -2206,7 +2207,7 @@
     // Assume we can convert any V4L2 format to any of supported output format for now, i.e,
     // ignoring v4l2Fmt.fourcc for now. Might need more subtle check if we support more v4l format
     // in the futrue.
-    for (const auto& v4l2Fmt : mSupportedFormats) {
+    for (const auto& v4l2Fmt : supportedFormats) {
         if (width == v4l2Fmt.width && height == v4l2Fmt.height) {
             return true;
         }
@@ -2541,11 +2542,9 @@
     mV4L2BufferReturned.notify_one();
 }
 
-Status ExternalCameraDeviceSession::configureStreams(
+Status ExternalCameraDeviceSession::isStreamCombinationSupported(
         const V3_2::StreamConfiguration& config,
-        V3_3::HalStreamConfiguration* out,
-        uint32_t blobBufferSize) {
-    ATRACE_CALL();
+        const std::vector<SupportedV4L2Format>& supportedFormats) {
     if (config.operationMode != StreamConfigurationMode::NORMAL_MODE) {
         ALOGE("%s: unsupported operation mode: %d", __FUNCTION__, config.operationMode);
         return Status::ILLEGAL_ARGUMENT;
@@ -2560,7 +2559,7 @@
     int numStallStream = 0;
     for (const auto& stream : config.streams) {
         // Check if the format/width/height combo is supported
-        if (!isSupported(stream)) {
+        if (!isSupported(stream, supportedFormats)) {
             return Status::ILLEGAL_ARGUMENT;
         }
         if (stream.format == PixelFormat::BLOB) {
@@ -2582,7 +2581,21 @@
         return Status::ILLEGAL_ARGUMENT;
     }
 
-    Status status = initStatus();
+    return Status::OK;
+}
+
+Status ExternalCameraDeviceSession::configureStreams(
+        const V3_2::StreamConfiguration& config,
+        V3_3::HalStreamConfiguration* out,
+        uint32_t blobBufferSize) {
+    ATRACE_CALL();
+
+    Status status = isStreamCombinationSupported(config, mSupportedFormats);
+    if (status != Status::OK) {
+        return status;
+    }
+
+    status = initStatus();
     if (status != Status::OK) {
         return status;
     }
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index cabeaa4..9cc55cb 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -193,13 +193,16 @@
     int configureV4l2StreamLocked(const SupportedV4L2Format& fmt, double fps = 0.0);
     int v4l2StreamOffLocked();
     int setV4l2FpsLocked(double fps);
+    static Status isStreamCombinationSupported(const V3_2::StreamConfiguration& config,
+            const std::vector<SupportedV4L2Format>& supportedFormats);
 
     // TODO: change to unique_ptr for better tracking
     sp<V4L2Frame> dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs); // Called with mLock hold
     void enqueueV4l2Frame(const sp<V4L2Frame>&);
 
     // Check if input Stream is one of supported stream setting on this device
-    bool isSupported(const Stream&);
+    static bool isSupported(const Stream& stream,
+            const std::vector<SupportedV4L2Format>& supportedFormats);
 
     // Validate and import request's output buffers and acquire fence
     virtual Status importRequestLocked(
diff --git a/camera/device/3.5/ICameraDevice.hal b/camera/device/3.5/ICameraDevice.hal
index a77380f..d9f2837 100644
--- a/camera/device/3.5/ICameraDevice.hal
+++ b/camera/device/3.5/ICameraDevice.hal
@@ -19,6 +19,7 @@
 import android.hardware.camera.common@1.0::Status;
 import @3.2::CameraMetadata;
 import @3.2::ICameraDevice;
+import @3.4::StreamConfiguration;
 
 /**
  * Camera device interface
@@ -75,4 +76,41 @@
     getPhysicalCameraCharacteristics(string physicalCameraId)
             generates (Status status, CameraMetadata cameraCharacteristics);
 
+
+    /**
+     * isStreamCombinationSupported:
+     *
+     * Check for device support of specific camera stream combination.
+     *
+     * The streamList must contain at least one output-capable stream, and may
+     * not contain more than one input-capable stream.
+     *
+     * ------------------------------------------------------------------------
+     *
+     * Preconditions:
+     *
+     * The framework can call this method at any time before, during and
+     * after active session configuration. This means that calls must not
+     * impact the performance of pending camera requests in any way. In
+     * particular there must not be any glitches or delays during normal
+     * camera streaming.
+     *
+     * Performance requirements:
+     * This call is expected to be significantly faster than stream
+     * configuration. In general HW and SW camera settings must not be
+     * changed and there must not be a user-visible impact on camera performance.
+     *
+     * @return Status Status code for the operation, one of:
+     *     OK:
+     *          On successful stream combination query.
+     *     METHOD_NOT_SUPPORTED:
+     *          The camera device does not support stream combination query.
+     *     INTERNAL_ERROR:
+     *          The stream combination query cannot complete due to internal
+     *          error.
+     * @return true in case the stream combination is supported, false otherwise.
+     *
+     */
+    isStreamCombinationSupported(@3.4::StreamConfiguration streams)
+            generates (Status status, bool queryStatus);
 };
diff --git a/camera/device/3.5/default/CameraDevice.cpp b/camera/device/3.5/default/CameraDevice.cpp
index a6969af..cffda4e 100644
--- a/camera/device/3.5/default/CameraDevice.cpp
+++ b/camera/device/3.5/default/CameraDevice.cpp
@@ -95,6 +95,57 @@
     return Void();
 }
 
+Return<void> CameraDevice::isStreamCombinationSupported(const V3_4::StreamConfiguration& streams,
+        V3_5::ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) {
+    Status status;
+    bool streamsSupported = false;
+
+    // Require module 2.5+ version.
+    if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_5) {
+        ALOGE("%s: is_stream_combination_supported must be called on camera module 2.5 or "\
+                "newer", __FUNCTION__);
+        status = Status::INTERNAL_ERROR;
+    } else {
+        camera_stream_combination_t streamComb{};
+        streamComb.operation_mode = static_cast<uint32_t> (streams.operationMode);
+        streamComb.num_streams = streams.streams.size();
+        camera_stream_t *streamBuffer  = new camera_stream_t[streamComb.num_streams];
+
+        size_t i = 0;
+        for (const auto &it : streams.streams) {
+            streamBuffer[i].stream_type = static_cast<int> (it.v3_2.streamType);
+            streamBuffer[i].width = it.v3_2.width;
+            streamBuffer[i].height = it.v3_2.height;
+            streamBuffer[i].format = static_cast<int> (it.v3_2.format);
+            streamBuffer[i].data_space = static_cast<android_dataspace_t> (it.v3_2.dataSpace);
+            streamBuffer[i].usage = static_cast<uint32_t> (it.v3_2.usage);
+            streamBuffer[i].physical_camera_id = it.physicalCameraId.c_str();
+            streamBuffer[i++].rotation = static_cast<int> (it.v3_2.rotation);
+        }
+        streamComb.streams = streamBuffer;
+        auto res = mModule->isStreamCombinationSupported(mCameraIdInt, &streamComb);
+        switch (res) {
+            case NO_ERROR:
+                streamsSupported = true;
+                status = Status::OK;
+                break;
+            case BAD_VALUE:
+                status = Status::OK;
+                break;
+            case INVALID_OPERATION:
+                status = Status::METHOD_NOT_SUPPORTED;
+                break;
+            default:
+                ALOGE("%s: Unexpected error: %d", __FUNCTION__, res);
+                status = Status::INTERNAL_ERROR;
+        };
+        delete [] streamBuffer;
+    }
+
+    _hidl_cb(status, streamsSupported);
+    return Void();
+}
+
 // End of methods from ::android::hardware::camera::device::V3_2::ICameraDevice.
 
 } // namespace implementation
diff --git a/camera/device/3.5/default/ExternalCameraDevice.cpp b/camera/device/3.5/default/ExternalCameraDevice.cpp
index e8d14b5..6a0b51e 100644
--- a/camera/device/3.5/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.5/default/ExternalCameraDevice.cpp
@@ -86,6 +86,27 @@
     return OK;
 }
 
+Return<void> ExternalCameraDevice::isStreamCombinationSupported(
+        const V3_4::StreamConfiguration& streams,
+        V3_5::ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) {
+
+    if (isInitFailed()) {
+        ALOGE("%s: camera %s. camera init failed!", __FUNCTION__, mCameraId.c_str());
+        _hidl_cb(Status::INTERNAL_ERROR, false);
+        return Void();
+    }
+
+    hidl_vec<V3_2::Stream> streamsV3_2(streams.streams.size());
+    size_t i = 0;
+    for (const auto& it : streams.streams) {
+        streamsV3_2[i++] = it.v3_2;
+    }
+    V3_2::StreamConfiguration streamConfig = {streamsV3_2, streams.operationMode};
+    auto status = ExternalCameraDeviceSession::isStreamCombinationSupported(streamConfig,
+            mSupportedFormats);
+    _hidl_cb(Status::OK, Status::OK == status);
+    return Void();
+}
 #undef UPDATE
 
 }  // namespace implementation
diff --git a/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h b/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h
index 6bdc60f..76c8cf8 100644
--- a/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h
+++ b/camera/device/3.5/default/include/device_v3_5_impl/CameraDevice_3_5.h
@@ -64,6 +64,10 @@
     Return<void> getPhysicalCameraCharacteristics(const hidl_string& physicalCameraId,
             V3_5::ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb);
 
+    Return<void> isStreamCombinationSupported(
+            const V3_4::StreamConfiguration& streams,
+            V3_5::ICameraDevice::isStreamCombinationSupported_cb _hidl_cb);
+
 private:
     struct TrampolineDeviceInterface_3_5 : public ICameraDevice {
         TrampolineDeviceInterface_3_5(sp<CameraDevice> parent) :
@@ -96,6 +100,13 @@
                 V3_5::ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb) override {
             return mParent->getPhysicalCameraCharacteristics(physicalCameraId, _hidl_cb);
         }
+
+        virtual Return<void> isStreamCombinationSupported(
+                const V3_4::StreamConfiguration& streams,
+                V3_5::ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) override {
+            return mParent->isStreamCombinationSupported(streams, _hidl_cb);
+        }
+
     private:
         sp<CameraDevice> mParent;
     };
diff --git a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
index 4d2d6b7..aa119fc 100644
--- a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
@@ -90,6 +90,12 @@
         return new TrampolineSessionInterface_3_5(this);
     }
 
+    static Status isStreamCombinationSupported(const V3_2::StreamConfiguration& config,
+            const std::vector<SupportedV4L2Format>& supportedFormats) {
+        return V3_4::implementation::ExternalCameraDeviceSession::isStreamCombinationSupported(
+                config, supportedFormats);
+    }
+
 protected:
     // Methods from v3.4 and earlier will trampoline to inherited implementation
     Return<void> configureStreams_3_5(
diff --git a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDevice_3_5.h b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDevice_3_5.h
index 7db86dc..b73490c 100644
--- a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDevice_3_5.h
+++ b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDevice_3_5.h
@@ -67,6 +67,10 @@
     Return<void> getPhysicalCameraCharacteristics(const hidl_string& physicalCameraId,
             V3_5::ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb);
 
+    Return<void> isStreamCombinationSupported(
+            const V3_4::StreamConfiguration& streams,
+            V3_5::ICameraDevice::isStreamCombinationSupported_cb _hidl_cb);
+
 protected:
     virtual sp<V3_4::implementation::ExternalCameraDeviceSession> createSession(
             const sp<V3_2::ICameraDeviceCallback>&,
@@ -116,6 +120,13 @@
                 V3_5::ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb) override {
             return mParent->getPhysicalCameraCharacteristics(physicalCameraId, _hidl_cb);
         }
+
+        virtual Return<void> isStreamCombinationSupported(
+                const V3_4::StreamConfiguration& streams,
+                V3_5::ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) override {
+            return mParent->isStreamCombinationSupported(streams, _hidl_cb);
+        }
+
     private:
         sp<ExternalCameraDevice> mParent;
     };
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index bb03d91..e376551 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -703,11 +703,14 @@
     void openEmptyDeviceSession(const std::string &name,
             sp<ICameraProvider> provider,
             sp<ICameraDeviceSession> *session /*out*/,
-            camera_metadata_t **staticMeta /*out*/);
+            camera_metadata_t **staticMeta /*out*/,
+            ::android::sp<ICameraDevice> *device = nullptr/*out*/);
     void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
             sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
             sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
             sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/);
+    void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion,
+            sp<device::V3_5::ICameraDevice> *device3_5/*out*/);
     void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
             StreamConfigurationMode configMode,
             ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2,
@@ -748,6 +751,9 @@
     void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion);
     void verifyMonochromeCameraResult(
             const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata);
+    void verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
+            const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
+            bool expectedStatus);
 
     void verifyBuffersReturned(sp<device::V3_2::ICameraDeviceSession> session,
             int deviceVerison, int32_t streamId, sp<DeviceCb> cb,
@@ -2769,9 +2775,12 @@
         sp<device::V3_3::ICameraDeviceSession> session3_3;
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
+        sp<device::V3_2::ICameraDevice> cameraDevice;
+        sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         openEmptyDeviceSession(name, mProvider,
-                &session /*out*/, &staticMeta /*out*/);
+                &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/);
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+        castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         outputStreams.clear();
         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
@@ -2797,6 +2806,8 @@
             createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
                                       &config3_2, &config3_4, &config3_5);
             if (session3_5 != nullptr) {
+                verifyStreamCombination(cameraDevice3_5, config3_4,
+                        /*expectedStatus*/ true);
                 config3_5.streamConfigCounter = streamConfigCounter++;
                 ret = session3_5->configureStreams_3_5(config3_5,
                         [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -2857,8 +2868,12 @@
         sp<device::V3_3::ICameraDeviceSession> session3_3;
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
-        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+        sp<device::V3_2::ICameraDevice> cameraDevice;
+        sp<device::V3_5::ICameraDevice> cameraDevice3_5;
+        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
+                &cameraDevice /*out*/);
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+        castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         outputStreams.clear();
         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
@@ -2881,6 +2896,7 @@
         createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
                                   &config3_2, &config3_4, &config3_5);
         if (session3_5 != nullptr) {
+            verifyStreamCombination(cameraDevice3_5, config3_4, /*expectedStatus*/ false);
             config3_5.streamConfigCounter = streamConfigCounter++;
             ret = session3_5->configureStreams_3_5(config3_5,
                     [](Status s, device::V3_4::HalStreamConfiguration) {
@@ -3044,8 +3060,12 @@
         sp<device::V3_3::ICameraDeviceSession> session3_3;
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
-        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+        sp<device::V3_2::ICameraDevice> cameraDevice;
+        sp<device::V3_5::ICameraDevice> cameraDevice3_5;
+        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
+                &cameraDevice /*out*/);
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+        castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         Status rc = isZSLModeAvailable(staticMeta);
         if (Status::METHOD_NOT_SUPPORTED == rc) {
@@ -3132,6 +3152,8 @@
                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
                                           &config3_2, &config3_4, &config3_5);
                 if (session3_5 != nullptr) {
+                    verifyStreamCombination(cameraDevice3_5, config3_4,
+                            /*expectedStatus*/ true);
                     config3_5.streamConfigCounter = streamConfigCounter++;
                     ret = session3_5->configureStreams_3_5(config3_5,
                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -3304,8 +3326,12 @@
         sp<device::V3_3::ICameraDeviceSession> session3_3;
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
-        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+        sp<device::V3_2::ICameraDevice> cameraDevice;
+        sp<device::V3_5::ICameraDevice> cameraDevice3_5;
+        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
+                &cameraDevice /*out*/);
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+        castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         outputBlobStreams.clear();
         ASSERT_EQ(Status::OK,
@@ -3346,6 +3372,8 @@
                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
                                           &config3_2, &config3_4, &config3_5);
                 if (session3_5 != nullptr) {
+                    verifyStreamCombination(cameraDevice3_5, config3_4,
+                            /*expectedStatus*/ true);
                     config3_5.streamConfigCounter = streamConfigCounter++;
                     ret = session3_5->configureStreams_3_5(config3_5,
                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -3403,8 +3431,12 @@
         sp<device::V3_3::ICameraDeviceSession> session3_3;
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
-        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+        sp<device::V3_2::ICameraDevice> cameraDevice;
+        sp<device::V3_5::ICameraDevice> cameraDevice3_5;
+        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
+                &cameraDevice /*out*/);
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+        castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         Status rc = isConstrainedModeAvailable(staticMeta);
         if (Status::METHOD_NOT_SUPPORTED == rc) {
@@ -3435,6 +3467,8 @@
         createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
                                   &config3_2, &config3_4, &config3_5);
         if (session3_5 != nullptr) {
+            verifyStreamCombination(cameraDevice3_5, config3_4,
+                    /*expectedStatus*/ true);
             config3_5.streamConfigCounter = streamConfigCounter++;
             ret = session3_5->configureStreams_3_5(config3_5,
                     [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -3608,8 +3642,12 @@
         sp<device::V3_3::ICameraDeviceSession> session3_3;
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
-        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+        sp<device::V3_2::ICameraDevice> cameraDevice;
+        sp<device::V3_5::ICameraDevice> cameraDevice3_5;
+        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
+                &cameraDevice /*out*/);
         castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+        castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         outputBlobStreams.clear();
         ASSERT_EQ(Status::OK,
@@ -3650,6 +3688,8 @@
                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
                                           &config3_2, &config3_4, &config3_5);
                 if (session3_5 != nullptr) {
+                    verifyStreamCombination(cameraDevice3_5, config3_4,
+                            /*expectedStatus*/ true);
                     config3_5.streamConfigCounter = streamConfigCounter++;
                     ret = session3_5->configureStreams_3_5(config3_5,
                             [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -5228,6 +5268,16 @@
     ASSERT_TRUE(ret.isOk());
 }
 
+void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice> &device,
+        int32_t deviceVersion, sp<device::V3_5::ICameraDevice> *device3_5/*out*/) {
+    ASSERT_NE(nullptr, device3_5);
+    if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
+        auto castResult = device::V3_5::ICameraDevice::castFrom(device);
+        ASSERT_TRUE(castResult.isOk());
+        *device3_5 = castResult;
+    }
+}
+
 //Cast camera device session to corresponding version
 void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
         sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
@@ -5262,6 +5312,21 @@
     }
 }
 
+void CameraHidlTest::verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
+        const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
+        bool expectedStatus) {
+    if (cameraDevice3_5.get() != nullptr) {
+        auto ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
+                [expectedStatus] (Status s, bool combStatus) {
+                    ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s));
+                    if (Status::OK == s) {
+                        ASSERT_TRUE(combStatus == expectedStatus);
+                    }
+                });
+        ASSERT_TRUE(ret.isOk());
+    }
+}
+
 // Verify logical camera static metadata
 void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
         const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
@@ -5531,10 +5596,9 @@
 }
 
 // Open a device session with empty callbacks and return static metadata.
-void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
-        sp<ICameraProvider> provider,
-        sp<ICameraDeviceSession> *session /*out*/,
-        camera_metadata_t **staticMeta /*out*/) {
+void CameraHidlTest::openEmptyDeviceSession(const std::string &name, sp<ICameraProvider> provider,
+        sp<ICameraDeviceSession> *session /*out*/, camera_metadata_t **staticMeta /*out*/,
+        ::android::sp<ICameraDevice> *cameraDevice /*out*/) {
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, staticMeta);
 
@@ -5551,6 +5615,9 @@
             device3_x = device;
         });
     ASSERT_TRUE(ret.isOk());
+    if (cameraDevice != nullptr) {
+        *cameraDevice = device3_x;
+    }
 
     sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
     ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
diff --git a/graphics/composer/2.3/IComposerClient.hal b/graphics/composer/2.3/IComposerClient.hal
index 87002ec..e5ee3c5 100644
--- a/graphics/composer/2.3/IComposerClient.hal
+++ b/graphics/composer/2.3/IComposerClient.hal
@@ -37,7 +37,7 @@
         INVALID = 0,
 
         /**
-         * Specifies that the display must a color transform even when
+         * Indicates that the display must apply a color transform even when
          * either the client or the device has chosen that all layers should
          * be composed by the client. This prevents the client from applying
          * the color transform during its composition step.
@@ -51,7 +51,7 @@
         SKIP_CLIENT_COLOR_TRANSFORM = 1,
 
         /**
-         * Specifies that the display supports PowerMode::DOZE and
+         * Indicates that the display supports PowerMode::DOZE and
          * PowerMode::DOZE_SUSPEND. DOZE_SUSPEND may not provide any benefit
          * over DOZE (see the definition of PowerMode for more information),
          * but if both DOZE and DOZE_SUSPEND are no different from
diff --git a/radio/1.3/IRadio.hal b/radio/1.3/IRadio.hal
index d582c71..2d64381 100644
--- a/radio/1.3/IRadio.hal
+++ b/radio/1.3/IRadio.hal
@@ -17,8 +17,12 @@
 package android.hardware.radio@1.3;
 
 import @1.2::IRadio;
+import @1.1::RadioAccessSpecifier;
 
 /**
+ * Note: IRadio 1.3 is an intermediate layer between Android P and Android Q. It's specifically
+ * designed for CBRS related interfaces. All other interfaces for Q are added in IRadio 1.4.
+ *
  * This interface is used by telephony and telecom to talk to cellular radio.
  * All the functions have minimum one parameter:
  * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
@@ -27,4 +31,33 @@
  * setResponseFunctions must work with @1.1::IRadioResponse and @1.1::IRadioIndication.
  */
 interface IRadio extends @1.2::IRadio {
+    /**
+     * Specify which bands modem's background scan must act on.
+     * If specifyChannels is true, it only scans bands specified in specifiers.
+     * If specifyChannels is false, it scans all bands.
+     *
+     * For example, CBRS is only on LTE band 48. By specifying this band,
+     * modem saves more power.
+     *
+     * @param serial Serial number of request.
+     * @param specifyChannels whether to scan bands defined in specifiers.
+     * @param specifiers which bands to scan. Only used if specifyChannels is true.
+     *
+     * Response callback is IRadioResponse.setSystemSelectionChannelsResponse()
+     */
+    oneway setSystemSelectionChannels(int32_t serial, bool specifyChannels,
+            vec<RadioAccessSpecifier> specifiers);
+
+   /**
+    * Toggle logical modem on and off. It should put the logical modem in low power
+    * mode without any activity, while the SIM card remains visible. The difference
+    * with setRadioPower is, setRadioPower affects all logical modem while this controls
+    * just one.
+    *
+    * @param serial Serial number of request.
+    * @param on True to turn on the logical modem, otherwise turn it off.
+    *
+    * Response function is IRadioResponse.enableModemResponse()
+    */
+    oneway enableModem(int32_t serial, bool on);
 };
diff --git a/radio/1.3/IRadioResponse.hal b/radio/1.3/IRadioResponse.hal
index 2bcdd02..abdf2ee 100644
--- a/radio/1.3/IRadioResponse.hal
+++ b/radio/1.3/IRadioResponse.hal
@@ -17,9 +17,33 @@
 package android.hardware.radio@1.3;
 
 import @1.2::IRadioResponse;
+import @1.0::RadioResponseInfo;
 
 /**
+ * Note: IRadio 1.3 is an intermediate layer between Android P and Android Q. It's specifically
+ * designed for CBRS related interfaces. All other interfaces for Q are added in IRadio 1.4.
+ *
  * Interface declaring response functions to solicited radio requests.
  */
 interface IRadioResponse extends @1.2::IRadioResponse {
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     */
+    oneway setSystemSelectionChannelsResponse(RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     */
+    oneway enableModemResponse(RadioResponseInfo info);
 };
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index 1b6d9a6..8854453 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -16,11 +16,11 @@
 
 package android.hardware.radio@1.4;
 
-import @1.4::DataProfileInfo;
 import @1.0::Dial;
 import @1.2::DataRequestReason;
 import @1.3::IRadio;
 import @1.4::AccessNetwork;
+import @1.4::DataProfileInfo;
 import @1.4::EmergencyServiceCategory;
 
 /**
diff --git a/radio/config/1.1/Android.bp b/radio/config/1.1/Android.bp
index 10c4c98..056510c 100644
--- a/radio/config/1.1/Android.bp
+++ b/radio/config/1.1/Android.bp
@@ -7,14 +7,20 @@
         enabled: true,
     },
     srcs: [
+        "IRadioConfig.hal",
         "IRadioConfigIndication.hal",
         "IRadioConfigResponse.hal",
+        "types.hal",
     ],
     interfaces: [
         "android.hardware.radio.config@1.0",
         "android.hardware.radio@1.0",
         "android.hidl.base@1.0",
     ],
+    types: [
+        "ModemInfo",
+        "PhoneCapability",
+    ],
     gen_java: true,
 }
 
diff --git a/radio/config/1.1/IRadioConfig.hal b/radio/config/1.1/IRadioConfig.hal
new file mode 100644
index 0000000..bc63339
--- /dev/null
+++ b/radio/config/1.1/IRadioConfig.hal
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.hardware.radio.config@1.1;
+
+import @1.0::IRadioConfig;
+import @1.1::IRadioConfigResponse;
+import @1.1::PhoneCapability;
+
+/**
+ * Note: IRadioConfig 1.1 is an intermediate layer between Android P and Android Q.
+ * It's specifically designed for CBRS related interfaces. All other interfaces
+ * for Q are added in IRadioConfig 1.2.
+ *
+ * This interface is used by telephony and telecom to talk to cellular radio for the purpose of
+ * radio configuration, and it is not associated with any specific modem or slot.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ */
+interface IRadioConfig extends @1.0::IRadioConfig {
+   /**
+     * Request current phone capability.
+     *
+     * @param serial Serial number of request.
+     *
+     * Response callback is IRadioResponse.getPhoneCapabilityResponse() which
+     * will return <@1.1::PhoneCapability>.
+     */
+    oneway getPhoneCapability(int32_t serial);
+
+   /**
+     * Set preferred data modem Id.
+     * In a multi-SIM device, notify modem layer which logical modem will be used primarily
+     * for data. It helps modem with resource optimization and decisions of what data connections
+     * should be satisfied.
+     *
+     * @param serial Serial number of request.
+     * @param modem Id the logical modem ID, which should match one of modem IDs returned
+     * from getPhoneCapability().
+     *
+     * Response callback is IRadioConfigResponse.setPreferredDataModemResponse()
+     */
+    oneway setPreferredDataModem(int32_t serial, uint8_t modemId);
+};
diff --git a/radio/config/1.1/IRadioConfigResponse.hal b/radio/config/1.1/IRadioConfigResponse.hal
index 5d75600..42a31b1 100644
--- a/radio/config/1.1/IRadioConfigResponse.hal
+++ b/radio/config/1.1/IRadioConfigResponse.hal
@@ -17,9 +17,37 @@
 package android.hardware.radio.config@1.1;
 
 import @1.0::IRadioConfigResponse;
+import @1.1::PhoneCapability;
+import android.hardware.radio@1.0::RadioResponseInfo;
 
 /**
+ * Note: IRadioConfig 1.1 is an intermediate layer between Android P and Android Q.
+ * It's specifically designed for CBRS related interfaces. All other interfaces
+ * for Q are be added in IRadioConfig 1.2.
+ *
  * Interface declaring response functions to solicited radio config requests.
  */
 interface IRadioConfigResponse extends @1.0::IRadioConfigResponse {
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     * @param phoneCapability <@1.1::PhoneCapability> it defines modem's capability for example
+     *        how many logical modems it has, how many data connections it supports.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     */
+    oneway getPhoneCapabilityResponse(RadioResponseInfo info, PhoneCapability phoneCapability);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     */
+    oneway setPreferredDataModemResponse(RadioResponseInfo info);
 };
diff --git a/radio/config/1.1/types.hal b/radio/config/1.1/types.hal
new file mode 100644
index 0000000..a7b9f86
--- /dev/null
+++ b/radio/config/1.1/types.hal
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.hardware.radio.config@1.1;
+
+/**
+ * Note: IRadioConfig 1.1 is an intermediate layer between Android P and Android Q.
+ * It's specifically designed for CBRS related interfaces. All other interfaces
+ * for Q are be added in IRadioConfig 1.2.
+ */
+
+/**
+ * A field in PhoneCapability that has information of each logical modem.
+ */
+struct ModemInfo {
+    /**
+     * Logical modem ID.
+     */
+    uint8_t modemId;
+};
+
+/**
+ * Phone capability which describes the data connection capability of modem.
+ * It's used to evaluate possible phone config change, for example from single
+ * SIM device to multi-SIM device.
+ */
+struct PhoneCapability {
+    /**
+     * maxActiveData defines how many logical modems can have
+     * PS attached simultaneously. For example, for L+L modem it
+     * should be 2.
+     */
+    uint8_t maxActiveData;
+    /**
+     * maxActiveData defines how many logical modems can have
+     * internet PDN connections simultaneously. For example, for L+L
+     * DSDS modem it’s 1, and for DSDA modem it’s 2.
+     */
+    uint8_t maxActiveInternetData;
+    /**
+     * Whether modem supports both internet PDN up so
+     * that we can do ping test before tearing down the
+     * other one.
+     */
+    bool isInternetLingeringSupported;
+    /**
+     * List of logical modem information.
+     */
+    vec<ModemInfo> logicalModemList;
+};
diff --git a/thermal/2.0/types.hal b/thermal/2.0/types.hal
index ad11849..a1c0325 100644
--- a/thermal/2.0/types.hal
+++ b/thermal/2.0/types.hal
@@ -71,9 +71,10 @@
     CRITICAL,
 
     /**
-     * User should be warned before shutdown.
+     * Key components in platform are shutting down due to thermal condition.
+     * Device functionalities will be limited.
      */
-    WARNING,
+    EMERGENCY,
 
     /**
      * Need shutdown immediately.