Snap for 9550355 from 27ed1063b7e7fc64cadca011a6ecb0917f976a13 to sdk-release

Change-Id: I97d7df74254e3fc2a97b106058d66642e331c412
diff --git a/common/apex_update_listener/apex_update_listener.cc b/common/apex_update_listener/apex_update_listener.cc
index 604f9d2..24f38bc 100644
--- a/common/apex_update_listener/apex_update_listener.cc
+++ b/common/apex_update_listener/apex_update_listener.cc
@@ -26,7 +26,7 @@
 ApexUpdateListener::ApexUpdateListener(
     ApexUpdateListener::Sigil, const std::string& apex_name,
     const std::string& apex_info_list_file_name, CallbackFunction callback,
-    int fd, int wd, std::set<Info> last_info)
+    int fd, int wd, const std::set<Info>& last_info)
     : apex_name_(apex_name),
       apex_info_list_file_name_(apex_info_list_file_name),
       callback_function_(callback),
diff --git a/common/apex_update_listener/apex_update_listener.h b/common/apex_update_listener/apex_update_listener.h
index 6263144..195d24c 100644
--- a/common/apex_update_listener/apex_update_listener.h
+++ b/common/apex_update_listener/apex_update_listener.h
@@ -66,7 +66,7 @@
   ApexUpdateListener(Sigil, const std::string& apex_name,
                      const std::string& apex_info_list_file_name,
                      CallbackFunction callback, int fd, int wd,
-                     std::set<Info> last_info);
+                     const std::set<Info>& last_info);
 
   static std::unique_ptr<ApexUpdateListener> Make(
       const std::string& apex_name, CallbackFunction callback,
diff --git a/common/hal/Android.bp b/common/hal/Android.bp
index 7726ddd..f953dc8 100644
--- a/common/hal/Android.bp
+++ b/common/hal/Android.bp
@@ -39,7 +39,7 @@
         "-Wextra"
     ],
     header_libs: [
-        "libgooglecamerahal_headers",
+        "//hardware/google/camera:libgooglecamerahal_headers",
         "libhardware_headers",
     ],
 }
diff --git a/common/hal/hidl_service/Android.bp b/common/hal/aidl_service/Android.bp
similarity index 79%
rename from common/hal/hidl_service/Android.bp
rename to common/hal/aidl_service/Android.bp
index 786e7a6..df5d70e 100644
--- a/common/hal/hidl_service/Android.bp
+++ b/common/hal/aidl_service/Android.bp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+//TODO: b/196432585
+//Change the service names to match AIDL instead of HIDL major, minor versioning. Currently
+//left alone to avoid accidentally breaking targets.
+
 package {
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
@@ -54,18 +58,18 @@
 }
 
 cc_genrule {
-   name: "hidl_camera_build_version",
+   name: "aidl_camera_build_version",
    tool_files: ["version_script.py"],
    cmd: "python3 $(location version_script.py) $(in) $(out)",
    vendor: true,
    srcs: [
-       "hidl_camera_build_version.inl",
+       "aidl_camera_build_version.inl",
    ],
-   out: ["hidl_camera_build_version.h"],
+   out: ["aidl_camera_build_version.h"],
 }
 
 cc_defaults {
-    name: "camera_service_defaults",
+    name: "camera_service_defaults_common",
     defaults: [
         "google_camera_hal_defaults",
         "apex_update_listener_cc_defaults_static",
@@ -73,35 +77,28 @@
     vendor: true,
     relative_install_path: "hw",
     srcs: [
-        "hidl_camera_device.cc",
-        "hidl_camera_device_session.cc",
-        "hidl_camera_provider.cc",
-        "hidl_profiler.cc",
+        "aidl_camera_device.cc",
+        "aidl_camera_device_session.cc",
+        "aidl_camera_provider.cc",
+        "aidl_profiler.cc",
         "hidl_thermal_utils.cc",
-        "hidl_utils.cc",
+        "aidl_utils.cc",
         "libc_wrappers.cc",
-        "service.cc",
     ],
     generated_headers: [
-        "hidl_camera_build_version",
+        "aidl_camera_build_version",
     ],
     compile_multilib: "first",
     shared_libs: [
-        "android.hardware.camera.device@3.2",
-        "android.hardware.camera.device@3.3",
-        "android.hardware.camera.device@3.4",
-        "android.hardware.camera.device@3.5",
-        "android.hardware.camera.device@3.6",
-        "android.hardware.camera.device@3.7",
-        "android.hardware.camera.provider@2.4",
-        "android.hardware.camera.provider@2.5",
-        "android.hardware.camera.provider@2.6",
-        "android.hardware.camera.provider@2.7",
+        "android.hardware.camera.device-V1-ndk",
+        "android.hardware.camera.common-V1-ndk",
+        "android.hardware.camera.provider-V1-ndk",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@3.0",
         "android.hardware.graphics.mapper@4.0",
         "android.hardware.thermal@2.0",
         "libbinder",
+        "libbinder_ndk",
         "libbase",
         "libcamera_metadata",
         "libcutils",
@@ -117,7 +114,17 @@
         "lib_profiler",
     ],
     static_libs: [
-        "android.hardware.camera.common@1.0-helper",
+        "libaidlcommonsupport",
+    ],
+}
+
+cc_defaults {
+    name: "camera_service_defaults",
+    defaults: [
+        "camera_service_defaults_common",
+    ],
+    srcs: [
+        "aidl_service.cc",
     ],
     vintf_fragments: [":android.hardware.camera.provider@2.7-service-google.xml"],
 }
diff --git a/common/hal/hidl_service/CleanSpec.mk b/common/hal/aidl_service/CleanSpec.mk
similarity index 100%
rename from common/hal/hidl_service/CleanSpec.mk
rename to common/hal/aidl_service/CleanSpec.mk
diff --git a/common/hal/hidl_service/hidl_camera_build_version.inl b/common/hal/aidl_service/aidl_camera_build_version.inl
similarity index 100%
rename from common/hal/hidl_service/hidl_camera_build_version.inl
rename to common/hal/aidl_service/aidl_camera_build_version.inl
diff --git a/common/hal/aidl_service/aidl_camera_device.cc b/common/hal/aidl_service/aidl_camera_device.cc
new file mode 100644
index 0000000..9d6c869
--- /dev/null
+++ b/common/hal/aidl_service/aidl_camera_device.cc
@@ -0,0 +1,271 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GCH_AidlCameraDevice"
+//#define LOG_NDEBUG 0
+#include "aidl_camera_device.h"
+
+#include <log/log.h>
+
+#include "aidl_camera_device_session.h"
+#include "aidl_profiler.h"
+#include "aidl_utils.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+namespace aidl_utils = ::android::hardware::camera::implementation::aidl_utils;
+
+using aidl::android::hardware::camera::common::Status;
+using ::android::google_camera_hal::HalCameraMetadata;
+
+const std::string AidlCameraDevice::kDeviceVersion = "1.1";
+
+std::shared_ptr<AidlCameraDevice> AidlCameraDevice::Create(
+    std::unique_ptr<CameraDevice> google_camera_device) {
+  auto device = ndk::SharedRefBase::make<AidlCameraDevice>();
+  if (device == nullptr) {
+    ALOGE("%s: Cannot create a AidlCameraDevice.", __FUNCTION__);
+    return nullptr;
+  }
+
+  status_t res = device->Initialize(std::move(google_camera_device));
+  if (res != OK) {
+    ALOGE("%s: Initializing AidlCameraDevice failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return nullptr;
+  }
+
+  return device;
+}
+
+status_t AidlCameraDevice::Initialize(
+    std::unique_ptr<CameraDevice> google_camera_device) {
+  if (google_camera_device == nullptr) {
+    ALOGE("%s: google_camera_device is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  camera_id_ = google_camera_device->GetPublicCameraId();
+  google_camera_device_ = std::move(google_camera_device);
+  aidl_profiler_ = AidlProfiler::Create(camera_id_);
+  if (aidl_profiler_ == nullptr) {
+    ALOGE("%s: Failed to create AidlProfiler.", __FUNCTION__);
+    return UNKNOWN_ERROR;
+  }
+  return OK;
+}
+
+ScopedAStatus AidlCameraDevice::getResourceCost(
+    CameraResourceCost* resource_cost) {
+  google_camera_hal::CameraResourceCost hal_cost;
+  if (resource_cost == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  status_t res = google_camera_device_->GetResourceCost(&hal_cost);
+  if (res != OK) {
+    ALOGE("%s: Getting resource cost failed for camera %u: %s(%d)",
+          __FUNCTION__, camera_id_, strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  res = aidl_utils::ConvertToAidlResourceCost(hal_cost, resource_cost);
+  if (res != OK) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDevice::getCameraCharacteristics(
+    CameraMetadata* characteristics_ret) {
+  if (characteristics_ret == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  characteristics_ret->metadata.clear();
+  std::unique_ptr<HalCameraMetadata> characteristics;
+  status_t res =
+      google_camera_device_->GetCameraCharacteristics(&characteristics);
+  if (res != OK) {
+    ALOGE("%s: Getting camera characteristics for camera %u failed: %s(%d)",
+          __FUNCTION__, camera_id_, strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  if (characteristics == nullptr) {
+    ALOGE("%s: Camera characteristics for camera %u is nullptr.", __FUNCTION__,
+          camera_id_);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  uint32_t metadata_size = characteristics->GetCameraMetadataSize();
+  uint8_t* chars_p = (uint8_t*)characteristics->GetRawCameraMetadata();
+  characteristics_ret->metadata.assign(chars_p, chars_p + metadata_size);
+
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDevice::setTorchMode(bool on) {
+  google_camera_hal::TorchMode hal_torch_mode;
+  hal_torch_mode = on ? google_camera_hal::TorchMode::kOn
+                      : google_camera_hal::TorchMode::kOff;
+  auto res = google_camera_device_->SetTorchMode(hal_torch_mode);
+  return aidl_utils::ConvertToAidlReturn(res);
+}
+
+ScopedAStatus AidlCameraDevice::turnOnTorchWithStrengthLevel(
+    int32_t torch_strength) {
+  status_t res =
+      google_camera_device_->TurnOnTorchWithStrengthLevel(torch_strength);
+  return aidl_utils::ConvertToAidlReturn(res);
+}
+
+ScopedAStatus AidlCameraDevice::getTorchStrengthLevel(int32_t* strength_level) {
+  if (strength_level == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  *strength_level = 0;
+  int32_t torch_strength;
+  status_t res = google_camera_device_->GetTorchStrengthLevel(torch_strength);
+  if (res != OK) {
+    ALOGE(
+        "%s: Getting camera flash unit torch strength level for camera %u "
+        "failed: %s(%d)",
+        __FUNCTION__, camera_id_, strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+  *strength_level = torch_strength;
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDevice::getPhysicalCameraCharacteristics(
+    const std::string& physicalCameraId, CameraMetadata* characteristics_ret) {
+  if (characteristics_ret == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  characteristics_ret->metadata.clear();
+  std::unique_ptr<HalCameraMetadata> physical_characteristics;
+  uint32_t physical_camera_id = atoi(physicalCameraId.c_str());
+  status_t res = google_camera_device_->GetPhysicalCameraCharacteristics(
+      physical_camera_id, &physical_characteristics);
+  if (res != OK) {
+    ALOGE("%s: Getting physical characteristics for camera %u failed: %s(%d)",
+          __FUNCTION__, camera_id_, strerror(-res), res);
+    return aidl_utils::ConvertToAidlReturn(res);
+  }
+
+  if (physical_characteristics == nullptr) {
+    ALOGE("%s: Physical characteristics for camera %u is nullptr.",
+          __FUNCTION__, physical_camera_id);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  uint32_t metadata_size = physical_characteristics->GetCameraMetadataSize();
+  uint8_t* physical_characteristics_p =
+      (uint8_t*)physical_characteristics->GetRawCameraMetadata();
+  characteristics_ret->metadata.assign(
+      physical_characteristics_p, physical_characteristics_p + metadata_size);
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDevice::open(
+    const std::shared_ptr<ICameraDeviceCallback>& callback,
+    std::shared_ptr<ICameraDeviceSession>* session_ret) {
+  if (session_ret == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  *session_ret = nullptr;
+  auto profiler = aidl_profiler_->MakeScopedProfiler(
+      AidlProfiler::ScopedType::kOpen,
+      google_camera_device_->GetProfiler(camera_id_,
+                                         aidl_profiler_->GetLatencyFlag()),
+      google_camera_device_->GetProfiler(camera_id_,
+                                         aidl_profiler_->GetFpsFlag()));
+
+  std::unique_ptr<google_camera_hal::CameraDeviceSession> session;
+  status_t res = google_camera_device_->CreateCameraDeviceSession(&session);
+  if (res != OK || session == nullptr) {
+    ALOGE("%s: Creating CameraDeviceSession failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return aidl_utils::ConvertToAidlReturn(res);
+  }
+
+  auto aidl_session = AidlCameraDeviceSession::Create(
+      callback, std::move(session), aidl_profiler_);
+  if (aidl_session == nullptr) {
+    ALOGE("%s: Creating AidlCameraDeviceSession failed.", __FUNCTION__);
+    return aidl_utils::ConvertToAidlReturn(res);
+  }
+  *session_ret = aidl_session;
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDevice::openInjectionSession(
+    const std::shared_ptr<ICameraDeviceCallback>&,
+    std::shared_ptr<ICameraInjectionSession>* session) {
+  if (session == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  *session = nullptr;
+  return ScopedAStatus::fromServiceSpecificError(
+      static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED));
+}
+
+binder_status_t AidlCameraDevice::dump(int fd, const char** /*args*/,
+                                       uint32_t /*numArgs*/) {
+  google_camera_device_->DumpState(fd);
+  return OK;
+}
+
+ScopedAStatus AidlCameraDevice::isStreamCombinationSupported(
+    const StreamConfiguration& streams, bool* supported) {
+  if (supported == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  *supported = false;
+  google_camera_hal::StreamConfiguration stream_config;
+  status_t res = aidl_utils::ConvertToHalStreamConfig(streams, &stream_config);
+  if (res != OK) {
+    ALOGE("%s: ConverToHalStreamConfig fail", __FUNCTION__);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+  *supported =
+      google_camera_device_->IsStreamCombinationSupported(stream_config);
+  return ScopedAStatus::ok();
+}
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/common/hal/aidl_service/aidl_camera_device.h b/common/hal/aidl_service/aidl_camera_device.h
new file mode 100644
index 0000000..86b7263
--- /dev/null
+++ b/common/hal/aidl_service/aidl_camera_device.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_DEVICE_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_DEVICE_H_
+
+#include <aidl/android/hardware/camera/device/BnCameraDevice.h>
+#include <aidl/android/hardware/camera/device/ICameraDeviceCallback.h>
+
+#include "aidl_profiler.h"
+#include "camera_device.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using aidl::android::hardware::camera::common::CameraResourceCost;
+using aidl::android::hardware::camera::device::BnCameraDevice;
+using aidl::android::hardware::camera::device::CameraMetadata;
+using aidl::android::hardware::camera::device::ICameraDevice;
+using aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using aidl::android::hardware::camera::device::ICameraDeviceSession;
+using aidl::android::hardware::camera::device::ICameraInjectionSession;
+using aidl::android::hardware::camera::device::StreamConfiguration;
+using ::android::hardware::camera::implementation::AidlProfiler;
+using ndk::ScopedAStatus;
+using ndk::ScopedFileDescriptor;
+
+using ::android::google_camera_hal::CameraDevice;
+
+// AidlCameraDevice implements the AIDL camera device interface, ICameraDevice,
+// using Google Camera HAL to provide information about the associated camera
+// device.
+class AidlCameraDevice : public BnCameraDevice {
+ public:
+  static const std::string kDeviceVersion;
+
+  // Create a AidlCameraDevice.
+  // google_camera_device is a google camera device that AidlCameraDevice
+  // is going to manage. Creating a AidlCameraDevice will fail if
+  // google_camera_device is nullptr.
+  static std::shared_ptr<AidlCameraDevice> Create(
+      std::unique_ptr<CameraDevice> google_camera_device);
+  virtual ~AidlCameraDevice() = default;
+
+  binder_status_t dump(int fd, const char**, uint32_t) override;
+
+  // Override functions in ICameraDevice
+  ScopedAStatus getCameraCharacteristics(
+      CameraMetadata* characteristics) override;
+
+  ScopedAStatus getPhysicalCameraCharacteristics(
+      const std::string& in_physicalCameraId,
+      CameraMetadata* characteristics) override;
+
+  ScopedAStatus getResourceCost(CameraResourceCost* resource_cost) override;
+
+  ScopedAStatus isStreamCombinationSupported(
+      const StreamConfiguration& in_streams, bool* supported) override;
+
+  ScopedAStatus open(const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+                     std::shared_ptr<ICameraDeviceSession>* session) override;
+
+  ScopedAStatus openInjectionSession(
+      const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+      std::shared_ptr<ICameraInjectionSession>* session) override;
+
+  ScopedAStatus setTorchMode(bool on) override;
+
+  ScopedAStatus turnOnTorchWithStrengthLevel(int32_t torchStrength) override;
+
+  ScopedAStatus getTorchStrengthLevel(int32_t* strength_level) override;
+
+  // End of override functions in ICameraDevice
+  AidlCameraDevice() = default;
+
+ private:
+  status_t Initialize(std::unique_ptr<CameraDevice> google_camera_device);
+
+  std::unique_ptr<CameraDevice> google_camera_device_;
+  uint32_t camera_id_ = 0;
+  std::shared_ptr<AidlProfiler> aidl_profiler_;
+};
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_DEVICE_H_
diff --git a/common/hal/aidl_service/aidl_camera_device_session.cc b/common/hal/aidl_service/aidl_camera_device_session.cc
new file mode 100644
index 0000000..49d8282
--- /dev/null
+++ b/common/hal/aidl_service/aidl_camera_device_session.cc
@@ -0,0 +1,812 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GCH_AidlCameraDeviceSession"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+#include "aidl_camera_device_session.h"
+
+#include <android/binder_ibinder_platform.h>
+#include <cutils/properties.h>
+#include <cutils/trace.h>
+#include <log/log.h>
+#include <malloc.h>
+#include <utils/Trace.h>
+
+#include "aidl_profiler.h"
+#include "aidl_utils.h"
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+namespace aidl_utils = ::android::hardware::camera::implementation::aidl_utils;
+
+using aidl::android::hardware::camera::common::Status;
+using aidl::android::hardware::camera::device::BufferRequest;
+using aidl::android::hardware::camera::device::BufferRequestStatus;
+using aidl::android::hardware::camera::device::CaptureResult;
+using aidl::android::hardware::camera::device::HalStream;
+using aidl::android::hardware::camera::device::NotifyMsg;
+using aidl::android::hardware::camera::device::StreamBuffer;
+using aidl::android::hardware::camera::device::StreamBufferRet;
+using aidl::android::hardware::camera::device::StreamBuffersVal;
+using aidl_utils::ConvertToAidlReturn;
+using ::android::hardware::thermal::V1_0::ThermalStatus;
+using ::android::hardware::thermal::V1_0::ThermalStatusCode;
+using ::android::hardware::thermal::V2_0::Temperature;
+using ::android::hardware::thermal::V2_0::TemperatureType;
+
+std::shared_ptr<AidlCameraDeviceSession> AidlCameraDeviceSession::Create(
+    const std::shared_ptr<ICameraDeviceCallback>& callback,
+    std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
+    std::shared_ptr<AidlProfiler> aidl_profiler) {
+  ATRACE_NAME("AidlCameraDeviceSession::Create");
+  auto session = ndk::SharedRefBase::make<AidlCameraDeviceSession>();
+  if (session == nullptr) {
+    ALOGE("%s: Cannot create a AidlCameraDeviceSession.", __FUNCTION__);
+    return nullptr;
+  }
+
+  status_t res =
+      session->Initialize(callback, std::move(device_session), aidl_profiler);
+  if (res != OK) {
+    ALOGE("%s: Initializing AidlCameraDeviceSession failed: %s(%d)",
+          __FUNCTION__, strerror(-res), res);
+    return nullptr;
+  }
+
+  return session;
+}
+
+AidlCameraDeviceSession::~AidlCameraDeviceSession() {
+  ATRACE_NAME("AidlCameraDeviceSession::~AidlCameraDeviceSession");
+  close();
+  // camera's closing, so flush any unused malloc pages
+  mallopt(M_PURGE, 0);
+}
+
+void AidlCameraDeviceSession::ProcessCaptureResult(
+    std::unique_ptr<google_camera_hal::CaptureResult> hal_result) {
+  std::shared_lock lock(aidl_device_callback_lock_);
+  if (aidl_device_callback_ == nullptr) {
+    ALOGE("%s: aidl_device_callback_ is nullptr", __FUNCTION__);
+    return;
+  }
+
+  {
+    std::lock_guard<std::mutex> pending_lock(pending_first_frame_buffers_mutex_);
+    if (!hal_result->output_buffers.empty() &&
+        num_pending_first_frame_buffers_ > 0 &&
+        first_request_frame_number_ == hal_result->frame_number) {
+      num_pending_first_frame_buffers_ -= hal_result->output_buffers.size();
+      if (num_pending_first_frame_buffers_ == 0) {
+        ALOGI("%s: First frame done", __FUNCTION__);
+        aidl_profiler_->FirstFrameEnd();
+        ATRACE_ASYNC_END("first_frame", 0);
+        ATRACE_ASYNC_END("switch_mode", 0);
+      }
+    }
+  }
+  for (auto& buffer : hal_result->output_buffers) {
+    aidl_profiler_->ProfileFrameRate("Stream " +
+                                     std::to_string(buffer.stream_id));
+  }
+
+  std::vector<CaptureResult> aidl_results(1);
+  status_t res = aidl_utils::ConvertToAidlCaptureResult(
+      result_metadata_queue_.get(), std::move(hal_result), &aidl_results[0]);
+  if (res != OK) {
+    ALOGE("%s: Converting to AIDL result failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return;
+  }
+
+  auto aidl_res = aidl_device_callback_->processCaptureResult(aidl_results);
+  if (!aidl_res.isOk()) {
+    ALOGE("%s: processCaptureResult transaction failed: %s.", __FUNCTION__,
+          aidl_res.getMessage());
+    return;
+  }
+}
+
+void AidlCameraDeviceSession::NotifyHalMessage(
+    const google_camera_hal::NotifyMessage& hal_message) {
+  std::shared_lock lock(aidl_device_callback_lock_);
+  if (aidl_device_callback_ == nullptr) {
+    ALOGE("%s: aidl_device_callback_ is nullptr", __FUNCTION__);
+    return;
+  }
+
+  std::vector<NotifyMsg> aidl_messages(1);
+  status_t res =
+      aidl_utils::ConverToAidlNotifyMessage(hal_message, &aidl_messages[0]);
+  if (res != OK) {
+    ALOGE("%s: Converting to AIDL message failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return;
+  }
+
+  auto aidl_res = aidl_device_callback_->notify(aidl_messages);
+  if (!aidl_res.isOk()) {
+    ALOGE("%s: notify transaction failed: %s.", __FUNCTION__,
+          aidl_res.getMessage());
+    return;
+  }
+}
+
+static void cleanupHandles(std::vector<native_handle_t*>& handles_to_delete) {
+  for (auto& handle : handles_to_delete) {
+    native_handle_delete(handle);
+  }
+}
+
+google_camera_hal::BufferRequestStatus
+AidlCameraDeviceSession::RequestStreamBuffers(
+    const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
+    std::vector<google_camera_hal::BufferReturn>* hal_buffer_returns) {
+  std::shared_lock lock(aidl_device_callback_lock_);
+  if (aidl_device_callback_ == nullptr) {
+    ALOGE("%s: aidl_device_callback_ is nullptr", __FUNCTION__);
+    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
+  }
+
+  if (hal_buffer_returns == nullptr) {
+    ALOGE("%s: hal_buffer_returns is nullptr", __FUNCTION__);
+    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
+  }
+
+  std::vector<BufferRequest> aidl_buffer_requests;
+  status_t res = aidl_utils::ConvertToAidlBufferRequest(hal_buffer_requests,
+                                                        &aidl_buffer_requests);
+  if (res != OK) {
+    ALOGE("%s: Converting to Aidl buffer request failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
+  }
+
+  BufferRequestStatus aidl_status;
+  std::vector<StreamBufferRet> stream_buffer_returns;
+  auto cb_status = aidl_device_callback_->requestStreamBuffers(
+      aidl_buffer_requests, &stream_buffer_returns, &aidl_status);
+
+  if (!cb_status.isOk()) {
+    ALOGE("%s: Transaction request stream buffers error: %s", __FUNCTION__,
+          cb_status.getMessage());
+    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
+  }
+
+  google_camera_hal::BufferRequestStatus hal_buffer_request_status;
+  res = aidl_utils::ConvertToHalBufferRequestStatus(aidl_status,
+                                                    &hal_buffer_request_status);
+  if (res != OK) {
+    ALOGE("%s: Converting to Hal buffer request status failed: %s(%d)",
+          __FUNCTION__, strerror(-res), res);
+    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
+  }
+
+  hal_buffer_returns->clear();
+  // Converting AIDL stream buffer returns to HAL stream buffer returns.
+  for (auto& stream_buffer_return : stream_buffer_returns) {
+    google_camera_hal::BufferReturn hal_buffer_return;
+    res = aidl_utils::ConvertToHalBufferReturnStatus(stream_buffer_return,
+                                                     &hal_buffer_return);
+    if (res != OK) {
+      ALOGE("%s: Converting to Hal buffer return status failed: %s(%d)",
+            __FUNCTION__, strerror(-res), res);
+      return google_camera_hal::BufferRequestStatus::kFailedUnknown;
+    }
+
+    using Tag = aidl::android::hardware::camera::device::StreamBuffersVal::Tag;
+    if (stream_buffer_return.val.getTag() == Tag::buffers) {
+      const std::vector<StreamBuffer>& aidl_buffers =
+          stream_buffer_return.val.get<Tag::buffers>();
+      std::vector<native_handle_t*> native_handles_to_delete;
+      for (auto& aidl_buffer : aidl_buffers) {
+        google_camera_hal::StreamBuffer hal_buffer = {};
+        aidl_utils::ConvertToHalStreamBuffer(aidl_buffer, &hal_buffer,
+                                             &native_handles_to_delete);
+        if (res != OK) {
+          ALOGE("%s: Converting to Hal stream buffer failed: %s(%d)",
+                __FUNCTION__, strerror(-res), res);
+          return google_camera_hal::BufferRequestStatus::kFailedUnknown;
+        }
+
+        if (!aidl_utils::IsAidlNativeHandleNull(aidl_buffer.acquireFence)) {
+          hal_buffer.acquire_fence = dupFromAidl(aidl_buffer.acquireFence);
+          if (hal_buffer.acquire_fence == nullptr) {
+            ALOGE("%s: Cloning Hal stream buffer acquire fence failed",
+                  __FUNCTION__);
+          }
+        }
+
+        hal_buffer.release_fence = nullptr;
+        // If buffer handle is not null, we need to import buffer handle and
+        // return to the caller.
+        if (!aidl_utils::IsAidlNativeHandleNull(aidl_buffer.buffer)) {
+          native_handle_t* aidl_buffer_native_handle =
+              makeFromAidl(aidl_buffer.buffer);
+          if (buffer_mapper_v4_ != nullptr) {
+            hal_buffer.buffer = ImportBufferHandle<
+                android::hardware::graphics::mapper::V4_0::IMapper,
+                android::hardware::graphics::mapper::V4_0::Error>(
+                buffer_mapper_v4_, aidl_buffer_native_handle);
+          } else if (buffer_mapper_v3_ != nullptr) {
+            hal_buffer.buffer = ImportBufferHandle<
+                android::hardware::graphics::mapper::V3_0::IMapper,
+                android::hardware::graphics::mapper::V3_0::Error>(
+                buffer_mapper_v3_, aidl_buffer_native_handle);
+          } else {
+            hal_buffer.buffer = ImportBufferHandle<
+                android::hardware::graphics::mapper::V2_0::IMapper,
+                android::hardware::graphics::mapper::V2_0::Error>(
+                buffer_mapper_v2_, aidl_buffer_native_handle);
+          }
+          native_handle_delete(aidl_buffer_native_handle);
+        }
+
+        hal_buffer_return.val.buffers.push_back(hal_buffer);
+      }
+
+      cleanupHandles(native_handles_to_delete);
+    }
+
+    hal_buffer_returns->push_back(hal_buffer_return);
+  }
+
+  return hal_buffer_request_status;
+}
+
+template <class T, class U>
+buffer_handle_t AidlCameraDeviceSession::ImportBufferHandle(
+    const sp<T> buffer_mapper_, const hidl_handle& buffer_hidl_handle) {
+  U mapper_error;
+  buffer_handle_t imported_buffer_handle;
+
+  auto hidl_res = buffer_mapper_->importBuffer(
+      buffer_hidl_handle, [&](const auto& error, const auto& buffer_handle) {
+        mapper_error = error;
+        imported_buffer_handle = static_cast<buffer_handle_t>(buffer_handle);
+      });
+  if (!hidl_res.isOk() || mapper_error != U::NONE) {
+    ALOGE("%s: Importing buffer failed: %s, mapper error %u", __FUNCTION__,
+          hidl_res.description().c_str(), mapper_error);
+    return nullptr;
+  }
+
+  return imported_buffer_handle;
+}
+
+void AidlCameraDeviceSession::ReturnStreamBuffers(
+    const std::vector<google_camera_hal::StreamBuffer>& return_hal_buffers) {
+  std::shared_lock lock(aidl_device_callback_lock_);
+  if (aidl_device_callback_ == nullptr) {
+    ALOGE("%s: aidl_device_callback_ is nullptr", __FUNCTION__);
+    return;
+  }
+
+  status_t res = OK;
+  std::vector<StreamBuffer> aidl_return_buffers;
+  aidl_return_buffers.resize(return_hal_buffers.size());
+  for (uint32_t i = 0; i < return_hal_buffers.size(); i++) {
+    res = aidl_utils::ConvertToAidlStreamBuffer(return_hal_buffers[i],
+                                                &aidl_return_buffers[i]);
+    if (res != OK) {
+      ALOGE("%s: Converting to Aidl stream buffer failed: %s(%d)", __FUNCTION__,
+            strerror(-res), res);
+      return;
+    }
+  }
+
+  auto aidl_res =
+      aidl_device_callback_->returnStreamBuffers(aidl_return_buffers);
+  if (!aidl_res.isOk()) {
+    ALOGE("%s: return stream buffers transaction failed: %s", __FUNCTION__,
+          aidl_res.getMessage());
+    return;
+  }
+}
+
+status_t AidlCameraDeviceSession::InitializeBufferMapper() {
+  buffer_mapper_v4_ =
+      android::hardware::graphics::mapper::V4_0::IMapper::getService();
+  if (buffer_mapper_v4_ != nullptr) {
+    return OK;
+  }
+
+  buffer_mapper_v3_ =
+      android::hardware::graphics::mapper::V3_0::IMapper::getService();
+  if (buffer_mapper_v3_ != nullptr) {
+    return OK;
+  }
+
+  buffer_mapper_v2_ =
+      android::hardware::graphics::mapper::V2_0::IMapper::getService();
+  if (buffer_mapper_v2_ != nullptr) {
+    return OK;
+  }
+
+  ALOGE("%s: Getting buffer mapper failed.", __FUNCTION__);
+  return UNKNOWN_ERROR;
+}
+
+status_t AidlCameraDeviceSession::Initialize(
+    const std::shared_ptr<ICameraDeviceCallback>& callback,
+    std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
+    std::shared_ptr<AidlProfiler> aidl_profiler) {
+  ATRACE_NAME("AidlCameraDeviceSession::Initialize");
+  if (device_session == nullptr) {
+    ALOGE("%s: device_session is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  if (aidl_profiler == nullptr) {
+    ALOGE("%s: aidl_profiler is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  status_t res = CreateMetadataQueue(&request_metadata_queue_,
+                                     kRequestMetadataQueueSizeBytes,
+                                     "ro.vendor.camera.req.fmq.size");
+  if (res != OK) {
+    ALOGE("%s: Creating request metadata queue failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  res = CreateMetadataQueue(&result_metadata_queue_,
+                            kResultMetadataQueueSizeBytes,
+                            "ro.vendor.camera.res.fmq.size");
+  if (res != OK) {
+    ALOGE("%s: Creating result metadata queue failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  // Initialize buffer mapper
+  res = InitializeBufferMapper();
+  if (res != OK) {
+    ALOGE("%s: Initialize buffer mapper failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  thermal_ = android::hardware::thermal::V2_0::IThermal::getService();
+  if (thermal_ == nullptr) {
+    ALOGE("%s: Getting thermal failed.", __FUNCTION__);
+    // Continue without getting thermal information.
+  }
+
+  aidl_device_callback_ = callback;
+  device_session_ = std::move(device_session);
+  aidl_profiler_ = aidl_profiler;
+
+  SetSessionCallbacks();
+  return OK;
+}
+
+void AidlCameraDeviceSession::SetSessionCallbacks() {
+  google_camera_hal::CameraDeviceSessionCallback session_callback = {
+      .process_capture_result = google_camera_hal::ProcessCaptureResultFunc(
+          [this](std::unique_ptr<google_camera_hal::CaptureResult> result) {
+            ProcessCaptureResult(std::move(result));
+          }),
+      .notify = google_camera_hal::NotifyFunc(
+          [this](const google_camera_hal::NotifyMessage& message) {
+            NotifyHalMessage(message);
+          }),
+      .request_stream_buffers = google_camera_hal::RequestStreamBuffersFunc(
+          [this](
+              const std::vector<google_camera_hal::BufferRequest>&
+                  hal_buffer_requests,
+              std::vector<google_camera_hal::BufferReturn>* hal_buffer_returns) {
+            return RequestStreamBuffers(hal_buffer_requests, hal_buffer_returns);
+          }),
+      .return_stream_buffers = google_camera_hal::ReturnStreamBuffersFunc(
+          [this](const std::vector<google_camera_hal::StreamBuffer>&
+                     return_hal_buffers) {
+            ReturnStreamBuffers(return_hal_buffers);
+          }),
+  };
+
+  google_camera_hal::ThermalCallback thermal_callback = {
+      .register_thermal_changed_callback =
+          google_camera_hal::RegisterThermalChangedCallbackFunc(
+              [this](google_camera_hal::NotifyThrottlingFunc notify_throttling,
+                     bool filter_type, google_camera_hal::TemperatureType type) {
+                return RegisterThermalChangedCallback(notify_throttling,
+                                                      filter_type, type);
+              }),
+      .unregister_thermal_changed_callback =
+          google_camera_hal::UnregisterThermalChangedCallbackFunc(
+              [this]() { UnregisterThermalChangedCallback(); }),
+  };
+
+  device_session_->SetSessionCallback(session_callback, thermal_callback);
+}
+
+status_t AidlCameraDeviceSession::RegisterThermalChangedCallback(
+    google_camera_hal::NotifyThrottlingFunc notify_throttling, bool filter_type,
+    google_camera_hal::TemperatureType type) {
+  std::lock_guard<std::mutex> lock(hidl_thermal_mutex_);
+  if (thermal_ == nullptr) {
+    ALOGE("%s: thermal was not initialized.", __FUNCTION__);
+    return NO_INIT;
+  }
+
+  if (thermal_changed_callback_ != nullptr) {
+    ALOGE("%s: thermal changed callback is already registered.", __FUNCTION__);
+    return ALREADY_EXISTS;
+  }
+
+  TemperatureType hidl_type;
+  status_t res =
+      hidl_thermal_utils::ConvertToHidlTemperatureType(type, &hidl_type);
+  if (res != OK) {
+    ALOGE("%s: Converting to HIDL type failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  std::unique_ptr<hidl_thermal_utils::HidlThermalChangedCallback> callback =
+      hidl_thermal_utils::HidlThermalChangedCallback::Create(notify_throttling);
+  thermal_changed_callback_ = callback.release();
+  ThermalStatus thermal_status;
+  auto hidl_res = thermal_->registerThermalChangedCallback(
+      thermal_changed_callback_, filter_type, hidl_type,
+      [&](ThermalStatus status) { thermal_status = status; });
+  if (!hidl_res.isOk() || thermal_status.code != ThermalStatusCode::SUCCESS) {
+    thermal_changed_callback_ = nullptr;
+    return UNKNOWN_ERROR;
+  }
+
+  return OK;
+}
+
+void AidlCameraDeviceSession::UnregisterThermalChangedCallback() {
+  std::lock_guard<std::mutex> lock(hidl_thermal_mutex_);
+  if (thermal_changed_callback_ == nullptr) {
+    // no-op if no thermal changed callback is registered.
+    return;
+  }
+
+  if (thermal_ == nullptr) {
+    ALOGE("%s: thermal was not initialized.", __FUNCTION__);
+    return;
+  }
+
+  ThermalStatus thermal_status;
+  auto hidl_res = thermal_->unregisterThermalChangedCallback(
+      thermal_changed_callback_,
+      [&](ThermalStatus status) { thermal_status = status; });
+  if (!hidl_res.isOk() || thermal_status.code != ThermalStatusCode::SUCCESS) {
+    ALOGW("%s: Unregstering thermal callback failed: %s", __FUNCTION__,
+          thermal_status.debugMessage.c_str());
+  }
+
+  thermal_changed_callback_ = nullptr;
+}
+
+status_t AidlCameraDeviceSession::CreateMetadataQueue(
+    std::unique_ptr<MetadataQueue>* metadata_queue, uint32_t default_size_bytes,
+    const char* override_size_property) {
+  if (metadata_queue == nullptr) {
+    ALOGE("%s: metadata_queue is nullptr", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  int32_t size = default_size_bytes;
+  if (override_size_property != nullptr) {
+    // Try to read the override size from the system property.
+    size = property_get_int32(override_size_property, default_size_bytes);
+    ALOGV("%s: request metadata queue size overridden to %d", __FUNCTION__,
+          size);
+  }
+
+  *metadata_queue =
+      std::make_unique<MetadataQueue>(static_cast<size_t>(size),
+                                      /*configureEventFlagWord*/ false);
+  if (!(*metadata_queue)->isValid()) {
+    ALOGE("%s: Creating metadata queue (size %d) failed.", __FUNCTION__, size);
+    return NO_INIT;
+  }
+
+  return OK;
+}
+
+ScopedAStatus AidlCameraDeviceSession::constructDefaultRequestSettings(
+    RequestTemplate type, CameraMetadata* aidl_return) {
+  ATRACE_NAME("AidlCameraDeviceSession::constructDefaultRequestSettings");
+  if (aidl_return == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  aidl_return->metadata.clear();
+  if (device_session_ == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  google_camera_hal::RequestTemplate hal_type;
+  status_t res = aidl_utils::ConvertToHalTemplateType(type, &hal_type);
+  if (res != OK) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+
+  std::unique_ptr<google_camera_hal::HalCameraMetadata> settings = nullptr;
+  res = device_session_->ConstructDefaultRequestSettings(hal_type, &settings);
+  if (res != OK) {
+    return aidl_utils::ConvertToAidlReturn(res);
+  }
+
+  uint32_t metadata_size = settings->GetCameraMetadataSize();
+  uint8_t* settings_p = (uint8_t*)settings->ReleaseCameraMetadata();
+  aidl_return->metadata.assign(settings_p, settings_p + metadata_size);
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDeviceSession::configureStreams(
+    const StreamConfiguration& requestedConfiguration,
+    std::vector<HalStream>* aidl_return) {
+  ATRACE_NAME("AidlCameraDeviceSession::configureStreams");
+  if (aidl_return == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  aidl_return->clear();
+  if (device_session_ == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+
+  auto profiler = aidl_profiler_->MakeScopedProfiler(
+      AidlProfiler::ScopedType::kConfigureStream,
+      device_session_->GetProfiler(aidl_profiler_->GetCameraId(),
+                                   aidl_profiler_->GetLatencyFlag()),
+      device_session_->GetProfiler(aidl_profiler_->GetCameraId(),
+                                   aidl_profiler_->GetFpsFlag()));
+
+  first_frame_requested_ = false;
+  num_pending_first_frame_buffers_ = 0;
+
+  google_camera_hal::StreamConfiguration hal_stream_config;
+  status_t res = aidl_utils::ConvertToHalStreamConfig(requestedConfiguration,
+                                                      &hal_stream_config);
+  if (res != OK) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+
+  std::vector<google_camera_hal::HalStream> hal_configured_streams;
+  res = device_session_->ConfigureStreams(hal_stream_config,
+                                          &hal_configured_streams);
+  if (res != OK) {
+    ALOGE("%s: Configuring streams failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return aidl_utils::ConvertToAidlReturn(res);
+  }
+
+  res = aidl_utils::ConvertToAidlHalStreamConfig(hal_configured_streams,
+                                                 aidl_return);
+  if (res != OK) {
+    return aidl_utils::ConvertToAidlReturn(res);
+  }
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDeviceSession::getCaptureRequestMetadataQueue(
+    ::aidl::android::hardware::common::fmq::MQDescriptor<
+        int8_t, SynchronizedReadWrite>* aidl_return) {
+  *aidl_return = request_metadata_queue_->dupeDesc();
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDeviceSession::getCaptureResultMetadataQueue(
+    ::aidl::android::hardware::common::fmq::MQDescriptor<
+        int8_t, SynchronizedReadWrite>* aidl_return) {
+  *aidl_return = result_metadata_queue_->dupeDesc();
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDeviceSession::processCaptureRequest(
+    const std::vector<CaptureRequest>& requests,
+    const std::vector<BufferCache>& cachesToRemove, int32_t* aidl_return) {
+  if (aidl_return == nullptr || device_session_ == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  *aidl_return = 0;
+  bool profile_first_request = false;
+  if (!first_frame_requested_) {
+    first_frame_requested_ = true;
+    profile_first_request = true;
+    ATRACE_BEGIN("AidlCameraDeviceSession::FirstRequest");
+    num_pending_first_frame_buffers_ = requests[0].outputBuffers.size();
+    first_request_frame_number_ = requests[0].frameNumber;
+    aidl_profiler_->FirstFrameStart();
+    ATRACE_ASYNC_BEGIN("first_frame", 0);
+  }
+
+  std::vector<google_camera_hal::BufferCache> hal_buffer_caches;
+
+  status_t res =
+      aidl_utils::ConvertToHalBufferCaches(cachesToRemove, &hal_buffer_caches);
+  if (res != OK) {
+    if (profile_first_request) {
+      ATRACE_END();
+    }
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+
+  device_session_->RemoveBufferCache(hal_buffer_caches);
+
+  // Converting AIDL requests to HAL requests.
+  std::vector<native_handle_t*> handles_to_delete;
+  std::vector<google_camera_hal::CaptureRequest> hal_requests;
+  for (auto& request : requests) {
+    google_camera_hal::CaptureRequest hal_request = {};
+    res = aidl_utils::ConvertToHalCaptureRequest(
+        request, request_metadata_queue_.get(), &hal_request,
+        &handles_to_delete);
+    if (res != OK) {
+      ALOGE("%s: Converting to HAL capture request failed: %s(%d)",
+            __FUNCTION__, strerror(-res), res);
+      if (profile_first_request) {
+        ATRACE_END();
+      }
+      cleanupHandles(handles_to_delete);
+      return aidl_utils::ConvertToAidlReturn(res);
+    }
+
+    hal_requests.push_back(std::move(hal_request));
+  }
+
+  uint32_t num_processed_requests = 0;
+  res = device_session_->ProcessCaptureRequest(hal_requests,
+                                               &num_processed_requests);
+  if (res != OK) {
+    ALOGE(
+        "%s: Processing capture request failed: %s(%d). Only processed %u"
+        " out of %zu.",
+        __FUNCTION__, strerror(-res), res, num_processed_requests,
+        hal_requests.size());
+  }
+  if (num_processed_requests > INT_MAX) {
+    cleanupHandles(handles_to_delete);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  *aidl_return = (int32_t)num_processed_requests;
+  if (profile_first_request) {
+    ATRACE_END();
+  }
+  cleanupHandles(handles_to_delete);
+  return aidl_utils::ConvertToAidlReturn(res);
+}
+
+ScopedAStatus AidlCameraDeviceSession::signalStreamFlush(
+    const std::vector<int32_t>&, int32_t) {
+  // TODO(b/143902312): Implement this.
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDeviceSession::flush() {
+  ATRACE_NAME("AidlCameraDeviceSession::flush");
+  ATRACE_ASYNC_BEGIN("switch_mode", 0);
+  if (device_session_ == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  auto profiler = aidl_profiler_->MakeScopedProfiler(
+      AidlProfiler::ScopedType::kFlush,
+      device_session_->GetProfiler(aidl_profiler_->GetCameraId(),
+                                   aidl_profiler_->GetLatencyFlag()),
+      device_session_->GetProfiler(aidl_profiler_->GetCameraId(),
+                                   aidl_profiler_->GetFpsFlag()));
+
+  status_t res = device_session_->Flush();
+  if (res != OK) {
+    ALOGE("%s: Flushing device failed: %s(%d).", __FUNCTION__, strerror(-res),
+          res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDeviceSession::close() {
+  ATRACE_NAME("AidlCameraDeviceSession::close");
+  if (device_session_ != nullptr) {
+    auto profiler = aidl_profiler_->MakeScopedProfiler(
+        AidlProfiler::ScopedType::kClose,
+        device_session_->GetProfiler(aidl_profiler_->GetCameraId(),
+                                     aidl_profiler_->GetLatencyFlag()),
+        device_session_->GetProfiler(aidl_profiler_->GetCameraId(),
+                                     aidl_profiler_->GetFpsFlag()));
+    device_session_ = nullptr;
+  }
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraDeviceSession::switchToOffline(
+    const std::vector<int32_t>&,
+    CameraOfflineSessionInfo* out_offlineSessionInfo,
+    std::shared_ptr<ICameraOfflineSession>* aidl_return) {
+  *out_offlineSessionInfo = CameraOfflineSessionInfo();
+  *aidl_return = nullptr;
+  return ScopedAStatus::fromServiceSpecificError(
+      static_cast<int32_t>(Status::INTERNAL_ERROR));
+}
+
+ScopedAStatus AidlCameraDeviceSession::isReconfigurationRequired(
+    const CameraMetadata& oldSessionParams,
+    const CameraMetadata& newSessionParams, bool* reconfiguration_required) {
+  ATRACE_NAME("AidlCameraDeviceSession::isReconfigurationRequired");
+  if (reconfiguration_required == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  *reconfiguration_required = true;
+  std::unique_ptr<google_camera_hal::HalCameraMetadata> old_hal_session_metadata;
+  status_t res = aidl_utils::ConvertToHalMetadata(
+      0, nullptr, oldSessionParams.metadata, &old_hal_session_metadata);
+  if (res != OK) {
+    ALOGE("%s: Converting to old session metadata failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  std::unique_ptr<google_camera_hal::HalCameraMetadata> new_hal_session_metadata;
+  res = aidl_utils::ConvertToHalMetadata(0, nullptr, newSessionParams.metadata,
+                                         &new_hal_session_metadata);
+  if (res != OK) {
+    ALOGE("%s: Converting to new session metadata failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  res = device_session_->IsReconfigurationRequired(
+      old_hal_session_metadata.get(), new_hal_session_metadata.get(),
+      reconfiguration_required);
+
+  if (res != OK) {
+    ALOGE("%s: IsReconfigurationRequired failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  return ScopedAStatus::ok();
+}
+
+::ndk::SpAIBinder AidlCameraDeviceSession::createBinder() {
+  auto binder = BnCameraDeviceSession::createBinder();
+  AIBinder_setInheritRt(binder.get(), true);
+  return binder;
+}
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/common/hal/aidl_service/aidl_camera_device_session.h b/common/hal/aidl_service/aidl_camera_device_session.h
new file mode 100644
index 0000000..3423d8f
--- /dev/null
+++ b/common/hal/aidl_service/aidl_camera_device_session.h
@@ -0,0 +1,224 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_DEVICE_SESSION_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_DEVICE_SESSION_H_
+
+#include <aidl/android/hardware/camera/device/BnCameraDeviceSession.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+#include <aidl/android/hardware/camera/device/ICameraDeviceCallback.h>
+#include <android/hardware/thermal/2.0/IThermal.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include <shared_mutex>
+
+#include "aidl_profiler.h"
+#include "camera_device_session.h"
+#include "hidl_thermal_utils.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::device::BnCameraDeviceSession;
+using ::aidl::android::hardware::camera::device::BufferCache;
+using ::aidl::android::hardware::camera::device::CameraMetadata;
+using ::aidl::android::hardware::camera::device::CameraOfflineSessionInfo;
+using ::aidl::android::hardware::camera::device::CaptureRequest;
+using ::aidl::android::hardware::camera::device::HalStream;
+using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::ICameraOfflineSession;
+using ::aidl::android::hardware::camera::device::RequestTemplate;
+using ::aidl::android::hardware::camera::device::StreamConfiguration;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::hardware::camera::implementation::AidlProfiler;
+using ndk::ScopedAStatus;
+
+using MetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+
+// AidlCameraDeviceSession implements the AIDL camera device session interface,
+// ICameraDeviceSession, that contains the methods to configure and request
+// captures from an active camera device.
+class AidlCameraDeviceSession : public BnCameraDeviceSession {
+ public:
+  // Create a AidlCameraDeviceSession.
+  // device_session is a google camera device session that
+  // AidlCameraDeviceSession is going to manage. Creating a
+  // AidlCameraDeviceSession will fail if device_session is
+  // nullptr.
+  static std::shared_ptr<AidlCameraDeviceSession> Create(
+      const std::shared_ptr<ICameraDeviceCallback>& callback,
+      std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
+      std::shared_ptr<AidlProfiler> aidl_profiler);
+
+  virtual ~AidlCameraDeviceSession();
+
+  // functions in ICameraDeviceSession
+
+  ScopedAStatus close() override;
+
+  ScopedAStatus configureStreams(const StreamConfiguration&,
+                                 std::vector<HalStream>*) override;
+
+  ScopedAStatus constructDefaultRequestSettings(
+      RequestTemplate in_type, CameraMetadata* _aidl_return) override;
+
+  ScopedAStatus flush() override;
+
+  ScopedAStatus getCaptureRequestMetadataQueue(
+      ::aidl::android::hardware::common::fmq::MQDescriptor<
+          int8_t, SynchronizedReadWrite>* _aidl_return) override;
+
+  ScopedAStatus getCaptureResultMetadataQueue(
+      ::aidl::android::hardware::common::fmq::MQDescriptor<
+          int8_t, SynchronizedReadWrite>* _aidl_return) override;
+
+  ScopedAStatus isReconfigurationRequired(
+      const CameraMetadata& in_oldSessionParams,
+      const CameraMetadata& in_newSessionParams, bool* _aidl_return) override;
+
+  ScopedAStatus processCaptureRequest(
+      const std::vector<CaptureRequest>& in_requests,
+      const std::vector<BufferCache>& in_cachesToRemove,
+      int32_t* _aidl_return) override;
+
+  ScopedAStatus signalStreamFlush(const std::vector<int32_t>& in_streamIds,
+                                  int32_t in_streamConfigCounter) override;
+
+  ScopedAStatus switchToOffline(
+      const std::vector<int32_t>& in_streamsToKeep,
+      CameraOfflineSessionInfo* out_offlineSessionInfo,
+      std::shared_ptr<ICameraOfflineSession>* _aidl_return) override;
+
+  ScopedAStatus repeatingRequestEnd(
+      int32_t /*in_frameNumber*/,
+      const std::vector<int32_t>& /*in_streamIds*/) override {
+    return ScopedAStatus::ok();
+  };
+
+  AidlCameraDeviceSession() = default;
+
+ protected:
+  ::ndk::SpAIBinder createBinder() override;
+
+ private:
+  static constexpr uint32_t kRequestMetadataQueueSizeBytes = 1 << 20;  // 1MB
+  static constexpr uint32_t kResultMetadataQueueSizeBytes = 1 << 20;   // 1MB
+
+  // Initialize the latest available gralloc buffer mapper.
+  status_t InitializeBufferMapper();
+
+  // Initialize AidlCameraDeviceSession with a CameraDeviceSession.
+  status_t Initialize(
+      const std::shared_ptr<ICameraDeviceCallback>& callback,
+      std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
+      std::shared_ptr<AidlProfiler> aidl_profiler);
+
+  // Create a metadata queue.
+  // If override_size_property contains a valid size, it will create a metadata
+  // queue of that size. If it override_size_property doesn't contain a valid
+  // size, it will create a metadata queue of the default size.
+  // default_size_bytes is the default size of the message queue in bytes.
+  // override_size_property is the name of the system property that contains
+  // the message queue size.
+  status_t CreateMetadataQueue(std::unique_ptr<MetadataQueue>* metadata_queue,
+                               uint32_t default_size_bytes,
+                               const char* override_size_property);
+
+  // Invoked when receiving a result from HAL.
+  void ProcessCaptureResult(
+      std::unique_ptr<google_camera_hal::CaptureResult> hal_result);
+
+  // Invoked when receiving a message from HAL.
+  void NotifyHalMessage(const google_camera_hal::NotifyMessage& hal_message);
+
+  // Invoked when requesting stream buffers from HAL.
+  google_camera_hal::BufferRequestStatus RequestStreamBuffers(
+      const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
+      std::vector<google_camera_hal::BufferReturn>* hal_buffer_returns);
+
+  // Invoked when returning stream buffers from HAL.
+  void ReturnStreamBuffers(
+      const std::vector<google_camera_hal::StreamBuffer>& return_hal_buffers);
+
+  // Import a buffer handle.
+  template <class T, class U>
+  buffer_handle_t ImportBufferHandle(const sp<T> buffer_mapper_,
+                                     const hidl_handle& buffer_hidl_handle);
+
+  // Set camera device session callbacks.
+  void SetSessionCallbacks();
+
+  // Register a thermal changed callback.
+  // notify_throttling will be invoked when thermal status changes.
+  // If filter_type is false, type will be ignored and all types will be
+  // monitored.
+  // If filter_type is true, only type will be monitored.
+  status_t RegisterThermalChangedCallback(
+      google_camera_hal::NotifyThrottlingFunc notify_throttling,
+      bool filter_type, google_camera_hal::TemperatureType type);
+
+  // Unregister thermal changed callback.
+  void UnregisterThermalChangedCallback();
+
+  std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session_;
+
+  // Metadata queue to read the request metadata from.
+  std::unique_ptr<MetadataQueue> request_metadata_queue_;
+
+  // Metadata queue to write the result metadata to.
+  std::unique_ptr<MetadataQueue> result_metadata_queue_;
+
+  // Assuming callbacks to framework is thread-safe, the shared mutex is only
+  // used to protect member variable writing and reading.
+  std::shared_mutex aidl_device_callback_lock_;
+  // Protected by aidl_device_callback_lock_
+  std::shared_ptr<ICameraDeviceCallback> aidl_device_callback_;
+
+  sp<android::hardware::graphics::mapper::V2_0::IMapper> buffer_mapper_v2_;
+  sp<android::hardware::graphics::mapper::V3_0::IMapper> buffer_mapper_v3_;
+  sp<android::hardware::graphics::mapper::V4_0::IMapper> buffer_mapper_v4_;
+
+  std::mutex hidl_thermal_mutex_;
+  sp<android::hardware::thermal::V2_0::IThermal> thermal_;
+
+  // Must be protected by hidl_thermal_mutex_.
+  sp<android::hardware::thermal::V2_0::IThermalChangedCallback>
+      thermal_changed_callback_;
+
+  // Flag for profiling first frame processing time.
+  bool first_frame_requested_ = false;
+
+  // The frame number of first capture request after configure stream
+  uint32_t first_request_frame_number_ = 0;
+
+  std::mutex pending_first_frame_buffers_mutex_;
+  // Profiling first frame process time. Stop timer when it become 0.
+  // Must be protected by pending_first_frame_buffers_mutex_
+  size_t num_pending_first_frame_buffers_ = 0;
+
+  std::shared_ptr<AidlProfiler> aidl_profiler_;
+};
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_DEVICE_SESSION_H_
diff --git a/common/hal/aidl_service/aidl_camera_provider.cc b/common/hal/aidl_service/aidl_camera_provider.cc
new file mode 100644
index 0000000..7eac3f2
--- /dev/null
+++ b/common/hal/aidl_service/aidl_camera_provider.cc
@@ -0,0 +1,397 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GCH_AidlCameraProvider"
+//#define LOG_NDEBUG 0
+#include "aidl_camera_provider.h"
+
+#include <log/log.h>
+
+#include <regex>
+
+#include "aidl_camera_device.h"
+#include "aidl_utils.h"
+#include "camera_device.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace implementation {
+
+namespace aidl_utils = ::android::hardware::camera::implementation::aidl_utils;
+
+using aidl::android::hardware::camera::common::CameraDeviceStatus;
+using aidl::android::hardware::camera::common::Status;
+using aidl::android::hardware::camera::common::TorchModeStatus;
+using aidl::android::hardware::camera::common::VendorTagSection;
+using ::android::google_camera_hal::CameraDevice;
+
+const std::string AidlCameraProvider::kProviderName = "internal";
+// "device@<version>/internal/<id>"
+const std::regex AidlCameraProvider::kDeviceNameRegex(
+    "device@([0-9]+\\.[0-9]+)/internal/(.+)");
+
+std::shared_ptr<AidlCameraProvider> AidlCameraProvider::Create() {
+  std::shared_ptr<AidlCameraProvider> provider =
+      ndk::SharedRefBase::make<AidlCameraProvider>();
+
+  status_t res = provider->Initialize();
+  if (res != OK) {
+    ALOGE("%s: Initializing AidlCameraProvider failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return nullptr;
+  }
+
+  return provider;
+}
+
+status_t AidlCameraProvider::Initialize() {
+  google_camera_provider_ = CameraProvider::Create();
+  if (google_camera_provider_ == nullptr) {
+    ALOGE("%s: Creating CameraProvider failed.", __FUNCTION__);
+    return NO_INIT;
+  }
+
+  camera_provider_callback_ = {
+      .camera_device_status_change = google_camera_hal::CameraDeviceStatusChangeFunc(
+          [this](std::string camera_id,
+                 google_camera_hal::CameraDeviceStatus new_status) {
+            if (callbacks_ == nullptr) {
+              ALOGE("%s: callbacks_ is null", __FUNCTION__);
+              return;
+            }
+            CameraDeviceStatus aidl_camera_device_status;
+            status_t res = aidl_utils::ConvertToAidlCameraDeviceStatus(
+                new_status, &aidl_camera_device_status);
+            if (res != OK) {
+              ALOGE(
+                  "%s: Converting to aidl camera device status failed: %s(%d)",
+                  __FUNCTION__, strerror(-res), res);
+              return;
+            }
+
+            std::unique_lock<std::mutex> lock(callbacks_lock_);
+            auto aidl_res = callbacks_->cameraDeviceStatusChange(
+                "device@" +
+                    device::implementation::AidlCameraDevice::kDeviceVersion +
+                    "/" + kProviderName + "/" + camera_id,
+                aidl_camera_device_status);
+            if (!aidl_res.isOk()) {
+              ALOGE("%s: device status change transaction error: %s",
+                    __FUNCTION__, aidl_res.getMessage());
+              return;
+            }
+          }),
+      .physical_camera_device_status_change =
+          google_camera_hal::PhysicalCameraDeviceStatusChangeFunc(
+              [this](std::string camera_id, std::string physical_camera_id,
+                     google_camera_hal::CameraDeviceStatus new_status) {
+                if (callbacks_ == nullptr) {
+                  ALOGE("%s: callbacks_ is null", __FUNCTION__);
+                  return;
+                }
+                /*auto castResult =
+                    provider::V2_6::ICameraProviderCallback::castFrom(callbacks_);
+                if (!castResult.isOk()) {
+                  ALOGE("%s: callbacks_ cannot be casted to version 2.6",
+                        __FUNCTION__);
+                  return;
+                }
+                sp<provider::V2_6::ICameraProviderCallback> callbacks_2_6_ =
+                    castResult;
+                if (callbacks_2_6_ == nullptr) {
+                  ALOGE("%s: callbacks_2_6_ is null", __FUNCTION__);
+                  return;
+                }*/
+
+                CameraDeviceStatus aidl_camera_device_status;
+                status_t res = aidl_utils::ConvertToAidlCameraDeviceStatus(
+                    new_status, &aidl_camera_device_status);
+                if (res != OK) {
+                  ALOGE(
+                      "%s: Converting to aidl camera device status failed: "
+                      "%s(%d)",
+                      __FUNCTION__, strerror(-res), res);
+                  return;
+                }
+
+                std::unique_lock<std::mutex> lock(callbacks_lock_);
+                auto aidl_res = callbacks_->physicalCameraDeviceStatusChange(
+                    "device@" +
+                        device::implementation::AidlCameraDevice::kDeviceVersion +
+                        "/" + kProviderName + "/" + camera_id,
+                    physical_camera_id, aidl_camera_device_status);
+                if (!aidl_res.isOk()) {
+                  ALOGE(
+                      "%s: physical camera status change transaction error: %s",
+                      __FUNCTION__, aidl_res.getMessage());
+                  return;
+                }
+              }),
+      .torch_mode_status_change = google_camera_hal::TorchModeStatusChangeFunc(
+          [this](std::string camera_id,
+                 google_camera_hal::TorchModeStatus new_status) {
+            if (callbacks_ == nullptr) {
+              ALOGE("%s: callbacks_ is null", __FUNCTION__);
+              return;
+            }
+
+            TorchModeStatus aidl_torch_status;
+            status_t res = aidl_utils::ConvertToAidlTorchModeStatus(
+                new_status, &aidl_torch_status);
+            if (res != OK) {
+              ALOGE("%s: Converting to aidl torch status failed: %s(%d)",
+                    __FUNCTION__, strerror(-res), res);
+              return;
+            }
+
+            std::unique_lock<std::mutex> lock(callbacks_lock_);
+            auto aidl_res = callbacks_->torchModeStatusChange(
+                "device@" +
+                    device::implementation::AidlCameraDevice::kDeviceVersion +
+                    "/" + kProviderName + "/" + camera_id,
+                aidl_torch_status);
+            if (!aidl_res.isOk()) {
+              ALOGE("%s: torch status change transaction error: %s",
+                    __FUNCTION__, aidl_res.getMessage());
+              return;
+            }
+          }),
+  };
+
+  google_camera_provider_->SetCallback(&camera_provider_callback_);
+  // purge pending malloc pages after initialization
+  mallopt(M_PURGE, 0);
+  return OK;
+}
+
+ScopedAStatus AidlCameraProvider::setCallback(
+    const std::shared_ptr<ICameraProviderCallback>& callback) {
+  if (callback == nullptr) {
+    ALOGE("AidlCameraProvider::setCallback() called with nullptr");
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+
+  bool first_time = false;
+  {
+    std::unique_lock<std::mutex> lock(callbacks_lock_);
+    first_time = callbacks_ == nullptr;
+    callbacks_ = callback;
+  }
+  google_camera_provider_->TriggerDeferredCallbacks();
+#ifdef __ANDROID_APEX__
+  if (first_time) {
+    std::string ready_property_name = "vendor.camera.hal.ready.count";
+    int ready_count = property_get_int32(ready_property_name.c_str(), 0);
+    property_set(ready_property_name.c_str(),
+                 std::to_string(++ready_count).c_str());
+    ALOGI("AidlCameraProvider::setCallback() first time ready count: %d ",
+          ready_count);
+  }
+#endif
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraProvider::getVendorTags(
+    std::vector<VendorTagSection>* vts) {
+  if (vts == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  vts->clear();
+  std::vector<google_camera_hal::VendorTagSection> hal_vendor_tag_sections;
+
+  status_t res =
+      google_camera_provider_->GetVendorTags(&hal_vendor_tag_sections);
+  if (res != OK) {
+    ALOGE("%s: Getting vendor tags failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  res = aidl_utils::ConvertToAidlVendorTagSections(hal_vendor_tag_sections, vts);
+  if (res != OK) {
+    ALOGE("%s: Converting to aidl vendor tags failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraProvider::getCameraIdList(
+    std::vector<std::string>* camera_ids_ret) {
+  if (camera_ids_ret == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  camera_ids_ret->clear();
+  std::vector<uint32_t> camera_ids;
+  status_t res = google_camera_provider_->GetCameraIdList(&camera_ids);
+  if (res != OK) {
+    ALOGE("%s: Getting camera ID list failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+
+  camera_ids_ret->resize(camera_ids.size());
+  for (uint32_t i = 0; i < camera_ids_ret->size(); i++) {
+    // camera ID is in the form of "device@<major>.<minor>/<type>/<id>"
+    (*camera_ids_ret)[i] =
+        "device@" + device::implementation::AidlCameraDevice::kDeviceVersion +
+        "/" + kProviderName + "/" + std::to_string(camera_ids[i]);
+  }
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraProvider::getConcurrentCameraIds(
+    std::vector<ConcurrentCameraIdCombination>* aidl_camera_id_combinations) {
+  if (aidl_camera_id_combinations == nullptr) {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+  aidl_camera_id_combinations->clear();
+  std::vector<std::unordered_set<uint32_t>> camera_id_combinations;
+  status_t res = google_camera_provider_->GetConcurrentStreamingCameraIds(
+      &camera_id_combinations);
+  if (res != OK) {
+    ALOGE(
+        "%s: Getting the combinations of concurrent streaming camera ids "
+        "failed: %s(%d)",
+        __FUNCTION__, strerror(-res), res);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+  aidl_camera_id_combinations->resize(camera_id_combinations.size());
+  int i = 0;
+  for (auto& combination : camera_id_combinations) {
+    std::vector<std::string> aidl_combination(combination.size());
+    int c = 0;
+    for (auto& camera_id : combination) {
+      aidl_combination[c] = std::to_string(camera_id);
+      c++;
+    }
+    (*aidl_camera_id_combinations)[i].combination = aidl_combination;
+    i++;
+  }
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraProvider::isConcurrentStreamCombinationSupported(
+    const std::vector<CameraIdAndStreamCombination>& configs, bool* supported) {
+  *supported = false;
+  std::vector<google_camera_hal::CameraIdAndStreamConfiguration>
+      devices_stream_configs(configs.size());
+  status_t res = OK;
+  size_t c = 0;
+  for (auto& config : configs) {
+    res = aidl_utils::ConvertToHalStreamConfig(
+        config.streamConfiguration,
+        &devices_stream_configs[c].stream_configuration);
+    if (res != OK) {
+      ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
+      return ScopedAStatus::fromServiceSpecificError(
+          static_cast<int32_t>(Status::INTERNAL_ERROR));
+    }
+    uint32_t camera_id = atoi(config.cameraId.c_str());
+    devices_stream_configs[c].camera_id = camera_id;
+    c++;
+  }
+  res = google_camera_provider_->IsConcurrentStreamCombinationSupported(
+      devices_stream_configs, supported);
+  if (res != OK) {
+    ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+  return ScopedAStatus::ok();
+}
+
+bool AidlCameraProvider::ParseDeviceName(const std::string& device_name,
+                                         std::string* device_version,
+                                         std::string* camera_id) {
+  std::string device_name_std(device_name.c_str());
+  std::smatch sm;
+
+  if (std::regex_match(device_name_std, sm,
+                       AidlCameraProvider::kDeviceNameRegex)) {
+    if (device_version != nullptr) {
+      *device_version = sm[1];
+    }
+    if (camera_id != nullptr) {
+      *camera_id = sm[2];
+    }
+    return true;
+  }
+  return false;
+}
+
+ScopedAStatus AidlCameraProvider::getCameraDeviceInterface(
+    const std::string& camera_device_name,
+    std::shared_ptr<ICameraDevice>* device) {
+  std::unique_ptr<CameraDevice> google_camera_device;
+  if (device == nullptr) {
+    ALOGE("%s: device is nullptr. ", __FUNCTION__);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+
+  // Parse camera_device_name.
+  std::string camera_id, device_version;
+
+  bool match = ParseDeviceName(camera_device_name, &device_version, &camera_id);
+  if (!match) {
+    ALOGE("%s: Device name parse fail. ", __FUNCTION__);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+  }
+
+  status_t res = google_camera_provider_->CreateCameraDevice(
+      atoi(camera_id.c_str()), &google_camera_device);
+  if (res != OK) {
+    ALOGE("%s: Creating CameraDevice failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return aidl_utils::ConvertToAidlReturn(res);
+  }
+
+  *device = device::implementation::AidlCameraDevice::Create(
+      std::move(google_camera_device));
+  if (*device == nullptr) {
+    ALOGE("%s: Creating AidlCameraDevice failed", __FUNCTION__);
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+  return ScopedAStatus::ok();
+}
+
+ScopedAStatus AidlCameraProvider::notifyDeviceStateChange(int64_t new_state) {
+  google_camera_hal::DeviceState device_state =
+      google_camera_hal::DeviceState::kNormal;
+  ::android::hardware::camera::implementation::aidl_utils::ConvertToHalDeviceState(
+      new_state, device_state);
+  google_camera_provider_->NotifyDeviceStateChange(device_state);
+  return ScopedAStatus::ok();
+}
+
+}  // namespace implementation
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/common/hal/aidl_service/aidl_camera_provider.h b/common/hal/aidl_service/aidl_camera_provider.h
new file mode 100644
index 0000000..7cd5bde
--- /dev/null
+++ b/common/hal/aidl_service/aidl_camera_provider.h
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_PROVIDER_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_PROVIDER_H_
+
+#include <aidl/android/hardware/camera/provider/BnCameraProvider.h>
+#include <aidl/android/hardware/camera/provider/ICameraProviderCallback.h>
+
+#include <regex>
+
+#include "camera_provider.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace implementation {
+
+using aidl::android::hardware::camera::common::VendorTagSection;
+using aidl::android::hardware::camera::device::ICameraDevice;
+using aidl::android::hardware::camera::provider::BnCameraProvider;
+using aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
+using aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination;
+using aidl::android::hardware::camera::provider::ICameraProviderCallback;
+
+using ::android::google_camera_hal::CameraProvider;
+using ndk::ScopedAStatus;
+
+// AidlCameraProvider implements the AIDL camera provider interface,
+// ICameraProvider, to enumerate the available individual camera devices
+// in the system, and provide updates about changes to device status.
+class AidlCameraProvider : public BnCameraProvider {
+ public:
+  static const std::string kProviderName;
+  static std::shared_ptr<AidlCameraProvider> Create();
+  virtual ~AidlCameraProvider() = default;
+
+  // Override functions in ICameraProvider.
+
+  ScopedAStatus setCallback(
+      const std::shared_ptr<ICameraProviderCallback>& callback) override;
+
+  ScopedAStatus getVendorTags(std::vector<VendorTagSection>* vts) override;
+
+  ScopedAStatus getCameraIdList(std::vector<std::string>* camera_ids) override;
+
+  ScopedAStatus getCameraDeviceInterface(
+      const std::string& in_cameraDeviceName,
+      std::shared_ptr<ICameraDevice>* device) override;
+
+  ScopedAStatus notifyDeviceStateChange(int64_t in_deviceState) override;
+
+  ScopedAStatus getConcurrentCameraIds(
+      std::vector<ConcurrentCameraIdCombination>* concurrent_camera_ids) override;
+
+  ScopedAStatus isConcurrentStreamCombinationSupported(
+      const std::vector<CameraIdAndStreamCombination>& in_configs,
+      bool* support) override;
+
+  // End of override functions in ICameraProvider.
+  AidlCameraProvider() = default;
+
+ private:
+  static const std::regex kDeviceNameRegex;
+
+  status_t Initialize();
+
+  // Parse device version and camera ID.
+  bool ParseDeviceName(const std::string& device_name,
+                       std::string* device_version, std::string* camera_id);
+
+  std::mutex callbacks_lock_;
+  std::shared_ptr<ICameraProviderCallback> callbacks_;
+
+  std::unique_ptr<CameraProvider> google_camera_provider_;
+  google_camera_hal::CameraProviderCallback camera_provider_callback_;
+};
+
+}  // namespace implementation
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_CAMERA_PROVIDER_H_
diff --git a/common/hal/hidl_service/hidl_profiler.cc b/common/hal/aidl_service/aidl_profiler.cc
similarity index 79%
rename from common/hal/hidl_service/hidl_profiler.cc
rename to common/hal/aidl_service/aidl_profiler.cc
index 7bb8027..5c7e90d 100644
--- a/common/hal/hidl_service/hidl_profiler.cc
+++ b/common/hal/aidl_service/aidl_profiler.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -15,9 +15,9 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "GCH_HidlProfiler"
+#define LOG_TAG "GCH_AidlProfiler"
 
-#include "hidl_profiler.h"
+#include "aidl_profiler.h"
 
 #include <log/log.h>
 
@@ -46,25 +46,31 @@
 constexpr char kIdleString[] = "<-- IDLE -->";
 constexpr char kOverall[] = "Overall";
 
-class HidlProfilerImpl : public HidlProfiler {
+class AidlProfilerImpl : public AidlProfiler {
  public:
-  HidlProfilerImpl(uint32_t camera_id, int32_t latency_flag, int32_t fps_flag)
+  AidlProfilerImpl(uint32_t camera_id, int32_t latency_flag, int32_t fps_flag)
       : camera_id_string_("Cam" + std::to_string(camera_id)),
         camera_id_(camera_id),
         latency_flag_(latency_flag),
         fps_flag_(fps_flag) {
   }
 
-  std::unique_ptr<HidlScopedProfiler> MakeScopedProfiler(
-      ScopedType type) override {
+  std::unique_ptr<AidlScopedProfiler> MakeScopedProfiler(
+      ScopedType type,
+      std::unique_ptr<google::camera_common::Profiler> custom_latency_profiler,
+      std::unique_ptr<google::camera_common::Profiler> custom_fps_profiler)
+      override {
     std::lock_guard lock(api_mutex_);
-
     if (type == ScopedType::kConfigureStream && fps_profiler_ == nullptr) {
-      fps_profiler_ = CreateFpsProfiler();
+      if (SetFpsProfiler(std::move(custom_fps_profiler)) == false) {
+        fps_profiler_ = CreateFpsProfiler();
+      }
     }
 
     if (latency_profiler_ == nullptr) {
-      latency_profiler_ = CreateLatencyProfiler();
+      if (SetLatencyProfiler(std::move(custom_latency_profiler)) == false) {
+        latency_profiler_ = CreateLatencyProfiler();
+      }
       if (latency_profiler_ != nullptr) {
         has_camera_open_ = false;
         config_count_ = 0;
@@ -105,7 +111,7 @@
         ALOGE("%s: Unknown type %d", __FUNCTION__, type);
         return nullptr;
     }
-    return std::make_unique<HidlScopedProfiler>(
+    return std::make_unique<AidlScopedProfiler>(
         latency_profiler_, name, id, [this, type]() {
           std::lock_guard lock(api_mutex_);
           if (type == ScopedType::kClose) {
@@ -141,33 +147,6 @@
     }
   }
 
-  void SetLatencyProfiler(std::unique_ptr<Profiler> profiler) override {
-    if (profiler == nullptr || latency_profiler_ == nullptr) {
-      return;
-    }
-    latency_profiler_ = std::move(profiler);
-    if (latency_profiler_ != nullptr) {
-      latency_profiler_->SetDumpFilePrefix(
-          "/data/vendor/camera/profiler/hidl_open_close_");
-      latency_profiler_->Start(kOverall, Profiler::kInvalidRequestId);
-      has_camera_open_ = false;
-      config_count_ = 0;
-      flush_count_ = 0;
-      idle_count_ = 0;
-    }
-  }
-
-  void SetFpsProfiler(std::unique_ptr<Profiler> profiler) override {
-    if (profiler == nullptr || fps_profiler_ == nullptr) {
-      return;
-    }
-    fps_profiler_ = std::move(profiler);
-    if (fps_profiler_ != nullptr) {
-      fps_profiler_->SetDumpFilePrefix(
-          "/data/vendor/camera/profiler/hidl_fps_");
-    }
-  }
-
  private:
   std::shared_ptr<Profiler> CreateLatencyProfiler() {
     if (latency_flag_ == Profiler::SetPropFlag::kDisable) {
@@ -179,7 +158,7 @@
       return nullptr;
     }
     profiler->SetDumpFilePrefix(
-        "/data/vendor/camera/profiler/hidl_open_close_");
+        "/data/vendor/camera/profiler/aidl_open_close_");
     profiler->Start(kOverall, Profiler::kInvalidRequestId);
     return profiler;
   }
@@ -193,7 +172,7 @@
       ALOGE("%s: Failed to create profiler", __FUNCTION__);
       return nullptr;
     }
-    profiler->SetDumpFilePrefix("/data/vendor/camera/profiler/hidl_fps_");
+    profiler->SetDumpFilePrefix("/data/vendor/camera/profiler/aidl_fps_");
     return profiler;
   }
 
@@ -226,6 +205,33 @@
     return fps_flag_;
   }
 
+  bool SetLatencyProfiler(std::unique_ptr<Profiler> profiler) {
+    if (profiler == nullptr) {
+      return false;
+    }
+    latency_profiler_ = std::move(profiler);
+    if (latency_profiler_ != nullptr) {
+      latency_profiler_->SetDumpFilePrefix(
+          "/data/vendor/camera/profiler/aidl_open_close_");
+      latency_profiler_->Start(kOverall, Profiler::kInvalidRequestId);
+      return true;
+    }
+    return false;
+  }
+
+  bool SetFpsProfiler(std::unique_ptr<Profiler> profiler) {
+    if (profiler == nullptr) {
+      return false;
+    }
+    fps_profiler_ = std::move(profiler);
+    if (fps_profiler_ != nullptr) {
+      fps_profiler_->SetDumpFilePrefix(
+          "/data/vendor/camera/profiler/aidl_fps_");
+      return true;
+    }
+    return false;
+  }
+
   const std::string camera_id_string_;
   const uint32_t camera_id_;
   const int32_t latency_flag_;
@@ -242,27 +248,16 @@
   uint8_t idle_count_;
 };
 
-class HidlProfilerMock : public HidlProfiler {
-  std::unique_ptr<HidlScopedProfiler> MakeScopedProfiler(ScopedType) override {
+class AidlProfilerMock : public AidlProfiler {
+  std::unique_ptr<AidlScopedProfiler> MakeScopedProfiler(
+      ScopedType, std::unique_ptr<google::camera_common::Profiler>,
+      std::unique_ptr<google::camera_common::Profiler>) override {
     return nullptr;
   }
 
-  void FirstFrameStart() override {
-  }
-
-  void FirstFrameEnd() override {
-  }
-
-  void ProfileFrameRate(const std::string&) override {
-  }
-
-  void SetLatencyProfiler(
-      std::unique_ptr<google::camera_common::Profiler> /* profiler */) override {
-  }
-
-  void SetFpsProfiler(
-      std::unique_ptr<google::camera_common::Profiler> /* profiler */) override {
-  }
+  void FirstFrameStart() override{};
+  void FirstFrameEnd() override{};
+  void ProfileFrameRate(const std::string&) override{};
 
   uint32_t GetCameraId() const override {
     return 0;
@@ -277,14 +272,14 @@
 
 }  // anonymous namespace
 
-std::shared_ptr<HidlProfiler> HidlProfiler::Create(uint32_t camera_id) {
+std::shared_ptr<AidlProfiler> AidlProfiler::Create(uint32_t camera_id) {
   int32_t latency_flag = property_get_int32(
       kPropKeyProfileOpenClose, Profiler::SetPropFlag::kCustomProfiler);
   int32_t fps_flag = property_get_int32(kPropKeyProfileFps,
                                         Profiler::SetPropFlag::kCustomProfiler);
   if (latency_flag == Profiler::SetPropFlag::kDisable &&
       fps_flag == Profiler::SetPropFlag::kDisable) {
-    return std::make_shared<HidlProfilerMock>();
+    return std::make_shared<AidlProfilerMock>();
   }
   // Use stopwatch flag to print result.
   if ((latency_flag & Profiler::SetPropFlag::kPrintBit) != 0) {
@@ -295,10 +290,10 @@
     fps_flag |= Profiler::SetPropFlag::kPrintFpsPerIntervalBit;
     fps_flag &= ~Profiler::SetPropFlag::kPrintBit;
   }
-  return std::make_shared<HidlProfilerImpl>(camera_id, latency_flag, fps_flag);
+  return std::make_shared<AidlProfilerImpl>(camera_id, latency_flag, fps_flag);
 }
 
-HidlScopedProfiler::HidlScopedProfiler(std::shared_ptr<Profiler> profiler,
+AidlScopedProfiler::AidlScopedProfiler(std::shared_ptr<Profiler> profiler,
                                        const std::string name, int id,
                                        std::function<void()> end_callback)
     : profiler_(profiler),
@@ -309,7 +304,7 @@
   profiler_->Start(kHalTotal, Profiler::kInvalidRequestId);
 }
 
-HidlScopedProfiler::~HidlScopedProfiler() {
+AidlScopedProfiler::~AidlScopedProfiler() {
   profiler_->End(kHalTotal, Profiler::kInvalidRequestId);
   profiler_->End(name_, id_);
   if (end_callback_) {
diff --git a/common/hal/hidl_service/hidl_profiler.h b/common/hal/aidl_service/aidl_profiler.h
similarity index 63%
rename from common/hal/hidl_service/hidl_profiler.h
rename to common/hal/aidl_service/aidl_profiler.h
index 131a0c3..1491056 100644
--- a/common/hal/hidl_service/hidl_profiler.h
+++ b/common/hal/aidl_service/aidl_profiler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_PROFILER_H_
-#define HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_PROFILER_H_
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_PROFILER_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_PROFILER_H_
 
 #include <memory>
 
@@ -26,13 +26,13 @@
 namespace camera {
 namespace implementation {
 
-class HidlScopedProfiler {
+class AidlScopedProfiler {
  public:
-  HidlScopedProfiler(std::shared_ptr<google::camera_common::Profiler> profiler,
+  AidlScopedProfiler(std::shared_ptr<google::camera_common::Profiler> profiler,
                      const std::string name, int id,
                      std::function<void()> end_callback);
 
-  ~HidlScopedProfiler();
+  ~AidlScopedProfiler();
 
  private:
   std::shared_ptr<google::camera_common::Profiler> profiler_;
@@ -41,7 +41,7 @@
   std::function<void()> end_callback_;
 };
 
-class HidlProfiler {
+class AidlProfiler {
  public:
   enum class ScopedType {
     kOpen,
@@ -49,13 +49,15 @@
     kFlush,
     kClose,
   };
-  virtual ~HidlProfiler() = default;
+  virtual ~AidlProfiler() = default;
 
-  static std::shared_ptr<HidlProfiler> Create(uint32_t camera_id);
+  static std::shared_ptr<AidlProfiler> Create(uint32_t camera_id);
 
   // Make a ScopedProfiler for given type.
-  virtual std::unique_ptr<HidlScopedProfiler> MakeScopedProfiler(
-      ScopedType type) = 0;
+  virtual std::unique_ptr<AidlScopedProfiler> MakeScopedProfiler(
+      ScopedType type,
+      std::unique_ptr<google::camera_common::Profiler> custom_latency_profiler,
+      std::unique_ptr<google::camera_common::Profiler> custom_fps_profiler) = 0;
 
   // Call when first frame is requested.
   virtual void FirstFrameStart() = 0;
@@ -66,20 +68,12 @@
   // Call to profile frame rate for each stream.
   virtual void ProfileFrameRate(const std::string& name) = 0;
 
-  // Give a customized latency profiler so that client side can intercept various calls.
-  virtual void SetLatencyProfiler(
-      std::unique_ptr<google::camera_common::Profiler> profiler) = 0;
-
-  // Give a customized fps profiler so that client side can intercept various calls.
-  virtual void SetFpsProfiler(
-      std::unique_ptr<google::camera_common::Profiler> profiler) = 0;
-
   virtual uint32_t GetCameraId() const = 0;
   virtual int32_t GetLatencyFlag() const = 0;
   virtual int32_t GetFpsFlag() const = 0;
 
  protected:
-  HidlProfiler() = default;
+  AidlProfiler() = default;
 };
 
 }  // namespace implementation
@@ -87,4 +81,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_PROFILER_H_
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_PROFILER_H_
diff --git a/common/hal/hidl_service/service.cc b/common/hal/aidl_service/aidl_service.cc
similarity index 65%
rename from common/hal/hidl_service/service.cc
rename to common/hal/aidl_service/aidl_service.cc
index 630869e..91f52b1 100644
--- a/common/hal/hidl_service/service.cc
+++ b/common/hal/aidl_service/aidl_service.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -20,21 +20,23 @@
 #define LOG_TAG "android.hardware.pixel.camera.provider@2.7-service"
 #endif
 
-#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
+#include <aidl/android/hardware/camera/provider/ICameraProvider.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
 #include <apex_update_listener.h>
 #include <binder/ProcessState.h>
-#include <cinttypes>
 #include <cutils/properties.h>
-#include <hidl/HidlLazyUtils.h>
 #include <hidl/HidlTransportSupport.h>
 #include <malloc.h>
 #include <utils/Errors.h>
 
-#include "hidl_camera_build_version.h"
-#include "hidl_camera_provider.h"
+#include <cinttypes>
 
-using ::android::hardware::camera::provider::V2_7::ICameraProvider;
-using ::android::hardware::camera::provider::V2_7::implementation::HidlCameraProvider;
+#include "aidl_camera_build_version.h"
+#include "aidl_camera_provider.h"
+
+using aidl::android::hardware::camera::provider::ICameraProvider;
+using ::android::hardware::camera::provider::implementation::AidlCameraProvider;
 
 #ifdef LAZY_SERVICE
 const bool kLazyService = true;
@@ -42,6 +44,8 @@
 const bool kLazyService = false;
 #endif
 
+const std::string kProviderInstance = "/internal/0";
+
 int main() {
   ALOGI("Google camera provider service is starting.");
   // The camera HAL may communicate to other vendor components via
@@ -51,6 +55,11 @@
   android::hardware::configureRpcThreadpool(/*maxThreads=*/6,
                                             /*callerWillJoin=*/true);
 
+  // Don't depend on vndbinder setting up threads in case we stop using them
+  // some day
+  ABinderProcess_setThreadPoolMaxThreadCount(6);
+  ABinderProcess_startThreadPool();
+
 #ifdef __ANDROID_APEX__
   int start_count = property_get_int32("vendor.camera.hal.start.count", 0);
   property_set("vendor.camera.hal.start.count",
@@ -72,25 +81,27 @@
   ALOGI("Not using ApexUpdateListener since not running in an apex.");
 #endif
 
-  android::sp<ICameraProvider> camera_provider = HidlCameraProvider::Create();
+  std::shared_ptr<ICameraProvider> camera_provider =
+      AidlCameraProvider::Create();
   if (camera_provider == nullptr) {
     return android::NO_INIT;
   }
+  std::string instance =
+      std::string() + AidlCameraProvider::descriptor + kProviderInstance;
   if (kLazyService) {
-    android::hardware::LazyServiceRegistrar& lazy_registrar =
-        android::hardware::LazyServiceRegistrar::getInstance();
-    if (lazy_registrar.registerService(camera_provider, "internal/0") !=
-        android::OK) {
-      ALOGE("Cannot register Google camera provider lazy service");
+    if (AServiceManager_registerLazyService(camera_provider->asBinder().get(),
+                                            instance.c_str()) != STATUS_OK) {
+      ALOGE("Cannot register AIDL Google camera provider lazy service");
       return android::NO_INIT;
     }
   } else {
-    if (camera_provider->registerAsService("internal/0") != android::OK) {
-      ALOGE("Cannot register Google camera provider service");
+    if (AServiceManager_addService(camera_provider->asBinder().get(),
+                                   instance.c_str()) != STATUS_OK) {
+      ALOGE("Cannot register AIDL Google camera provider service");
       return android::NO_INIT;
     }
   }
-  android::hardware::joinRpcThreadpool();
+  ABinderProcess_joinThreadPool();
 
   // In normal operation, the threadpool should never return.
   return EXIT_FAILURE;
diff --git a/common/hal/aidl_service/aidl_utils.cc b/common/hal/aidl_service/aidl_utils.cc
new file mode 100644
index 0000000..b5a4028
--- /dev/null
+++ b/common/hal/aidl_service/aidl_utils.cc
@@ -0,0 +1,1133 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GCH_AidlUtils"
+//#define LOG_NDEBUG 0
+#include "aidl_utils.h"
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <log/log.h>
+
+#include <regex>
+
+#include "aidl_camera_device.h"
+#include "aidl_camera_provider.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace implementation {
+namespace aidl_utils {
+
+using AidlCameraProvider = provider::implementation::AidlCameraProvider;
+using AidlCameraDevice = device::implementation::AidlCameraDevice;
+using AidlStatus = aidl::android::hardware::camera::common::Status;
+
+ScopedAStatus ConvertToAidlReturn(status_t hal_status) {
+  switch (hal_status) {
+    case OK:
+      return ScopedAStatus::ok();
+    case BAD_VALUE:
+      return ScopedAStatus::fromServiceSpecificError(
+          static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
+    case -EBUSY:
+      return ScopedAStatus::fromServiceSpecificError(
+          static_cast<int32_t>(Status::CAMERA_IN_USE));
+    case -EUSERS:
+      return ScopedAStatus::fromServiceSpecificError(
+          static_cast<int32_t>(Status::MAX_CAMERAS_IN_USE));
+    case UNKNOWN_TRANSACTION:
+    case INVALID_OPERATION:
+      return ScopedAStatus::fromServiceSpecificError(
+          static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED));
+    case DEAD_OBJECT:
+      return ScopedAStatus::fromServiceSpecificError(
+          static_cast<int32_t>(Status::CAMERA_DISCONNECTED));
+    default:
+      return ScopedAStatus::fromServiceSpecificError(
+          static_cast<int32_t>(Status::INTERNAL_ERROR));
+  }
+}
+
+status_t ConvertToAidlVendorTagType(
+    google_camera_hal::CameraMetadataType hal_type,
+    CameraMetadataType* aidl_type) {
+  if (aidl_type == nullptr) {
+    ALOGE("%s: aidl_type is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (hal_type) {
+    case google_camera_hal::CameraMetadataType::kByte:
+      *aidl_type = CameraMetadataType::BYTE;
+      break;
+    case google_camera_hal::CameraMetadataType::kInt32:
+      *aidl_type = CameraMetadataType::INT32;
+      break;
+    case google_camera_hal::CameraMetadataType::kFloat:
+      *aidl_type = CameraMetadataType::FLOAT;
+      break;
+    case google_camera_hal::CameraMetadataType::kInt64:
+      *aidl_type = CameraMetadataType::INT64;
+      break;
+    case google_camera_hal::CameraMetadataType::kDouble:
+      *aidl_type = CameraMetadataType::DOUBLE;
+      break;
+    case google_camera_hal::CameraMetadataType::kRational:
+      *aidl_type = CameraMetadataType::RATIONAL;
+      break;
+    default:
+      ALOGE("%s: Unknown google_camera_hal::CameraMetadataType: %u",
+            __FUNCTION__, hal_type);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToAidlVendorTagSections(
+    const std::vector<google_camera_hal::VendorTagSection>& hal_sections,
+    std::vector<VendorTagSection>* aidl_sections) {
+  if (aidl_sections == nullptr) {
+    ALOGE("%s: aidl_sections is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  aidl_sections->resize(hal_sections.size());
+  for (uint32_t i = 0; i < hal_sections.size(); i++) {
+    (*aidl_sections)[i].sectionName = hal_sections[i].section_name;
+    (*aidl_sections)[i].tags.resize(hal_sections[i].tags.size());
+
+    for (uint32_t j = 0; j < hal_sections[i].tags.size(); j++) {
+      (*aidl_sections)[i].tags[j].tagId = hal_sections[i].tags[j].tag_id;
+      (*aidl_sections)[i].tags[j].tagName = hal_sections[i].tags[j].tag_name;
+      status_t res =
+          ConvertToAidlVendorTagType(hal_sections[i].tags[j].tag_type,
+                                     &(*aidl_sections)[i].tags[j].tagType);
+      if (res != OK) {
+        ALOGE("%s: Converting to aidl vendor tag type failed. ", __FUNCTION__);
+        return res;
+      }
+    }
+  }
+  return OK;
+}
+
+status_t ConvertToAidlResourceCost(
+    const google_camera_hal::CameraResourceCost& hal_cost,
+    CameraResourceCost* aidl_cost) {
+  if (aidl_cost == nullptr) {
+    ALOGE("%s: aidl_cost is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  aidl_cost->resourceCost = hal_cost.resource_cost;
+  aidl_cost->conflictingDevices.resize(hal_cost.conflicting_devices.size());
+
+  for (uint32_t i = 0; i < hal_cost.conflicting_devices.size(); i++) {
+    aidl_cost->conflictingDevices[i] =
+        "device@" + AidlCameraDevice::kDeviceVersion + "/" +
+        AidlCameraProvider::kProviderName + "/" +
+        std::to_string(hal_cost.conflicting_devices[i]);
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalTemplateType(
+    RequestTemplate aidl_template,
+    google_camera_hal::RequestTemplate* hal_template) {
+  if (hal_template == nullptr) {
+    ALOGE("%s: hal_template is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (aidl_template) {
+    case RequestTemplate::PREVIEW:
+      *hal_template = google_camera_hal::RequestTemplate::kPreview;
+      break;
+    case RequestTemplate::STILL_CAPTURE:
+      *hal_template = google_camera_hal::RequestTemplate::kStillCapture;
+      break;
+    case RequestTemplate::VIDEO_RECORD:
+      *hal_template = google_camera_hal::RequestTemplate::kVideoRecord;
+      break;
+    case RequestTemplate::VIDEO_SNAPSHOT:
+      *hal_template = google_camera_hal::RequestTemplate::kVideoSnapshot;
+      break;
+    case RequestTemplate::ZERO_SHUTTER_LAG:
+      *hal_template = google_camera_hal::RequestTemplate::kZeroShutterLag;
+      break;
+    case RequestTemplate::MANUAL:
+      *hal_template = google_camera_hal::RequestTemplate::kManual;
+      break;
+    default:
+      ALOGE("%s: Unknown AIDL RequestTemplate: %u", __FUNCTION__, aidl_template);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToAidlHalStreamConfig(
+    const std::vector<google_camera_hal::HalStream>& hal_configured_streams,
+    std::vector<HalStream>* aidl_hal_streams) {
+  if (aidl_hal_streams == nullptr) {
+    ALOGE("%s: aidl_hal_streams is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  aidl_hal_streams->resize(hal_configured_streams.size());
+
+  for (uint32_t i = 0; i < hal_configured_streams.size(); i++) {
+    auto& dst = (*aidl_hal_streams)[i];
+    dst.supportOffline = false;
+    if (hal_configured_streams[i].is_physical_camera_stream) {
+      dst.physicalCameraId =
+          std::to_string(hal_configured_streams[i].physical_camera_id);
+    }
+
+    dst.overrideDataSpace =
+        static_cast<aidl::android::hardware::graphics::common::Dataspace>(
+            hal_configured_streams[i].override_data_space);
+
+    dst.id = hal_configured_streams[i].id;
+
+    dst.overrideFormat =
+        static_cast<aidl::android::hardware::graphics::common::PixelFormat>(
+            hal_configured_streams[i].override_format);
+
+    dst.producerUsage =
+        static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+            hal_configured_streams[i].producer_usage);
+
+    dst.consumerUsage =
+        static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+            hal_configured_streams[i].consumer_usage);
+
+    dst.maxBuffers = hal_configured_streams[i].max_buffers;
+  }
+
+  return OK;
+}
+
+status_t WriteToResultMetadataQueue(
+    camera_metadata_t* metadata,
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* result_metadata_queue) {
+  if (result_metadata_queue == nullptr) {
+    return BAD_VALUE;
+  }
+
+  if (result_metadata_queue->availableToWrite() <= 0) {
+    ALOGW("%s: result_metadata_queue is not available to write", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  uint32_t size = get_camera_metadata_size(metadata);
+  bool success = result_metadata_queue->write(
+      reinterpret_cast<const int8_t*>(metadata), size);
+  if (!success) {
+    ALOGW("%s: Writing to result metadata queue failed. (size=%u)",
+          __FUNCTION__, size);
+    return INVALID_OPERATION;
+  }
+
+  return OK;
+}
+
+// Try writing result metadata to result metadata queue. If failed, return
+// the metadata to the caller in out_hal_metadata.
+status_t TryWritingToResultMetadataQueue(
+    std::unique_ptr<google_camera_hal::HalCameraMetadata> hal_metadata,
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* result_metadata_queue,
+    uint64_t* fmq_result_size,
+    std::unique_ptr<google_camera_hal::HalCameraMetadata>* out_hal_metadata) {
+  if (out_hal_metadata == nullptr) {
+    ALOGE("%s: out_hal_metadata is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  *out_hal_metadata = std::move(hal_metadata);
+
+  if (fmq_result_size == nullptr) {
+    ALOGE("%s: fmq_result_size is nullptr", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  *fmq_result_size = 0;
+  if (*out_hal_metadata == nullptr) {
+    return OK;
+  }
+
+  camera_metadata_t* metadata = (*out_hal_metadata)->ReleaseCameraMetadata();
+  // Temporarily use the raw metadata to write to metadata queue.
+  status_t res = WriteToResultMetadataQueue(metadata, result_metadata_queue);
+  *out_hal_metadata = google_camera_hal::HalCameraMetadata::Create(metadata);
+
+  if (res != OK) {
+    ALOGW("%s: Writing to result metadata queue failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  *fmq_result_size = (*out_hal_metadata)->GetCameraMetadataSize();
+  *out_hal_metadata = nullptr;
+  return OK;
+}
+
+status_t ConvertToAidlResultMetadata(
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* result_metadata_queue,
+    std::unique_ptr<google_camera_hal::HalCameraMetadata> hal_metadata,
+    std::vector<uint8_t>* aidl_metadata, uint64_t* fmq_result_size) {
+  if (TryWritingToResultMetadataQueue(std::move(hal_metadata),
+                                      result_metadata_queue, fmq_result_size,
+                                      &hal_metadata) == OK) {
+    return OK;
+  }
+
+  // If writing to metadata queue failed, attach the metadata to aidl_metadata.
+  if (aidl_metadata == nullptr) {
+    ALOGE("%s: aidl_metadata is nullptr", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  uint32_t metadata_size = hal_metadata->GetCameraMetadataSize();
+  uint8_t* metadata_p =
+      reinterpret_cast<uint8_t*>(hal_metadata->ReleaseCameraMetadata());
+  // TODO: Do we reallly need to copy here ?
+  aidl_metadata->assign(metadata_p, metadata_p + metadata_size);
+
+  return OK;
+}
+
+status_t ConvertToAidlBufferStatus(google_camera_hal::BufferStatus hal_status,
+                                   BufferStatus* aidl_status) {
+  if (aidl_status == nullptr) {
+    ALOGE("%s: aidl_status is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (hal_status) {
+    case google_camera_hal::BufferStatus::kOk:
+      *aidl_status = BufferStatus::OK;
+      break;
+    case google_camera_hal::BufferStatus::kError:
+      *aidl_status = BufferStatus::ERROR;
+      break;
+    default:
+      ALOGE("%s: Unknown HAL buffer status: %u", __FUNCTION__, hal_status);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+aidl::android::hardware::common::NativeHandle makeToAidlIfNotNull(
+    const native_handle_t* nh) {
+  if (nh == nullptr) {
+    return aidl::android::hardware::common::NativeHandle();
+  }
+  return makeToAidl(nh);
+}
+
+status_t ConvertToAidlStreamBuffer(
+    const google_camera_hal::StreamBuffer& hal_buffer,
+    StreamBuffer* aidl_buffer) {
+  if (aidl_buffer == nullptr) {
+    ALOGE("%s: aidl_buffer is nullptr", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  aidl_buffer->streamId = hal_buffer.stream_id;
+  aidl_buffer->bufferId = hal_buffer.buffer_id;
+  aidl_buffer->buffer = aidl::android::hardware::common::NativeHandle();
+
+  status_t res =
+      ConvertToAidlBufferStatus(hal_buffer.status, &aidl_buffer->status);
+  if (res != OK) {
+    ALOGE("%s: Converting to AIDL buffer status failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  aidl_buffer->acquireFence = aidl::android::hardware::common::NativeHandle();
+  aidl_buffer->releaseFence = makeToAidlIfNotNull(hal_buffer.release_fence);
+  return OK;
+}
+
+status_t ConvertToAidlCaptureResultInternal(
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* result_metadata_queue,
+    google_camera_hal::CaptureResult* hal_result, CaptureResult* aidl_result) {
+  if (aidl_result == nullptr) {
+    ALOGE("%s: aidl_result is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  if (hal_result == nullptr) {
+    ALOGE("%s: hal_result is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  aidl_result->frameNumber = hal_result->frame_number;
+
+  status_t res = ConvertToAidlResultMetadata(
+      result_metadata_queue, std::move(hal_result->result_metadata),
+      &aidl_result->result.metadata, (uint64_t*)&aidl_result->fmqResultSize);
+  if (res != OK) {
+    ALOGE("%s: Converting to AIDL result metadata failed: %s(%d).",
+          __FUNCTION__, strerror(-res), res);
+    return res;
+  }
+
+  aidl_result->outputBuffers.resize(hal_result->output_buffers.size());
+  for (uint32_t i = 0; i < aidl_result->outputBuffers.size(); i++) {
+    res = ConvertToAidlStreamBuffer(hal_result->output_buffers[i],
+                                    &aidl_result->outputBuffers[i]);
+    if (res != OK) {
+      ALOGE("%s: Converting to AIDL output stream buffer failed: %s(%d)",
+            __FUNCTION__, strerror(-res), res);
+      return res;
+    }
+  }
+
+  uint32_t num_input_buffers = hal_result->input_buffers.size();
+  if (num_input_buffers > 0) {
+    if (num_input_buffers > 1) {
+      ALOGW("%s: HAL result should not have more than 1 input buffer. (=%u)",
+            __FUNCTION__, num_input_buffers);
+    }
+
+    res = ConvertToAidlStreamBuffer(hal_result->input_buffers[0],
+                                    &aidl_result->inputBuffer);
+    if (res != OK) {
+      ALOGE("%s: Converting to AIDL input stream buffer failed: %s(%d)",
+            __FUNCTION__, strerror(-res), res);
+      return res;
+    }
+  } else {
+    aidl_result->inputBuffer.streamId = -1;
+  }
+
+  aidl_result->partialResult = hal_result->partial_result;
+  return OK;
+}
+
+status_t ConvertToAidlCaptureResult(
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* result_metadata_queue,
+    std::unique_ptr<google_camera_hal::CaptureResult> hal_result,
+    CaptureResult* aidl_result) {
+  if (aidl_result == nullptr) {
+    ALOGE("%s: aidl_result is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  if (hal_result == nullptr) {
+    ALOGE("%s: hal_result is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  status_t res = ConvertToAidlCaptureResultInternal(
+      result_metadata_queue, hal_result.get(), aidl_result);
+  if (res != OK) {
+    ALOGE("%s: Converting to AIDL result internal failed: %s(%d).",
+          __FUNCTION__, strerror(-res), res);
+    return res;
+  }
+
+  uint32_t num_physical_metadata = hal_result->physical_metadata.size();
+  aidl_result->physicalCameraMetadata.resize(num_physical_metadata);
+
+  for (uint32_t i = 0; i < num_physical_metadata; i++) {
+    aidl_result->physicalCameraMetadata[i].physicalCameraId =
+        std::to_string(hal_result->physical_metadata[i].physical_camera_id);
+
+    res = ConvertToAidlResultMetadata(
+        result_metadata_queue,
+        std::move(hal_result->physical_metadata[i].metadata),
+        &aidl_result->physicalCameraMetadata[i].metadata.metadata,
+        (uint64_t*)&aidl_result->physicalCameraMetadata[i].fmqMetadataSize);
+    if (res != OK) {
+      ALOGE("%s: Converting to AIDL physical metadata failed: %s(%d).",
+            __FUNCTION__, strerror(-res), res);
+      return res;
+    }
+  }
+
+  return OK;
+}
+
+status_t ConvertToAidlErrorMessage(
+    const google_camera_hal::ErrorMessage& hal_error, NotifyMsg* aidl_msg) {
+  using Tag = aidl::android::hardware::camera::device::NotifyMsg::Tag;
+  if (aidl_msg == nullptr) {
+    ALOGE("%s: aidl_msg is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  ErrorMsg aidl_error;
+  aidl_error.frameNumber = hal_error.frame_number;
+  aidl_error.errorStreamId = hal_error.error_stream_id;
+
+  switch (hal_error.error_code) {
+    case google_camera_hal::ErrorCode::kErrorDevice:
+      aidl_error.errorCode = ErrorCode::ERROR_DEVICE;
+      break;
+    case google_camera_hal::ErrorCode::kErrorRequest:
+      aidl_error.errorCode = ErrorCode::ERROR_REQUEST;
+      break;
+    case google_camera_hal::ErrorCode::kErrorResult:
+      aidl_error.errorCode = ErrorCode::ERROR_RESULT;
+      break;
+    case google_camera_hal::ErrorCode::kErrorBuffer:
+      aidl_error.errorCode = ErrorCode::ERROR_BUFFER;
+      break;
+    default:
+      ALOGE("%s: Unknown error code: %u", __FUNCTION__, hal_error.error_code);
+      return BAD_VALUE;
+  }
+  aidl_msg->set<Tag::error>(aidl_error);
+  return OK;
+}
+
+status_t ConvertToAidlShutterMessage(
+    const google_camera_hal::ShutterMessage& hal_shutter, NotifyMsg* aidl_msg) {
+  using Tag = aidl::android::hardware::camera::device::NotifyMsg::Tag;
+  if (aidl_msg == nullptr) {
+    ALOGE("%s: aidl_msg is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+  ShutterMsg aidl_shutter;
+  aidl_shutter.frameNumber = hal_shutter.frame_number;
+  aidl_shutter.timestamp = hal_shutter.timestamp_ns;
+  aidl_shutter.readoutTimestamp = hal_shutter.readout_timestamp_ns;
+  aidl_msg->set<Tag::shutter>(aidl_shutter);
+  return OK;
+}
+
+status_t ConverToAidlNotifyMessage(
+    const google_camera_hal::NotifyMessage& hal_message,
+    NotifyMsg* aidl_message) {
+  if (aidl_message == nullptr) {
+    ALOGE("%s: aidl_message is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  status_t res;
+  switch (hal_message.type) {
+    case google_camera_hal::MessageType::kError:
+      res = ConvertToAidlErrorMessage(hal_message.message.error, aidl_message);
+      if (res != OK) {
+        ALOGE("%s: Converting to AIDL error message failed: %s(%d)",
+              __FUNCTION__, strerror(-res), res);
+        return res;
+      }
+      break;
+    case google_camera_hal::MessageType::kShutter:
+      res = ConvertToAidlShutterMessage(hal_message.message.shutter,
+                                        aidl_message);
+      if (res != OK) {
+        ALOGE("%s: Converting to AIDL shutter message failed: %s(%d)",
+              __FUNCTION__, strerror(-res), res);
+        return res;
+      }
+      break;
+    default:
+      ALOGE("%s: Unknown message type: %u", __FUNCTION__, hal_message.type);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToAidlCameraDeviceStatus(
+    google_camera_hal::CameraDeviceStatus hal_camera_device_status,
+    CameraDeviceStatus* aidl_camera_device_status) {
+  if (aidl_camera_device_status == nullptr) {
+    ALOGE("%s: aidl_camera_device_status is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (hal_camera_device_status) {
+    case google_camera_hal::CameraDeviceStatus::kNotPresent:
+      *aidl_camera_device_status = CameraDeviceStatus::NOT_PRESENT;
+      break;
+    case google_camera_hal::CameraDeviceStatus::kPresent:
+      *aidl_camera_device_status = CameraDeviceStatus::PRESENT;
+      break;
+    case google_camera_hal::CameraDeviceStatus::kEnumerating:
+      *aidl_camera_device_status = CameraDeviceStatus::ENUMERATING;
+      break;
+    default:
+      ALOGE("%s: Unknown HAL camera device status: %u", __FUNCTION__,
+            hal_camera_device_status);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToAidlTorchModeStatus(
+    google_camera_hal::TorchModeStatus hal_torch_status,
+    TorchModeStatus* aidl_torch_status) {
+  if (aidl_torch_status == nullptr) {
+    ALOGE("%s: aidl_torch_status is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (hal_torch_status) {
+    case google_camera_hal::TorchModeStatus::kNotAvailable:
+      *aidl_torch_status = TorchModeStatus::NOT_AVAILABLE;
+      break;
+    case google_camera_hal::TorchModeStatus::kAvailableOff:
+      *aidl_torch_status = TorchModeStatus::AVAILABLE_OFF;
+      break;
+    case google_camera_hal::TorchModeStatus::kAvailableOn:
+      *aidl_torch_status = TorchModeStatus::AVAILABLE_ON;
+      break;
+    default:
+      ALOGE("%s: Unknown HAL torch mode status: %u", __FUNCTION__,
+            hal_torch_status);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToAidlBufferRequest(
+    const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
+    std::vector<BufferRequest>* aidl_buffer_requests) {
+  if (aidl_buffer_requests == nullptr) {
+    ALOGE("%s: aidl_buffer_request is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  aidl_buffer_requests->resize(hal_buffer_requests.size());
+  for (uint32_t i = 0; i < hal_buffer_requests.size(); i++) {
+    (*aidl_buffer_requests)[i].streamId = hal_buffer_requests[i].stream_id;
+    (*aidl_buffer_requests)[i].numBuffersRequested =
+        hal_buffer_requests[i].num_buffers_requested;
+  }
+  return OK;
+}
+
+status_t ConvertToHalBufferStatus(BufferStatus aidl_status,
+                                  google_camera_hal::BufferStatus* hal_status) {
+  if (hal_status == nullptr) {
+    ALOGE("%s: hal_status is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (aidl_status) {
+    case BufferStatus::OK:
+      *hal_status = google_camera_hal::BufferStatus::kOk;
+      break;
+    case BufferStatus::ERROR:
+      *hal_status = google_camera_hal::BufferStatus::kError;
+      break;
+    default:
+      ALOGE("%s: Unknown AIDL buffer status: %u", __FUNCTION__, aidl_status);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+bool IsAidlNativeHandleNull(const NativeHandle& handle) {
+  return (handle.fds.size() == 0 && handle.ints.size() == 0);
+}
+
+native_handle_t* makeFromAidlIfNotNull(const NativeHandle& handle) {
+  if (IsAidlNativeHandleNull(handle)) {
+    return nullptr;
+  }
+  return makeFromAidl(handle);
+}
+
+// We have a handles_to_delete parameter since makeFromAidl creates a
+// native_handle_t
+status_t ConvertToHalStreamBuffer(
+    const StreamBuffer& aidl_buffer, google_camera_hal::StreamBuffer* hal_buffer,
+    std::vector<native_handle_t*>* handles_to_delete) {
+  if (hal_buffer == nullptr || handles_to_delete == nullptr) {
+    ALOGE("%s: hal_buffer / handles_to_delete is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  hal_buffer->stream_id = aidl_buffer.streamId;
+  hal_buffer->buffer_id = aidl_buffer.bufferId;
+  native_handle_t* buf_handle = makeFromAidlIfNotNull(aidl_buffer.buffer);
+  hal_buffer->buffer = buf_handle;
+  if (buf_handle != nullptr) {
+    handles_to_delete->emplace_back(buf_handle);
+  }
+
+  status_t res =
+      ConvertToHalBufferStatus(aidl_buffer.status, &hal_buffer->status);
+  if (res != OK) {
+    ALOGE("%s: Converting to HAL buffer status failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  native_handle_t* acquire_handle =
+      makeFromAidlIfNotNull(aidl_buffer.acquireFence);
+  native_handle_t* release_handle =
+      makeFromAidlIfNotNull(aidl_buffer.releaseFence);
+  hal_buffer->acquire_fence = acquire_handle;
+  hal_buffer->release_fence = release_handle;
+  if (acquire_handle != nullptr) {
+    handles_to_delete->emplace_back(acquire_handle);
+  }
+
+  if (release_handle != nullptr) {
+    handles_to_delete->emplace_back(release_handle);
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalMetadata(
+    uint32_t message_queue_setting_size,
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* request_metadata_queue,
+    const std::vector<uint8_t>& request_settings,
+    std::unique_ptr<google_camera_hal::HalCameraMetadata>* hal_metadata) {
+  if (hal_metadata == nullptr) {
+    ALOGE("%s: hal_metadata is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  const camera_metadata_t* metadata = nullptr;
+  std::vector<int8_t> metadata_queue_settings;
+
+  if (message_queue_setting_size == 0) {
+    // Use the settings in the request.
+    if (request_settings.size() != 0) {
+      metadata =
+          reinterpret_cast<const camera_metadata_t*>(request_settings.data());
+    }
+  } else {
+    // Read the settings from request metadata queue.
+    if (request_metadata_queue == nullptr) {
+      ALOGE("%s: request_metadata_queue is nullptr", __FUNCTION__);
+      return BAD_VALUE;
+    }
+
+    metadata_queue_settings.resize(message_queue_setting_size);
+    bool success = request_metadata_queue->read(metadata_queue_settings.data(),
+                                                message_queue_setting_size);
+    if (!success) {
+      ALOGE("%s: Failed to read from request metadata queue.", __FUNCTION__);
+      return BAD_VALUE;
+    }
+
+    metadata = reinterpret_cast<const camera_metadata_t*>(
+        metadata_queue_settings.data());
+  }
+
+  if (metadata == nullptr) {
+    *hal_metadata = nullptr;
+    return OK;
+  }
+
+  *hal_metadata = google_camera_hal::HalCameraMetadata::Clone(metadata);
+  return OK;
+}
+
+status_t ConvertToHalCaptureRequest(
+    const CaptureRequest& aidl_request,
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* request_metadata_queue,
+    google_camera_hal::CaptureRequest* hal_request,
+    std::vector<native_handle_t*>* handles_to_delete) {
+  if (hal_request == nullptr) {
+    ALOGE("%s: hal_request is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  hal_request->frame_number = aidl_request.frameNumber;
+
+  status_t res = ConvertToHalMetadata(
+      aidl_request.fmqSettingsSize, request_metadata_queue,
+      aidl_request.settings.metadata, &hal_request->settings);
+  if (res != OK) {
+    ALOGE("%s: Converting metadata failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  google_camera_hal::StreamBuffer hal_buffer = {};
+  if (!IsAidlNativeHandleNull(aidl_request.inputBuffer.buffer)) {
+    res = ConvertToHalStreamBuffer(aidl_request.inputBuffer, &hal_buffer,
+                                   handles_to_delete);
+    if (res != OK) {
+      ALOGE("%s: Converting hal stream buffer failed: %s(%d)", __FUNCTION__,
+            strerror(-res), res);
+      return res;
+    }
+
+    hal_request->input_buffers.push_back(hal_buffer);
+    hal_request->input_width = aidl_request.inputWidth;
+    hal_request->input_height = aidl_request.inputHeight;
+  }
+
+  for (auto& buffer : aidl_request.outputBuffers) {
+    hal_buffer = {};
+    status_t res =
+        ConvertToHalStreamBuffer(buffer, &hal_buffer, handles_to_delete);
+    if (res != OK) {
+      ALOGE("%s: Converting hal stream buffer failed: %s(%d)", __FUNCTION__,
+            strerror(-res), res);
+      return res;
+    }
+
+    hal_request->output_buffers.push_back(hal_buffer);
+  }
+
+  for (auto aidl_physical_settings : aidl_request.physicalCameraSettings) {
+    std::unique_ptr<google_camera_hal::HalCameraMetadata> hal_physical_settings;
+    res = ConvertToHalMetadata(
+        aidl_physical_settings.fmqSettingsSize, request_metadata_queue,
+        aidl_physical_settings.settings.metadata, &hal_physical_settings);
+    if (res != OK) {
+      ALOGE("%s: Converting to HAL metadata failed: %s(%d)", __FUNCTION__,
+            strerror(-res), res);
+      return res;
+    }
+
+    uint32_t camera_id = std::stoul(aidl_physical_settings.physicalCameraId);
+    hal_request->physical_camera_settings.emplace(
+        camera_id, std::move(hal_physical_settings));
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalBufferCaches(
+    const std::vector<BufferCache>& aidl_buffer_caches,
+    std::vector<google_camera_hal::BufferCache>* hal_buffer_caches) {
+  if (hal_buffer_caches == nullptr) {
+    ALOGE("%s: hal_buffer_caches is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  for (auto aidl_cache : aidl_buffer_caches) {
+    google_camera_hal::BufferCache hal_cache;
+    hal_cache.stream_id = aidl_cache.streamId;
+    hal_cache.buffer_id = aidl_cache.bufferId;
+
+    hal_buffer_caches->push_back(hal_cache);
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalStreamConfigurationMode(
+    StreamConfigurationMode aidl_mode,
+    google_camera_hal::StreamConfigurationMode* hal_mode) {
+  if (hal_mode == nullptr) {
+    ALOGE("%s: hal_mode is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (aidl_mode) {
+    case StreamConfigurationMode::NORMAL_MODE:
+      *hal_mode = google_camera_hal::StreamConfigurationMode::kNormal;
+      break;
+    case StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE:
+      *hal_mode =
+          google_camera_hal::StreamConfigurationMode::kConstrainedHighSpeed;
+      break;
+    default:
+      ALOGE("%s: Unknown configuration mode %u", __FUNCTION__, aidl_mode);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+static bool sensorPixelModeContains(const Stream& aidl_stream, uint32_t key) {
+  using aidl::android::hardware::camera::metadata::SensorPixelMode;
+  for (auto& i : aidl_stream.sensorPixelModesUsed) {
+    if (i == static_cast<SensorPixelMode>(key)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+status_t ConvertToHalStreamConfig(
+    const StreamConfiguration& aidl_stream_config,
+    google_camera_hal::StreamConfiguration* hal_stream_config) {
+  if (hal_stream_config == nullptr) {
+    ALOGE("%s: hal_stream_config is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  status_t res;
+
+  for (auto aidl_stream : aidl_stream_config.streams) {
+    google_camera_hal::Stream hal_stream;
+    res = ConvertToHalStream(aidl_stream, &hal_stream);
+    if (res != OK) {
+      ALOGE("%s: Converting to HAL stream failed: %s(%d)", __FUNCTION__,
+            strerror(-res), res);
+      return res;
+    }
+    hal_stream_config->streams.push_back(hal_stream);
+  }
+
+  res = ConvertToHalStreamConfigurationMode(aidl_stream_config.operationMode,
+                                            &hal_stream_config->operation_mode);
+  if (res != OK) {
+    ALOGE("%s: Converting to HAL opeation mode failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  res = ConvertToHalMetadata(0, nullptr,
+                             aidl_stream_config.sessionParams.metadata,
+                             &hal_stream_config->session_params);
+  if (res != OK) {
+    ALOGE("%s: Converting to HAL metadata failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  hal_stream_config->stream_config_counter =
+      aidl_stream_config.streamConfigCounter;
+  hal_stream_config->multi_resolution_input_image =
+      aidl_stream_config.multiResolutionInputImage;
+
+  return OK;
+}
+
+status_t ConvertToHalStreamType(StreamType aidl_stream_type,
+                                google_camera_hal::StreamType* hal_stream_type) {
+  if (hal_stream_type == nullptr) {
+    ALOGE("%s: hal_stream_type is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (aidl_stream_type) {
+    case StreamType::OUTPUT:
+      *hal_stream_type = google_camera_hal::StreamType::kOutput;
+      break;
+    case StreamType::INPUT:
+      *hal_stream_type = google_camera_hal::StreamType::kInput;
+      break;
+    default:
+      ALOGE("%s: Unknown stream type: %u", __FUNCTION__, aidl_stream_type);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalStreamRotation(
+    StreamRotation aidl_stream_rotation,
+    google_camera_hal::StreamRotation* hal_stream_rotation) {
+  if (hal_stream_rotation == nullptr) {
+    ALOGE("%s: hal_stream_rotation is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (aidl_stream_rotation) {
+    case StreamRotation::ROTATION_0:
+      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation0;
+      break;
+    case StreamRotation::ROTATION_90:
+      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation90;
+      break;
+    case StreamRotation::ROTATION_180:
+      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation180;
+      break;
+    case StreamRotation::ROTATION_270:
+      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation270;
+      break;
+    default:
+      ALOGE("%s: Unknown stream rotation: %u", __FUNCTION__,
+            aidl_stream_rotation);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalStream(const Stream& aidl_stream,
+                            google_camera_hal::Stream* hal_stream) {
+  if (hal_stream == nullptr) {
+    ALOGE("%s: hal_stream is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  *hal_stream = {};
+
+  hal_stream->id = aidl_stream.id;
+
+  status_t res =
+      ConvertToHalStreamType(aidl_stream.streamType, &hal_stream->stream_type);
+  if (res != OK) {
+    ALOGE("%s: Converting to HAL stream type failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  hal_stream->width = aidl_stream.width;
+  hal_stream->height = aidl_stream.height;
+  hal_stream->format = (android_pixel_format_t)aidl_stream.format;
+  hal_stream->usage = (uint64_t)aidl_stream.usage;
+  hal_stream->data_space = (android_dataspace_t)aidl_stream.dataSpace;
+
+  res = ConvertToHalStreamRotation(aidl_stream.rotation, &hal_stream->rotation);
+  if (res != OK) {
+    ALOGE("%s: Converting to HAL stream rotation failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  if (aidl_stream.physicalCameraId.empty()) {
+    hal_stream->is_physical_camera_stream = false;
+  } else {
+    hal_stream->is_physical_camera_stream = true;
+    hal_stream->physical_camera_id = std::stoul(aidl_stream.physicalCameraId);
+  }
+
+  hal_stream->buffer_size = aidl_stream.bufferSize;
+  hal_stream->group_id = aidl_stream.groupId;
+
+  hal_stream->used_in_max_resolution_mode = sensorPixelModeContains(
+      aidl_stream, ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
+  hal_stream->used_in_default_resolution_mode =
+      aidl_stream.sensorPixelModesUsed.size() > 0
+          ? sensorPixelModeContains(aidl_stream,
+                                    ANDROID_SENSOR_PIXEL_MODE_DEFAULT)
+          : true;
+  hal_stream->dynamic_profile = static_cast<
+      camera_metadata_enum_android_request_available_dynamic_range_profiles_map>(
+      aidl_stream.dynamicRangeProfile);
+
+  hal_stream->use_case =
+      static_cast<camera_metadata_enum_android_scaler_available_stream_use_cases>(
+          aidl_stream.useCase);
+
+  return OK;
+}
+
+status_t ConvertToHalBufferRequestStatus(
+    const BufferRequestStatus& aidl_buffer_request_status,
+    google_camera_hal::BufferRequestStatus* hal_buffer_request_status) {
+  if (hal_buffer_request_status == nullptr) {
+    ALOGE("%s: hal_buffer_request_status is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  switch (aidl_buffer_request_status) {
+    case BufferRequestStatus::OK:
+      *hal_buffer_request_status = google_camera_hal::BufferRequestStatus::kOk;
+      break;
+    case BufferRequestStatus::FAILED_PARTIAL:
+      *hal_buffer_request_status =
+          google_camera_hal::BufferRequestStatus::kFailedPartial;
+      break;
+    case BufferRequestStatus::FAILED_CONFIGURING:
+      *hal_buffer_request_status =
+          google_camera_hal::BufferRequestStatus::kFailedConfiguring;
+      break;
+    case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS:
+      *hal_buffer_request_status =
+          google_camera_hal::BufferRequestStatus::kFailedIllegalArgs;
+      break;
+    case BufferRequestStatus::FAILED_UNKNOWN:
+      *hal_buffer_request_status =
+          google_camera_hal::BufferRequestStatus::kFailedUnknown;
+      break;
+    default:
+      ALOGE("%s: Failed unknown buffer request error code %d", __FUNCTION__,
+            aidl_buffer_request_status);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalBufferReturnStatus(
+    const StreamBufferRet& aidl_stream_buffer_return,
+    google_camera_hal::BufferReturn* hal_buffer_return) {
+  using Tag = aidl::android::hardware::camera::device::StreamBuffersVal::Tag;
+  if (hal_buffer_return == nullptr) {
+    ALOGE("%s: hal_buffer_return is nullptr.", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  if (aidl_stream_buffer_return.val.getTag() == Tag::error) {
+    switch (aidl_stream_buffer_return.val.get<Tag::error>()) {
+      case StreamBufferRequestError::NO_BUFFER_AVAILABLE:
+        hal_buffer_return->val.error =
+            google_camera_hal::StreamBufferRequestError::kNoBufferAvailable;
+        break;
+      case StreamBufferRequestError::MAX_BUFFER_EXCEEDED:
+        hal_buffer_return->val.error =
+            google_camera_hal::StreamBufferRequestError::kMaxBufferExceeded;
+        break;
+      case StreamBufferRequestError::STREAM_DISCONNECTED:
+        hal_buffer_return->val.error =
+            google_camera_hal::StreamBufferRequestError::kStreamDisconnected;
+        break;
+      case StreamBufferRequestError::UNKNOWN_ERROR:
+        hal_buffer_return->val.error =
+            google_camera_hal::StreamBufferRequestError::kUnknownError;
+        break;
+      default:
+        ALOGE("%s: Unknown StreamBufferRequestError %d", __FUNCTION__,
+              aidl_stream_buffer_return.val.get<Tag::error>());
+        return BAD_VALUE;
+    }
+  } else {
+    hal_buffer_return->val.error =
+        google_camera_hal::StreamBufferRequestError::kOk;
+  }
+
+  return OK;
+}
+
+status_t ConvertToHalDeviceState(
+    int64_t aidl_device_state,
+    google_camera_hal::DeviceState& hal_device_state) {
+  switch (aidl_device_state) {
+    case ICameraProvider::DEVICE_STATE_NORMAL:
+      hal_device_state = google_camera_hal::DeviceState::kNormal;
+      break;
+    case ICameraProvider::DEVICE_STATE_BACK_COVERED:
+      hal_device_state = google_camera_hal::DeviceState::kBackCovered;
+      break;
+    case ICameraProvider::DEVICE_STATE_FRONT_COVERED:
+      hal_device_state = google_camera_hal::DeviceState::kFrontCovered;
+      break;
+    case ICameraProvider::DEVICE_STATE_FOLDED:
+      hal_device_state = google_camera_hal::DeviceState::kFolded;
+      break;
+    default:
+      ALOGE("%s: Failed unknown device state", __FUNCTION__);
+      return BAD_VALUE;
+  }
+
+  return OK;
+}
+
+}  // namespace aidl_utils
+}  // namespace implementation
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/common/hal/aidl_service/aidl_utils.h b/common/hal/aidl_service/aidl_utils.h
new file mode 100644
index 0000000..05873f3
--- /dev/null
+++ b/common/hal/aidl_service/aidl_utils.h
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_UTILS_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_UTILS_H_
+
+#include <aidl/android/hardware/camera/common/CameraMetadataType.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+#include <aidl/android/hardware/camera/provider/ICameraProvider.h>
+#include <aidlcommonsupport/NativeHandle.h>
+/*#include <android/hardware/camera/common/1.0/types.h>
+#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.8/types.h>*/
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/MessageQueue.h>
+#include <hal_types.h>
+
+#include <memory>
+
+#include "aidl_camera_provider.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace implementation {
+namespace aidl_utils {
+
+using aidl::android::hardware::camera::common::CameraDeviceStatus;
+using aidl::android::hardware::camera::common::CameraMetadataType;
+using aidl::android::hardware::camera::common::CameraResourceCost;
+using aidl::android::hardware::camera::common::Status;
+using aidl::android::hardware::camera::common::TorchModeStatus;
+using aidl::android::hardware::camera::common::VendorTagSection;
+using aidl::android::hardware::camera::device::BufferCache;
+using aidl::android::hardware::camera::device::BufferRequest;
+using aidl::android::hardware::camera::device::BufferRequestStatus;
+using aidl::android::hardware::camera::device::BufferStatus;
+using aidl::android::hardware::camera::device::CaptureRequest;
+using aidl::android::hardware::camera::device::CaptureResult;
+using aidl::android::hardware::camera::device::ErrorCode;
+using aidl::android::hardware::camera::device::ErrorMsg;
+using aidl::android::hardware::camera::device::HalStream;
+using aidl::android::hardware::camera::device::NotifyMsg;
+using aidl::android::hardware::camera::device::RequestTemplate;
+using aidl::android::hardware::camera::device::ShutterMsg;
+using aidl::android::hardware::camera::device::Stream;
+using aidl::android::hardware::camera::device::StreamBuffer;
+using aidl::android::hardware::camera::device::StreamBufferRequestError;
+using aidl::android::hardware::camera::device::StreamBufferRet;
+using aidl::android::hardware::camera::device::StreamBuffersVal;
+using aidl::android::hardware::camera::device::StreamConfiguration;
+using aidl::android::hardware::camera::device::StreamConfigurationMode;
+using aidl::android::hardware::camera::device::StreamRotation;
+using aidl::android::hardware::camera::device::StreamType;
+using aidl::android::hardware::camera::provider::ICameraProvider;
+using aidl::android::hardware::common::NativeHandle;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+
+using ndk::ScopedAStatus;
+
+// Util functions to convert the types between AIDL and Google Camera HAL.
+
+// Conversions from HAL to AIDL
+
+ScopedAStatus ConvertToAidlReturn(status_t hal_status);
+
+status_t ConvertToAidlVendorTagSections(
+    const std::vector<google_camera_hal::VendorTagSection>& hal_sections,
+    std::vector<VendorTagSection>* aidl_sections);
+
+status_t ConvertToAidlVendorTagType(
+    google_camera_hal::CameraMetadataType hal_type,
+    CameraMetadataType* aidl_type);
+
+status_t ConvertToAidlResourceCost(
+    const google_camera_hal::CameraResourceCost& hal_cost,
+    CameraResourceCost* aidl_cost);
+
+status_t ConvertToAidlHalStreamConfig(
+    const std::vector<google_camera_hal::HalStream>& hal_configured_streams,
+    std::vector<HalStream>* aidl_hal_stream_config);
+
+status_t ConverToAidlNotifyMessage(
+    const google_camera_hal::NotifyMessage& hal_message,
+    NotifyMsg* aidl_message);
+
+// Convert from HAL CameraDeviceStatus to AIDL CameraDeviceStatus
+// kNotPresent is converted to CameraDeviceStatus::NOT_PRESENT.
+// kPresent is converted to CameraDeviceStatus::PRESENT.
+// kEnumerating is converted to CameraDeviceStatus::ENUMERATING.
+status_t ConvertToAidlCameraDeviceStatus(
+    google_camera_hal::CameraDeviceStatus hal_camera_device_status,
+    CameraDeviceStatus* aidl_camera_device_status);
+
+// Convert from HAL TorchModeStatus to AIDL TorchModeStatus
+// kNotAvailable is converted to TorchModeStatus::NOT_AVAILABLE.
+// kAvailableOff is converted to TorchModeStatus::AVAILABLE_OFF.
+// kAvailableOn is converted to TorchModeStatus::AVAILABLE_ON.
+status_t ConvertToAidlTorchModeStatus(
+    google_camera_hal::TorchModeStatus hal_torch_status,
+    TorchModeStatus* aidl_torch_status);
+
+// Convert a HAL request to a AIDL request.
+status_t ConvertToAidlBufferRequest(
+    const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
+    std::vector<BufferRequest>* aidl_buffer_requests);
+
+status_t ConvertToHalBufferStatus(BufferStatus aidl_status,
+                                  google_camera_hal::BufferStatus* hal_status);
+
+// Convert a HAL result to a AIDL result. It will try to write the result
+// metadata to result_metadata_queue. If it fails, it will write the result
+// metadata in aidl_result.
+status_t ConvertToAidlCaptureResult(
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* result_metadata_queue,
+    std::unique_ptr<google_camera_hal::CaptureResult> hal_result,
+    CaptureResult* aidl_result);
+
+// Convert a HAL stream buffer to a AIDL aidl stream buffer.
+status_t ConvertToAidlStreamBuffer(
+    const google_camera_hal::StreamBuffer& hal_buffer,
+    StreamBuffer* aidl_buffer);
+
+// Conversions from AIDL to HAL.
+status_t ConvertToHalTemplateType(
+    RequestTemplate aidl_template,
+    google_camera_hal::RequestTemplate* hal_template);
+
+bool IsAidlNativeHandleNull(const NativeHandle& handle);
+
+status_t ConvertToHalStreamBuffer(
+    const StreamBuffer& aidl_buffer, google_camera_hal::StreamBuffer* hal_buffer,
+    std::vector<native_handle_t*>* handles_to_delete);
+
+status_t ConvertToHalMetadata(
+    uint32_t message_queue_setting_size,
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* request_metadata_queue,
+    const std::vector<uint8_t>& request_settings,
+    std::unique_ptr<google_camera_hal::HalCameraMetadata>* hal_metadata);
+
+status_t ConvertToHalCaptureRequest(
+    const CaptureRequest& aidl_request,
+    AidlMessageQueue<int8_t, SynchronizedReadWrite>* request_metadata_queue,
+    google_camera_hal::CaptureRequest* hal_request,
+    std::vector<native_handle_t*>* native_handles_to_delete);
+
+status_t ConvertToHalBufferCaches(
+    const std::vector<BufferCache>& aidl_buffer_caches,
+    std::vector<google_camera_hal::BufferCache>* hal_buffer_caches);
+
+status_t ConvertToHalStreamConfig(
+    const StreamConfiguration& aidl_stream_config,
+    google_camera_hal::StreamConfiguration* hal_stream_config);
+
+status_t ConvertToHalStreamConfigurationMode(
+    StreamConfigurationMode aidl_mode,
+    google_camera_hal::StreamConfigurationMode* hal_mode);
+
+status_t ConvertToHalStream(const Stream& aidl_stream,
+                            google_camera_hal::Stream* hal_stream);
+
+status_t ConvertToHalStreamRotation(
+    StreamRotation aidl_stream_rotation,
+    google_camera_hal::StreamRotation* hal_stream_rotation);
+
+status_t ConvertToHalStreamType(StreamType aidl_stream_type,
+                                google_camera_hal::StreamType* hal_stream_type);
+
+status_t ConvertToHalBufferRequestStatus(
+    const BufferRequestStatus& aidl_buffer_request_status,
+    google_camera_hal::BufferRequestStatus* hal_buffer_request_status);
+
+status_t ConvertToHalBufferReturnStatus(
+    const StreamBufferRet& aidl_stream_buffer_return,
+    google_camera_hal::BufferReturn* hal_buffer_return);
+
+status_t ConvertToHalDeviceState(
+    const int64_t aidl_device_state,
+    google_camera_hal::DeviceState& hal_device_state);
+
+}  // namespace aidl_utils
+}  // namespace implementation
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_AIDL_SERVICE_AIDL_UTILS_H_
diff --git a/common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google-lazy.rc b/common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google-lazy.rc
new file mode 100644
index 0000000..423a708
--- /dev/null
+++ b/common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google-lazy.rc
@@ -0,0 +1,10 @@
+service vendor.camera-provider-2-7-google /vendor/bin/hw/android.hardware.camera.provider@2.7-service-google-lazy
+    interface aidl android.hardware.camera.provider.ICameraProvider/internal/0
+    oneshot
+    disabled
+    class hal
+    user system
+    group system
+    capabilities SYS_NICE
+    rlimit rtprio 10 10
+    task_profiles CameraServiceCapacity CameraServicePerformance
diff --git a/common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google.rc b/common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google.rc
similarity index 100%
rename from common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google.rc
rename to common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google.rc
diff --git a/common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google.xml b/common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google.xml
new file mode 100644
index 0000000..5e74ac5
--- /dev/null
+++ b/common/hal/aidl_service/android.hardware.camera.provider@2.7-service-google.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.camera.provider</name>
+        <version>1</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <instance>internal/0</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/common/hal/hidl_service/hidl_thermal_utils.cc b/common/hal/aidl_service/hidl_thermal_utils.cc
similarity index 98%
rename from common/hal/hidl_service/hidl_thermal_utils.cc
rename to common/hal/aidl_service/hidl_thermal_utils.cc
index 578371b..cb2c915 100644
--- a/common/hal/hidl_service/hidl_thermal_utils.cc
+++ b/common/hal/aidl_service/hidl_thermal_utils.cc
@@ -16,17 +16,14 @@
 
 #define LOG_TAG "GCH_HidlThermalUtils"
 //#define LOG_NDEBUG 0
-#include <log/log.h>
-
 #include "hidl_thermal_utils.h"
-#include "hidl_utils.h"
+
+#include <log/log.h>
 
 namespace android {
 namespace hardware {
 namespace hidl_thermal_utils {
 
-namespace hidl_utils = ::android::hardware::camera::implementation::hidl_utils;
-
 std::unique_ptr<HidlThermalChangedCallback> HidlThermalChangedCallback::Create(
     google_camera_hal::NotifyThrottlingFunc notify_throttling) {
   auto thermal_changed_callback = std::unique_ptr<HidlThermalChangedCallback>(
diff --git a/common/hal/hidl_service/hidl_thermal_utils.h b/common/hal/aidl_service/hidl_thermal_utils.h
similarity index 100%
rename from common/hal/hidl_service/hidl_thermal_utils.h
rename to common/hal/aidl_service/hidl_thermal_utils.h
diff --git a/common/hal/hidl_service/libc_wrappers.cc b/common/hal/aidl_service/libc_wrappers.cc
similarity index 87%
rename from common/hal/hidl_service/libc_wrappers.cc
rename to common/hal/aidl_service/libc_wrappers.cc
index 45b260b..3534fa8 100644
--- a/common/hal/hidl_service/libc_wrappers.cc
+++ b/common/hal/aidl_service/libc_wrappers.cc
@@ -3,6 +3,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+
 #include <string>
 #include <unordered_map>
 
@@ -171,18 +172,24 @@
 }
 #endif
 
-using dlopen_function_type = void* (*)(const char*, int);
+using __loader_dlopen_function_type = void* (*)(const char* filename, int flags,
+                                                const void* caller_addr);
 
 // This is a temporary workaround for prebuilts calling dlopen with absolute
-// paths.
-extern "C" void* dlopen(const char* filename, int flags) {
-  static auto real_dlopen_function =
-      reinterpret_cast<dlopen_function_type>(dlsym(RTLD_NEXT, "dlopen"));
-  if (!real_dlopen_function) {
-    ALOGE("Could not RTLD_NEXT dlopen, something very wrong.");
+// paths. We interpose __loader_dlopen instead of dlopen because dlopen calls
+// __builtin_return_address to determine the linker namespace. We need
+// caller_addr to point to the original caller and not "this" lib for the case
+// of system libs that use dlopen.
+extern "C" void* __loader_dlopen(const char* filename, int flags,
+                                 const void* caller_addr) {
+  static auto real__loader_dlopen_function =
+      reinterpret_cast<__loader_dlopen_function_type>(
+          dlsym(RTLD_NEXT, "__loader_dlopen"));
+  if (!real__loader_dlopen_function) {
+    ALOGE("Could not RTLD_NEXT __loader_dlopen, something very wrong.");
     std::abort();
   }
-  void* ret = real_dlopen_function(filename, flags);
+  void* ret = real__loader_dlopen_function(filename, flags, caller_addr);
   if (!ret) {
     ALOGI("dlopen(%s) failed, seeing if we can fix it", filename);
     std::string original_filename(filename);
@@ -191,7 +198,8 @@
       std::string new_filename = "/apex/com.google.pixel.camera.hal/" +
                                  original_filename.substr(strlen("/vendor/"));
       ALOGI("Trying %s instead of %s\n", new_filename.c_str(), filename);
-      ret = real_dlopen_function(new_filename.c_str(), flags);
+      ret = real__loader_dlopen_function(new_filename.c_str(), flags,
+                                         caller_addr);
       if (ret) {
         ALOGE(
             "ERROR: Update your code to not use absolute paths. dlopen(%s) "
diff --git a/common/hal/hidl_service/version_script.py b/common/hal/aidl_service/version_script.py
similarity index 98%
rename from common/hal/hidl_service/version_script.py
rename to common/hal/aidl_service/version_script.py
index 882b85c..54c2a2f 100644
--- a/common/hal/hidl_service/version_script.py
+++ b/common/hal/aidl_service/version_script.py
@@ -20,7 +20,7 @@
 import re
 import sys
 
-BRANCH_SPECIFIC_VERSION_IDENTIFIER = 3  # sc-v2
+BRANCH_SPECIFIC_VERSION_IDENTIFIER = 6  # main
 DEFAULT_ENG_BUILD_NUMBER = 2147480000
 DEFAULT_BAD_BUILD_NUMBER = DEFAULT_ENG_BUILD_NUMBER - 1
 
diff --git a/common/hal/common/hal_types.h b/common/hal/common/hal_types.h
index 3563e94..7c18b34 100644
--- a/common/hal/common/hal_types.h
+++ b/common/hal/common/hal_types.h
@@ -106,7 +106,7 @@
 };
 
 // See the definition of
-// ::android::hardware::camera::device::V3_7::Stream;
+// ::android::hardware::camera::device::V3_8::Stream;
 struct Stream {
   int32_t id = -1;
   StreamType stream_type = StreamType::kOutput;
@@ -122,6 +122,11 @@
   int32_t group_id = -1;
   bool used_in_max_resolution_mode = false;
   bool used_in_default_resolution_mode = true;
+  camera_metadata_enum_android_request_available_dynamic_range_profiles_map
+      dynamic_profile =
+          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+  camera_metadata_enum_android_scaler_available_stream_use_cases use_case =
+      ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
 };
 
 // See the definition of
@@ -132,7 +137,7 @@
 };
 
 // See the definition of
-// ::android::hardware::camera::device::V3_7::StreamConfiguration;
+// ::android::hardware::camera::device::V3_8::StreamConfiguration;
 struct StreamConfiguration {
   std::vector<Stream> streams;
   StreamConfigurationMode operation_mode;
@@ -253,14 +258,15 @@
 };
 
 // See the definition of
-// ::android::hardware::camera::device::V3_2::ShutterMsg
+// ::android::hardware::camera::device::V3_8::ShutterMsg
 struct ShutterMessage {
   uint32_t frame_number = 0;
   uint64_t timestamp_ns = 0;
+  uint64_t readout_timestamp_ns = 0;
 };
 
 // See the definition of
-// ::android::hardware::camera::device::V3_2::NotifyMsg
+// ::android::hardware::camera::device::V3_8::NotifyMsg
 struct NotifyMessage {
   MessageType type = MessageType::kError;
 
diff --git a/common/hal/common/vendor_tag_defs.h b/common/hal/common/vendor_tag_defs.h
index eef389d..8b7c6ce 100644
--- a/common/hal/common/vendor_tag_defs.h
+++ b/common/hal/common/vendor_tag_defs.h
@@ -47,6 +47,7 @@
   kNonWarpedCropRegion,
   kHdrUsageMode,
   kSwDenoiseEnabled,
+  kVideoSwDenoiseEnabled,
   // This should not be used as a vendor tag ID on its own, but as a placeholder
   // to indicate the end of currently defined vendor tag IDs
   kEndMarker
@@ -66,7 +67,12 @@
 
   // Uses UW camera with a larger margin. In this way, we get a better video
   // stabilization quality, while preserving a similar FoV as the main camera.
-  kSuperstabMode
+  kSuperstabMode,
+
+  // Tracks an object of interest with a frame delay. For example, tracking is
+  // done at app side which is N frame later than HAL where N is the pipeline
+  // depth.
+  kDelayedTrackingMode,
 };
 
 // Logical camera vendor tags
@@ -214,6 +220,15 @@
     {.tag_id = VendorTagIds::kSwDenoiseEnabled,
      .tag_name = "SwDenoiseEnabled",
      .tag_type = CameraMetadataType::kByte},
+    // Video software denoise enabled
+    //
+    // Indicates whether the software denoise for video is enabled
+    //
+    // Present in: Characteristics
+    // Payload: VideoSwDenoiseEnabled
+    {.tag_id = VendorTagIds::kVideoSwDenoiseEnabled,
+     .tag_name = "VideoSwDenoiseEnabled",
+     .tag_type = CameraMetadataType::kByte},
 };
 
 // Google Camera HAL vendor tag sections
diff --git a/common/hal/google_camera_hal/Android.bp b/common/hal/google_camera_hal/Android.bp
index 3850283..59640ea 100644
--- a/common/hal/google_camera_hal/Android.bp
+++ b/common/hal/google_camera_hal/Android.bp
@@ -70,6 +70,7 @@
         "realtime_process_block.cc",
         "realtime_zsl_request_processor.cc",
         "realtime_zsl_result_processor.cc",
+        "realtime_zsl_result_request_processor.cc",
         "rgbird_capture_session.cc",
         "rgbird_depth_result_processor.cc",
         "rgbird_result_request_processor.cc",
@@ -96,6 +97,7 @@
     ],
     header_libs: [
         "lib_depth_generator_headers",
+        "libgooglecamerahal_headers",
     ],
     // b/129863492, clang-tidy nondeterministic seg fault
     tidy: false,
diff --git a/common/hal/google_camera_hal/camera_device.cc b/common/hal/google_camera_hal/camera_device.cc
index fba579a..55c3a41 100644
--- a/common/hal/google_camera_hal/camera_device.cc
+++ b/common/hal/google_camera_hal/camera_device.cc
@@ -167,6 +167,21 @@
     return res;
   }
 
+  std::unique_ptr<HalCameraMetadata> static_metadata;
+  res = camera_device_hwl_->GetCameraCharacteristics(&static_metadata);
+  if (res != OK) {
+    ALOGE("%s: Getting camera characteristics failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  res = utils::GetStreamUseCases(static_metadata.get(), &stream_use_cases_);
+  if (res != OK) {
+    ALOGE("%s: Getting stream use cases failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
   return OK;
 }
 
@@ -208,6 +223,23 @@
   return camera_device_hwl_->SetTorchMode(mode);
 }
 
+status_t CameraDevice::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
+  ATRACE_CALL();
+  return camera_device_hwl_->TurnOnTorchWithStrengthLevel(torch_strength);
+}
+
+status_t CameraDevice::GetTorchStrengthLevel(int32_t& torch_strength) const {
+  ATRACE_CALL();
+  status_t res = camera_device_hwl_->GetTorchStrengthLevel(torch_strength);
+  if (res != OK) {
+    ALOGE("%s: GetTorchStrengthLevel() failed: %s (%d).", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
+  return res;
+}
+
 status_t CameraDevice::DumpState(int fd) {
   ATRACE_CALL();
   return camera_device_hwl_->DumpState(fd);
@@ -247,6 +279,10 @@
 
 bool CameraDevice::IsStreamCombinationSupported(
     const StreamConfiguration& stream_config) {
+  if (!utils::IsStreamUseCaseSupported(stream_config, stream_use_cases_)) {
+    return false;
+  }
+
   bool supported =
       camera_device_hwl_->IsStreamCombinationSupported(stream_config);
   if (!supported) {
@@ -307,10 +343,7 @@
 
 std::unique_ptr<google::camera_common::Profiler> CameraDevice::GetProfiler(
     uint32_t camera_id, int option) {
-  if (option & google::camera_common::Profiler::SetPropFlag::kCustomProfiler) {
-    return camera_device_hwl_->GetProfiler(camera_id, option);
-  }
-  return nullptr;
+  return camera_device_hwl_->GetProfiler(camera_id, option);
 }
 
 }  // namespace google_camera_hal
diff --git a/common/hal/google_camera_hal/camera_device.h b/common/hal/google_camera_hal/camera_device.h
index 8edcbd7..80245f1 100644
--- a/common/hal/google_camera_hal/camera_device.h
+++ b/common/hal/google_camera_hal/camera_device.h
@@ -62,6 +62,13 @@
   // unchanged after this CameraDevice instance is destroyed.
   status_t SetTorchMode(TorchMode mode);
 
+  // Change the brightness level of the flash unit in Torch mode.
+  // If the torch is OFF and torchStrength > 0, the torch will be turned ON.
+  status_t TurnOnTorchWithStrengthLevel(int32_t torch_strength);
+
+  // Get the flash unit strength level of this camera device.
+  status_t GetTorchStrengthLevel(int32_t& torch_strength) const;
+
   // Create a CameraDeviceSession to handle capture requests. This method will
   // return ALREADY_EXISTS if previous session has not been destroyed.
   // Created CameraDeviceSession remain valid even after this CameraDevice
@@ -103,6 +110,8 @@
   std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries_;
   // Opened library handles that should be closed on destruction
   std::vector<void*> external_capture_session_lib_handles_;
+  // Stream use cases supported by this camera device
+  std::set<int64_t> stream_use_cases_;
 
   const std::vector<std::string>* configure_streams_libs_ = nullptr;
 };
diff --git a/common/hal/google_camera_hal/camera_device_session.cc b/common/hal/google_camera_hal/camera_device_session.cc
index 0b690b6..f0fb273 100644
--- a/common/hal/google_camera_hal/camera_device_session.cc
+++ b/common/hal/google_camera_hal/camera_device_session.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 #define LOG_TAG "GCH_CameraDeviceSession"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 #include "camera_device_session.h"
@@ -431,6 +431,13 @@
     return res;
   }
 
+  res = utils::GetStreamUseCases(characteristics.get(), &stream_use_cases_);
+  if (res != OK) {
+    ALOGE("%s: Initializing stream use case failed: %s(%d)", __FUNCTION__,
+          strerror(-res), res);
+    return res;
+  }
+
   res = InitializeBufferManagement(characteristics.get());
   if (res != OK) {
     ALOGE("%s: Initialize buffer management failed: %s(%d)", __FUNCTION__,
@@ -689,6 +696,15 @@
   operation_mode_ = stream_config.operation_mode;
   multi_res_reprocess_ = stream_config.multi_resolution_input_image;
 
+  // TODO: We would ideally want this to be a part of CreateCaptureSession,
+  // which internally calls IsStreamCombinationSupported. However this
+  // IsStreamCombinationSupported doesn't match the
+  // CameraDevice::IsStreamCombination. We should look at unifying the two for a
+  // potentially cleaner code-base.
+  if (!utils::IsStreamUseCaseSupported(stream_config, stream_use_cases_)) {
+    return BAD_VALUE;
+  }
+
   capture_session_ = CreateCaptureSession(
       stream_config, kWrapperCaptureSessionEntries,
       external_capture_session_entries_, kCaptureSessionEntries,
@@ -1416,6 +1432,8 @@
       }
     };
 
+    device_session_hwl_->RemoveCachedBuffers(buffer_handle_it->second);
+
     if (buffer_mapper_v4_ != nullptr) {
       free_buffer_mapper(buffer_mapper_v4_);
     } else if (buffer_mapper_v3_ != nullptr) {
@@ -1840,9 +1858,9 @@
       ALOGI("%s: stream %d, buffer request error %d", __FUNCTION__,
             buffer_return.stream_id, buffer_return.val.error);
     }
-
     pending_requests_tracker_->TrackBufferAcquisitionFailure(stream_id,
                                                              num_buffers);
+    pending_requests_tracker_->DumpStatus();
     // TODO(b/129362905): Return partial buffers.
     return UNKNOWN_ERROR;
   }
diff --git a/common/hal/google_camera_hal/camera_device_session.h b/common/hal/google_camera_hal/camera_device_session.h
index b2b0fda..768cf26 100644
--- a/common/hal/google_camera_hal/camera_device_session.h
+++ b/common/hal/google_camera_hal/camera_device_session.h
@@ -423,6 +423,9 @@
   // Protected by request_record_lock_;
   std::set<uint32_t> ignore_shutters_;
 
+  // Stream use cases supported by this camera device
+  std::set<int64_t> stream_use_cases_;
+
   static constexpr int32_t kInvalidStreamId = -1;
 
   // Whether measure the time of buffer allocation
diff --git a/common/hal/google_camera_hal/camera_provider.cc b/common/hal/google_camera_hal/camera_provider.cc
index e3f5e85..30e184d 100644
--- a/common/hal/google_camera_hal/camera_provider.cc
+++ b/common/hal/google_camera_hal/camera_provider.cc
@@ -23,6 +23,9 @@
 #include <log/log.h>
 #include <utils/Trace.h>
 
+#if !GCH_HWL_USE_DLOPEN
+#include "lyric_hwl/madvise_library_list.h"
+#endif
 #include "vendor_tag_defs.h"
 #include "vendor_tag_utils.h"
 
@@ -282,6 +285,8 @@
 #if GCH_HWL_USE_DLOPEN
   configure_streams_libs = reinterpret_cast<decltype(configure_streams_libs)>(
       dlsym(hwl_lib_handle_, "configure_streams_libraries"));
+#else
+  configure_streams_libs = &configure_streams_libraries;
 #endif
   *device =
       CameraDevice::Create(std::move(camera_device_hwl),
@@ -318,15 +323,15 @@
   }
 
   // Create the HWL camera provider
-  *camera_provider_hwl = std::unique_ptr<CameraProviderHwl>(create_hwl());
+  camera_provider_hwl->reset(create_hwl());
+#else
+  camera_provider_hwl->reset(CreateCameraProviderHwl());
+#endif
+
   if (*camera_provider_hwl == nullptr) {
     ALOGE("Error! Creating CameraProviderHwl failed");
     return UNKNOWN_ERROR;
   }
-#else
-  *camera_provider_hwl =
-      std::unique_ptr<CameraProviderHwl>(CreateCameraProviderHwl());
-#endif
 
   return OK;
 }
diff --git a/common/hal/google_camera_hal/hdrplus_capture_session.cc b/common/hal/google_camera_hal/hdrplus_capture_session.cc
index 4e05d13..9a78e6e 100644
--- a/common/hal/google_camera_hal/hdrplus_capture_session.cc
+++ b/common/hal/google_camera_hal/hdrplus_capture_session.cc
@@ -480,8 +480,8 @@
   }
 
   // Create result dispatcher
-  result_dispatcher_ =
-      ResultDispatcher::Create(kPartialResult, process_capture_result, notify);
+  result_dispatcher_ = ResultDispatcher::Create(
+      kPartialResult, process_capture_result, notify, "HdrplusDispatcher");
   if (result_dispatcher_ == nullptr) {
     ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
     return UNKNOWN_ERROR;
@@ -653,9 +653,10 @@
   }
 
   if (message.type == MessageType::kShutter) {
-    status_t res =
-        result_dispatcher_->AddShutter(message.message.shutter.frame_number,
-                                       message.message.shutter.timestamp_ns);
+    status_t res = result_dispatcher_->AddShutter(
+        message.message.shutter.frame_number,
+        message.message.shutter.timestamp_ns,
+        message.message.shutter.readout_timestamp_ns);
     if (res != OK) {
       ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
             message.message.shutter.frame_number, strerror(-res), res);
diff --git a/common/hal/google_camera_hal/hdrplus_capture_session.h b/common/hal/google_camera_hal/hdrplus_capture_session.h
index 2519541..8369196 100644
--- a/common/hal/google_camera_hal/hdrplus_capture_session.h
+++ b/common/hal/google_camera_hal/hdrplus_capture_session.h
@@ -33,7 +33,7 @@
 // process chains (realtime and HDR+)
 //
 // 1. RealtimeZslRequestProcessor -> RealtimeProcessBlock ->
-//    RealtimeZslResultProcessor
+//    RealtimeZslResultRequestProcessor
 // 2. HdrplusRequestProcessor -> HdrplusProcessBlock -> HdrplusResultProcessor
 //
 // It only supports a single physical camera device session.
diff --git a/common/hal/google_camera_hal/pending_requests_tracker.cc b/common/hal/google_camera_hal/pending_requests_tracker.cc
index 87ad722..23eae69 100644
--- a/common/hal/google_camera_hal/pending_requests_tracker.cc
+++ b/common/hal/google_camera_hal/pending_requests_tracker.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 #define LOG_TAG "GCH_PendingRequestsTracker"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 #include <log/log.h>
@@ -318,5 +318,33 @@
   stream_acquired_buffers_[overridden_stream_id] -= num_buffers;
 }
 
+void PendingRequestsTracker::DumpStatus() {
+  std::string pending_requests_string = "{";
+  {
+    std::lock_guard<std::mutex> lock(pending_requests_mutex_);
+    for (auto& [stream_id, num_pending_buffers] : stream_pending_buffers_) {
+      pending_requests_string += "{" + std::to_string(stream_id) + ": " +
+                                 std::to_string(num_pending_buffers) + "},";
+    }
+  }
+  pending_requests_string += "}";
+
+  std::string pending_acquisition_string = "{";
+  {
+    std::lock_guard<std::mutex> lock(pending_acquisition_mutex_);
+    for (auto& [stream_id, num_acquired_buffers] : stream_acquired_buffers_) {
+      pending_acquisition_string += "{" + std::to_string(stream_id) + ": " +
+                                    std::to_string(num_acquired_buffers) + "},";
+    }
+  }
+  pending_acquisition_string += "}";
+
+  ALOGI(
+      "%s: Buffers (including dummy) pending return from HWL: %s. Buffers "
+      "proactively acquired from the framework: %s.",
+      __FUNCTION__, pending_requests_string.c_str(),
+      pending_acquisition_string.c_str());
+}
+
 }  // namespace google_camera_hal
 }  // namespace android
diff --git a/common/hal/google_camera_hal/pending_requests_tracker.h b/common/hal/google_camera_hal/pending_requests_tracker.h
index cdff661..529eb6a 100644
--- a/common/hal/google_camera_hal/pending_requests_tracker.h
+++ b/common/hal/google_camera_hal/pending_requests_tracker.h
@@ -63,6 +63,9 @@
   // Notify the request tracker that the buffer cache manager has been flushed.
   void OnBufferCacheFlushed();
 
+  // Dump the buffer counting status
+  void DumpStatus();
+
   virtual ~PendingRequestsTracker() = default;
 
  protected:
diff --git a/common/hal/google_camera_hal/realtime_zsl_result_processor.cc b/common/hal/google_camera_hal/realtime_zsl_result_processor.cc
index d337f88..0475c46 100644
--- a/common/hal/google_camera_hal/realtime_zsl_result_processor.cc
+++ b/common/hal/google_camera_hal/realtime_zsl_result_processor.cc
@@ -15,16 +15,16 @@
  */
 
 //#define LOG_NDEBUG 0
+#include "hal_types.h"
 #define LOG_TAG "GCH_RealtimeZslResultProcessor"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 
-#include "realtime_zsl_result_processor.h"
-
 #include <inttypes.h>
 #include <log/log.h>
 #include <utils/Trace.h>
 
 #include "hal_utils.h"
+#include "realtime_zsl_result_processor.h"
 
 namespace android {
 namespace google_camera_hal {
@@ -249,6 +249,7 @@
       result->output_buffers.size() == 0) {
     return;
   }
+
   process_capture_result_(std::move(result));
 }
 
diff --git a/common/hal/google_camera_hal/realtime_zsl_result_processor.h b/common/hal/google_camera_hal/realtime_zsl_result_processor.h
index 3a59df2..61106e3 100644
--- a/common/hal/google_camera_hal/realtime_zsl_result_processor.h
+++ b/common/hal/google_camera_hal/realtime_zsl_result_processor.h
@@ -17,15 +17,16 @@
 #ifndef HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_REALTIME_ZSL_RESULT_PROCESSOR_H_
 #define HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_REALTIME_ZSL_RESULT_PROCESSOR_H_
 
+#include <shared_mutex>
+
 #include "internal_stream_manager.h"
 #include "result_processor.h"
 
 namespace android {
 namespace google_camera_hal {
 
-// RealtimeZslResultProcessor implements a ResultProcessor that return filled
-// raw buffer and matedata to internal stream manager and forwards the results
-// without raw buffer to its callback functions.
+// RealtimeZslResultProcessor implements a ResultProcessor that return
+// filled raw buffer and metadata to internal stream manager.
 class RealtimeZslResultProcessor : public ResultProcessor {
  public:
   static std::unique_ptr<RealtimeZslResultProcessor> Create(
@@ -42,7 +43,7 @@
       const std::vector<ProcessBlockRequest>& process_block_requests,
       const CaptureRequest& remaining_session_request) override;
 
-  // Return filled raw buffer and matedata to internal stream manager
+  // Return filled raw buffer and metadata to internal stream manager
   // and forwards the results without raw buffer to its callback functions.
   void ProcessResult(ProcessBlockResult block_result) override;
 
@@ -57,6 +58,17 @@
                              android_pixel_format_t pixel_format,
                              uint32_t partial_result_count);
 
+  InternalStreamManager* internal_stream_manager_;
+  int32_t stream_id_ = -1;
+  // Partial result count reported by HAL
+  uint32_t partial_result_count_;
+
+  std::mutex callback_lock_;
+
+  // The following callbacks must be protected by callback_lock_.
+  ProcessCaptureResultFunc process_capture_result_;
+  NotifyFunc notify_;
+
  private:
   // Save face detect mode for HDR+
   void SaveFdForHdrplus(const CaptureRequest& request);
@@ -68,14 +80,7 @@
   // Handle Lens shading metadata from result for HDR+
   status_t HandleLsResultForHdrplus(uint32_t frameNumber,
                                     HalCameraMetadata* metadata);
-  std::mutex callback_lock_;
 
-  // The following callbacks must be protected by callback_lock_.
-  ProcessCaptureResultFunc process_capture_result_;
-  NotifyFunc notify_;
-
-  InternalStreamManager* internal_stream_manager_;
-  int32_t stream_id_ = -1;
   android_pixel_format_t pixel_format_;
 
   // Current face detect mode set by framework.
@@ -97,11 +102,10 @@
   // lens_shading_lock_
   std::unordered_map<uint32_t, uint8_t> requested_lens_shading_map_modes_;
 
-  // Partial result count reported by HAL
-  uint32_t partial_result_count_;
+  std::shared_mutex process_block_shared_lock_;
 };
 
 }  // namespace google_camera_hal
 }  // namespace android
 
-#endif  // HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_REALTIME_ZSL_RESULT_PROCESSOR_H_
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_REALTIME_ZSL_RESULT_REQUEST_PROCESSOR_H_
diff --git a/common/hal/google_camera_hal/realtime_zsl_result_request_processor.cc b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.cc
new file mode 100644
index 0000000..be455eb
--- /dev/null
+++ b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.cc
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "GCH_RealtimeZslResultRequestProcessor"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+
+#include "realtime_zsl_result_request_processor.h"
+
+#include <inttypes.h>
+#include <log/log.h>
+#include <utils/Trace.h>
+
+#include <memory>
+
+#include "hal_types.h"
+#include "hal_utils.h"
+#include "realtime_zsl_result_processor.h"
+
+namespace android {
+namespace google_camera_hal {
+
+bool RealtimeZslResultRequestProcessor::AllDataCollected(
+    const RequestEntry& request_entry) const {
+  return request_entry.zsl_buffer_received &&
+         request_entry.framework_buffer_count ==
+             static_cast<int>(
+                 request_entry.capture_request->output_buffers.size()) &&
+         request_entry.partial_results_received == partial_result_count_;
+}
+
+std::unique_ptr<RealtimeZslResultRequestProcessor>
+RealtimeZslResultRequestProcessor::Create(
+    InternalStreamManager* internal_stream_manager, int32_t stream_id,
+    android_pixel_format_t pixel_format, uint32_t partial_result_count) {
+  ATRACE_CALL();
+  if (internal_stream_manager == nullptr) {
+    ALOGE("%s: internal_stream_manager is nullptr.", __FUNCTION__);
+    return nullptr;
+  }
+
+  auto result_processor = std::unique_ptr<RealtimeZslResultRequestProcessor>(
+      new RealtimeZslResultRequestProcessor(internal_stream_manager, stream_id,
+                                            pixel_format, partial_result_count));
+  if (result_processor == nullptr) {
+    ALOGE("%s: Creating RealtimeZslResultRequestProcessor failed.",
+          __FUNCTION__);
+    return nullptr;
+  }
+
+  return result_processor;
+}
+
+RealtimeZslResultRequestProcessor::RealtimeZslResultRequestProcessor(
+    InternalStreamManager* internal_stream_manager, int32_t stream_id,
+    android_pixel_format_t pixel_format, uint32_t partial_result_count)
+    : RealtimeZslResultProcessor(internal_stream_manager, stream_id,
+                                 pixel_format, partial_result_count) {
+}
+
+void RealtimeZslResultRequestProcessor::UpdateOutputBufferCount(
+    int32_t frame_number, int output_buffer_count, bool is_preview_intent) {
+  ATRACE_CALL();
+  std::lock_guard<std::mutex> lock(callback_lock_);
+  // Cache the CaptureRequest in a queue as the metadata and buffers may not
+  // come together.
+  RequestEntry request_entry = {
+      .capture_request = std::make_unique<CaptureRequest>(),
+      .framework_buffer_count = output_buffer_count};
+  request_entry.capture_request->frame_number = frame_number;
+  if (!is_preview_intent) {
+    // If no preview intent is provided, RealtimeZslRequestProcessor will not
+    // add an internal buffer to the request so there is no ZSL buffer to wait
+    // for in that case.
+    request_entry.zsl_buffer_received = true;
+  }
+
+  pending_frame_number_to_requests_[frame_number] = std::move(request_entry);
+}
+
+void RealtimeZslResultRequestProcessor::ProcessResult(
+    ProcessBlockResult block_result) {
+  ATRACE_CALL();
+  std::lock_guard<std::mutex> lock(callback_lock_);
+  std::unique_ptr<CaptureResult> result = std::move(block_result.result);
+  if (result == nullptr) {
+    ALOGW("%s: Received a nullptr result.", __FUNCTION__);
+    return;
+  }
+
+  // May change to ALOGD for per-frame results.
+  ALOGV(
+      "%s: Received result at frame: %d, has metadata (%s), output buffer "
+      "counts: %zu, input buffer counts: %zu",
+      __FUNCTION__, result->frame_number,
+      (result->result_metadata ? "yes" : "no"), result->output_buffers.size(),
+      result->input_buffers.size());
+
+  // Pending request should always exist
+  RequestEntry& pending_request =
+      pending_frame_number_to_requests_[result->frame_number];
+  if (pending_request.capture_request == nullptr) {
+    pending_request.capture_request = std::make_unique<CaptureRequest>();
+    pending_request.capture_request->frame_number = result->frame_number;
+  }
+
+  // Return filled raw buffer to internal stream manager
+  // And remove raw buffer from result
+  status_t res;
+  std::vector<StreamBuffer> modified_output_buffers;
+  for (uint32_t i = 0; i < result->output_buffers.size(); i++) {
+    if (stream_id_ == result->output_buffers[i].stream_id) {
+      pending_request.has_returned_output_to_internal_stream_manager = true;
+      res = internal_stream_manager_->ReturnFilledBuffer(
+          result->frame_number, result->output_buffers[i]);
+      if (res != OK) {
+        ALOGW("%s: (%d)ReturnStreamBuffer fail", __FUNCTION__,
+              result->frame_number);
+      }
+      pending_request.zsl_buffer_received = true;
+    } else {
+      modified_output_buffers.push_back(result->output_buffers[i]);
+    }
+  }
+
+  if (result->output_buffers.size() > 0) {
+    result->output_buffers.clear();
+    result->output_buffers = modified_output_buffers;
+  }
+
+  if (result->result_metadata) {
+    result->result_metadata->Erase(ANDROID_CONTROL_ENABLE_ZSL);
+
+    res = internal_stream_manager_->ReturnMetadata(
+        stream_id_, result->frame_number, result->result_metadata.get(),
+        result->partial_result);
+    if (res != OK) {
+      ALOGW("%s: (%d)ReturnMetadata fail", __FUNCTION__, result->frame_number);
+    }
+
+    if (result->partial_result == partial_result_count_) {
+      res =
+          hal_utils::SetEnableZslMetadata(result->result_metadata.get(), false);
+      if (res != OK) {
+        ALOGW("%s: SetEnableZslMetadata (%d) fail", __FUNCTION__,
+              result->frame_number);
+      }
+    }
+  }
+
+  // Return directly for frames with errors.
+  if (pending_error_frames_.find(result->frame_number) !=
+      pending_error_frames_.end()) {
+    RequestEntry& error_entry = pending_error_frames_[result->frame_number];
+    return ReturnResultDirectlyForFramesWithErrorsLocked(
+        error_entry, pending_request, std::move(result));
+  }
+
+  // Fill in final result metadata
+  if (result->result_metadata != nullptr) {
+    pending_request.partial_results_received++;
+    if (result->partial_result < partial_result_count_) {
+      // Early result, clone it
+      pending_request.capture_request->settings =
+          HalCameraMetadata::Clone(result->result_metadata.get());
+    } else {
+      // Final result, early result may or may not exist
+      if (pending_request.capture_request->settings == nullptr) {
+        // No early result, i.e. partial results disabled. Clone final result
+        pending_request.capture_request->settings =
+            HalCameraMetadata::Clone(result->result_metadata.get());
+      } else {
+        // Append early result to final result
+        pending_request.capture_request->settings->Append(
+            result->result_metadata->GetRawCameraMetadata());
+      }
+    }
+  }
+
+  // Fill in output buffers
+  if (!result->output_buffers.empty()) {
+    auto& output_buffers = pending_request.capture_request->output_buffers;
+    output_buffers.insert(output_buffers.begin(), result->output_buffers.begin(),
+                          result->output_buffers.end());
+  }
+
+  // Fill in input buffers
+  if (!result->input_buffers.empty()) {
+    auto& input_buffers = pending_request.capture_request->input_buffers;
+    input_buffers.insert(input_buffers.begin(), result->input_buffers.begin(),
+                         result->input_buffers.end());
+  }
+
+  // Submit the request and remove the request from the cache when all data is collected.
+  if (AllDataCollected(pending_request)) {
+    res = ProcessRequest(*pending_request.capture_request);
+    pending_frame_number_to_requests_.erase(result->frame_number);
+    if (res != OK) {
+      ALOGE("%s: ProcessRequest fail", __FUNCTION__);
+      return;
+    }
+  }
+}
+
+status_t RealtimeZslResultRequestProcessor::ConfigureStreams(
+    InternalStreamManager* /*internal_stream_manager*/,
+    const StreamConfiguration& stream_config,
+    StreamConfiguration* process_block_stream_config) {
+  ATRACE_CALL();
+  if (process_block_stream_config == nullptr) {
+    ALOGE("%s: process_block_stream_config is nullptr", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  process_block_stream_config->streams = stream_config.streams;
+  process_block_stream_config->operation_mode = stream_config.operation_mode;
+  process_block_stream_config->session_params =
+      HalCameraMetadata::Clone(stream_config.session_params.get());
+  process_block_stream_config->stream_config_counter =
+      stream_config.stream_config_counter;
+  process_block_stream_config->multi_resolution_input_image =
+      stream_config.multi_resolution_input_image;
+
+  return OK;
+}
+
+status_t RealtimeZslResultRequestProcessor::SetProcessBlock(
+    std::unique_ptr<ProcessBlock> process_block) {
+  ATRACE_CALL();
+  if (process_block == nullptr) {
+    ALOGE("%s: process_block is nullptr", __FUNCTION__);
+    return BAD_VALUE;
+  }
+
+  std::lock_guard lock(process_block_shared_lock_);
+  if (process_block_ != nullptr) {
+    ALOGE("%s: Already configured.", __FUNCTION__);
+    return ALREADY_EXISTS;
+  }
+
+  process_block_ = std::move(process_block);
+  return OK;
+}
+
+status_t RealtimeZslResultRequestProcessor::ProcessRequest(
+    const CaptureRequest& request) {
+  ATRACE_CALL();
+  std::shared_lock lock(process_block_shared_lock_);
+  if (process_block_ == nullptr) {
+    ALOGE("%s: Not configured yet.", __FUNCTION__);
+    return NO_INIT;
+  }
+
+  CaptureRequest block_request;
+  block_request.frame_number = request.frame_number;
+  block_request.settings = HalCameraMetadata::Clone(request.settings.get());
+  block_request.input_buffers = request.input_buffers;
+  block_request.input_width = request.input_width;
+  block_request.input_height = request.input_height;
+
+  for (auto& metadata : request.input_buffer_metadata) {
+    block_request.input_buffer_metadata.push_back(
+        HalCameraMetadata::Clone(metadata.get()));
+  }
+
+  block_request.output_buffers = request.output_buffers;
+  for (auto& [camera_id, physical_metadata] : request.physical_camera_settings) {
+    block_request.physical_camera_settings[camera_id] =
+        HalCameraMetadata::Clone(physical_metadata.get());
+  }
+
+  std::vector<ProcessBlockRequest> block_requests(1);
+  block_requests[0].request = std::move(block_request);
+
+  return process_block_->ProcessRequests(block_requests, request);
+}
+
+status_t RealtimeZslResultRequestProcessor::Flush() {
+  ATRACE_CALL();
+  std::shared_lock lock(process_block_shared_lock_);
+  if (process_block_ == nullptr) {
+    return OK;
+  }
+
+  return process_block_->Flush();
+}
+
+void RealtimeZslResultRequestProcessor::Notify(
+    const ProcessBlockNotifyMessage& block_message) {
+  ATRACE_CALL();
+  std::lock_guard<std::mutex> lock(callback_lock_);
+  const NotifyMessage& message = block_message.message;
+  if (notify_ == nullptr) {
+    ALOGE("%s: notify_ is nullptr. Dropping a message.", __FUNCTION__);
+    return;
+  }
+
+  // Will return buffer for kErrorRequest and kErrorBuffer.
+  if (message.type == MessageType::kError) {
+    // May change to ALOGD for per-frame error messages.
+    ALOGV("%s: Received error message at frame: %d, error code (%d)",
+          __FUNCTION__, message.message.error.frame_number,
+          static_cast<int>(message.message.error.error_code));
+    if (message.message.error.error_code == ErrorCode::kErrorRequest ||
+        message.message.error.error_code == ErrorCode::kErrorBuffer) {
+      pending_error_frames_.try_emplace(
+          message.message.error.frame_number,
+          RequestEntry{.capture_request = std::make_unique<CaptureRequest>()});
+      if (message.message.error.error_code == ErrorCode::kErrorRequest) {
+        // ProcessCaptureResult is not called in the case of metadata error.
+        // Therefore, treat it as if a metadata callback arrived so that we can
+        // know when the request is complete.
+        pending_error_frames_[message.message.error.frame_number]
+            .partial_results_received++;
+      }
+    }
+    // Gives latched results (those that have arrived but are waiting for
+    // AllDataCollected()) a chance to return their valid buffer.
+    uint32_t frame_number = message.message.error.frame_number;
+    auto result = std::make_unique<CaptureResult>();
+    result->frame_number = frame_number;
+    if (pending_frame_number_to_requests_.find(frame_number) !=
+        pending_frame_number_to_requests_.end()) {
+      RequestEntry& pending_request =
+          pending_frame_number_to_requests_[frame_number];
+      if (pending_request.zsl_buffer_received) {
+        ReturnResultDirectlyForFramesWithErrorsLocked(
+            pending_error_frames_[frame_number], pending_request,
+            std::move(result));
+      }
+    }
+  } else {
+    // May change to ALOGD for per-frame shutter messages.
+    ALOGV("%s: Received shutter message for frame %d, timestamp_ns: %" PRId64
+          ", readout_timestamp_ns: %" PRId64,
+          __FUNCTION__, message.message.shutter.frame_number,
+          message.message.shutter.timestamp_ns,
+          message.message.shutter.readout_timestamp_ns);
+  }
+  notify_(message);
+}
+
+void RealtimeZslResultRequestProcessor::CombineErrorAndPendingEntriesToResult(
+    RequestEntry& error_entry, RequestEntry& pending_request,
+    std::unique_ptr<CaptureResult>& result) const {
+  result->output_buffers.insert(
+      result->output_buffers.end(),
+      pending_request.capture_request->output_buffers.begin(),
+      pending_request.capture_request->output_buffers.end());
+  result->input_buffers.insert(
+      result->input_buffers.end(),
+      pending_request.capture_request->input_buffers.begin(),
+      pending_request.capture_request->input_buffers.end());
+  error_entry.capture_request->output_buffers = result->output_buffers;
+  error_entry.capture_request->input_buffers = result->input_buffers;
+  error_entry.zsl_buffer_received = pending_request.zsl_buffer_received;
+  error_entry.framework_buffer_count = pending_request.framework_buffer_count;
+  if (pending_request.capture_request->settings != nullptr) {
+    if (result->result_metadata == nullptr) {
+      // result is a buffer-only result and we have early metadata sitting in
+      // pending_request. Copy this early metadata and its partial_result count.
+      result->result_metadata = HalCameraMetadata::Clone(
+          pending_request.capture_request->settings.get());
+      result->partial_result = pending_request.partial_results_received;
+    } else {
+      // result carries final metadata and we have early metadata sitting in
+      // pending_request. Append the early metadata but keep the
+      // partial_result count to reflect that this is the final metadata.
+      result->result_metadata->Append(
+          pending_request.capture_request->settings->GetRawCameraMetadata());
+    }
+    error_entry.partial_results_received += result->partial_result;
+  }
+
+  // Reset capture request for pending request as all data has been
+  // transferred to error_entry already.
+  pending_request.capture_request = std::make_unique<CaptureRequest>();
+  pending_request.capture_request->frame_number = result->frame_number;
+}
+
+void RealtimeZslResultRequestProcessor::ReturnResultDirectlyForFramesWithErrorsLocked(
+    RequestEntry& error_entry, RequestEntry& pending_request,
+    std::unique_ptr<CaptureResult> result) {
+  // Also need to process pending buffers and metadata for the frame if exists.
+  // If the result is complete (buffers and all partial results arrived), send
+  // the callback directly. Otherwise wait until the missing pieces arrive.
+  CombineErrorAndPendingEntriesToResult(error_entry, pending_request, result);
+
+  if (AllDataCollected(error_entry)) {
+    pending_error_frames_.erase(result->frame_number);
+    pending_frame_number_to_requests_.erase(result->frame_number);
+  }
+
+  // Don't send result to framework if only internal raw callback
+  if (pending_request.has_returned_output_to_internal_stream_manager &&
+      result->result_metadata == nullptr && result->output_buffers.size() == 0) {
+    return;
+  }
+  ALOGV("%s: Returning capture result for frame %d due to existing errors.",
+        __FUNCTION__, result->frame_number);
+  process_capture_result_(std::move(result));
+  return;
+}
+
+}  // namespace google_camera_hal
+}  // namespace android
diff --git a/common/hal/google_camera_hal/realtime_zsl_result_request_processor.h b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.h
new file mode 100644
index 0000000..5454916
--- /dev/null
+++ b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_REALTIME_ZSL_RESULT_REQUEST_PROCESSOR_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_REALTIME_ZSL_RESULT_REQUEST_PROCESSOR_H_
+
+#include <cstdint>
+#include <shared_mutex>
+
+#include "hal_types.h"
+#include "internal_stream_manager.h"
+#include "realtime_zsl_result_processor.h"
+#include "request_processor.h"
+#include "result_processor.h"
+
+namespace android {
+namespace google_camera_hal {
+
+// RealtimeZslResultRequestProcessor implements a RealtimeZslResultProcessor
+// that return filled raw buffer and metadata to internal stream manager. It
+// also implements a RequestProcess to forward the results.
+class RealtimeZslResultRequestProcessor : public RealtimeZslResultProcessor,
+                                          RequestProcessor {
+ public:
+  static std::unique_ptr<RealtimeZslResultRequestProcessor> Create(
+      InternalStreamManager* internal_stream_manager, int32_t stream_id,
+      android_pixel_format_t pixel_format, uint32_t partial_result_count = 1);
+
+  virtual ~RealtimeZslResultRequestProcessor() = default;
+
+  // Override functions of RealtimeZslResultProcessor start.
+  void ProcessResult(ProcessBlockResult block_result) override;
+
+  void Notify(const ProcessBlockNotifyMessage& block_message) override;
+  // Override functions of RealtimeZslResultProcessor end.
+
+  // Override functions of RequestProcessor start.
+  status_t ConfigureStreams(
+      InternalStreamManager* internal_stream_manager,
+      const StreamConfiguration& stream_config,
+      StreamConfiguration* process_block_stream_config) override;
+
+  status_t SetProcessBlock(std::unique_ptr<ProcessBlock> process_block) override;
+
+  status_t ProcessRequest(const CaptureRequest& request) override;
+
+  status_t Flush() override;
+  // Override functions of RequestProcessor end.
+
+  void UpdateOutputBufferCount(int32_t frame_number, int output_buffer_count,
+                               bool is_preview_intent);
+
+ protected:
+  RealtimeZslResultRequestProcessor(
+      InternalStreamManager* internal_stream_manager, int32_t stream_id,
+      android_pixel_format_t pixel_format, uint32_t partial_result_count);
+
+ private:
+  std::shared_mutex process_block_shared_lock_;
+
+  // Protected by process_block_shared_lock_.
+  std::unique_ptr<ProcessBlock> process_block_;
+
+  // Simple wrapper struct to add partial result count to CaptureResult
+  struct RequestEntry {
+    std::unique_ptr<CaptureRequest> capture_request = nullptr;
+    uint32_t partial_results_received = 0;
+    bool zsl_buffer_received = false;
+    int framework_buffer_count = INT_MAX;
+    // Whether there were filled raw buffers that have been returned to internal
+    // stream manager.
+    bool has_returned_output_to_internal_stream_manager = false;
+  };
+
+  bool AllDataCollected(const RequestEntry& request_entry) const;
+
+  // A helper function to combine information for the same frame number from
+  // `pending_error_frames_` and `pending_frame_number_to_requests_` to the
+  // `result`. This is a 3-way update, where `pending_request` info is copied to
+  // `error_entry` and `result`, and `pending_request` info gets reset.
+  void CombineErrorAndPendingEntriesToResult(
+      RequestEntry& error_entry, RequestEntry& pending_request,
+      std::unique_ptr<CaptureResult>& result) const;
+
+  // Returns result directly for frames with errors, if applicable. Call site
+  // must hold callback_lock_.
+  void ReturnResultDirectlyForFramesWithErrorsLocked(
+      RequestEntry& error_entry, RequestEntry& pending_request,
+      std::unique_ptr<CaptureResult> result);
+
+  // Results collected so far on a valid frame. Results are passed to the
+  // processor block once all items in the RequestEntry struct are complete -
+  // i.e. all buffers arrived an all partial results arrived.
+  std::unordered_map<uint32_t, RequestEntry> pending_frame_number_to_requests_;
+  // Results collected so far on a frame with an error. Each result item gets
+  // reported to the upper layer as it comes in, and once the RequestEntry
+  // struct is complete the entry is removed.
+  std::unordered_map<uint32_t, RequestEntry> pending_error_frames_;
+};
+
+}  // namespace google_camera_hal
+}  // namespace android
+
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_REALTIME_ZSL_RESULT_REQUEST_PROCESSOR_H_
diff --git a/common/hal/google_camera_hal/rgbird_capture_session.cc b/common/hal/google_camera_hal/rgbird_capture_session.cc
index 5ec8e98..919a2fa 100644
--- a/common/hal/google_camera_hal/rgbird_capture_session.cc
+++ b/common/hal/google_camera_hal/rgbird_capture_session.cc
@@ -986,8 +986,8 @@
   }
 
   // Create result dispatcher
-  result_dispatcher_ =
-      ResultDispatcher::Create(kPartialResult, process_capture_result, notify);
+  result_dispatcher_ = ResultDispatcher::Create(
+      kPartialResult, process_capture_result, notify, "RgbirdDispatcher");
   if (result_dispatcher_ == nullptr) {
     ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
     return UNKNOWN_ERROR;
@@ -1093,9 +1093,10 @@
   }
 
   if (message.type == MessageType::kShutter) {
-    status_t res =
-        result_dispatcher_->AddShutter(message.message.shutter.frame_number,
-                                       message.message.shutter.timestamp_ns);
+    status_t res = result_dispatcher_->AddShutter(
+        message.message.shutter.frame_number,
+        message.message.shutter.timestamp_ns,
+        message.message.shutter.readout_timestamp_ns);
     if (res != OK) {
       ALOGE("%s: frame(%d) fail to AddShutter", __FUNCTION__,
             message.message.shutter.frame_number);
diff --git a/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc b/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
index fa25403..ab17df8 100644
--- a/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
+++ b/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 
 #define LOG_TAG "GCH_ZslSnapshotCaptureSession"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
@@ -27,6 +27,7 @@
 #include <utils/Trace.h>
 
 #include "hal_utils.h"
+#include "realtime_zsl_result_request_processor.h"
 #include "snapshot_request_processor.h"
 #include "snapshot_result_processor.h"
 #include "system/graphics-base-v1.0.h"
@@ -140,6 +141,57 @@
 #endif
 }
 
+std::unique_ptr<ProcessBlock>
+ZslSnapshotCaptureSession::CreateDenoiseProcessBlock() {
+  ATRACE_CALL();
+#if GCH_HWL_USE_DLOPEN
+  bool found_process_block = false;
+  for (const auto& lib_path :
+       utils::FindLibraryPaths(kExternalProcessBlockDir)) {
+    ALOGI("%s: Loading %s", __FUNCTION__, lib_path.c_str());
+    void* lib_handle = nullptr;
+    lib_handle = dlopen(lib_path.c_str(), RTLD_NOW);
+    if (lib_handle == nullptr) {
+      ALOGW("Failed loading %s.", lib_path.c_str());
+      continue;
+    }
+
+    GetProcessBlockFactoryFunc external_process_block_t =
+        reinterpret_cast<GetProcessBlockFactoryFunc>(
+            dlsym(lib_handle, "GetProcessBlockFactory"));
+    if (external_process_block_t == nullptr) {
+      ALOGE("%s: dlsym failed (%s) when loading %s.", __FUNCTION__,
+            "GetProcessBlockFactoryFunc", lib_path.c_str());
+      dlclose(lib_handle);
+      lib_handle = nullptr;
+      continue;
+    }
+
+    if (external_process_block_t()->GetBlockName() == "DenoiseProcessBlock") {
+      denoise_process_block_factory_ = external_process_block_t;
+      denoise_process_block_lib_handle_ = lib_handle;
+      found_process_block = true;
+      break;
+    }
+  }
+  if (!found_process_block) {
+    ALOGE("%s: denoise process block does not exist", __FUNCTION__);
+    return nullptr;
+  }
+
+  return denoise_process_block_factory_()->CreateProcessBlock(
+      camera_device_session_hwl_);
+#else
+  if (GetDenoiseProcessBlockFactory == nullptr) {
+    ALOGE("%s: denoise process block does not exist", __FUNCTION__);
+    return nullptr;
+  }
+  denoise_process_block_factory_ = GetDenoiseProcessBlockFactory;
+  return GetDenoiseProcessBlockFactory()->CreateProcessBlock(
+      camera_device_session_hwl_);
+#endif
+}
+
 bool ZslSnapshotCaptureSession::IsStreamConfigurationSupported(
     CameraDeviceSessionHwl* device_session_hwl,
     const StreamConfiguration& stream_config) {
@@ -167,7 +219,11 @@
   bool has_preview_stream = false;
   for (const auto& stream : stream_config.streams) {
     if (stream.is_physical_camera_stream) {
-      ALOGE("%s: support logical camera only", __FUNCTION__);
+      ALOGE("%s: support logical stream only", __FUNCTION__);
+      return false;
+    }
+    if (utils::IsSecuredStream(stream)) {
+      ALOGE("%s: don't support secured stream", __FUNCTION__);
       return false;
     }
     if (utils::IsJPEGSnapshotStream(stream) ||
@@ -242,6 +298,9 @@
   // SnapshotRequestProcessor before the lib handle is released.
   release_thread.join();
   dlclose(snapshot_process_block_lib_handle_);
+  dlclose(denoise_process_block_lib_handle_);
+
+  ALOGI("%s: finished", __FUNCTION__);
 }
 
 status_t ZslSnapshotCaptureSession::BuildPipelines(
@@ -353,14 +412,27 @@
   }
 
   // Create preview result processor. Stream ID is not set at this stage.
-  auto realtime_result_processor = RealtimeZslResultProcessor::Create(
-      internal_stream_manager_.get(), additional_stream_id,
-      HAL_PIXEL_FORMAT_YCBCR_420_888, partial_result_count_);
+
+  std::unique_ptr<ResultProcessor> realtime_result_processor;
+  if (video_sw_denoise_enabled_) {
+    auto processor = RealtimeZslResultRequestProcessor::Create(
+        internal_stream_manager_.get(), additional_stream_id,
+        HAL_PIXEL_FORMAT_YCBCR_420_888, partial_result_count_);
+    realtime_zsl_result_request_processor_ = processor.get();
+    realtime_result_processor = std::move(processor);
+  } else {
+    realtime_result_processor = RealtimeZslResultProcessor::Create(
+        internal_stream_manager_.get(), additional_stream_id,
+        HAL_PIXEL_FORMAT_YCBCR_420_888, partial_result_count_);
+  }
+
   if (realtime_result_processor == nullptr) {
-    ALOGE("%s: Creating RealtimeZslResultProcessor failed.", __FUNCTION__);
+    ALOGE(
+        "%s: Creating "
+        "RealtimeZslResultProcessor/RealtimeZslResultRequestProcessor failed.",
+        __FUNCTION__);
     return UNKNOWN_ERROR;
   }
-  realtime_result_processor_ = realtime_result_processor.get();
   realtime_result_processor->SetResultCallback(process_capture_result, notify);
 
   res = process_block->SetResultProcessor(std::move(realtime_result_processor));
@@ -385,6 +457,56 @@
     }
   }
 
+  if (video_sw_denoise_enabled_) {
+    StreamConfiguration denoise_process_block_stream_config;
+    // Configure streams for request processor
+    res = realtime_zsl_result_request_processor_->ConfigureStreams(
+        internal_stream_manager_.get(), stream_config,
+        &denoise_process_block_stream_config);
+
+    if (res != OK) {
+      ALOGE(
+          "%s: Configuring stream for process block "
+          "(RealtimeZslResultRequestProcessor) failed.",
+          __FUNCTION__);
+      return res;
+    }
+
+    std::unique_ptr<ProcessBlock> denoise_processor =
+        CreateDenoiseProcessBlock();
+    // Create preview result processor. Stream ID is not set at this stage.
+    auto basic_result_processor = BasicResultProcessor::Create();
+    if (basic_result_processor == nullptr) {
+      ALOGE("%s: Creating BasicResultProcessor failed.", __FUNCTION__);
+      return UNKNOWN_ERROR;
+    }
+    basic_result_processor_ = basic_result_processor.get();
+    basic_result_processor->SetResultCallback(process_capture_result, notify);
+
+    res =
+        denoise_processor->SetResultProcessor(std::move(basic_result_processor));
+    if (res != OK) {
+      ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
+      return res;
+    }
+
+    // Configure streams for process block.
+    res = denoise_processor->ConfigureStreams(
+        denoise_process_block_stream_config, stream_config);
+    if (res != OK) {
+      ALOGE("%s: Configuring stream for process block failed.", __FUNCTION__);
+      return res;
+    }
+
+    res = realtime_zsl_result_request_processor_->SetProcessBlock(
+        std::move(denoise_processor));
+    if (res != OK) {
+      ALOGE("%s: Setting process block for RequestProcessor failed: %s(%d)",
+            __FUNCTION__, strerror(-res), res);
+      return res;
+    }
+  }
+
   return OK;
 }
 
@@ -487,13 +609,11 @@
     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
   ATRACE_CALL();
   if (realtime_process_block_ != nullptr ||
-      realtime_result_processor_ != nullptr ||
       realtime_request_processor_ != nullptr) {
     ALOGE(
-        "%s: realtime_process_block_(%p) or realtime_result_processor_(%p) or "
-        "realtime_request_processor_(%p) is/are "
-        "already set",
-        __FUNCTION__, realtime_process_block_, realtime_result_processor_,
+        "%s: realtime_process_block_(%p) or realtime_request_processor_(%p) "
+        "is/are already set",
+        __FUNCTION__, realtime_process_block_,
         realtime_request_processor_.get());
     return BAD_VALUE;
   }
@@ -596,6 +716,16 @@
     return BAD_VALUE;
   }
 
+  camera_metadata_ro_entry video_sw_denoise_entry;
+  res = characteristics->Get(VendorTagIds::kVideoSwDenoiseEnabled,
+                             &video_sw_denoise_entry);
+  if (res == OK && video_sw_denoise_entry.data.u8[0] == 1) {
+    video_sw_denoise_enabled_ = true;
+    ALOGI("%s: video sw denoise is enabled.", __FUNCTION__);
+  } else {
+    ALOGI("%s: video sw denoise is disabled.", __FUNCTION__);
+  }
+
   for (auto stream : stream_config.streams) {
     if (utils::IsPreviewStream(stream)) {
       hal_preview_stream_id_ = stream.id;
@@ -682,12 +812,17 @@
 status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
   ATRACE_CALL();
   bool is_zsl_request = false;
+  bool is_preview_intent = false;
   camera_metadata_ro_entry entry;
   if (request.settings != nullptr) {
     if (request.settings->Get(ANDROID_CONTROL_ENABLE_ZSL, &entry) == OK &&
         *entry.data.u8 == ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
       is_zsl_request = true;
     }
+    if (request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) == OK &&
+        *entry.data.u8 == ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW) {
+      is_preview_intent = true;
+    }
   }
   status_t res = result_dispatcher_->AddPendingRequest(request, is_zsl_request);
   if (res != OK) {
@@ -701,9 +836,20 @@
       ALOGW(
           "%s: frame (%d) fall back to real time request for snapshot: %s (%d)",
           __FUNCTION__, request.frame_number, strerror(-res), res);
+      if (realtime_zsl_result_request_processor_ != nullptr) {
+        realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
+            request.frame_number, request.output_buffers.size(),
+            is_preview_intent);
+      }
       res = realtime_request_processor_->ProcessRequest(request);
     }
   } else {
+    if (realtime_zsl_result_request_processor_ != nullptr) {
+      realtime_zsl_result_request_processor_->UpdateOutputBufferCount(
+          request.frame_number, request.output_buffers.size(),
+          is_preview_intent);
+    }
+
     res = realtime_request_processor_->ProcessRequest(request);
   }
 
@@ -750,9 +896,10 @@
   }
 
   if (message.type == MessageType::kShutter) {
-    status_t res =
-        result_dispatcher_->AddShutter(message.message.shutter.frame_number,
-                                       message.message.shutter.timestamp_ns);
+    status_t res = result_dispatcher_->AddShutter(
+        message.message.shutter.frame_number,
+        message.message.shutter.timestamp_ns,
+        message.message.shutter.readout_timestamp_ns);
     if (res != OK) {
       ALOGE("%s: AddShutter for frame %u failed: %s (%d).", __FUNCTION__,
             message.message.shutter.frame_number, strerror(-res), res);
diff --git a/common/hal/google_camera_hal/zsl_snapshot_capture_session.h b/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
index 74b3cc3..a376030 100644
--- a/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
+++ b/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
@@ -17,6 +17,7 @@
 #ifndef HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_ZSL_SNAPSHOT_CAPTURE_SESSION_H_
 #define HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_ZSL_SNAPSHOT_CAPTURE_SESSION_H_
 
+#include "basic_result_processor.h"
 #include "camera_buffer_allocator_hwl.h"
 #include "camera_device_session_hwl.h"
 #include "capture_session.h"
@@ -26,6 +27,7 @@
 #include "process_block.h"
 #include "realtime_zsl_request_processor.h"
 #include "realtime_zsl_result_processor.h"
+#include "realtime_zsl_result_request_processor.h"
 #include "request_processor.h"
 #include "result_processor.h"
 #include "snapshot_request_processor.h"
@@ -42,7 +44,7 @@
 //
 //  1.SnapshotRequestProcessor->SnapshotProcessBlock->SnapshotResultProcessor
 //
-//  2.RealtimeZslRequestProcessor->CaptureSessionWrapperProcessBlock->RealtimeZslResultProcessor
+//  2.RealtimeZslRequestProcessor->CaptureSessionWrapperProcessBlock->RealtimeZslResultRequestProcessor->DenoiseProcessBlock->BasicResultProcessor
 //                                    ||  /\
 //                                    \/  ||
 //                             embedded capture session
@@ -128,6 +130,7 @@
       std::vector<HalStream>* hal_configured_streams);
 
   std::unique_ptr<ProcessBlock> CreateSnapshotProcessBlock();
+  std::unique_ptr<ProcessBlock> CreateDenoiseProcessBlock();
 
   // Invoked when receiving a result from result processor.
   void ProcessCaptureResult(std::unique_ptr<CaptureResult> result);
@@ -138,12 +141,11 @@
   std::unique_ptr<InternalStreamManager> internal_stream_manager_;
 
   std::unique_ptr<RealtimeZslRequestProcessor> realtime_request_processor_;
+  RealtimeZslResultRequestProcessor* realtime_zsl_result_request_processor_ =
+      nullptr;
   // CaptureSessionWrapperProcessBlock will be owned and released by
   // RealtimeZslRequestProcessor.
   CaptureSessionWrapperProcessBlock* realtime_process_block_ = nullptr;
-  // RealtimeZslResultProcessor will be owned and released by
-  // CaptureSessionWrapperProcessBlock.
-  RealtimeZslResultProcessor* realtime_result_processor_ = nullptr;
 
   std::unique_ptr<SnapshotRequestProcessor> snapshot_request_processor_;
   // SnapshotProcessBlock will be owned and released by
@@ -152,6 +154,8 @@
   // SnapshotResultProcessor will be owned and released by SnapshotProcessBlock.
   SnapshotResultProcessor* snapshot_result_processor_ = nullptr;
 
+  BasicResultProcessor* basic_result_processor_ = nullptr;
+
   // Use this stream id to check the request is ZSL compatible
   int32_t hal_preview_stream_id_ = -1;
 
@@ -181,8 +185,15 @@
   // Opened library handles that should be closed on destruction
   void* snapshot_process_block_lib_handle_ = nullptr;
 
+  GetProcessBlockFactoryFunc denoise_process_block_factory_;
+  // Opened library handles that should be closed on destruction
+  void* denoise_process_block_lib_handle_ = nullptr;
+
   // Partial result count reported by HAL
   uint32_t partial_result_count_ = 1;
+
+  // Whether video software denoise is enabled
+  bool video_sw_denoise_enabled_ = false;
 };
 
 }  // namespace google_camera_hal
diff --git a/common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google-lazy.rc b/common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google-lazy.rc
deleted file mode 100644
index ff619d8..0000000
--- a/common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google-lazy.rc
+++ /dev/null
@@ -1,13 +0,0 @@
-service vendor.camera-provider-2-7-google /vendor/bin/hw/android.hardware.camera.provider@2.7-service-google-lazy
-    interface android.hardware.camera.provider@2.4::ICameraProvider internal/0
-    interface android.hardware.camera.provider@2.5::ICameraProvider internal/0
-    interface android.hardware.camera.provider@2.6::ICameraProvider internal/0
-    interface android.hardware.camera.provider@2.7::ICameraProvider internal/0
-    oneshot
-    disabled
-    class hal
-    user system
-    group system
-    capabilities SYS_NICE
-    rlimit rtprio 10 10
-    task_profiles CameraServiceCapacity CameraServicePerformance
diff --git a/common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google.xml b/common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google.xml
deleted file mode 100644
index 481b46e..0000000
--- a/common/hal/hidl_service/android.hardware.camera.provider@2.7-service-google.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!-- Copyright (C) 2020 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.
--->
-
-<manifest version="1.0" type="device">
-    <hal format="hidl">
-        <name>android.hardware.camera.provider</name>
-        <transport>hwbinder</transport>
-        <version>2.7</version>
-        <interface>
-            <name>ICameraProvider</name>
-            <instance>internal/0</instance>
-        </interface>
-    </hal>
-</manifest>
diff --git a/common/hal/hidl_service/hidl_camera_device.cc b/common/hal/hidl_service/hidl_camera_device.cc
deleted file mode 100644
index fd45a5b..0000000
--- a/common/hal/hidl_service/hidl_camera_device.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define LOG_TAG "GCH_HidlCameraDevice"
-//#define LOG_NDEBUG 0
-#include "hidl_camera_device.h"
-
-#include <log/log.h>
-
-#include "hidl_camera_device_session.h"
-#include "hidl_profiler.h"
-#include "hidl_utils.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace device {
-namespace V3_7 {
-namespace implementation {
-
-namespace hidl_utils = ::android::hardware::camera::implementation::hidl_utils;
-
-using ::android::google_camera_hal::HalCameraMetadata;
-
-const std::string HidlCameraDevice::kDeviceVersion = "3.7";
-
-std::unique_ptr<HidlCameraDevice> HidlCameraDevice::Create(
-    std::unique_ptr<CameraDevice> google_camera_device) {
-  auto device = std::unique_ptr<HidlCameraDevice>(new HidlCameraDevice());
-  if (device == nullptr) {
-    ALOGE("%s: Cannot create a HidlCameraDevice.", __FUNCTION__);
-    return nullptr;
-  }
-
-  status_t res = device->Initialize(std::move(google_camera_device));
-  if (res != OK) {
-    ALOGE("%s: Initializing HidlCameraDevice failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return nullptr;
-  }
-
-  return device;
-}
-
-status_t HidlCameraDevice::Initialize(
-    std::unique_ptr<CameraDevice> google_camera_device) {
-  if (google_camera_device == nullptr) {
-    ALOGE("%s: google_camera_device is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  camera_id_ = google_camera_device->GetPublicCameraId();
-  google_camera_device_ = std::move(google_camera_device);
-  hidl_profiler_ = HidlProfiler::Create(camera_id_);
-  if (hidl_profiler_ == nullptr) {
-    ALOGE("%s: Failed to create HidlProfiler.", __FUNCTION__);
-    return UNKNOWN_ERROR;
-  }
-  hidl_profiler_->SetLatencyProfiler(google_camera_device_->GetProfiler(
-      camera_id_, hidl_profiler_->GetLatencyFlag()));
-  hidl_profiler_->SetFpsProfiler(google_camera_device_->GetProfiler(
-      camera_id_, hidl_profiler_->GetFpsFlag()));
-
-  return OK;
-}
-
-Return<void> HidlCameraDevice::getResourceCost(
-    ICameraDevice::getResourceCost_cb _hidl_cb) {
-  google_camera_hal::CameraResourceCost hal_cost;
-  CameraResourceCost hidl_cost;
-
-  status_t res = google_camera_device_->GetResourceCost(&hal_cost);
-  if (res != OK) {
-    ALOGE("%s: Getting resource cost failed for camera %u: %s(%d)",
-          __FUNCTION__, camera_id_, strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_cost);
-    return Void();
-  }
-
-  res = hidl_utils::ConvertToHidlResourceCost(hal_cost, &hidl_cost);
-  if (res != OK) {
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_cost);
-    return Void();
-  }
-
-  _hidl_cb(Status::OK, hidl_cost);
-  return Void();
-}
-
-Return<void> HidlCameraDevice::getCameraCharacteristics(
-    ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
-  V3_2::CameraMetadata hidl_characteristics;
-  std::unique_ptr<HalCameraMetadata> characteristics;
-  status_t res =
-      google_camera_device_->GetCameraCharacteristics(&characteristics);
-  if (res != OK) {
-    ALOGE("%s: Getting camera characteristics for camera %u failed: %s(%d)",
-          __FUNCTION__, camera_id_, strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_characteristics);
-    return Void();
-  }
-
-  if (characteristics == nullptr) {
-    ALOGE("%s: Camera characteristics for camera %u is nullptr.", __FUNCTION__,
-          camera_id_);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_characteristics);
-    return Void();
-  }
-
-  uint32_t metadata_size = characteristics->GetCameraMetadataSize();
-  hidl_characteristics.setToExternal(
-      (uint8_t*)characteristics->ReleaseCameraMetadata(), metadata_size,
-      /*shouldOwn*/ true);
-
-  _hidl_cb(Status::OK, hidl_characteristics);
-  return Void();
-}
-
-Return<Status> HidlCameraDevice::setTorchMode(TorchMode mode) {
-  google_camera_hal::TorchMode hal_torch_mode;
-  status_t res = hidl_utils::ConvertToHalTorchMode(mode, &hal_torch_mode);
-  if (res != OK) {
-    ALOGE("%s: failed to convert torch mode", __FUNCTION__);
-    return Status::INTERNAL_ERROR;
-  }
-
-  res = google_camera_device_->SetTorchMode(hal_torch_mode);
-  return hidl_utils::ConvertToHidlStatus(res);
-}
-
-Return<void> HidlCameraDevice::open(
-    const sp<V3_2::ICameraDeviceCallback>& callback,
-    ICameraDevice::open_cb _hidl_cb) {
-  auto profiler =
-      hidl_profiler_->MakeScopedProfiler(HidlProfiler::ScopedType::kOpen);
-
-  std::unique_ptr<google_camera_hal::CameraDeviceSession> session;
-  status_t res = google_camera_device_->CreateCameraDeviceSession(&session);
-  if (res != OK || session == nullptr) {
-    ALOGE("%s: Creating CameraDeviceSession failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(hidl_utils::ConvertToHidlStatus(res), nullptr);
-    return Void();
-  }
-
-  auto hidl_session = HidlCameraDeviceSession::Create(
-      callback, std::move(session), hidl_profiler_);
-  if (hidl_session == nullptr) {
-    ALOGE("%s: Creating HidlCameraDeviceSession failed.", __FUNCTION__);
-    _hidl_cb(hidl_utils::ConvertToHidlStatus(res), nullptr);
-    return Void();
-  }
-
-  _hidl_cb(Status::OK, hidl_session.release());
-  return Void();
-}
-
-Return<void> HidlCameraDevice::dumpState(
-    const ::android::hardware::hidl_handle& handle) {
-  if (handle.getNativeHandle() == nullptr) {
-    ALOGE("%s: handle is nullptr", __FUNCTION__);
-    return Void();
-  }
-
-  if (handle->numFds != 1 || handle->numInts != 0) {
-    ALOGE("%s: handle must contain 1 fd(%d) and 0 ints(%d)", __FUNCTION__,
-          handle->numFds, handle->numInts);
-    return Void();
-  }
-
-  int fd = handle->data[0];
-  google_camera_device_->DumpState(fd);
-  return Void();
-}
-
-Return<void> HidlCameraDevice::getPhysicalCameraCharacteristics(
-    const hidl_string& physicalCameraId,
-    ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb) {
-  V3_2::CameraMetadata hidl_characteristics;
-  std::unique_ptr<HalCameraMetadata> physical_characteristics;
-
-  uint32_t physical_camera_id = atoi(physicalCameraId.c_str());
-  status_t res = google_camera_device_->GetPhysicalCameraCharacteristics(
-      physical_camera_id, &physical_characteristics);
-  if (res != OK) {
-    ALOGE("%s: Getting physical characteristics for camera %u failed: %s(%d)",
-          __FUNCTION__, camera_id_, strerror(-res), res);
-    _hidl_cb(hidl_utils::ConvertToHidlStatus(res), hidl_characteristics);
-    return Void();
-  }
-
-  if (physical_characteristics == nullptr) {
-    ALOGE("%s: Physical characteristics for camera %u is nullptr.",
-          __FUNCTION__, physical_camera_id);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_characteristics);
-    return Void();
-  }
-
-  uint32_t metadata_size = physical_characteristics->GetCameraMetadataSize();
-  hidl_characteristics.setToExternal(
-      (uint8_t*)physical_characteristics->ReleaseCameraMetadata(),
-      metadata_size, /*shouldOwn=*/true);
-
-  _hidl_cb(Status::OK, hidl_characteristics);
-  return Void();
-}
-
-Return<void> HidlCameraDevice::isStreamCombinationSupported(
-    const V3_4::StreamConfiguration& streams,
-    ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) {
-  StreamConfiguration streams3_7;
-
-  hidl_utils::ConvertStreamConfigurationV34ToV37(streams, &streams3_7);
-
-  return isStreamCombinationSupported_3_7(streams3_7, _hidl_cb);
-}
-
-Return<void> HidlCameraDevice::isStreamCombinationSupported_3_7(
-    const V3_7::StreamConfiguration& streams,
-    ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) {
-  bool is_supported = false;
-  google_camera_hal::StreamConfiguration stream_config;
-  status_t res = hidl_utils::ConverToHalStreamConfig(streams, &stream_config);
-  if (res != OK) {
-    ALOGE("%s: ConverToHalStreamConfig fail", __FUNCTION__);
-    _hidl_cb(Status::INTERNAL_ERROR, is_supported);
-    return Void();
-  }
-  is_supported =
-      google_camera_device_->IsStreamCombinationSupported(stream_config);
-
-  _hidl_cb(Status::OK, is_supported);
-  return Void();
-}
-
-}  // namespace implementation
-}  // namespace V3_7
-}  // namespace device
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
diff --git a/common/hal/hidl_service/hidl_camera_device.h b/common/hal/hidl_service/hidl_camera_device.h
deleted file mode 100644
index 824d64d..0000000
--- a/common/hal/hidl_service/hidl_camera_device.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_DEVICE_H_
-#define HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_DEVICE_H_
-
-#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
-#include <android/hardware/camera/device/3.7/ICameraDevice.h>
-
-#include "camera_device.h"
-#include "hidl_profiler.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace device {
-namespace V3_7 {
-namespace implementation {
-
-using ::android::hardware::camera::common::V1_0::CameraResourceCost;
-using ::android::hardware::camera::common::V1_0::Status;
-using ::android::hardware::camera::common::V1_0::TorchMode;
-using ::android::hardware::camera::device::V3_5::ICameraDeviceCallback;
-using ::android::hardware::camera::device::V3_7::ICameraDevice;
-using ::android::hardware::camera::implementation::HidlProfiler;
-
-using ::android::google_camera_hal::CameraDevice;
-
-// HidlCameraDevice implements the HIDL camera device interface, ICameraDevice,
-// using Google Camera HAL to provide information about the associated camera
-// device.
-class HidlCameraDevice : public ICameraDevice {
- public:
-  static const std::string kDeviceVersion;
-
-  // Create a HidlCameraDevice.
-  // google_camera_device is a google camera device that HidlCameraDevice
-  // is going to manage. Creating a HidlCameraDevice will fail if
-  // google_camera_device is nullptr.
-  static std::unique_ptr<HidlCameraDevice> Create(
-      std::unique_ptr<CameraDevice> google_camera_device);
-  virtual ~HidlCameraDevice() = default;
-
-  // Override functions in ICameraDevice
-  Return<void> getResourceCost(
-      ICameraDevice::getResourceCost_cb _hidl_cb) override;
-
-  Return<void> getCameraCharacteristics(
-      ICameraDevice::getCameraCharacteristics_cb _hidl_cb) override;
-
-  Return<Status> setTorchMode(TorchMode mode) override;
-
-  Return<void> open(const sp<V3_2::ICameraDeviceCallback>& callback,
-                    ICameraDevice::open_cb _hidl_cb) override;
-
-  Return<void> dumpState(const ::android::hardware::hidl_handle& handle) override;
-
-  Return<void> getPhysicalCameraCharacteristics(
-      const hidl_string& physicalCameraId,
-      ICameraDevice::getPhysicalCameraCharacteristics_cb _hidl_cb) override;
-
-  Return<void> isStreamCombinationSupported(
-      const V3_4::StreamConfiguration& streams,
-      ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) override;
-
-  Return<void> isStreamCombinationSupported_3_7(
-      const StreamConfiguration& streams,
-      ICameraDevice::isStreamCombinationSupported_cb _hidl_cb) override;
-
-  // End of override functions in ICameraDevice
-
- protected:
-  HidlCameraDevice() = default;
-
- private:
-  status_t Initialize(std::unique_ptr<CameraDevice> google_camera_device);
-
-  std::unique_ptr<CameraDevice> google_camera_device_;
-  uint32_t camera_id_ = 0;
-  std::shared_ptr<HidlProfiler> hidl_profiler_;
-};
-
-}  // namespace implementation
-}  // namespace V3_7
-}  // namespace device
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_DEVICE_H_
diff --git a/common/hal/hidl_service/hidl_camera_device_session.cc b/common/hal/hidl_service/hidl_camera_device_session.cc
deleted file mode 100644
index 3af335e..0000000
--- a/common/hal/hidl_service/hidl_camera_device_session.cc
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define LOG_TAG "GCH_HidlCameraDeviceSession"
-#define ATRACE_TAG ATRACE_TAG_CAMERA
-//#define LOG_NDEBUG 0
-#include "hidl_camera_device_session.h"
-
-#include <cutils/properties.h>
-#include <cutils/trace.h>
-#include <log/log.h>
-#include <malloc.h>
-#include <utils/Trace.h>
-
-#include "hidl_profiler.h"
-#include "hidl_utils.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace device {
-namespace V3_7 {
-namespace implementation {
-
-namespace hidl_utils = ::android::hardware::camera::implementation::hidl_utils;
-
-using ::android::hardware::camera::device::V3_2::NotifyMsg;
-using ::android::hardware::camera::device::V3_2::StreamBuffer;
-using ::android::hardware::camera::device::V3_4::CaptureResult;
-using ::android::hardware::camera::device::V3_5::BufferRequest;
-using ::android::hardware::camera::device::V3_5::BufferRequestStatus;
-using ::android::hardware::camera::device::V3_5::StreamBufferRet;
-using ::android::hardware::camera::device::V3_5::StreamBuffersVal;
-using ::android::hardware::camera::device::V3_6::HalStreamConfiguration;
-using ::android::hardware::thermal::V1_0::ThermalStatus;
-using ::android::hardware::thermal::V1_0::ThermalStatusCode;
-using ::android::hardware::thermal::V2_0::Temperature;
-using ::android::hardware::thermal::V2_0::TemperatureType;
-
-std::unique_ptr<HidlCameraDeviceSession> HidlCameraDeviceSession::Create(
-    const sp<V3_2::ICameraDeviceCallback>& callback,
-    std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
-    std::shared_ptr<HidlProfiler> hidl_profiler) {
-  ATRACE_NAME("HidlCameraDeviceSession::Create");
-  auto session =
-      std::unique_ptr<HidlCameraDeviceSession>(new HidlCameraDeviceSession());
-  if (session == nullptr) {
-    ALOGE("%s: Cannot create a HidlCameraDeviceSession.", __FUNCTION__);
-    return nullptr;
-  }
-
-  status_t res =
-      session->Initialize(callback, std::move(device_session), hidl_profiler);
-  if (res != OK) {
-    ALOGE("%s: Initializing HidlCameraDeviceSession failed: %s(%d)",
-          __FUNCTION__, strerror(-res), res);
-    return nullptr;
-  }
-
-  return session;
-}
-
-HidlCameraDeviceSession::~HidlCameraDeviceSession() {
-  ATRACE_NAME("HidlCameraDeviceSession::~HidlCameraDeviceSession");
-  close();
-  // camera's closing, so flush any unused malloc pages
-  mallopt(M_PURGE, 0);
-}
-
-void HidlCameraDeviceSession::ProcessCaptureResult(
-    std::unique_ptr<google_camera_hal::CaptureResult> hal_result) {
-  std::shared_lock lock(hidl_device_callback_lock_);
-  if (hidl_device_callback_ == nullptr) {
-    ALOGE("%s: hidl_device_callback_ is nullptr", __FUNCTION__);
-    return;
-  }
-
-  {
-    std::lock_guard<std::mutex> pending_lock(pending_first_frame_buffers_mutex_);
-    if (!hal_result->output_buffers.empty() &&
-        num_pending_first_frame_buffers_ > 0 &&
-        first_request_frame_number_ == hal_result->frame_number) {
-      num_pending_first_frame_buffers_ -= hal_result->output_buffers.size();
-      if (num_pending_first_frame_buffers_ == 0) {
-        ALOGI("%s: First frame done", __FUNCTION__);
-        hidl_profiler_->FirstFrameEnd();
-        ATRACE_ASYNC_END("first_frame", 0);
-        ATRACE_ASYNC_END("switch_mode", 0);
-      }
-    }
-  }
-  for (auto& buffer : hal_result->output_buffers) {
-    hidl_profiler_->ProfileFrameRate("Stream " +
-                                     std::to_string(buffer.stream_id));
-  }
-
-  hidl_vec<CaptureResult> hidl_results(1);
-  status_t res = hidl_utils::ConvertToHidlCaptureResult(
-      result_metadata_queue_.get(), std::move(hal_result), &hidl_results[0]);
-  if (res != OK) {
-    ALOGE("%s: Converting to HIDL result failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return;
-  }
-
-  auto hidl_res = hidl_device_callback_->processCaptureResult_3_4(hidl_results);
-  if (!hidl_res.isOk()) {
-    ALOGE("%s: processCaptureResult transaction failed: %s.", __FUNCTION__,
-          hidl_res.description().c_str());
-    return;
-  }
-}
-
-void HidlCameraDeviceSession::NotifyHalMessage(
-    const google_camera_hal::NotifyMessage& hal_message) {
-  std::shared_lock lock(hidl_device_callback_lock_);
-  if (hidl_device_callback_ == nullptr) {
-    ALOGE("%s: hidl_device_callback_ is nullptr", __FUNCTION__);
-    return;
-  }
-
-  hidl_vec<NotifyMsg> hidl_messages(1);
-  status_t res =
-      hidl_utils::ConverToHidlNotifyMessage(hal_message, &hidl_messages[0]);
-  if (res != OK) {
-    ALOGE("%s: Converting to HIDL message failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return;
-  }
-
-  auto hidl_res = hidl_device_callback_->notify(hidl_messages);
-  if (!hidl_res.isOk()) {
-    ALOGE("%s: notify transaction failed: %s.", __FUNCTION__,
-          hidl_res.description().c_str());
-    return;
-  }
-}
-
-google_camera_hal::BufferRequestStatus
-HidlCameraDeviceSession::RequestStreamBuffers(
-    const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
-    std::vector<google_camera_hal::BufferReturn>* hal_buffer_returns) {
-  std::shared_lock lock(hidl_device_callback_lock_);
-  if (hidl_device_callback_ == nullptr) {
-    ALOGE("%s: hidl_device_callback_ is nullptr", __FUNCTION__);
-    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
-  }
-
-  if (hal_buffer_returns == nullptr) {
-    ALOGE("%s: hal_buffer_returns is nullptr", __FUNCTION__);
-    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
-  }
-
-  hidl_vec<BufferRequest> hidl_buffer_requests;
-  status_t res = hidl_utils::ConvertToHidlBufferRequest(hal_buffer_requests,
-                                                        &hidl_buffer_requests);
-  if (res != OK) {
-    ALOGE("%s: Converting to Hidl buffer request failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
-  }
-
-  BufferRequestStatus hidl_status;
-  hidl_vec<StreamBufferRet> stream_buffer_returns;
-  auto cb_status = hidl_device_callback_->requestStreamBuffers(
-      hidl_buffer_requests, [&hidl_status, &stream_buffer_returns](
-                                BufferRequestStatus status_ret,
-                                const hidl_vec<StreamBufferRet>& buffer_ret) {
-        hidl_status = status_ret;
-        stream_buffer_returns = std::move(buffer_ret);
-      });
-  if (!cb_status.isOk()) {
-    ALOGE("%s: Transaction request stream buffers error: %s", __FUNCTION__,
-          cb_status.description().c_str());
-    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
-  }
-
-  google_camera_hal::BufferRequestStatus hal_buffer_request_status;
-  res = hidl_utils::ConvertToHalBufferRequestStatus(hidl_status,
-                                                    &hal_buffer_request_status);
-  if (res != OK) {
-    ALOGE("%s: Converting to Hal buffer request status failed: %s(%d)",
-          __FUNCTION__, strerror(-res), res);
-    return google_camera_hal::BufferRequestStatus::kFailedUnknown;
-  }
-
-  hal_buffer_returns->clear();
-  // Converting HIDL stream buffer returns to HAL stream buffer returns.
-  for (auto& stream_buffer_return : stream_buffer_returns) {
-    google_camera_hal::BufferReturn hal_buffer_return;
-    res = hidl_utils::ConvertToHalBufferReturnStatus(stream_buffer_return,
-                                                     &hal_buffer_return);
-    if (res != OK) {
-      ALOGE("%s: Converting to Hal buffer return status failed: %s(%d)",
-            __FUNCTION__, strerror(-res), res);
-      return google_camera_hal::BufferRequestStatus::kFailedUnknown;
-    }
-
-    if (stream_buffer_return.val.getDiscriminator() ==
-        V3_5::StreamBuffersVal::hidl_discriminator::buffers) {
-      const hidl_vec<StreamBuffer>& hidl_buffers =
-          stream_buffer_return.val.buffers();
-      for (auto& hidl_buffer : hidl_buffers) {
-        google_camera_hal::StreamBuffer hal_buffer = {};
-        hidl_utils::ConvertToHalStreamBuffer(hidl_buffer, &hal_buffer);
-        if (res != OK) {
-          ALOGE("%s: Converting to Hal stream buffer failed: %s(%d)",
-                __FUNCTION__, strerror(-res), res);
-          return google_camera_hal::BufferRequestStatus::kFailedUnknown;
-        }
-
-        if (hidl_buffer.acquireFence.getNativeHandle() != nullptr) {
-          hal_buffer.acquire_fence =
-              native_handle_clone(hidl_buffer.acquireFence.getNativeHandle());
-          if (hal_buffer.acquire_fence == nullptr) {
-            ALOGE("%s: Cloning Hal stream buffer acquire fence failed",
-                  __FUNCTION__);
-          }
-        }
-
-        hal_buffer.release_fence = nullptr;
-        // If buffer handle is not null, we need to import buffer handle and
-        // return to the caller.
-        if (hidl_buffer.buffer.getNativeHandle() != nullptr) {
-          if (buffer_mapper_v4_ != nullptr) {
-            hal_buffer.buffer = ImportBufferHandle<
-                android::hardware::graphics::mapper::V4_0::IMapper,
-                android::hardware::graphics::mapper::V4_0::Error>(
-                buffer_mapper_v4_, hidl_buffer.buffer);
-          } else if (buffer_mapper_v3_ != nullptr) {
-            hal_buffer.buffer = ImportBufferHandle<
-                android::hardware::graphics::mapper::V3_0::IMapper,
-                android::hardware::graphics::mapper::V3_0::Error>(
-                buffer_mapper_v3_, hidl_buffer.buffer);
-          } else {
-            hal_buffer.buffer = ImportBufferHandle<
-                android::hardware::graphics::mapper::V2_0::IMapper,
-                android::hardware::graphics::mapper::V2_0::Error>(
-                buffer_mapper_v2_, hidl_buffer.buffer);
-          }
-        }
-
-        hal_buffer_return.val.buffers.push_back(hal_buffer);
-      }
-    }
-
-    hal_buffer_returns->push_back(hal_buffer_return);
-  }
-
-  return hal_buffer_request_status;
-}
-
-template <class T, class U>
-buffer_handle_t HidlCameraDeviceSession::ImportBufferHandle(
-    const sp<T> buffer_mapper_, const hidl_handle& buffer_hidl_handle) {
-  U mapper_error;
-  buffer_handle_t imported_buffer_handle;
-
-  auto hidl_res = buffer_mapper_->importBuffer(
-      buffer_hidl_handle, [&](const auto& error, const auto& buffer_handle) {
-        mapper_error = error;
-        imported_buffer_handle = static_cast<buffer_handle_t>(buffer_handle);
-      });
-  if (!hidl_res.isOk() || mapper_error != U::NONE) {
-    ALOGE("%s: Importing buffer failed: %s, mapper error %u", __FUNCTION__,
-          hidl_res.description().c_str(), mapper_error);
-    return nullptr;
-  }
-
-  return imported_buffer_handle;
-}
-
-void HidlCameraDeviceSession::ReturnStreamBuffers(
-    const std::vector<google_camera_hal::StreamBuffer>& return_hal_buffers) {
-  std::shared_lock lock(hidl_device_callback_lock_);
-  if (hidl_device_callback_ == nullptr) {
-    ALOGE("%s: hidl_device_callback_ is nullptr", __FUNCTION__);
-    return;
-  }
-
-  status_t res = OK;
-  hidl_vec<StreamBuffer> hidl_return_buffers;
-  hidl_return_buffers.resize(return_hal_buffers.size());
-  for (uint32_t i = 0; i < return_hal_buffers.size(); i++) {
-    res = hidl_utils::ConvertToHidlStreamBuffer(return_hal_buffers[i],
-                                                &hidl_return_buffers[i]);
-    if (res != OK) {
-      ALOGE("%s: Converting to Hidl stream buffer failed: %s(%d)", __FUNCTION__,
-            strerror(-res), res);
-      return;
-    }
-  }
-
-  auto hidl_res =
-      hidl_device_callback_->returnStreamBuffers(hidl_return_buffers);
-  if (!hidl_res.isOk()) {
-    ALOGE("%s: return stream buffers transaction failed: %s.", __FUNCTION__,
-          hidl_res.description().c_str());
-    return;
-  }
-}
-
-status_t HidlCameraDeviceSession::InitializeBufferMapper() {
-  buffer_mapper_v4_ =
-      android::hardware::graphics::mapper::V4_0::IMapper::getService();
-  if (buffer_mapper_v4_ != nullptr) {
-    return OK;
-  }
-
-  buffer_mapper_v3_ =
-      android::hardware::graphics::mapper::V3_0::IMapper::getService();
-  if (buffer_mapper_v3_ != nullptr) {
-    return OK;
-  }
-
-  buffer_mapper_v2_ =
-      android::hardware::graphics::mapper::V2_0::IMapper::getService();
-  if (buffer_mapper_v2_ != nullptr) {
-    return OK;
-  }
-
-  ALOGE("%s: Getting buffer mapper failed.", __FUNCTION__);
-  return UNKNOWN_ERROR;
-}
-
-status_t HidlCameraDeviceSession::Initialize(
-    const sp<V3_2::ICameraDeviceCallback>& callback,
-    std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
-    std::shared_ptr<HidlProfiler> hidl_profiler) {
-  ATRACE_NAME("HidlCameraDeviceSession::Initialize");
-  if (device_session == nullptr) {
-    ALOGE("%s: device_session is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  if (hidl_profiler == nullptr) {
-    ALOGE("%s: hidl_profiler is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  status_t res = CreateMetadataQueue(&request_metadata_queue_,
-                                     kRequestMetadataQueueSizeBytes,
-                                     "ro.vendor.camera.req.fmq.size");
-  if (res != OK) {
-    ALOGE("%s: Creating request metadata queue failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  res = CreateMetadataQueue(&result_metadata_queue_,
-                            kResultMetadataQueueSizeBytes,
-                            "ro.vendor.camera.res.fmq.size");
-  if (res != OK) {
-    ALOGE("%s: Creating result metadata queue failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  // Cast V3.2 callback to V3.5
-  auto cast_res = ICameraDeviceCallback::castFrom(callback);
-  if (!cast_res.isOk()) {
-    ALOGE("%s: Cannot convert to V3.5 device callback.", __FUNCTION__);
-    return UNKNOWN_ERROR;
-  }
-
-  // Initialize buffer mapper
-  res = InitializeBufferMapper();
-  if (res != OK) {
-    ALOGE("%s: Initialize buffer mapper failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  thermal_ = android::hardware::thermal::V2_0::IThermal::getService();
-  if (thermal_ == nullptr) {
-    ALOGE("%s: Getting thermal failed.", __FUNCTION__);
-    // Continue without getting thermal information.
-  }
-
-  hidl_device_callback_ = cast_res;
-  device_session_ = std::move(device_session);
-  hidl_profiler_ = hidl_profiler;
-
-  SetSessionCallbacks();
-  return OK;
-}
-
-void HidlCameraDeviceSession::SetSessionCallbacks() {
-  google_camera_hal::CameraDeviceSessionCallback session_callback = {
-      .process_capture_result = google_camera_hal::ProcessCaptureResultFunc(
-          [this](std::unique_ptr<google_camera_hal::CaptureResult> result) {
-            ProcessCaptureResult(std::move(result));
-          }),
-      .notify = google_camera_hal::NotifyFunc(
-          [this](const google_camera_hal::NotifyMessage& message) {
-            NotifyHalMessage(message);
-          }),
-      .request_stream_buffers = google_camera_hal::RequestStreamBuffersFunc(
-          [this](
-              const std::vector<google_camera_hal::BufferRequest>&
-                  hal_buffer_requests,
-              std::vector<google_camera_hal::BufferReturn>* hal_buffer_returns) {
-            return RequestStreamBuffers(hal_buffer_requests, hal_buffer_returns);
-          }),
-      .return_stream_buffers = google_camera_hal::ReturnStreamBuffersFunc(
-          [this](const std::vector<google_camera_hal::StreamBuffer>&
-                     return_hal_buffers) {
-            ReturnStreamBuffers(return_hal_buffers);
-          }),
-  };
-
-  google_camera_hal::ThermalCallback thermal_callback = {
-      .register_thermal_changed_callback =
-          google_camera_hal::RegisterThermalChangedCallbackFunc(
-              [this](google_camera_hal::NotifyThrottlingFunc notify_throttling,
-                     bool filter_type, google_camera_hal::TemperatureType type) {
-                return RegisterThermalChangedCallback(notify_throttling,
-                                                      filter_type, type);
-              }),
-      .unregister_thermal_changed_callback =
-          google_camera_hal::UnregisterThermalChangedCallbackFunc(
-              [this]() { UnregisterThermalChangedCallback(); }),
-  };
-
-  device_session_->SetSessionCallback(session_callback, thermal_callback);
-}
-
-status_t HidlCameraDeviceSession::RegisterThermalChangedCallback(
-    google_camera_hal::NotifyThrottlingFunc notify_throttling, bool filter_type,
-    google_camera_hal::TemperatureType type) {
-  std::lock_guard<std::mutex> lock(hidl_thermal_mutex_);
-  if (thermal_ == nullptr) {
-    ALOGE("%s: thermal was not initialized.", __FUNCTION__);
-    return NO_INIT;
-  }
-
-  if (thermal_changed_callback_ != nullptr) {
-    ALOGE("%s: thermal changed callback is already registered.", __FUNCTION__);
-    return ALREADY_EXISTS;
-  }
-
-  TemperatureType hidl_type;
-  status_t res =
-      hidl_thermal_utils::ConvertToHidlTemperatureType(type, &hidl_type);
-  if (res != OK) {
-    ALOGE("%s: Converting to HIDL type failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  std::unique_ptr<hidl_thermal_utils::HidlThermalChangedCallback> callback =
-      hidl_thermal_utils::HidlThermalChangedCallback::Create(notify_throttling);
-  thermal_changed_callback_ = callback.release();
-  ThermalStatus thermal_status;
-  auto hidl_res = thermal_->registerThermalChangedCallback(
-      thermal_changed_callback_, filter_type, hidl_type,
-      [&](ThermalStatus status) { thermal_status = status; });
-  if (!hidl_res.isOk() || thermal_status.code != ThermalStatusCode::SUCCESS) {
-    thermal_changed_callback_ = nullptr;
-    return UNKNOWN_ERROR;
-  }
-
-  return OK;
-}
-
-void HidlCameraDeviceSession::UnregisterThermalChangedCallback() {
-  std::lock_guard<std::mutex> lock(hidl_thermal_mutex_);
-  if (thermal_changed_callback_ == nullptr) {
-    // no-op if no thermal changed callback is registered.
-    return;
-  }
-
-  if (thermal_ == nullptr) {
-    ALOGE("%s: thermal was not initialized.", __FUNCTION__);
-    return;
-  }
-
-  ThermalStatus thermal_status;
-  auto hidl_res = thermal_->unregisterThermalChangedCallback(
-      thermal_changed_callback_,
-      [&](ThermalStatus status) { thermal_status = status; });
-  if (!hidl_res.isOk() || thermal_status.code != ThermalStatusCode::SUCCESS) {
-    ALOGW("%s: Unregstering thermal callback failed: %s", __FUNCTION__,
-          thermal_status.debugMessage.c_str());
-  }
-
-  thermal_changed_callback_ = nullptr;
-}
-
-status_t HidlCameraDeviceSession::CreateMetadataQueue(
-    std::unique_ptr<MetadataQueue>* metadata_queue, uint32_t default_size_bytes,
-    const char* override_size_property) {
-  if (metadata_queue == nullptr) {
-    ALOGE("%s: metadata_queue is nullptr", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  int32_t size = default_size_bytes;
-  if (override_size_property != nullptr) {
-    // Try to read the override size from the system property.
-    size = property_get_int32(override_size_property, default_size_bytes);
-    ALOGV("%s: request metadata queue size overridden to %d", __FUNCTION__,
-          size);
-  }
-
-  *metadata_queue = std::make_unique<MetadataQueue>(
-      static_cast<size_t>(size), /*configureEventFlagWord=*/false);
-  if (!(*metadata_queue)->isValid()) {
-    ALOGE("%s: Creating metadata queue (size %d) failed.", __FUNCTION__, size);
-    return NO_INIT;
-  }
-
-  return OK;
-}
-
-Return<void> HidlCameraDeviceSession::constructDefaultRequestSettings(
-    RequestTemplate type,
-    ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) {
-  ATRACE_NAME("HidlCameraDeviceSession::constructDefaultRequestSettings");
-  V3_2::CameraMetadata hidl_metadata;
-
-  if (device_session_ == nullptr) {
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_metadata);
-    return Void();
-  }
-
-  google_camera_hal::RequestTemplate hal_type;
-  status_t res = hidl_utils::ConvertToHalTemplateType(type, &hal_type);
-  if (res != OK) {
-    _hidl_cb(Status::ILLEGAL_ARGUMENT, hidl_metadata);
-    return Void();
-  }
-
-  std::unique_ptr<google_camera_hal::HalCameraMetadata> settings = nullptr;
-  res = device_session_->ConstructDefaultRequestSettings(hal_type, &settings);
-  if (res != OK) {
-    _hidl_cb(hidl_utils::ConvertToHidlStatus(res), hidl_metadata);
-    return Void();
-  }
-
-  uint32_t metadata_size = settings->GetCameraMetadataSize();
-  hidl_metadata.setToExternal((uint8_t*)settings->ReleaseCameraMetadata(),
-                              metadata_size, /*shouldOwn=*/true);
-  _hidl_cb(Status::OK, hidl_metadata);
-
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::configureStreams_3_7(
-    const StreamConfiguration& requestedConfiguration,
-    ICameraDeviceSession::configureStreams_3_6_cb _hidl_cb) {
-  ATRACE_NAME("HidlCameraDeviceSession::configureStreams_3_7");
-  HalStreamConfiguration hidl_hal_configs;
-  if (device_session_ == nullptr) {
-    _hidl_cb(Status::ILLEGAL_ARGUMENT, hidl_hal_configs);
-    return Void();
-  }
-
-  auto profiler = hidl_profiler_->MakeScopedProfiler(
-      HidlProfiler::ScopedType::kConfigureStream);
-
-  first_frame_requested_ = false;
-  num_pending_first_frame_buffers_ = 0;
-
-  google_camera_hal::StreamConfiguration hal_stream_config;
-  status_t res = hidl_utils::ConverToHalStreamConfig(requestedConfiguration,
-                                                     &hal_stream_config);
-  if (res != OK) {
-    _hidl_cb(Status::ILLEGAL_ARGUMENT, hidl_hal_configs);
-    return Void();
-  }
-
-  std::vector<google_camera_hal::HalStream> hal_configured_streams;
-  res = device_session_->ConfigureStreams(hal_stream_config,
-                                          &hal_configured_streams);
-  if (res != OK) {
-    ALOGE("%s: Configuring streams failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(hidl_utils::ConvertToHidlStatus(res), hidl_hal_configs);
-    return Void();
-  }
-
-  res = hidl_utils::ConvertToHidlHalStreamConfig(hal_configured_streams,
-                                                 &hidl_hal_configs);
-  _hidl_cb(hidl_utils::ConvertToHidlStatus(res), hidl_hal_configs);
-
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::getCaptureRequestMetadataQueue(
-    ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) {
-  _hidl_cb(*request_metadata_queue_->getDesc());
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::getCaptureResultMetadataQueue(
-    ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) {
-  _hidl_cb(*result_metadata_queue_->getDesc());
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::processCaptureRequest_3_7(
-    const hidl_vec<CaptureRequest>& requests,
-    const hidl_vec<BufferCache>& cachesToRemove,
-    processCaptureRequest_3_7_cb _hidl_cb) {
-  if (device_session_ == nullptr) {
-    _hidl_cb(Status::ILLEGAL_ARGUMENT, 0);
-    return Void();
-  }
-
-  bool profile_first_request = false;
-  if (!first_frame_requested_) {
-    first_frame_requested_ = true;
-    profile_first_request = true;
-    ATRACE_BEGIN("HidlCameraDeviceSession::FirstRequest");
-    num_pending_first_frame_buffers_ =
-        requests[0].v3_4.v3_2.outputBuffers.size();
-    first_request_frame_number_ = requests[0].v3_4.v3_2.frameNumber;
-    hidl_profiler_->FirstFrameStart();
-    ATRACE_ASYNC_BEGIN("first_frame", 0);
-  }
-
-  std::vector<google_camera_hal::BufferCache> hal_buffer_caches;
-
-  status_t res =
-      hidl_utils::ConvertToHalBufferCaches(cachesToRemove, &hal_buffer_caches);
-  if (res != OK) {
-    _hidl_cb(Status::ILLEGAL_ARGUMENT, 0);
-    if (profile_first_request) {
-      ATRACE_END();
-    }
-    return Void();
-  }
-
-  device_session_->RemoveBufferCache(hal_buffer_caches);
-
-  // Converting HIDL requests to HAL requests.
-  std::vector<google_camera_hal::CaptureRequest> hal_requests;
-  for (auto& request : requests) {
-    google_camera_hal::CaptureRequest hal_request = {};
-    res = hidl_utils::ConvertToHalCaptureRequest(
-        request, request_metadata_queue_.get(), &hal_request);
-    if (res != OK) {
-      ALOGE("%s: Converting to HAL capture request failed: %s(%d)",
-            __FUNCTION__, strerror(-res), res);
-      _hidl_cb(hidl_utils::ConvertToHidlStatus(res), 0);
-      if (profile_first_request) {
-        ATRACE_END();
-      }
-      return Void();
-    }
-
-    hal_requests.push_back(std::move(hal_request));
-  }
-
-  uint32_t num_processed_requests = 0;
-  res = device_session_->ProcessCaptureRequest(hal_requests,
-                                               &num_processed_requests);
-  if (res != OK) {
-    ALOGE(
-        "%s: Processing capture request failed: %s(%d). Only processed %u"
-        " out of %zu.",
-        __FUNCTION__, strerror(-res), res, num_processed_requests,
-        hal_requests.size());
-  }
-
-  _hidl_cb(hidl_utils::ConvertToHidlStatus(res), num_processed_requests);
-  if (profile_first_request) {
-    ATRACE_END();
-  }
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::signalStreamFlush(
-    const hidl_vec<int32_t>& /*streamIds*/, uint32_t /*streamConfigCounter*/) {
-  // TODO(b/143902312): Implement this.
-  return Void();
-}
-
-Return<Status> HidlCameraDeviceSession::flush() {
-  ATRACE_NAME("HidlCameraDeviceSession::flush");
-  ATRACE_ASYNC_BEGIN("switch_mode", 0);
-  if (device_session_ == nullptr) {
-    return Status::INTERNAL_ERROR;
-  }
-
-  hidl_profiler_->SetLatencyProfiler(device_session_->GetProfiler(
-      hidl_profiler_->GetCameraId(), hidl_profiler_->GetLatencyFlag()));
-  hidl_profiler_->SetFpsProfiler(device_session_->GetProfiler(
-      hidl_profiler_->GetCameraId(), hidl_profiler_->GetFpsFlag()));
-  auto profiler =
-      hidl_profiler_->MakeScopedProfiler(HidlProfiler::ScopedType::kFlush);
-
-  status_t res = device_session_->Flush();
-  if (res != OK) {
-    ALOGE("%s: Flushing device failed: %s(%d).", __FUNCTION__, strerror(-res),
-          res);
-    return Status::INTERNAL_ERROR;
-  }
-
-  return Status::OK;
-}
-
-Return<void> HidlCameraDeviceSession::close() {
-  ATRACE_NAME("HidlCameraDeviceSession::close");
-  if (device_session_ != nullptr) {
-    auto profiler =
-        hidl_profiler_->MakeScopedProfiler(HidlProfiler::ScopedType::kClose);
-    device_session_ = nullptr;
-  }
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::isReconfigurationRequired(
-    const V3_2::CameraMetadata& oldSessionParams,
-    const V3_2::CameraMetadata& newSessionParams,
-    ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) {
-  ATRACE_NAME("HidlCameraDeviceSession::isReconfigurationRequired");
-  std::unique_ptr<google_camera_hal::HalCameraMetadata> old_hal_session_metadata;
-  status_t res = hidl_utils::ConvertToHalMetadata(0, nullptr, oldSessionParams,
-                                                  &old_hal_session_metadata);
-  if (res != OK) {
-    ALOGE("%s: Converting to old session metadata failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, true);
-    return Void();
-  }
-
-  std::unique_ptr<google_camera_hal::HalCameraMetadata> new_hal_session_metadata;
-  res = hidl_utils::ConvertToHalMetadata(0, nullptr, newSessionParams,
-                                         &new_hal_session_metadata);
-  if (res != OK) {
-    ALOGE("%s: Converting to new session metadata failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, true);
-    return Void();
-  }
-
-  bool reconfiguration_required = true;
-  res = device_session_->IsReconfigurationRequired(
-      old_hal_session_metadata.get(), new_hal_session_metadata.get(),
-      &reconfiguration_required);
-
-  if (res != OK) {
-    ALOGE("%s: IsReconfigurationRequired failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, true);
-    return Void();
-  }
-
-  _hidl_cb(Status::OK, reconfiguration_required);
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::configureStreams(
-    const V3_2::StreamConfiguration&, configureStreams_cb _hidl_cb) {
-  _hidl_cb(Status::ILLEGAL_ARGUMENT, V3_2::HalStreamConfiguration());
-  return Void();
-}
-Return<void> HidlCameraDeviceSession::configureStreams_3_3(
-    const V3_2::StreamConfiguration&, configureStreams_3_3_cb _hidl_cb) {
-  _hidl_cb(Status::ILLEGAL_ARGUMENT, V3_3::HalStreamConfiguration());
-  return Void();
-}
-Return<void> HidlCameraDeviceSession::configureStreams_3_4(
-    const V3_4::StreamConfiguration&, configureStreams_3_4_cb _hidl_cb) {
-  _hidl_cb(Status::ILLEGAL_ARGUMENT, V3_4::HalStreamConfiguration());
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::configureStreams_3_5(
-    const V3_5::StreamConfiguration& requestedConfiguration,
-    configureStreams_3_5_cb _hidl_cb) {
-  configureStreams_3_6(
-      requestedConfiguration,
-      [_hidl_cb](Status s, device::V3_6::HalStreamConfiguration halConfig) {
-        V3_4::HalStreamConfiguration halConfig3_4;
-        halConfig3_4.streams.resize(halConfig.streams.size());
-        for (size_t i = 0; i < halConfig.streams.size(); i++) {
-          halConfig3_4.streams[i] = halConfig.streams[i].v3_4;
-        }
-        _hidl_cb(s, halConfig3_4);
-      });
-
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::configureStreams_3_6(
-    const V3_5::StreamConfiguration& requestedConfiguration,
-    configureStreams_3_6_cb _hidl_cb) {
-  StreamConfiguration requestedConfiguration3_7;
-  requestedConfiguration3_7.streams.resize(
-      requestedConfiguration.v3_4.streams.size());
-  for (size_t i = 0; i < requestedConfiguration.v3_4.streams.size(); i++) {
-    requestedConfiguration3_7.streams[i].v3_4 =
-        requestedConfiguration.v3_4.streams[i];
-    requestedConfiguration3_7.streams[i].groupId = -1;
-  }
-  requestedConfiguration3_7.operationMode =
-      requestedConfiguration.v3_4.operationMode;
-  requestedConfiguration3_7.sessionParams =
-      requestedConfiguration.v3_4.sessionParams;
-  requestedConfiguration3_7.streamConfigCounter =
-      requestedConfiguration.streamConfigCounter;
-  requestedConfiguration3_7.multiResolutionInputImage = false;
-
-  configureStreams_3_7(requestedConfiguration3_7, _hidl_cb);
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::switchToOffline(
-    const hidl_vec<int32_t>&, switchToOffline_cb _hidl_cb) {
-  _hidl_cb(Status::ILLEGAL_ARGUMENT, V3_6::CameraOfflineSessionInfo(), nullptr);
-  return Void();
-}
-
-Return<void> HidlCameraDeviceSession::processCaptureRequest(
-    const hidl_vec<V3_2::CaptureRequest>& requests,
-    const hidl_vec<BufferCache>& cachesToRemove,
-    processCaptureRequest_cb _hidl_cb) {
-  hidl_vec<V3_4::CaptureRequest> requests_3_4;
-  requests_3_4.resize(requests.size());
-  for (uint32_t i = 0; i < requests_3_4.size(); i++) {
-    requests_3_4[i].v3_2 = requests[i];
-  }
-
-  return processCaptureRequest_3_4(requests_3_4, cachesToRemove, _hidl_cb);
-}
-
-Return<void> HidlCameraDeviceSession::processCaptureRequest_3_4(
-    const hidl_vec<V3_4::CaptureRequest>& requests,
-    const hidl_vec<BufferCache>& cachesToRemove,
-    processCaptureRequest_cb _hidl_cb) {
-  hidl_vec<V3_7::CaptureRequest> requests_3_7;
-  requests_3_7.resize(requests.size());
-  for (uint32_t i = 0; i < requests_3_7.size(); i++) {
-    requests_3_7[i].v3_4 = requests[i];
-  }
-
-  return processCaptureRequest_3_7(requests_3_7, cachesToRemove, _hidl_cb);
-}
-
-}  // namespace implementation
-}  // namespace V3_7
-}  // namespace device
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
diff --git a/common/hal/hidl_service/hidl_camera_device_session.h b/common/hal/hidl_service/hidl_camera_device_session.h
deleted file mode 100644
index ea2b600..0000000
--- a/common/hal/hidl_service/hidl_camera_device_session.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_DEVICE_SESSION_H_
-#define HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_DEVICE_SESSION_H_
-
-#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
-#include <android/hardware/camera/device/3.7/ICameraDevice.h>
-#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
-#include <android/hardware/thermal/2.0/IThermal.h>
-#include <fmq/MessageQueue.h>
-
-#include <shared_mutex>
-
-#include "camera_device_session.h"
-#include "hidl_profiler.h"
-#include "hidl_thermal_utils.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace device {
-namespace V3_7 {
-namespace implementation {
-
-using ::android::hardware::camera::common::V1_0::Status;
-using ::android::hardware::camera::device::V3_2::BufferCache;
-using ::android::hardware::camera::device::V3_2::RequestTemplate;
-using ::android::hardware::camera::device::V3_5::ICameraDeviceCallback;
-using ::android::hardware::camera::device::V3_7::CaptureRequest;
-using ::android::hardware::camera::device::V3_7::ICameraDeviceSession;
-using ::android::hardware::camera::device::V3_7::StreamConfiguration;
-using ::android::hardware::camera::implementation::HidlProfiler;
-
-using MetadataQueue =
-    ::android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-// HidlCameraDeviceSession implements the HIDL camera device session interface,
-// ICameraDeviceSession, that contains the methods to configure and request
-// captures from an active camera device.
-class HidlCameraDeviceSession : public ICameraDeviceSession {
- public:
-  // Create a HidlCameraDeviceSession.
-  // device_session is a google camera device session that
-  // HidlCameraDeviceSession is going to manage. Creating a
-  // HidlCameraDeviceSession will fail if device_session is
-  // nullptr.
-  static std::unique_ptr<HidlCameraDeviceSession> Create(
-      const sp<V3_2::ICameraDeviceCallback>& callback,
-      std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
-      std::shared_ptr<HidlProfiler> hidl_profiler);
-
-  virtual ~HidlCameraDeviceSession();
-
-  // Override functions in ICameraDeviceSession
-  Return<void> configureStreams_3_7(
-      const StreamConfiguration& requestedConfiguration,
-      configureStreams_3_7_cb _hidl_cb) override;
-
-  Return<void> processCaptureRequest_3_7(
-      const hidl_vec<CaptureRequest>& requests,
-      const hidl_vec<BufferCache>& cachesToRemove,
-      processCaptureRequest_3_7_cb _hidl_cb) override;
-
-  Return<void> configureStreams_3_6(
-      const V3_5::StreamConfiguration& requestedConfiguration,
-      ICameraDeviceSession::configureStreams_3_6_cb _hidl_cb) override;
-
-  Return<void> switchToOffline(const hidl_vec<int32_t>& streamsToKeep,
-                               switchToOffline_cb _hidl_cb) override;
-
-  Return<void> constructDefaultRequestSettings(
-      RequestTemplate type,
-      ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override;
-
-  Return<void> configureStreams_3_5(
-      const V3_5::StreamConfiguration& requestedConfiguration,
-      ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb) override;
-
-  Return<void> getCaptureRequestMetadataQueue(
-      ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override;
-
-  Return<void> getCaptureResultMetadataQueue(
-      ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override;
-
-  Return<void> processCaptureRequest_3_4(
-      const hidl_vec<V3_4::CaptureRequest>& requests,
-      const hidl_vec<BufferCache>& cachesToRemove,
-      processCaptureRequest_3_4_cb _hidl_cb) override;
-
-  Return<void> signalStreamFlush(const hidl_vec<int32_t>& streamIds,
-                                 uint32_t streamConfigCounter) override;
-
-  Return<void> isReconfigurationRequired(const V3_2::CameraMetadata& oldSessionParams,
-      const V3_2::CameraMetadata& newSessionParams,
-      ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) override;
-
-  Return<Status> flush() override;
-
-  Return<void> close() override;
-
-  // Legacy methods
-  Return<void> configureStreams(const V3_2::StreamConfiguration&,
-                                configureStreams_cb _hidl_cb) override;
-
-  Return<void> configureStreams_3_3(const V3_2::StreamConfiguration&,
-                                    configureStreams_3_3_cb _hidl_cb) override;
-
-  Return<void> configureStreams_3_4(const V3_4::StreamConfiguration&,
-                                    configureStreams_3_4_cb _hidl_cb) override;
-
-  Return<void> processCaptureRequest(
-      const hidl_vec<V3_2::CaptureRequest>& requests,
-      const hidl_vec<BufferCache>& cachesToRemove,
-      processCaptureRequest_cb _hidl_cb) override;
-  // End of override functions in ICameraDeviceSession
-
- protected:
-  HidlCameraDeviceSession() = default;
-
- private:
-  static constexpr uint32_t kRequestMetadataQueueSizeBytes = 1 << 20;  // 1MB
-  static constexpr uint32_t kResultMetadataQueueSizeBytes = 1 << 20;   // 1MB
-
-  // Initialize the latest available gralloc buffer mapper.
-  status_t InitializeBufferMapper();
-
-  // Initialize HidlCameraDeviceSession with a CameraDeviceSession.
-  status_t Initialize(
-      const sp<V3_2::ICameraDeviceCallback>& callback,
-      std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session,
-      std::shared_ptr<HidlProfiler> hidl_profiler);
-
-  // Create a metadata queue.
-  // If override_size_property contains a valid size, it will create a metadata
-  // queue of that size. If it override_size_property doesn't contain a valid
-  // size, it will create a metadata queue of the default size.
-  // default_size_bytes is the default size of the message queue in bytes.
-  // override_size_property is the name of the system property that contains
-  // the message queue size.
-  status_t CreateMetadataQueue(std::unique_ptr<MetadataQueue>* metadata_queue,
-                               uint32_t default_size_bytes,
-                               const char* override_size_property);
-
-  // Invoked when receiving a result from HAL.
-  void ProcessCaptureResult(
-      std::unique_ptr<google_camera_hal::CaptureResult> hal_result);
-
-  // Invoked when reciving a message from HAL.
-  void NotifyHalMessage(const google_camera_hal::NotifyMessage& hal_message);
-
-  // Invoked when requesting stream buffers from HAL.
-  google_camera_hal::BufferRequestStatus RequestStreamBuffers(
-      const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
-      std::vector<google_camera_hal::BufferReturn>* hal_buffer_returns);
-
-  // Invoked when returning stream buffers from HAL.
-  void ReturnStreamBuffers(
-      const std::vector<google_camera_hal::StreamBuffer>& return_hal_buffers);
-
-  // Import a buffer handle.
-  template <class T, class U>
-  buffer_handle_t ImportBufferHandle(const sp<T> buffer_mapper_,
-                                     const hidl_handle& buffer_hidl_handle);
-
-  // Set camera device session callbacks.
-  void SetSessionCallbacks();
-
-  // Register a thermal changed callback.
-  // notify_throttling will be invoked when thermal status changes.
-  // If filter_type is false, type will be ignored and all types will be
-  // monitored.
-  // If filter_type is true, only type will be monitored.
-  status_t RegisterThermalChangedCallback(
-      google_camera_hal::NotifyThrottlingFunc notify_throttling,
-      bool filter_type, google_camera_hal::TemperatureType type);
-
-  // Unregister thermal changed callback.
-  void UnregisterThermalChangedCallback();
-
-  std::unique_ptr<google_camera_hal::CameraDeviceSession> device_session_;
-
-  // Metadata queue to read the request metadata from.
-  std::unique_ptr<MetadataQueue> request_metadata_queue_;
-
-  // Metadata queue to write the result metadata to.
-  std::unique_ptr<MetadataQueue> result_metadata_queue_;
-
-  // Assuming callbacks to framework is thread-safe, the shared mutex is only
-  // used to protect member variable writing and reading.
-  std::shared_mutex hidl_device_callback_lock_;
-  // Protected by hidl_device_callback_lock_
-  sp<ICameraDeviceCallback> hidl_device_callback_;
-
-  sp<android::hardware::graphics::mapper::V2_0::IMapper> buffer_mapper_v2_;
-  sp<android::hardware::graphics::mapper::V3_0::IMapper> buffer_mapper_v3_;
-  sp<android::hardware::graphics::mapper::V4_0::IMapper> buffer_mapper_v4_;
-
-  std::mutex hidl_thermal_mutex_;
-  sp<android::hardware::thermal::V2_0::IThermal> thermal_;
-
-  // Must be protected by hidl_thermal_mutex_.
-  sp<android::hardware::thermal::V2_0::IThermalChangedCallback>
-      thermal_changed_callback_;
-
-  // Flag for profiling first frame processing time.
-  bool first_frame_requested_ = false;
-
-  // The frame number of first capture request after configure stream
-  uint32_t first_request_frame_number_ = 0;
-
-  std::mutex pending_first_frame_buffers_mutex_;
-  // Profiling first frame process time. Stop timer when it become 0.
-  // Must be protected by pending_first_frame_buffers_mutex_
-  size_t num_pending_first_frame_buffers_ = 0;
-
-  std::shared_ptr<HidlProfiler> hidl_profiler_;
-};
-
-}  // namespace implementation
-}  // namespace V3_7
-}  // namespace device
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_DEVICE_SESSION_H_
diff --git a/common/hal/hidl_service/hidl_camera_provider.cc b/common/hal/hidl_service/hidl_camera_provider.cc
deleted file mode 100644
index 528d23d..0000000
--- a/common/hal/hidl_service/hidl_camera_provider.cc
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define LOG_TAG "GCH_HidlCameraProvider"
-//#define LOG_NDEBUG 0
-#include <log/log.h>
-#include <regex>
-
-#include "camera_device.h"
-#include "hidl_camera_device.h"
-#include "hidl_camera_provider.h"
-#include "hidl_utils.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace provider {
-namespace V2_7 {
-namespace implementation {
-
-namespace hidl_utils = ::android::hardware::camera::implementation::hidl_utils;
-
-using ::android::google_camera_hal::CameraDevice;
-using ::android::hardware::Void;
-using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
-using ::android::hardware::camera::common::V1_0::TorchModeStatus;
-using ::android::hardware::camera::common::V1_0::VendorTagSection;
-
-const std::string HidlCameraProvider::kProviderName = "internal";
-// "device@<version>/internal/<id>"
-const std::regex HidlCameraProvider::kDeviceNameRegex(
-    "device@([0-9]+\\.[0-9]+)/internal/(.+)");
-
-android::sp<HidlCameraProvider> HidlCameraProvider::Create() {
-  android::sp<HidlCameraProvider> provider = new HidlCameraProvider();
-
-  status_t res = provider->Initialize();
-  if (res != OK) {
-    ALOGE("%s: Initializing HidlCameraProvider failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return nullptr;
-  }
-
-  return provider;
-}
-
-status_t HidlCameraProvider::Initialize() {
-  google_camera_provider_ = CameraProvider::Create();
-  if (google_camera_provider_ == nullptr) {
-    ALOGE("%s: Creating CameraProvider failed.", __FUNCTION__);
-    return NO_INIT;
-  }
-
-  camera_provider_callback_ = {
-      .camera_device_status_change = google_camera_hal::CameraDeviceStatusChangeFunc(
-          [this](std::string camera_id,
-                 google_camera_hal::CameraDeviceStatus new_status) {
-            if (callbacks_ == nullptr) {
-              ALOGE("%s: callbacks_ is null", __FUNCTION__);
-              return;
-            }
-            CameraDeviceStatus hidl_camera_device_status;
-            status_t res = hidl_utils::ConvertToHidlCameraDeviceStatus(
-                new_status, &hidl_camera_device_status);
-            if (res != OK) {
-              ALOGE(
-                  "%s: Converting to hidl camera device status failed: %s(%d)",
-                  __FUNCTION__, strerror(-res), res);
-              return;
-            }
-
-            std::unique_lock<std::mutex> lock(callbacks_lock_);
-            auto cb_status = callbacks_->cameraDeviceStatusChange(
-                "device@" +
-                    device::V3_7::implementation::HidlCameraDevice::kDeviceVersion +
-                    "/" + kProviderName + "/" + camera_id,
-                hidl_camera_device_status);
-            if (!cb_status.isOk()) {
-              ALOGE("%s: device status change transaction error: %s",
-                    __FUNCTION__, cb_status.description().c_str());
-              return;
-            }
-          }),
-      .physical_camera_device_status_change = google_camera_hal::
-          PhysicalCameraDeviceStatusChangeFunc([this](
-                                                   std::string camera_id,
-                                                   std::string physical_camera_id,
-                                                   google_camera_hal::CameraDeviceStatus
-                                                       new_status) {
-            if (callbacks_ == nullptr) {
-              ALOGE("%s: callbacks_ is null", __FUNCTION__);
-              return;
-            }
-            auto castResult =
-                provider::V2_6::ICameraProviderCallback::castFrom(callbacks_);
-            if (!castResult.isOk()) {
-              ALOGE("%s: callbacks_ cannot be casted to version 2.6",
-                    __FUNCTION__);
-              return;
-            }
-            sp<provider::V2_6::ICameraProviderCallback> callbacks_2_6_ =
-                castResult;
-            if (callbacks_2_6_ == nullptr) {
-              ALOGE("%s: callbacks_2_6_ is null", __FUNCTION__);
-              return;
-            }
-
-            CameraDeviceStatus hidl_camera_device_status;
-            status_t res = hidl_utils::ConvertToHidlCameraDeviceStatus(
-                new_status, &hidl_camera_device_status);
-            if (res != OK) {
-              ALOGE(
-                  "%s: Converting to hidl camera device status failed: %s(%d)",
-                  __FUNCTION__, strerror(-res), res);
-              return;
-            }
-
-            std::unique_lock<std::mutex> lock(callbacks_lock_);
-            callbacks_2_6_->physicalCameraDeviceStatusChange(
-                "device@" +
-                    device::V3_7::implementation::HidlCameraDevice::kDeviceVersion +
-                    "/" + kProviderName + "/" + camera_id,
-                physical_camera_id, hidl_camera_device_status);
-          }),
-      .torch_mode_status_change = google_camera_hal::TorchModeStatusChangeFunc(
-          [this](std::string camera_id,
-                 google_camera_hal::TorchModeStatus new_status) {
-            if (callbacks_ == nullptr) {
-              ALOGE("%s: callbacks_ is null", __FUNCTION__);
-              return;
-            }
-
-            TorchModeStatus hidl_torch_status;
-            status_t res = hidl_utils::ConvertToHidlTorchModeStatus(
-                new_status, &hidl_torch_status);
-            if (res != OK) {
-              ALOGE("%s: Converting to hidl torch status failed: %s(%d)",
-                    __FUNCTION__, strerror(-res), res);
-              return;
-            }
-
-            std::unique_lock<std::mutex> lock(callbacks_lock_);
-            auto cb_status = callbacks_->torchModeStatusChange(
-                "device@" +
-                    device::V3_7::implementation::HidlCameraDevice::kDeviceVersion +
-                    "/" + kProviderName + "/" + camera_id,
-                hidl_torch_status);
-            if (!cb_status.isOk()) {
-              ALOGE("%s: torch status change transaction error: %s",
-                    __FUNCTION__, cb_status.description().c_str());
-              return;
-            }
-          }),
-  };
-
-  google_camera_provider_->SetCallback(&camera_provider_callback_);
-  // purge pending malloc pages after initialization
-  mallopt(M_PURGE, 0);
-  return OK;
-}
-
-Return<Status> HidlCameraProvider::setCallback(
-    const sp<ICameraProviderCallback>& callback) {
-  bool first_time = false;
-  {
-    std::unique_lock<std::mutex> lock(callbacks_lock_);
-    first_time = callbacks_ == nullptr;
-    callbacks_ = callback;
-  }
-  google_camera_provider_->TriggerDeferredCallbacks();
-#ifdef __ANDROID_APEX__
-  if (first_time) {
-    std::string ready_property_name = "vendor.camera.hal.ready.count";
-    int ready_count = property_get_int32(ready_property_name.c_str(), 0);
-    property_set(ready_property_name.c_str(),
-                 std::to_string(++ready_count).c_str());
-    ALOGI("HidlCameraProvider::setCallback() first time ready count: %d ",
-          ready_count);
-  }
-#endif
-  return Status::OK;
-}
-
-Return<void> HidlCameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
-  hidl_vec<VendorTagSection> hidl_vendor_tag_sections;
-  std::vector<google_camera_hal::VendorTagSection> hal_vendor_tag_sections;
-
-  status_t res =
-      google_camera_provider_->GetVendorTags(&hal_vendor_tag_sections);
-  if (res != OK) {
-    ALOGE("%s: Getting vendor tags failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_vendor_tag_sections);
-    return Void();
-  }
-
-  res = hidl_utils::ConvertToHidlVendorTagSections(hal_vendor_tag_sections,
-                                                   &hidl_vendor_tag_sections);
-  if (res != OK) {
-    ALOGE("%s: Converting to hidl vendor tags failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_vendor_tag_sections);
-    return Void();
-  }
-
-  _hidl_cb(Status::OK, hidl_vendor_tag_sections);
-  return Void();
-}
-
-Return<void> HidlCameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
-  std::vector<uint32_t> camera_ids;
-  hidl_vec<hidl_string> hidl_camera_ids;
-  status_t res = google_camera_provider_->GetCameraIdList(&camera_ids);
-  if (res != OK) {
-    ALOGE("%s: Getting camera ID list failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_camera_ids);
-    return Void();
-  }
-
-  hidl_camera_ids.resize(camera_ids.size());
-  for (uint32_t i = 0; i < hidl_camera_ids.size(); i++) {
-    // camera ID is in the form of "device@<major>.<minor>/<type>/<id>"
-    hidl_camera_ids[i] =
-        "device@" +
-        device::V3_7::implementation::HidlCameraDevice::kDeviceVersion + "/" +
-        kProviderName + "/" + std::to_string(camera_ids[i]);
-  }
-
-  _hidl_cb(Status::OK, hidl_camera_ids);
-  return Void();
-}
-
-Return<void> HidlCameraProvider::getConcurrentStreamingCameraIds(
-    getConcurrentStreamingCameraIds_cb _hidl_cb) {
-  hidl_vec<hidl_vec<hidl_string>> hidl_camera_id_combinations;
-  std::vector<std::unordered_set<uint32_t>> camera_id_combinations;
-  status_t res = google_camera_provider_->GetConcurrentStreamingCameraIds(
-      &camera_id_combinations);
-  if (res != OK) {
-    ALOGE(
-        "%s: Getting the combinations of concurrent streaming camera ids "
-        "failed: %s(%d)",
-        __FUNCTION__, strerror(-res), res);
-    _hidl_cb(Status::INTERNAL_ERROR, hidl_camera_id_combinations);
-    return Void();
-  }
-  hidl_camera_id_combinations.resize(camera_id_combinations.size());
-  int i = 0;
-  for (auto& combination : camera_id_combinations) {
-    hidl_vec<hidl_string> hidl_combination(combination.size());
-    int c = 0;
-    for (auto& camera_id : combination) {
-      hidl_combination[c] = std::to_string(camera_id);
-      c++;
-    }
-    hidl_camera_id_combinations[i] = hidl_combination;
-    i++;
-  }
-  _hidl_cb(Status::OK, hidl_camera_id_combinations);
-  return Void();
-}
-
-Return<void> HidlCameraProvider::isConcurrentStreamCombinationSupported(
-    const hidl_vec<provider::V2_6::CameraIdAndStreamCombination>& configs,
-    isConcurrentStreamCombinationSupported_cb _hidl_cb) {
-  hidl_vec<CameraIdAndStreamCombination> configs2_7;
-  configs2_7.resize(configs.size());
-  for (size_t i = 0; i < configs.size(); i++) {
-    configs2_7[i].cameraId = configs[i].cameraId;
-
-    hidl_utils::ConvertStreamConfigurationV34ToV37(
-        configs[i].streamConfiguration, &configs2_7[i].streamConfiguration);
-  }
-
-  return isConcurrentStreamCombinationSupported_2_7(configs2_7, _hidl_cb);
-}
-
-Return<void> HidlCameraProvider::isConcurrentStreamCombinationSupported_2_7(
-    const hidl_vec<CameraIdAndStreamCombination>& configs,
-    isConcurrentStreamCombinationSupported_cb _hidl_cb) {
-  std::vector<google_camera_hal::CameraIdAndStreamConfiguration>
-      devices_stream_configs(configs.size());
-  status_t res = OK;
-  size_t c = 0;
-  for (auto& config : configs) {
-    res = hidl_utils::ConverToHalStreamConfig(
-        config.streamConfiguration,
-        &devices_stream_configs[c].stream_configuration);
-    if (res != OK) {
-      ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
-      _hidl_cb(Status::INTERNAL_ERROR, false);
-      return Void();
-    }
-    uint32_t camera_id = atoi(config.cameraId.c_str());
-    devices_stream_configs[c].camera_id = camera_id;
-    c++;
-  }
-  bool is_supported = false;
-  res = google_camera_provider_->IsConcurrentStreamCombinationSupported(
-      devices_stream_configs, &is_supported);
-  if (res != OK) {
-    ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
-    _hidl_cb(Status::INTERNAL_ERROR, false);
-    return Void();
-  }
-  _hidl_cb(Status::OK, is_supported);
-  return Void();
-}
-
-Return<void> HidlCameraProvider::isSetTorchModeSupported(
-    isSetTorchModeSupported_cb _hidl_cb) {
-  bool is_supported = google_camera_provider_->IsSetTorchModeSupported();
-  _hidl_cb(Status::OK, is_supported);
-  return Void();
-}
-
-Return<void> HidlCameraProvider::getCameraDeviceInterface_V1_x(
-    const hidl_string& /*cameraDeviceName*/,
-    getCameraDeviceInterface_V1_x_cb _hidl_cb) {
-  _hidl_cb(Status::OPERATION_NOT_SUPPORTED, nullptr);
-  return Void();
-}
-
-bool HidlCameraProvider::ParseDeviceName(const hidl_string& device_name,
-                                         std::string* device_version,
-                                         std::string* camera_id) {
-  std::string device_name_std(device_name.c_str());
-  std::smatch sm;
-
-  if (std::regex_match(device_name_std, sm,
-                       HidlCameraProvider::kDeviceNameRegex)) {
-    if (device_version != nullptr) {
-      *device_version = sm[1];
-    }
-    if (camera_id != nullptr) {
-      *camera_id = sm[2];
-    }
-    return true;
-  }
-  return false;
-}
-
-Return<void> HidlCameraProvider::getCameraDeviceInterface_V3_x(
-    const hidl_string& camera_device_name,
-    getCameraDeviceInterface_V3_x_cb _hidl_cb) {
-  std::unique_ptr<CameraDevice> google_camera_device;
-
-  // Parse camera_device_name.
-  std::string camera_id, device_version;
-
-  bool match = ParseDeviceName(camera_device_name, &device_version, &camera_id);
-  if (!match) {
-    ALOGE("%s: Device name parse fail. ", __FUNCTION__);
-    _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
-    return Void();
-  }
-
-  status_t res = google_camera_provider_->CreateCameraDevice(
-      atoi(camera_id.c_str()), &google_camera_device);
-  if (res != OK) {
-    ALOGE("%s: Creating CameraDevice failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    _hidl_cb(hidl_utils::ConvertToHidlStatus(res), nullptr);
-    return Void();
-  }
-
-  auto hidl_camera_device =
-      device::V3_7::implementation::HidlCameraDevice::Create(
-          std::move(google_camera_device));
-  if (hidl_camera_device == nullptr) {
-    ALOGE("%s: Creating HidlCameraDevice failed", __FUNCTION__);
-    _hidl_cb(Status::INTERNAL_ERROR, nullptr);
-    return Void();
-  }
-
-  _hidl_cb(Status::OK, hidl_camera_device.release());
-  return Void();
-}
-
-Return<void> HidlCameraProvider::notifyDeviceStateChange(
-    hardware::hidl_bitfield<DeviceState> new_state) {
-  google_camera_hal::DeviceState device_state =
-      google_camera_hal::DeviceState::kNormal;
-  ::android::hardware::camera::implementation::hidl_utils::ConvertToHalDeviceState(
-      new_state, device_state);
-  google_camera_provider_->NotifyDeviceStateChange(device_state);
-  return Void();
-}
-
-}  // namespace implementation
-}  // namespace V2_7
-}  // namespace provider
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
diff --git a/common/hal/hidl_service/hidl_camera_provider.h b/common/hal/hidl_service/hidl_camera_provider.h
deleted file mode 100644
index 31efc14..0000000
--- a/common/hal/hidl_service/hidl_camera_provider.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_PROVIDER_H_
-#define HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_PROVIDER_H_
-
-#include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h>
-#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
-#include <regex>
-#include "camera_provider.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace provider {
-namespace V2_7 {
-namespace implementation {
-
-using ::android::sp;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::camera::common::V1_0::Status;
-using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
-using ::android::hardware::camera::provider::V2_5::DeviceState;
-using ::android::hardware::camera::provider::V2_7::CameraIdAndStreamCombination;
-using ::android::hardware::camera::provider::V2_7::ICameraProvider;
-
-using ::android::google_camera_hal::CameraProvider;
-
-// HidlCameraProvider implements the HIDL camera provider interface,
-// ICameraProvider, to enumerate the available individual camera devices
-// in the system, and provide updates about changes to device status.
-class HidlCameraProvider : public ICameraProvider {
- public:
-  static const std::string kProviderName;
-  static android::sp<HidlCameraProvider> Create();
-  virtual ~HidlCameraProvider() = default;
-
-  // Override functions in ICameraProvider.
-  Return<Status> setCallback(
-      const sp<ICameraProviderCallback>& callback) override;
-
-  Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override;
-
-  Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override;
-
-  Return<void> isSetTorchModeSupported(
-      isSetTorchModeSupported_cb _hidl_cb) override;
-
-  Return<void> getConcurrentStreamingCameraIds(
-      getConcurrentStreamingCameraIds_cb _hidl_cb) override;
-
-  Return<void> isConcurrentStreamCombinationSupported(
-      const hidl_vec<V2_6::CameraIdAndStreamCombination>& configs,
-      isConcurrentStreamCombinationSupported_cb _hidl_cb) override;
-
-  Return<void> isConcurrentStreamCombinationSupported_2_7(
-      const hidl_vec<CameraIdAndStreamCombination>& configs,
-      isConcurrentStreamCombinationSupported_cb _hidl_cb) override;
-
-  Return<void> getCameraDeviceInterface_V1_x(
-      const hidl_string& cameraDeviceName,
-      getCameraDeviceInterface_V1_x_cb _hidl_cb) override;
-
-  Return<void> getCameraDeviceInterface_V3_x(
-      const hidl_string& cameraDeviceName,
-      getCameraDeviceInterface_V3_x_cb _hidl_cb) override;
-
-  Return<void> notifyDeviceStateChange(
-      hardware::hidl_bitfield<DeviceState> newState) override;
-  // End of override functions in ICameraProvider.
-
- protected:
-  HidlCameraProvider() = default;
-
- private:
-  static const std::regex kDeviceNameRegex;
-
-  status_t Initialize();
-
-  // Parse device version and camera ID.
-  bool ParseDeviceName(const hidl_string& device_name,
-                       std::string* device_version, std::string* camera_id);
-
-  std::mutex callbacks_lock_;
-  sp<ICameraProviderCallback> callbacks_;
-
-  std::unique_ptr<CameraProvider> google_camera_provider_;
-  google_camera_hal::CameraProviderCallback camera_provider_callback_;
-};
-
-}  // namespace implementation
-}  // namespace V2_7
-}  // namespace provider
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_CAMERA_PROVIDER_H_
diff --git a/common/hal/hidl_service/hidl_utils.cc b/common/hal/hidl_service/hidl_utils.cc
deleted file mode 100644
index 1b39958..0000000
--- a/common/hal/hidl_service/hidl_utils.cc
+++ /dev/null
@@ -1,1163 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define LOG_TAG "GCH_HidlUtils"
-//#define LOG_NDEBUG 0
-#include <log/log.h>
-#include <regex>
-
-#include "hidl_camera_device.h"
-#include "hidl_utils.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace implementation {
-namespace hidl_utils {
-
-using ::android::hardware::camera::device::V3_2::ErrorCode;
-using ::android::hardware::camera::device::V3_2::ErrorMsg;
-using ::android::hardware::camera::device::V3_2::MsgType;
-using ::android::hardware::camera::device::V3_2::ShutterMsg;
-using ::android::hardware::camera::device::V3_7::implementation::HidlCameraDevice;
-using android::hardware::camera::metadata::V3_6::
-    CameraMetadataEnumAndroidSensorPixelMode;
-using ::android::hardware::camera::provider::V2_7::implementation::HidlCameraProvider;
-
-status_t ConvertToHidlVendorTagType(
-    google_camera_hal::CameraMetadataType hal_type,
-    CameraMetadataType* hidl_type) {
-  if (hidl_type == nullptr) {
-    ALOGE("%s: hidl_type is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hal_type) {
-    case google_camera_hal::CameraMetadataType::kByte:
-      *hidl_type = CameraMetadataType::BYTE;
-      break;
-    case google_camera_hal::CameraMetadataType::kInt32:
-      *hidl_type = CameraMetadataType::INT32;
-      break;
-    case google_camera_hal::CameraMetadataType::kFloat:
-      *hidl_type = CameraMetadataType::FLOAT;
-      break;
-    case google_camera_hal::CameraMetadataType::kInt64:
-      *hidl_type = CameraMetadataType::INT64;
-      break;
-    case google_camera_hal::CameraMetadataType::kDouble:
-      *hidl_type = CameraMetadataType::DOUBLE;
-      break;
-    case google_camera_hal::CameraMetadataType::kRational:
-      *hidl_type = CameraMetadataType::RATIONAL;
-      break;
-    default:
-      ALOGE("%s: Unknown google_camera_hal::CameraMetadataType: %u",
-            __FUNCTION__, hal_type);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlResourceCost(
-    const google_camera_hal::CameraResourceCost& hal_cost,
-    CameraResourceCost* hidl_cost) {
-  if (hidl_cost == nullptr) {
-    ALOGE("%s: hidl_cost is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_cost->resourceCost = hal_cost.resource_cost;
-  hidl_cost->conflictingDevices.resize(hal_cost.conflicting_devices.size());
-
-  for (uint32_t i = 0; i < hal_cost.conflicting_devices.size(); i++) {
-    hidl_cost->conflictingDevices[i] =
-        "device@" + HidlCameraDevice::kDeviceVersion + "/" +
-        HidlCameraProvider::kProviderName + "/" +
-        std::to_string(hal_cost.conflicting_devices[i]);
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlVendorTagSections(
-    const std::vector<google_camera_hal::VendorTagSection>& hal_sections,
-    hidl_vec<VendorTagSection>* hidl_sections) {
-  if (hidl_sections == nullptr) {
-    ALOGE("%s: hidl_sections is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_sections->resize(hal_sections.size());
-  for (uint32_t i = 0; i < hal_sections.size(); i++) {
-    (*hidl_sections)[i].sectionName = hal_sections[i].section_name;
-    (*hidl_sections)[i].tags.resize(hal_sections[i].tags.size());
-
-    for (uint32_t j = 0; j < hal_sections[i].tags.size(); j++) {
-      (*hidl_sections)[i].tags[j].tagId = hal_sections[i].tags[j].tag_id;
-      (*hidl_sections)[i].tags[j].tagName = hal_sections[i].tags[j].tag_name;
-      status_t res =
-          ConvertToHidlVendorTagType(hal_sections[i].tags[j].tag_type,
-                                     &(*hidl_sections)[i].tags[j].tagType);
-      if (res != OK) {
-        ALOGE("%s: Converting to hidl vendor tag type failed. ", __FUNCTION__);
-        return res;
-      }
-    }
-  }
-
-  return OK;
-}
-
-Status ConvertToHidlStatus(status_t hal_status) {
-  switch (hal_status) {
-    case OK:
-      return Status::OK;
-    case BAD_VALUE:
-      return Status::ILLEGAL_ARGUMENT;
-    case -EBUSY:
-      return Status::CAMERA_IN_USE;
-    case -EUSERS:
-      return Status::MAX_CAMERAS_IN_USE;
-    case UNKNOWN_TRANSACTION:
-      return Status::METHOD_NOT_SUPPORTED;
-    case INVALID_OPERATION:
-      return Status::OPERATION_NOT_SUPPORTED;
-    case DEAD_OBJECT:
-      return Status::CAMERA_DISCONNECTED;
-    default:
-      return Status::INTERNAL_ERROR;
-  }
-}
-
-status_t ConvertToHalTemplateType(
-    RequestTemplate hidl_template,
-    google_camera_hal::RequestTemplate* hal_template) {
-  if (hal_template == nullptr) {
-    ALOGE("%s: hal_template is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hidl_template) {
-    case RequestTemplate::PREVIEW:
-      *hal_template = google_camera_hal::RequestTemplate::kPreview;
-      break;
-    case RequestTemplate::STILL_CAPTURE:
-      *hal_template = google_camera_hal::RequestTemplate::kStillCapture;
-      break;
-    case RequestTemplate::VIDEO_RECORD:
-      *hal_template = google_camera_hal::RequestTemplate::kVideoRecord;
-      break;
-    case RequestTemplate::VIDEO_SNAPSHOT:
-      *hal_template = google_camera_hal::RequestTemplate::kVideoSnapshot;
-      break;
-    case RequestTemplate::ZERO_SHUTTER_LAG:
-      *hal_template = google_camera_hal::RequestTemplate::kZeroShutterLag;
-      break;
-    case RequestTemplate::MANUAL:
-      *hal_template = google_camera_hal::RequestTemplate::kManual;
-      break;
-    default:
-      ALOGE("%s: Unknown HIDL RequestTemplate: %u", __FUNCTION__,
-            hidl_template);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlHalStreamConfig(
-    const std::vector<google_camera_hal::HalStream>& hal_configured_streams,
-    HalStreamConfiguration* hidl_hal_stream_config) {
-  if (hidl_hal_stream_config == nullptr) {
-    ALOGE("%s: hidl_hal_stream_config is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_hal_stream_config->streams.resize(hal_configured_streams.size());
-
-  for (uint32_t i = 0; i < hal_configured_streams.size(); i++) {
-    hidl_hal_stream_config->streams[i].supportOffline = false;
-    if (hal_configured_streams[i].is_physical_camera_stream) {
-      hidl_hal_stream_config->streams[i].v3_4.physicalCameraId =
-          std::to_string(hal_configured_streams[i].physical_camera_id);
-    }
-
-    hidl_hal_stream_config->streams[i].v3_4.v3_3.overrideDataSpace =
-        hal_configured_streams[i].override_data_space;
-
-    hidl_hal_stream_config->streams[i].v3_4.v3_3.v3_2.id =
-        hal_configured_streams[i].id;
-
-    hidl_hal_stream_config->streams[i].v3_4.v3_3.v3_2.overrideFormat =
-        (::android::hardware::graphics::common::V1_0::PixelFormat)
-            hal_configured_streams[i]
-                .override_format;
-
-    hidl_hal_stream_config->streams[i].v3_4.v3_3.v3_2.producerUsage =
-        hal_configured_streams[i].producer_usage;
-
-    hidl_hal_stream_config->streams[i].v3_4.v3_3.v3_2.consumerUsage =
-        hal_configured_streams[i].consumer_usage;
-
-    hidl_hal_stream_config->streams[i].v3_4.v3_3.v3_2.maxBuffers =
-        hal_configured_streams[i].max_buffers;
-  }
-
-  return OK;
-}
-
-status_t WriteToResultMetadataQueue(
-    camera_metadata_t* metadata,
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* result_metadata_queue) {
-  if (result_metadata_queue == nullptr) {
-    return BAD_VALUE;
-  }
-
-  if (result_metadata_queue->availableToWrite() <= 0) {
-    ALOGW("%s: result_metadata_queue is not available to write", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  uint32_t size = get_camera_metadata_size(metadata);
-  bool success = result_metadata_queue->write(
-      reinterpret_cast<const uint8_t*>(metadata), size);
-  if (!success) {
-    ALOGW("%s: Writing to result metadata queue failed. (size=%u)",
-          __FUNCTION__, size);
-    return INVALID_OPERATION;
-  }
-
-  return OK;
-}
-
-// Try writing result metadata to result metadata queue. If failed, return
-// the metadata to the caller in out_hal_metadata.
-status_t TryWritingToResultMetadataQueue(
-    std::unique_ptr<google_camera_hal::HalCameraMetadata> hal_metadata,
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* result_metadata_queue,
-    uint64_t* fmq_result_size,
-    std::unique_ptr<google_camera_hal::HalCameraMetadata>* out_hal_metadata) {
-  if (out_hal_metadata == nullptr) {
-    ALOGE("%s: out_hal_metadata is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  *out_hal_metadata = std::move(hal_metadata);
-
-  if (fmq_result_size == nullptr) {
-    ALOGE("%s: fmq_result_size is nullptr", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  *fmq_result_size = 0;
-  if (*out_hal_metadata == nullptr) {
-    return OK;
-  }
-
-  camera_metadata_t* metadata = (*out_hal_metadata)->ReleaseCameraMetadata();
-  // Temporarily use the raw metadata to write to metadata queue.
-  status_t res = WriteToResultMetadataQueue(metadata, result_metadata_queue);
-  *out_hal_metadata = google_camera_hal::HalCameraMetadata::Create(metadata);
-
-  if (res != OK) {
-    ALOGW("%s: Writing to result metadata queue failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  *fmq_result_size = (*out_hal_metadata)->GetCameraMetadataSize();
-  *out_hal_metadata = nullptr;
-  return OK;
-}
-
-status_t ConverToHidlResultMetadata(
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* result_metadata_queue,
-    std::unique_ptr<google_camera_hal::HalCameraMetadata> hal_metadata,
-    CameraMetadata* hidl_metadata, uint64_t* fmq_result_size) {
-  if (TryWritingToResultMetadataQueue(std::move(hal_metadata),
-                                      result_metadata_queue, fmq_result_size,
-                                      &hal_metadata) == OK) {
-    return OK;
-  }
-
-  // If writing to metadata queue failed, attach the metadata to hidl_metadata.
-  if (hidl_metadata == nullptr) {
-    ALOGE("%s: hidl_metadata is nullptr", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  uint32_t metadata_size = hal_metadata->GetCameraMetadataSize();
-  hidl_metadata->setToExternal(
-      reinterpret_cast<uint8_t*>(hal_metadata->ReleaseCameraMetadata()),
-      metadata_size, /*shouldOwn=*/true);
-
-  return OK;
-}
-
-status_t ConvertToHidlBufferStatus(google_camera_hal::BufferStatus hal_status,
-                                   BufferStatus* hidl_status) {
-  if (hidl_status == nullptr) {
-    ALOGE("%s: hidl_status is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hal_status) {
-    case google_camera_hal::BufferStatus::kOk:
-      *hidl_status = BufferStatus::OK;
-      break;
-    case google_camera_hal::BufferStatus::kError:
-      *hidl_status = BufferStatus::ERROR;
-      break;
-    default:
-      ALOGE("%s: Unknown HAL buffer status: %u", __FUNCTION__, hal_status);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlStreamBuffer(
-    const google_camera_hal::StreamBuffer& hal_buffer,
-    StreamBuffer* hidl_buffer) {
-  if (hidl_buffer == nullptr) {
-    ALOGE("%s: hidl_buffer is nullptr", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_buffer->streamId = hal_buffer.stream_id;
-  hidl_buffer->bufferId = hal_buffer.buffer_id;
-  hidl_buffer->buffer = nullptr;
-
-  status_t res =
-      ConvertToHidlBufferStatus(hal_buffer.status, &hidl_buffer->status);
-  if (res != OK) {
-    ALOGE("%s: Converting to HIDL buffer status failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  hidl_buffer->acquireFence = nullptr;
-  hidl_buffer->releaseFence = hal_buffer.release_fence;
-  return OK;
-}
-
-status_t ConvertToHidlCaptureResult_V3_2(
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* result_metadata_queue,
-    google_camera_hal::CaptureResult* hal_result,
-    device::V3_2::CaptureResult* hidl_result) {
-  if (hidl_result == nullptr) {
-    ALOGE("%s: hidl_result is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  if (hal_result == nullptr) {
-    ALOGE("%s: hal_result is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_result->frameNumber = hal_result->frame_number;
-
-  status_t res = ConverToHidlResultMetadata(
-      result_metadata_queue, std::move(hal_result->result_metadata),
-      &hidl_result->result, &hidl_result->fmqResultSize);
-  if (res != OK) {
-    ALOGE("%s: Converting to HIDL result metadata failed: %s(%d).",
-          __FUNCTION__, strerror(-res), res);
-    return res;
-  }
-
-  hidl_result->outputBuffers.resize(hal_result->output_buffers.size());
-  for (uint32_t i = 0; i < hidl_result->outputBuffers.size(); i++) {
-    res = ConvertToHidlStreamBuffer(hal_result->output_buffers[i],
-                                    &hidl_result->outputBuffers[i]);
-    if (res != OK) {
-      ALOGE("%s: Converting to HIDL output stream buffer failed: %s(%d)",
-            __FUNCTION__, strerror(-res), res);
-      return res;
-    }
-  }
-
-  uint32_t num_input_buffers = hal_result->input_buffers.size();
-  if (num_input_buffers > 0) {
-    if (num_input_buffers > 1) {
-      ALOGW("%s: HAL result should not have more than 1 input buffer. (=%u)",
-            __FUNCTION__, num_input_buffers);
-    }
-
-    res = ConvertToHidlStreamBuffer(hal_result->input_buffers[0],
-                                    &hidl_result->inputBuffer);
-    if (res != OK) {
-      ALOGE("%s: Converting to HIDL input stream buffer failed: %s(%d)",
-            __FUNCTION__, strerror(-res), res);
-      return res;
-    }
-  } else {
-    hidl_result->inputBuffer.streamId = -1;
-  }
-
-  hidl_result->partialResult = hal_result->partial_result;
-  return OK;
-}
-
-status_t ConvertToHidlCaptureResult(
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* result_metadata_queue,
-    std::unique_ptr<google_camera_hal::CaptureResult> hal_result,
-    CaptureResult* hidl_result) {
-  if (hidl_result == nullptr) {
-    ALOGE("%s: hidl_result is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  if (hal_result == nullptr) {
-    ALOGE("%s: hal_result is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  status_t res = ConvertToHidlCaptureResult_V3_2(
-      result_metadata_queue, hal_result.get(), &hidl_result->v3_2);
-  if (res != OK) {
-    ALOGE("%s: Converting to V3.2 HIDL result failed: %s(%d).", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  uint32_t num_physical_metadata = hal_result->physical_metadata.size();
-  hidl_result->physicalCameraMetadata.resize(num_physical_metadata);
-
-  for (uint32_t i = 0; i < num_physical_metadata; i++) {
-    hidl_result->physicalCameraMetadata[i].physicalCameraId =
-        std::to_string(hal_result->physical_metadata[i].physical_camera_id);
-
-    res = ConverToHidlResultMetadata(
-        result_metadata_queue,
-        std::move(hal_result->physical_metadata[i].metadata),
-        &hidl_result->physicalCameraMetadata[i].metadata,
-        &hidl_result->physicalCameraMetadata[i].fmqMetadataSize);
-    if (res != OK) {
-      ALOGE("%s: Converting to HIDL physical metadata failed: %s(%d).",
-            __FUNCTION__, strerror(-res), res);
-      return res;
-    }
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlErrorMessage(
-    const google_camera_hal::ErrorMessage& hal_error, ErrorMsg* hidl_error) {
-  if (hidl_error == nullptr) {
-    ALOGE("%s: hidl_error is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_error->frameNumber = hal_error.frame_number;
-  hidl_error->errorStreamId = hal_error.error_stream_id;
-
-  switch (hal_error.error_code) {
-    case google_camera_hal::ErrorCode::kErrorDevice:
-      hidl_error->errorCode = ErrorCode::ERROR_DEVICE;
-      break;
-    case google_camera_hal::ErrorCode::kErrorRequest:
-      hidl_error->errorCode = ErrorCode::ERROR_REQUEST;
-      break;
-    case google_camera_hal::ErrorCode::kErrorResult:
-      hidl_error->errorCode = ErrorCode::ERROR_RESULT;
-      break;
-    case google_camera_hal::ErrorCode::kErrorBuffer:
-      hidl_error->errorCode = ErrorCode::ERROR_BUFFER;
-      break;
-    default:
-      ALOGE("%s: Unknown error code: %u", __FUNCTION__, hal_error.error_code);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlShutterMessage(
-    const google_camera_hal::ShutterMessage& hal_shutter,
-    ShutterMsg* hidl_shutter) {
-  if (hidl_shutter == nullptr) {
-    ALOGE("%s: hidl_shutter is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_shutter->frameNumber = hal_shutter.frame_number;
-  hidl_shutter->timestamp = hal_shutter.timestamp_ns;
-  return OK;
-}
-
-status_t ConverToHidlNotifyMessage(
-    const google_camera_hal::NotifyMessage& hal_message,
-    NotifyMsg* hidl_message) {
-  if (hidl_message == nullptr) {
-    ALOGE("%s: hidl_message is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  status_t res;
-  switch (hal_message.type) {
-    case google_camera_hal::MessageType::kError:
-      hidl_message->type = MsgType::ERROR;
-      res = ConvertToHidlErrorMessage(hal_message.message.error,
-                                      &hidl_message->msg.error);
-      if (res != OK) {
-        ALOGE("%s: Converting to HIDL error message failed: %s(%d)",
-              __FUNCTION__, strerror(-res), res);
-        return res;
-      }
-      break;
-    case google_camera_hal::MessageType::kShutter:
-      hidl_message->type = MsgType::SHUTTER;
-      res = ConvertToHidlShutterMessage(hal_message.message.shutter,
-                                        &hidl_message->msg.shutter);
-      if (res != OK) {
-        ALOGE("%s: Converting to HIDL shutter message failed: %s(%d)",
-              __FUNCTION__, strerror(-res), res);
-        return res;
-      }
-      break;
-    default:
-      ALOGE("%s: Unknown message type: %u", __FUNCTION__, hal_message.type);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlCameraDeviceStatus(
-    google_camera_hal::CameraDeviceStatus hal_camera_device_status,
-    CameraDeviceStatus* hidl_camera_device_status) {
-  if (hidl_camera_device_status == nullptr) {
-    ALOGE("%s: hidl_camera_device_status is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hal_camera_device_status) {
-    case google_camera_hal::CameraDeviceStatus::kNotPresent:
-      *hidl_camera_device_status = CameraDeviceStatus::NOT_PRESENT;
-      break;
-    case google_camera_hal::CameraDeviceStatus::kPresent:
-      *hidl_camera_device_status = CameraDeviceStatus::PRESENT;
-      break;
-    case google_camera_hal::CameraDeviceStatus::kEnumerating:
-      *hidl_camera_device_status = CameraDeviceStatus::ENUMERATING;
-      break;
-    default:
-      ALOGE("%s: Unknown HAL camera device status: %u", __FUNCTION__,
-            hal_camera_device_status);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlTorchModeStatus(
-    google_camera_hal::TorchModeStatus hal_torch_status,
-    TorchModeStatus* hidl_torch_status) {
-  if (hidl_torch_status == nullptr) {
-    ALOGE("%s: hidl_torch_status is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hal_torch_status) {
-    case google_camera_hal::TorchModeStatus::kNotAvailable:
-      *hidl_torch_status = TorchModeStatus::NOT_AVAILABLE;
-      break;
-    case google_camera_hal::TorchModeStatus::kAvailableOff:
-      *hidl_torch_status = TorchModeStatus::AVAILABLE_OFF;
-      break;
-    case google_camera_hal::TorchModeStatus::kAvailableOn:
-      *hidl_torch_status = TorchModeStatus::AVAILABLE_ON;
-      break;
-    default:
-      ALOGE("%s: Unknown HAL torch mode status: %u", __FUNCTION__,
-            hal_torch_status);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHidlBufferRequest(
-    const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
-    hidl_vec<BufferRequest>* hidl_buffer_requests) {
-  if (hidl_buffer_requests == nullptr) {
-    ALOGE("%s: hidl_buffer_request is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hidl_buffer_requests->resize(hal_buffer_requests.size());
-  for (uint32_t i = 0; i < hal_buffer_requests.size(); i++) {
-    (*hidl_buffer_requests)[i].streamId = hal_buffer_requests[i].stream_id;
-    (*hidl_buffer_requests)[i].numBuffersRequested =
-        hal_buffer_requests[i].num_buffers_requested;
-  }
-  return OK;
-}
-
-status_t ConvertToHalBufferStatus(BufferStatus hidl_status,
-                                  google_camera_hal::BufferStatus* hal_status) {
-  if (hal_status == nullptr) {
-    ALOGE("%s: hal_status is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hidl_status) {
-    case BufferStatus::OK:
-      *hal_status = google_camera_hal::BufferStatus::kOk;
-      break;
-    case BufferStatus::ERROR:
-      *hal_status = google_camera_hal::BufferStatus::kError;
-      break;
-    default:
-      ALOGE("%s: Unknown HIDL buffer status: %u", __FUNCTION__, hidl_status);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalStreamBuffer(const StreamBuffer& hidl_buffer,
-                                  google_camera_hal::StreamBuffer* hal_buffer) {
-  if (hal_buffer == nullptr) {
-    ALOGE("%s: hal_buffer is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hal_buffer->stream_id = hidl_buffer.streamId;
-  hal_buffer->buffer_id = hidl_buffer.bufferId;
-  hal_buffer->buffer = hidl_buffer.buffer.getNativeHandle();
-
-  status_t res =
-      ConvertToHalBufferStatus(hidl_buffer.status, &hal_buffer->status);
-  if (res != OK) {
-    ALOGE("%s: Converting to HAL buffer status failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  hal_buffer->acquire_fence = hidl_buffer.acquireFence.getNativeHandle();
-  hal_buffer->release_fence = hidl_buffer.releaseFence.getNativeHandle();
-
-  return OK;
-}
-
-status_t ConvertToHalMetadata(
-    uint32_t message_queue_setting_size,
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* request_metadata_queue,
-    const CameraMetadata& request_settings,
-    std::unique_ptr<google_camera_hal::HalCameraMetadata>* hal_metadata) {
-  if (hal_metadata == nullptr) {
-    ALOGE("%s: hal_metadata is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  const camera_metadata_t* metadata = nullptr;
-  CameraMetadata metadata_queue_settings;
-
-  if (message_queue_setting_size == 0) {
-    // Use the settings in the request.
-    if (request_settings.size() != 0) {
-      metadata =
-          reinterpret_cast<const camera_metadata_t*>(request_settings.data());
-    }
-  } else {
-    // Read the settings from request metadata queue.
-    if (request_metadata_queue == nullptr) {
-      ALOGE("%s: request_metadata_queue is nullptr", __FUNCTION__);
-      return BAD_VALUE;
-    }
-
-    metadata_queue_settings.resize(message_queue_setting_size);
-    bool success = request_metadata_queue->read(metadata_queue_settings.data(),
-                                                message_queue_setting_size);
-    if (!success) {
-      ALOGE("%s: Failed to read from request metadata queue.", __FUNCTION__);
-      return BAD_VALUE;
-    }
-
-    metadata = reinterpret_cast<const camera_metadata_t*>(
-        metadata_queue_settings.data());
-  }
-
-  if (metadata == nullptr) {
-    *hal_metadata = nullptr;
-    return OK;
-  }
-
-  *hal_metadata = google_camera_hal::HalCameraMetadata::Clone(metadata);
-  return OK;
-}
-
-status_t ConvertToHalCaptureRequest(
-    const CaptureRequest& hidl_request,
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* request_metadata_queue,
-    google_camera_hal::CaptureRequest* hal_request) {
-  if (hal_request == nullptr) {
-    ALOGE("%s: hal_request is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  hal_request->frame_number = hidl_request.v3_4.v3_2.frameNumber;
-
-  status_t res = ConvertToHalMetadata(
-      hidl_request.v3_4.v3_2.fmqSettingsSize, request_metadata_queue,
-      hidl_request.v3_4.v3_2.settings, &hal_request->settings);
-  if (res != OK) {
-    ALOGE("%s: Converting metadata failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  google_camera_hal::StreamBuffer hal_buffer = {};
-  if (hidl_request.v3_4.v3_2.inputBuffer.buffer != nullptr) {
-    res = ConvertToHalStreamBuffer(hidl_request.v3_4.v3_2.inputBuffer,
-                                   &hal_buffer);
-    if (res != OK) {
-      ALOGE("%s: Converting hal stream buffer failed: %s(%d)", __FUNCTION__,
-            strerror(-res), res);
-      return res;
-    }
-
-    hal_request->input_buffers.push_back(hal_buffer);
-    hal_request->input_width = hidl_request.inputWidth;
-    hal_request->input_height = hidl_request.inputHeight;
-  }
-
-  for (auto& buffer : hidl_request.v3_4.v3_2.outputBuffers) {
-    hal_buffer = {};
-    status_t res = ConvertToHalStreamBuffer(buffer, &hal_buffer);
-    if (res != OK) {
-      ALOGE("%s: Converting hal stream buffer failed: %s(%d)", __FUNCTION__,
-            strerror(-res), res);
-      return res;
-    }
-
-    hal_request->output_buffers.push_back(hal_buffer);
-  }
-
-  for (auto hidl_physical_settings : hidl_request.v3_4.physicalCameraSettings) {
-    std::unique_ptr<google_camera_hal::HalCameraMetadata> hal_physical_settings;
-    res = ConvertToHalMetadata(
-        hidl_physical_settings.fmqSettingsSize, request_metadata_queue,
-        hidl_physical_settings.settings, &hal_physical_settings);
-    if (res != OK) {
-      ALOGE("%s: Converting to HAL metadata failed: %s(%d)", __FUNCTION__,
-            strerror(-res), res);
-      return res;
-    }
-
-    uint32_t camera_id = std::stoul(hidl_physical_settings.physicalCameraId);
-    hal_request->physical_camera_settings.emplace(
-        camera_id, std::move(hal_physical_settings));
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalBufferCaches(
-    const hidl_vec<BufferCache>& hidl_buffer_caches,
-    std::vector<google_camera_hal::BufferCache>* hal_buffer_caches) {
-  if (hal_buffer_caches == nullptr) {
-    ALOGE("%s: hal_buffer_caches is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  for (auto hidl_cache : hidl_buffer_caches) {
-    google_camera_hal::BufferCache hal_cache;
-    hal_cache.stream_id = hidl_cache.streamId;
-    hal_cache.buffer_id = hidl_cache.bufferId;
-
-    hal_buffer_caches->push_back(hal_cache);
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalStreamConfigurationMode(
-    StreamConfigurationMode hidl_mode,
-    google_camera_hal::StreamConfigurationMode* hal_mode) {
-  if (hal_mode == nullptr) {
-    ALOGE("%s: hal_mode is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hidl_mode) {
-    case StreamConfigurationMode::NORMAL_MODE:
-      *hal_mode = google_camera_hal::StreamConfigurationMode::kNormal;
-      break;
-    case StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE:
-      *hal_mode =
-          google_camera_hal::StreamConfigurationMode::kConstrainedHighSpeed;
-      break;
-    default:
-      ALOGE("%s: Unknown configuration mode %u", __FUNCTION__, hidl_mode);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-static bool sensorPixelModeContains(const device::V3_7::Stream& hidl_stream,
-                                    uint32_t key) {
-  for (auto& i : hidl_stream.sensorPixelModesUsed) {
-    if (i == static_cast<CameraMetadataEnumAndroidSensorPixelMode>(key)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-status_t ConverToHalStreamConfig(
-    const StreamConfiguration& hidl_stream_config,
-    google_camera_hal::StreamConfiguration* hal_stream_config) {
-  if (hal_stream_config == nullptr) {
-    ALOGE("%s: hal_stream_config is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  status_t res;
-
-  for (auto hidl_stream : hidl_stream_config.streams) {
-    google_camera_hal::Stream hal_stream;
-    res = ConvertToHalStream(hidl_stream.v3_4, &hal_stream);
-    if (res != OK) {
-      ALOGE("%s: Converting to HAL stream failed: %s(%d)", __FUNCTION__,
-            strerror(-res), res);
-      return res;
-    }
-    hal_stream.group_id = hidl_stream.groupId;
-
-    hal_stream.used_in_max_resolution_mode = sensorPixelModeContains(
-        hidl_stream, ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
-    hal_stream.used_in_default_resolution_mode =
-        hidl_stream.sensorPixelModesUsed.size() > 0
-            ? sensorPixelModeContains(hidl_stream,
-                                      ANDROID_SENSOR_PIXEL_MODE_DEFAULT)
-            : true;
-    hal_stream_config->streams.push_back(hal_stream);
-  }
-
-  res = ConvertToHalStreamConfigurationMode(hidl_stream_config.operationMode,
-                                            &hal_stream_config->operation_mode);
-  if (res != OK) {
-    ALOGE("%s: Converting to HAL opeation mode failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  res = ConvertToHalMetadata(0, nullptr, hidl_stream_config.sessionParams,
-                             &hal_stream_config->session_params);
-  if (res != OK) {
-    ALOGE("%s: Converting to HAL metadata failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  hal_stream_config->stream_config_counter =
-      hidl_stream_config.streamConfigCounter;
-  hal_stream_config->multi_resolution_input_image =
-      hidl_stream_config.multiResolutionInputImage;
-
-  return OK;
-}
-
-status_t ConverToHalStreamConfig(
-    const device::V3_4::StreamConfiguration& hidl_stream_config,
-    google_camera_hal::StreamConfiguration* hal_stream_config) {
-  if (hal_stream_config == nullptr) {
-    ALOGE("%s: hal_stream_config is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  status_t res;
-  for (auto hidl_stream : hidl_stream_config.streams) {
-    google_camera_hal::Stream hal_stream;
-    res = ConvertToHalStream(hidl_stream, &hal_stream);
-    if (res != OK) {
-      ALOGE("%s: Converting to HAL stream failed: %s(%d)", __FUNCTION__,
-            strerror(-res), res);
-      return res;
-    }
-    hal_stream_config->streams.push_back(hal_stream);
-  }
-
-  res = ConvertToHalStreamConfigurationMode(hidl_stream_config.operationMode,
-                                            &hal_stream_config->operation_mode);
-  if (res != OK) {
-    ALOGE("%s: Converting to HAL opeation mode failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  res = ConvertToHalMetadata(0, nullptr, hidl_stream_config.sessionParams,
-                             &hal_stream_config->session_params);
-  if (res != OK) {
-    ALOGE("%s: Converting to HAL metadata failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalStreamType(StreamType hidl_stream_type,
-                                google_camera_hal::StreamType* hal_stream_type) {
-  if (hal_stream_type == nullptr) {
-    ALOGE("%s: hal_stream_type is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hidl_stream_type) {
-    case StreamType::OUTPUT:
-      *hal_stream_type = google_camera_hal::StreamType::kOutput;
-      break;
-    case StreamType::INPUT:
-      *hal_stream_type = google_camera_hal::StreamType::kInput;
-      break;
-    default:
-      ALOGE("%s: Unknown stream type: %u", __FUNCTION__, hidl_stream_type);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalStreamRotation(
-    StreamRotation hidl_stream_rotation,
-    google_camera_hal::StreamRotation* hal_stream_rotation) {
-  if (hal_stream_rotation == nullptr) {
-    ALOGE("%s: hal_stream_rotation is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hidl_stream_rotation) {
-    case StreamRotation::ROTATION_0:
-      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation0;
-      break;
-    case StreamRotation::ROTATION_90:
-      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation90;
-      break;
-    case StreamRotation::ROTATION_180:
-      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation180;
-      break;
-    case StreamRotation::ROTATION_270:
-      *hal_stream_rotation = google_camera_hal::StreamRotation::kRotation270;
-      break;
-    default:
-      ALOGE("%s: Unknown stream rotation: %u", __FUNCTION__,
-            hidl_stream_rotation);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalStream(const Stream& hidl_stream,
-                            google_camera_hal::Stream* hal_stream) {
-  if (hal_stream == nullptr) {
-    ALOGE("%s: hal_stream is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  *hal_stream = {};
-
-  hal_stream->id = hidl_stream.v3_2.id;
-
-  status_t res = ConvertToHalStreamType(hidl_stream.v3_2.streamType,
-                                        &hal_stream->stream_type);
-  if (res != OK) {
-    ALOGE("%s: Converting to HAL stream type failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  hal_stream->width = hidl_stream.v3_2.width;
-  hal_stream->height = hidl_stream.v3_2.height;
-  hal_stream->format = (android_pixel_format_t)hidl_stream.v3_2.format;
-  hal_stream->usage = (uint64_t)hidl_stream.v3_2.usage;
-  hal_stream->data_space = (android_dataspace_t)hidl_stream.v3_2.dataSpace;
-
-  res = ConvertToHalStreamRotation(hidl_stream.v3_2.rotation,
-                                   &hal_stream->rotation);
-  if (res != OK) {
-    ALOGE("%s: Converting to HAL stream rotation failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
-    return res;
-  }
-
-  if (hidl_stream.physicalCameraId.empty()) {
-    hal_stream->is_physical_camera_stream = false;
-  } else {
-    hal_stream->is_physical_camera_stream = true;
-    hal_stream->physical_camera_id = std::stoul(hidl_stream.physicalCameraId);
-  }
-
-  hal_stream->buffer_size = hidl_stream.bufferSize;
-
-  return OK;
-}
-
-status_t ConvertToHalTorchMode(TorchMode hidl_torch_mode,
-                               google_camera_hal::TorchMode* hal_torch_mode) {
-  if (hal_torch_mode == nullptr) {
-    ALOGE("%s: hal_torch_mode is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hidl_torch_mode) {
-    case TorchMode::ON:
-      *hal_torch_mode = google_camera_hal::TorchMode::kOn;
-      break;
-    case TorchMode::OFF:
-      *hal_torch_mode = google_camera_hal::TorchMode::kOff;
-      break;
-    default:
-      ALOGE("%s: Unknown torch mode: %u", __FUNCTION__, hidl_torch_mode);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalBufferRequestStatus(
-    const BufferRequestStatus& hidl_buffer_request_status,
-    google_camera_hal::BufferRequestStatus* hal_buffer_request_status) {
-  if (hal_buffer_request_status == nullptr) {
-    ALOGE("%s: hal_buffer_request_status is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  switch (hidl_buffer_request_status) {
-    case BufferRequestStatus::OK:
-      *hal_buffer_request_status = google_camera_hal::BufferRequestStatus::kOk;
-      break;
-    case BufferRequestStatus::FAILED_PARTIAL:
-      *hal_buffer_request_status =
-          google_camera_hal::BufferRequestStatus::kFailedPartial;
-      break;
-    case BufferRequestStatus::FAILED_CONFIGURING:
-      *hal_buffer_request_status =
-          google_camera_hal::BufferRequestStatus::kFailedConfiguring;
-      break;
-    case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS:
-      *hal_buffer_request_status =
-          google_camera_hal::BufferRequestStatus::kFailedIllegalArgs;
-      break;
-    case BufferRequestStatus::FAILED_UNKNOWN:
-      *hal_buffer_request_status =
-          google_camera_hal::BufferRequestStatus::kFailedUnknown;
-      break;
-    default:
-      ALOGE("%s: Failed unknown buffer request error code %d", __FUNCTION__,
-            hidl_buffer_request_status);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-
-status_t ConvertToHalBufferReturnStatus(
-    const StreamBufferRet& hidl_stream_buffer_return,
-    google_camera_hal::BufferReturn* hal_buffer_return) {
-  if (hal_buffer_return == nullptr) {
-    ALOGE("%s: hal_buffer_return is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  if (hidl_stream_buffer_return.val.getDiscriminator() ==
-      StreamBuffersVal::hidl_discriminator::error) {
-    switch (hidl_stream_buffer_return.val.error()) {
-      case StreamBufferRequestError::NO_BUFFER_AVAILABLE:
-        hal_buffer_return->val.error =
-            google_camera_hal::StreamBufferRequestError::kNoBufferAvailable;
-        break;
-      case StreamBufferRequestError::MAX_BUFFER_EXCEEDED:
-        hal_buffer_return->val.error =
-            google_camera_hal::StreamBufferRequestError::kMaxBufferExceeded;
-        break;
-      case StreamBufferRequestError::STREAM_DISCONNECTED:
-        hal_buffer_return->val.error =
-            google_camera_hal::StreamBufferRequestError::kStreamDisconnected;
-        break;
-      case StreamBufferRequestError::UNKNOWN_ERROR:
-        hal_buffer_return->val.error =
-            google_camera_hal::StreamBufferRequestError::kUnknownError;
-        break;
-      default:
-        ALOGE("%s: Unknown StreamBufferRequestError %d", __FUNCTION__,
-              hidl_stream_buffer_return.val.error());
-        return BAD_VALUE;
-    }
-  } else {
-    hal_buffer_return->val.error =
-        google_camera_hal::StreamBufferRequestError::kOk;
-  }
-
-  return OK;
-}
-
-status_t ConvertStreamConfigurationV34ToV37(
-    const device::V3_4::StreamConfiguration& config_3_4,
-    StreamConfiguration* config_3_7) {
-  if (config_3_7 == nullptr) {
-    ALOGE("%s: config_3_7 is nullptr.", __FUNCTION__);
-    return BAD_VALUE;
-  }
-
-  config_3_7->streams.resize(config_3_4.streams.size());
-  for (size_t i = 0; i < config_3_4.streams.size(); i++) {
-    config_3_7->streams[i].v3_4 = config_3_4.streams[i];
-    config_3_7->streams[i].groupId = -1;
-  }
-  config_3_7->operationMode = config_3_4.operationMode;
-  config_3_7->sessionParams = config_3_4.sessionParams;
-  config_3_7->multiResolutionInputImage = false;
-
-  return OK;
-}
-
-status_t ConvertToHalDeviceState(
-    const hardware::hidl_bitfield<DeviceState> hidl_device_state,
-    google_camera_hal::DeviceState& hal_device_state) {
-  switch (static_cast<DeviceState>(hidl_device_state)) {
-    case DeviceState::NORMAL:
-      hal_device_state = google_camera_hal::DeviceState::kNormal;
-      break;
-    case DeviceState::BACK_COVERED:
-      hal_device_state = google_camera_hal::DeviceState::kBackCovered;
-      break;
-    case DeviceState::FRONT_COVERED:
-      hal_device_state = google_camera_hal::DeviceState::kFrontCovered;
-      break;
-    case DeviceState::FOLDED:
-      hal_device_state = google_camera_hal::DeviceState::kFolded;
-      break;
-    default:
-      ALOGE("%s: Failed unknown device state", __FUNCTION__);
-      return BAD_VALUE;
-  }
-
-  return OK;
-}
-}  // namespace hidl_utils
-}  // namespace implementation
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
diff --git a/common/hal/hidl_service/hidl_utils.h b/common/hal/hidl_service/hidl_utils.h
deleted file mode 100644
index c8003e7..0000000
--- a/common/hal/hidl_service/hidl_utils.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_UTILS_H_
-#define HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_UTILS_H_
-
-#include <android/hardware/camera/common/1.0/types.h>
-#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
-#include <fmq/MessageQueue.h>
-#include <hal_types.h>
-#include <hidl/HidlSupport.h>
-#include <memory>
-#include "hidl_camera_provider.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace implementation {
-namespace hidl_utils {
-
-using ::android::hardware::hidl_vec;
-using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
-using ::android::hardware::camera::common::V1_0::CameraMetadataType;
-using ::android::hardware::camera::common::V1_0::CameraResourceCost;
-using ::android::hardware::camera::common::V1_0::Status;
-using ::android::hardware::camera::common::V1_0::TorchMode;
-using ::android::hardware::camera::common::V1_0::TorchModeStatus;
-using ::android::hardware::camera::common::V1_0::VendorTagSection;
-using ::android::hardware::camera::device::V3_2::BufferCache;
-using ::android::hardware::camera::device::V3_2::BufferStatus;
-using ::android::hardware::camera::device::V3_2::CameraMetadata;
-using ::android::hardware::camera::device::V3_2::NotifyMsg;
-using ::android::hardware::camera::device::V3_2::RequestTemplate;
-using ::android::hardware::camera::device::V3_2::StreamBuffer;
-using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
-using ::android::hardware::camera::device::V3_2::StreamRotation;
-using ::android::hardware::camera::device::V3_2::StreamType;
-using ::android::hardware::camera::device::V3_4::CaptureResult;
-using ::android::hardware::camera::device::V3_4::Stream;
-using ::android::hardware::camera::device::V3_5::BufferRequest;
-using ::android::hardware::camera::device::V3_5::BufferRequestStatus;
-using ::android::hardware::camera::device::V3_5::StreamBufferRequestError;
-using ::android::hardware::camera::device::V3_5::StreamBufferRet;
-using ::android::hardware::camera::device::V3_5::StreamBuffersVal;
-using ::android::hardware::camera::device::V3_6::HalStreamConfiguration;
-using ::android::hardware::camera::device::V3_7::CaptureRequest;
-using ::android::hardware::camera::device::V3_7::StreamConfiguration;
-using ::android::hardware::camera::provider::V2_5::DeviceState;
-
-// Util functions to convert the types between HIDL and Google Camera HAL.
-
-// Conversions from HAL to HIDL
-status_t ConvertToHidlVendorTagSections(
-    const std::vector<google_camera_hal::VendorTagSection>& hal_sections,
-    hidl_vec<VendorTagSection>* hidl_sections);
-
-status_t ConvertToHidlVendorTagType(
-    google_camera_hal::CameraMetadataType hal_type,
-    CameraMetadataType* hidl_type);
-
-status_t ConvertToHidlResourceCost(
-    const google_camera_hal::CameraResourceCost& hal_cost,
-    CameraResourceCost* hidl_cost);
-
-status_t ConvertToHidlHalStreamConfig(
-    const std::vector<google_camera_hal::HalStream>& hal_configured_streams,
-    HalStreamConfiguration* hidl_hal_stream_config);
-
-// Convert a HAL result to a HIDL result. It will try to write the result
-// metadata to result_metadata_queue. If it fails, it will write the result
-// metadata in hidl_result.
-status_t ConvertToHidlCaptureResult(
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* result_metadata_queue,
-    std::unique_ptr<google_camera_hal::CaptureResult> hal_result,
-    CaptureResult* hidl_result);
-
-status_t ConverToHidlNotifyMessage(
-    const google_camera_hal::NotifyMessage& hal_message,
-    NotifyMsg* hidl_message);
-
-// Convert from HAL status_t to HIDL Status
-// OK is converted to Status::OK.
-// BAD_VALUE is converted to Status::ILLEGAL_ARGUMENT.
-// -EBUSY is converted to Status::CAMERA_IN_USE.
-// -EUSERS is converted to Status::MAX_CAMERAS_IN_USE.
-// UNKNOWN_TRANSACTION is converted to Status::METHOD_NOT_SUPPORTED.
-// INVALID_OPERATION is converted to Status::OPERATION_NOT_SUPPORTED.
-// DEAD_OBJECT is converted to Status::CAMERA_DISCONNECTED.
-// All other errors are converted to Status::INTERNAL_ERROR.
-Status ConvertToHidlStatus(status_t hal_status);
-
-// Convert from HAL CameraDeviceStatus to HIDL CameraDeviceStatus
-// kNotPresent is converted to CameraDeviceStatus::NOT_PRESENT.
-// kPresent is converted to CameraDeviceStatus::PRESENT.
-// kEnumerating is converted to CameraDeviceStatus::ENUMERATING.
-status_t ConvertToHidlCameraDeviceStatus(
-    google_camera_hal::CameraDeviceStatus hal_camera_device_status,
-    CameraDeviceStatus* hidl_camera_device_status);
-
-// Convert from HAL TorchModeStatus to HIDL TorchModeStatus
-// kNotAvailable is converted to TorchModeStatus::NOT_AVAILABLE.
-// kAvailableOff is converted to TorchModeStatus::AVAILABLE_OFF.
-// kAvailableOn is converted to TorchModeStatus::AVAILABLE_ON.
-status_t ConvertToHidlTorchModeStatus(
-    google_camera_hal::TorchModeStatus hal_torch_status,
-    TorchModeStatus* hidl_torch_status);
-
-// Convert a HAL request to a HIDL request.
-status_t ConvertToHidlBufferRequest(
-    const std::vector<google_camera_hal::BufferRequest>& hal_buffer_requests,
-    hidl_vec<BufferRequest>* hidl_buffer_requests);
-
-// Convert a HAL stream buffer to a HIDL hidl stream buffer.
-status_t ConvertToHidlStreamBuffer(
-    const google_camera_hal::StreamBuffer& hal_buffer,
-    StreamBuffer* hidl_buffer);
-
-// Conversions from HIDL to HAL.
-status_t ConvertToHalTemplateType(
-    RequestTemplate hidl_template,
-    google_camera_hal::RequestTemplate* hal_template);
-
-status_t ConvertToHalStreamBuffer(const StreamBuffer& hidl_buffer,
-                                  google_camera_hal::StreamBuffer* hal_buffer);
-
-status_t ConvertToHalMetadata(
-    uint32_t message_queue_setting_size,
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* request_metadata_queue,
-    const CameraMetadata& request_settings,
-    std::unique_ptr<google_camera_hal::HalCameraMetadata>* hal_metadata);
-
-status_t ConvertToHalCaptureRequest(
-    const CaptureRequest& hidl_request,
-    MessageQueue<uint8_t, kSynchronizedReadWrite>* request_metadata_queue,
-    google_camera_hal::CaptureRequest* hal_request);
-
-status_t ConvertToHalBufferCaches(
-    const hidl_vec<BufferCache>& hidl_buffer_caches,
-    std::vector<google_camera_hal::BufferCache>* hal_buffer_caches);
-
-status_t ConverToHalStreamConfig(
-    const StreamConfiguration& hidl_stream_config,
-    google_camera_hal::StreamConfiguration* hal_stream_config);
-
-status_t ConverToHalStreamConfig(
-    const device::V3_4::StreamConfiguration& hidl_stream_config,
-    google_camera_hal::StreamConfiguration* hal_stream_config);
-
-status_t ConvertToHalStreamConfigurationMode(
-    StreamConfigurationMode hidl_mode,
-    google_camera_hal::StreamConfigurationMode* hal_mode);
-
-status_t ConvertToHalBufferStatus(BufferStatus hidl_status,
-                                  google_camera_hal::BufferStatus* hal_status);
-
-status_t ConvertToHalStream(const Stream& hidl_stream,
-                            google_camera_hal::Stream* hal_stream);
-
-status_t ConvertToHalStreamRotation(
-    StreamRotation hidl_stream_rotation,
-    google_camera_hal::StreamRotation* hal_stream_rotation);
-
-status_t ConvertToHalStreamType(StreamType hidl_stream_type,
-                                google_camera_hal::StreamType* hal_stream_type);
-
-status_t ConvertToHalTorchMode(TorchMode hidl_torch_mode,
-                               google_camera_hal::TorchMode* hal_torch_mode);
-
-status_t ConvertToHalBufferRequestStatus(
-    const BufferRequestStatus& hidl_buffer_request_status,
-    google_camera_hal::BufferRequestStatus* hal_buffer_request_status);
-
-status_t ConvertToHalBufferReturnStatus(
-    const StreamBufferRet& hidl_stream_buffer_return,
-    google_camera_hal::BufferReturn* hal_buffer_return);
-
-status_t ConvertStreamConfigurationV34ToV37(
-    const device::V3_4::StreamConfiguration& config_3_4,
-    StreamConfiguration* config_3_7);
-
-status_t ConvertToHalDeviceState(
-    const hardware::hidl_bitfield<DeviceState> hidl_device_state,
-    google_camera_hal::DeviceState& hal_device_state);
-
-}  // namespace hidl_utils
-}  // namespace implementation
-}  // namespace camera
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HARDWARE_GOOGLE_CAMERA_HAL_HIDL_SERVICE_HIDL_UTILS_H_
diff --git a/common/hal/hwl_interface/camera_device_hwl.h b/common/hal/hwl_interface/camera_device_hwl.h
index 19cd5fa..8bd8ead 100644
--- a/common/hal/hwl_interface/camera_device_hwl.h
+++ b/common/hal/hwl_interface/camera_device_hwl.h
@@ -58,6 +58,17 @@
   // unchanged after this CameraDevice instance is destroyed.
   virtual status_t SetTorchMode(TorchMode mode) = 0;
 
+  // Change the torch strength level of this camera device. If the torch is OFF
+  // and torchStrength > 0, then the torch will turn ON.
+  virtual status_t TurnOnTorchWithStrengthLevel(int32_t /*torch_strength*/) {
+    return UNKNOWN_TRANSACTION;
+  }
+
+  // Get the torch strength level of this camera device HWL.
+  virtual status_t GetTorchStrengthLevel(int32_t& /*torch_strength*/) const {
+    return UNKNOWN_TRANSACTION;
+  }
+
   // Dump the camera device states in fd, using dprintf() or write().
   virtual status_t DumpState(int fd) = 0;
 
diff --git a/common/hal/hwl_interface/camera_device_session_hwl.h b/common/hal/hwl_interface/camera_device_session_hwl.h
index 0dcfebd..c8094a5 100644
--- a/common/hal/hwl_interface/camera_device_session_hwl.h
+++ b/common/hal/hwl_interface/camera_device_session_hwl.h
@@ -122,6 +122,13 @@
   // this method should return an empty std::vector.
   virtual std::vector<uint32_t> GetPhysicalCameraIds() const = 0;
 
+  // Returns true if the two given physical camera ids can be streamed
+  // simultaneously from this device session.
+  virtual bool CanStreamSimultaneously(uint32_t /* physical_camera_id_1 */,
+                                       uint32_t /* physical_camera_id_2 */) const {
+    return true;
+  }
+
   // Return the characteristics that this camera device session is associated with.
   virtual status_t GetCameraCharacteristics(
       std::unique_ptr<HalCameraMetadata>* characteristics) const = 0;
@@ -165,11 +172,23 @@
   // Get zoom ratio mapper from HWL.
   virtual std::unique_ptr<ZoomRatioMapperHwl> GetZoomRatioMapperHwl() = 0;
 
+  // Get maximum number of cameras allowed to stream concurrently.
+  virtual int GetMaxSupportedConcurrentCameras() const {
+    return 1;
+  }
+
   // Get customized profiler
   virtual std::unique_ptr<google::camera_common::Profiler> GetProfiler(
       uint32_t /* camera_id */, int /* option */) {
     return nullptr;
   }
+
+  // Release unused framework buffers from cache. This should be called when a
+  // ProcessCaptureRequest call includes a non-empty cachesToRemove argument. It
+  // is used to pass the list of buffers to the HWL to handle any internal
+  // caching of file descriptors done by the HWL.
+  virtual void RemoveCachedBuffers(const native_handle_t* /*handle*/) {
+  }
 };
 
 }  // namespace google_camera_hal
diff --git a/common/hal/hwl_interface/process_block.h b/common/hal/hwl_interface/process_block.h
index 8303aba..455dadd 100644
--- a/common/hal/hwl_interface/process_block.h
+++ b/common/hal/hwl_interface/process_block.h
@@ -113,6 +113,9 @@
 #if !GCH_HWL_USE_DLOPEN
 extern "C" __attribute__((weak)) ExternalProcessBlockFactory*
 GetSnapshotProcessBlockFactory();
+
+extern "C" __attribute__((weak)) ExternalProcessBlockFactory*
+GetDenoiseProcessBlockFactory();
 #endif
 
 }  // namespace google_camera_hal
diff --git a/common/hal/tests/camera_device_tests.cc b/common/hal/tests/camera_device_tests.cc
index c7ec3e6..3b0e6e4 100644
--- a/common/hal/tests/camera_device_tests.cc
+++ b/common/hal/tests/camera_device_tests.cc
@@ -94,6 +94,20 @@
   EXPECT_EQ(device->SetTorchMode(TorchMode::kOn), OK);
 }
 
+TEST(CameraDeviceTests, TurnOnTorchWithStrengthLevel) {
+  auto mock_device_hwl = MockDeviceHwl::Create();
+  ASSERT_NE(mock_device_hwl, nullptr);
+  int32_t new_torch_strength = 5;
+
+  auto device = CameraDevice::Create(std::move(mock_device_hwl));
+  ASSERT_NE(device, nullptr);
+
+  EXPECT_EQ(device->TurnOnTorchWithStrengthLevel(new_torch_strength), OK);
+  int32_t torch_strength = 0;
+  EXPECT_EQ(device->GetTorchStrengthLevel(torch_strength), OK);
+  EXPECT_EQ(torch_strength, new_torch_strength);
+}
+
 TEST(CameraDeviceTests, DumpState) {
   auto mock_device_hwl = MockDeviceHwl::Create();
   ASSERT_NE(mock_device_hwl, nullptr);
diff --git a/common/hal/tests/mock_device_hwl.h b/common/hal/tests/mock_device_hwl.h
index 18b7ef4..f36015b 100644
--- a/common/hal/tests/mock_device_hwl.h
+++ b/common/hal/tests/mock_device_hwl.h
@@ -83,6 +83,20 @@
     return OK;
   }
 
+   status_t TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
+    if (torch_strength < 1) {
+      return BAD_VALUE;
+    }
+
+    torch_strength_ = torch_strength;
+    return OK;
+  }
+
+  status_t GetTorchStrengthLevel(int32_t& torch_strength) const {
+    torch_strength = torch_strength_;
+    return OK;
+  }
+
   // Dump the camera device states in fd, using dprintf() or write().
   status_t DumpState(int fd) {
     if (fd < 0) {
@@ -132,6 +146,7 @@
       physical_camera_characteristics_;
 
   std::string dump_string_;
+  int32_t torch_strength_ = 0;
 
  protected:
   MockDeviceHwl() {
diff --git a/common/hal/tests/mock_device_session_hwl.cc b/common/hal/tests/mock_device_session_hwl.cc
index 43e914e..5a8af01 100644
--- a/common/hal/tests/mock_device_session_hwl.cc
+++ b/common/hal/tests/mock_device_session_hwl.cc
@@ -183,6 +183,7 @@
                                      .message.shutter = {
                                          .frame_number = frame_number,
                                          .timestamp_ns = 0,
+                                         .readout_timestamp_ns = 0,
                                      }};
     callback->second.notify(request.pipeline_id, shutter_message);
 
diff --git a/common/hal/tests/result_dispatcher_tests.cc b/common/hal/tests/result_dispatcher_tests.cc
index 75df29e..4964ab3 100644
--- a/common/hal/tests/result_dispatcher_tests.cc
+++ b/common/hal/tests/result_dispatcher_tests.cc
@@ -64,7 +64,8 @@
         [this](std::unique_ptr<CaptureResult> result) {
           ProcessCaptureResult(std::move(result));
         },
-        [this](const NotifyMessage& message) { Notify(message); });
+        [this](const NotifyMessage& message) { Notify(message); },
+        "TestResultDispatcher");
 
     ASSERT_NE(result_dispatcher_, nullptr)
         << "Creating ResultDispatcher failed";
@@ -309,14 +310,17 @@
 
 TEST_F(ResultDispatcherTests, ShutterOrder) {
   static constexpr uint64_t kFrameDurationNs = 100;
+  static constexpr uint64_t kFrameExposureTimeNs = 33;
 
   std::vector<uint32_t> unordered_frame_numbers = {3, 1, 2, 5, 4, 6};
   AddPendingRequestsToDispatcher(unordered_frame_numbers);
 
   // Add unordered shutters to dispatcher.
   for (auto frame_number : unordered_frame_numbers) {
-    EXPECT_EQ(result_dispatcher_->AddShutter(frame_number,
-                                             frame_number * kFrameDurationNs),
+    EXPECT_EQ(result_dispatcher_->AddShutter(
+                  frame_number,
+                  frame_number * kFrameDurationNs - kFrameExposureTimeNs,
+                  frame_number * kFrameDurationNs),
               OK);
   }
 
@@ -398,6 +402,7 @@
 
 TEST_F(ResultDispatcherTests, ShutterOrderWithRemovePengingRequest) {
   static constexpr uint64_t kFrameDurationNs = 100;
+  static constexpr uint64_t kFrameExposureTimeNs = 33;
 
   std::vector<uint32_t> unordered_frame_numbers = {3, 1, 2, 5, 4, 6};
   AddPendingRequestsToDispatcher(unordered_frame_numbers);
@@ -407,8 +412,10 @@
   // After erase iter, unordered_frame_numbers = {3, 1, 5, 4, 6};
   unordered_frame_numbers.erase(iter);
   for (auto frame_number : unordered_frame_numbers) {
-    EXPECT_EQ(result_dispatcher_->AddShutter(frame_number,
-                                             frame_number * kFrameDurationNs),
+    EXPECT_EQ(result_dispatcher_->AddShutter(
+                  frame_number,
+                  frame_number * kFrameDurationNs - kFrameExposureTimeNs,
+                  frame_number * kFrameDurationNs),
               OK);
   }
 
diff --git a/common/hal/utils/camera_blob.h b/common/hal/utils/camera_blob.h
new file mode 100644
index 0000000..f038b55
--- /dev/null
+++ b/common/hal/utils/camera_blob.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_UTILS_CAMERA_BLOB_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_UTILS_CAMERA_BLOB_H_
+
+#include <cstdint>
+
+namespace android {
+namespace google_camera_hal {
+
+/**
+ * CameraBlob:
+ *
+ * Transport header for camera blob types; generally compressed JPEG buffers in
+ * output streams.
+ *
+ * To capture JPEG images, a stream is created using the pixel format
+ * HAL_PIXEL_FORMAT_BLOB and dataspace HAL_DATASPACE_V0_JFIF. The buffer size
+ * for the stream is calculated by the framework, based on the static metadata
+ * field android.jpeg.maxSize. Since compressed JPEG images are of variable
+ * size, the HAL needs to include the final size of the compressed image using
+ * this structure inside the output stream buffer. The camera blob ID field must
+ * be set to CameraBlobId::JPEG.
+ *
+ * The transport header must be at the end of the JPEG output stream
+ * buffer. That means the jpegBlobId must start at byte[buffer_size -
+ * sizeof(CameraBlob)], where the buffer_size is the size of gralloc
+ * buffer. Any HAL using this transport header must account for it in
+ * android.jpeg.maxSize. The JPEG data itself starts at the beginning of the
+ * buffer and must be blobSize bytes long.
+ *
+ * Copied from hardware/interfaces/camera/device/aidl/CameraBlobId.aidl
+ */
+enum CameraBlobId : uint32_t {
+  JPEG = 0x00FF,
+};
+
+struct CameraBlob {
+  CameraBlobId blob_id;
+  uint32_t blob_size;
+};
+
+}  // namespace google_camera_hal
+}  // namespace android
+
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_UTILS_CAMERA_BLOB_H_
diff --git a/common/hal/utils/hal_utils.cc b/common/hal/utils/hal_utils.cc
index e45e179..58febe7 100644
--- a/common/hal/utils/hal_utils.cc
+++ b/common/hal/utils/hal_utils.cc
@@ -743,6 +743,8 @@
   if (message.type == MessageType::kShutter) {
     ALOGI("== frame_number:%u", message.message.shutter.frame_number);
     ALOGI("== time_stamp:%" PRIu64, message.message.shutter.timestamp_ns);
+    ALOGI("== readout_time_stamp:%" PRIu64,
+          message.message.shutter.readout_timestamp_ns);
   } else if (message.type == MessageType::kError) {
     ALOGI("== frame_number:%u", message.message.error.frame_number);
     ALOGI("== error_code:%u", message.message.error.error_code);
diff --git a/common/hal/utils/result_dispatcher.cc b/common/hal/utils/result_dispatcher.cc
index 6de6863..fdf9502 100644
--- a/common/hal/utils/result_dispatcher.cc
+++ b/common/hal/utils/result_dispatcher.cc
@@ -17,12 +17,16 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "GCH_ResultDispatcher"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
-#include <log/log.h>
-#include <utils/Trace.h>
+#include "result_dispatcher.h"
 
 #include <inttypes.h>
+#include <log/log.h>
+#include <sys/resource.h>
+#include <utils/Trace.h>
 
-#include "result_dispatcher.h"
+#include <string>
+#include <string_view>
+
 #include "utils.h"
 
 namespace android {
@@ -30,12 +34,14 @@
 
 std::unique_ptr<ResultDispatcher> ResultDispatcher::Create(
     uint32_t partial_result_count,
-    ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
+    ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
+    std::string_view name) {
   ATRACE_CALL();
   auto dispatcher = std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
-      partial_result_count, process_capture_result, notify));
+      partial_result_count, process_capture_result, notify, name));
   if (dispatcher == nullptr) {
-    ALOGE("%s: Creating ResultDispatcher failed.", __FUNCTION__);
+    ALOGE("[%s] %s: Creating ResultDispatcher failed.",
+          std::string(name).c_str(), __FUNCTION__);
     return nullptr;
   }
 
@@ -44,8 +50,10 @@
 
 ResultDispatcher::ResultDispatcher(
     uint32_t partial_result_count,
-    ProcessCaptureResultFunc process_capture_result, NotifyFunc notify)
+    ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
+    std::string_view name)
     : kPartialResultCount(partial_result_count),
+      name_(name),
       process_capture_result_(process_capture_result),
       notify_(notify) {
   ATRACE_CALL();
@@ -56,9 +64,18 @@
     status_t res =
         utils::SetRealtimeThread(notify_callback_thread_.native_handle());
     if (res != OK) {
-      ALOGE("%s: SetRealtimeThread fail", __FUNCTION__);
+      ALOGE("[%s] %s: SetRealtimeThread fail", name_.c_str(), __FUNCTION__);
     } else {
-      ALOGI("%s: SetRealtimeThread OK", __FUNCTION__);
+      ALOGI("[%s] %s: SetRealtimeThread OK", name_.c_str(), __FUNCTION__);
+    }
+  } else {
+    // Assign higher priority to reduce the preemption when CPU usage is high
+    int32_t res = setpriority(
+        PRIO_PROCESS,
+        pthread_gettid_np(notify_callback_thread_.native_handle()), -20);
+    if (res != 0) {
+      ALOGE("[%s] %s: Set thread priority fail with error: %s", name_.c_str(),
+            __FUNCTION__, strerror(errno));
     }
   }
 }
@@ -87,8 +104,8 @@
 
   status_t res = AddPendingRequestLocked(pending_request);
   if (res != OK) {
-    ALOGE("%s: Adding a pending request failed: %s(%d).", __FUNCTION__,
-          strerror(-res), res);
+    ALOGE("[%s] %s: Adding a pending request failed: %s(%d).", name_.c_str(),
+          __FUNCTION__, strerror(-res), res);
     RemovePendingRequestLocked(pending_request.frame_number);
     return res;
   }
@@ -103,23 +120,23 @@
 
   status_t res = AddPendingShutterLocked(frame_number);
   if (res != OK) {
-    ALOGE("%s: Adding pending shutter for frame %u failed: %s(%d)",
-          __FUNCTION__, frame_number, strerror(-res), res);
+    ALOGE("[%s] %s: Adding pending shutter for frame %u failed: %s(%d)",
+          name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
     return res;
   }
 
   res = AddPendingFinalResultMetadataLocked(frame_number);
   if (res != OK) {
-    ALOGE("%s: Adding pending result metadata for frame %u failed: %s(%d)",
-          __FUNCTION__, frame_number, strerror(-res), res);
+    ALOGE("[%s] %s: Adding pending result metadata for frame %u failed: %s(%d)",
+          name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
     return res;
   }
 
   for (auto& buffer : pending_request.input_buffers) {
     res = AddPendingBufferLocked(frame_number, buffer, /*is_input=*/true);
     if (res != OK) {
-      ALOGE("%s: Adding pending input buffer for frame %u failed: %s(%d)",
-            __FUNCTION__, frame_number, strerror(-res), res);
+      ALOGE("[%s] %s: Adding pending input buffer for frame %u failed: %s(%d)",
+            name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
       return res;
     }
   }
@@ -127,8 +144,8 @@
   for (auto& buffer : pending_request.output_buffers) {
     res = AddPendingBufferLocked(frame_number, buffer, /*is_input=*/false);
     if (res != OK) {
-      ALOGE("%s: Adding pending output buffer for frame %u failed: %s(%d)",
-            __FUNCTION__, frame_number, strerror(-res), res);
+      ALOGE("[%s] %s: Adding pending output buffer for frame %u failed: %s(%d)",
+            name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
       return res;
     }
   }
@@ -139,8 +156,8 @@
 status_t ResultDispatcher::AddPendingShutterLocked(uint32_t frame_number) {
   ATRACE_CALL();
   if (pending_shutters_.find(frame_number) != pending_shutters_.end()) {
-    ALOGE("%s: Pending shutter for frame %u already exists.", __FUNCTION__,
-          frame_number);
+    ALOGE("[%s] %s: Pending shutter for frame %u already exists.",
+          name_.c_str(), __FUNCTION__, frame_number);
     return ALREADY_EXISTS;
   }
 
@@ -153,8 +170,8 @@
   ATRACE_CALL();
   if (pending_final_metadata_.find(frame_number) !=
       pending_final_metadata_.end()) {
-    ALOGE("%s: Pending final result metadata for frame %u already exists.",
-          __FUNCTION__, frame_number);
+    ALOGE("[%s] %s: Pending final result metadata for frame %u already exists.",
+          name_.c_str(), __FUNCTION__, frame_number);
     return ALREADY_EXISTS;
   }
 
@@ -174,8 +191,8 @@
 
   if (stream_pending_buffers_map_[stream_id].find(frame_number) !=
       stream_pending_buffers_map_[stream_id].end()) {
-    ALOGE("%s: Pending buffer of stream %u for frame %u already exists.",
-          __FUNCTION__, stream_id, frame_number);
+    ALOGE("[%s] %s: Pending buffer of stream %u for frame %u already exists.",
+          name_.c_str(), __FUNCTION__, stream_id, frame_number);
     return ALREADY_EXISTS;
   }
 
@@ -205,8 +222,8 @@
                             std::move(result->physical_metadata),
                             result->partial_result);
     if (res != OK) {
-      ALOGE("%s: Adding result metadata failed: %s (%d)", __FUNCTION__,
-            strerror(-res), res);
+      ALOGE("[%s] %s: Adding result metadata failed: %s (%d)", name_.c_str(),
+            __FUNCTION__, strerror(-res), res);
       failed = true;
     }
   }
@@ -214,8 +231,8 @@
   for (auto& buffer : result->output_buffers) {
     res = AddBuffer(frame_number, buffer);
     if (res != OK) {
-      ALOGE("%s: Adding an output buffer failed: %s (%d)", __FUNCTION__,
-            strerror(-res), res);
+      ALOGE("[%s] %s: Adding an output buffer failed: %s (%d)", name_.c_str(),
+            __FUNCTION__, strerror(-res), res);
       failed = true;
     }
   }
@@ -223,8 +240,8 @@
   for (auto& buffer : result->input_buffers) {
     res = AddBuffer(frame_number, buffer);
     if (res != OK) {
-      ALOGE("%s: Adding an input buffer failed: %s (%d)", __FUNCTION__,
-            strerror(-res), res);
+      ALOGE("[%s] %s: Adding an input buffer failed: %s (%d)", name_.c_str(),
+            __FUNCTION__, strerror(-res), res);
       failed = true;
     }
   }
@@ -237,28 +254,31 @@
 }
 
 status_t ResultDispatcher::AddShutter(uint32_t frame_number,
-                                      int64_t timestamp_ns) {
+                                      int64_t timestamp_ns,
+                                      int64_t readout_timestamp_ns) {
   ATRACE_CALL();
-  std::lock_guard<std::mutex> lock(result_lock_);
+  {
+    std::lock_guard<std::mutex> lock(result_lock_);
 
-  auto shutter_it = pending_shutters_.find(frame_number);
-  if (shutter_it == pending_shutters_.end()) {
-    ALOGE("%s: Cannot find the pending shutter for frame %u", __FUNCTION__,
-          frame_number);
-    return NAME_NOT_FOUND;
+    auto shutter_it = pending_shutters_.find(frame_number);
+    if (shutter_it == pending_shutters_.end()) {
+      ALOGE("[%s] %s: Cannot find the pending shutter for frame %u",
+            name_.c_str(), __FUNCTION__, frame_number);
+      return NAME_NOT_FOUND;
+    }
+
+    if (shutter_it->second.ready) {
+      ALOGE("[%s] %s: Already received shutter (%" PRId64
+            ") for frame %u. New timestamp %" PRId64,
+            name_.c_str(), __FUNCTION__, shutter_it->second.timestamp_ns,
+            frame_number, timestamp_ns);
+      return ALREADY_EXISTS;
+    }
+
+    shutter_it->second.timestamp_ns = timestamp_ns;
+    shutter_it->second.readout_timestamp_ns = readout_timestamp_ns;
+    shutter_it->second.ready = true;
   }
-
-  if (shutter_it->second.ready) {
-    ALOGE("%s: Already received shutter (%" PRId64
-          ") for frame %u. New "
-          "timestamp %" PRId64,
-          __FUNCTION__, shutter_it->second.timestamp_ns, frame_number,
-          timestamp_ns);
-    return ALREADY_EXISTS;
-  }
-
-  shutter_it->second.timestamp_ns = timestamp_ns;
-  shutter_it->second.ready = true;
   {
     std::unique_lock<std::mutex> lock(notify_callback_lock_);
     is_result_shutter_updated_ = true;
@@ -284,8 +304,8 @@
   }
 
   NotifyMessage message = {.type = MessageType::kError, .message.error = error};
-  ALOGV("%s: Notify error %u for frame %u stream %d", __FUNCTION__,
-        error.error_code, frame_number, error.error_stream_id);
+  ALOGV("[%s] %s: Notify error %u for frame %u stream %d", name_.c_str(),
+        __FUNCTION__, error.error_code, frame_number, error.error_stream_id);
   notify_(message);
 
   return OK;
@@ -314,14 +334,14 @@
 
   auto metadata_it = pending_final_metadata_.find(frame_number);
   if (metadata_it == pending_final_metadata_.end()) {
-    ALOGE("%s: Cannot find the pending result metadata for frame %u",
-          __FUNCTION__, frame_number);
+    ALOGE("[%s] %s: Cannot find the pending result metadata for frame %u",
+          name_.c_str(), __FUNCTION__, frame_number);
     return NAME_NOT_FOUND;
   }
 
   if (metadata_it->second.ready) {
-    ALOGE("%s: Already received final result metadata for frame %u.",
-          __FUNCTION__, frame_number);
+    ALOGE("[%s] %s: Already received final result metadata for frame %u.",
+          name_.c_str(), __FUNCTION__, frame_number);
     return ALREADY_EXISTS;
   }
 
@@ -337,13 +357,15 @@
     uint32_t partial_result) {
   ATRACE_CALL();
   if (metadata == nullptr) {
-    ALOGE("%s: metadata is nullptr.", __FUNCTION__);
+    ALOGE("[%s] %s: metadata is nullptr.", name_.c_str(), __FUNCTION__);
     return BAD_VALUE;
   }
 
   if (partial_result > kPartialResultCount) {
-    ALOGE("%s: partial_result %u cannot be larger than partial result count %u",
-          __FUNCTION__, partial_result, kPartialResultCount);
+    ALOGE(
+        "[%s] %s: partial_result %u cannot be larger than partial result count "
+        "%u",
+        name_.c_str(), __FUNCTION__, partial_result, kPartialResultCount);
     return BAD_VALUE;
   }
 
@@ -366,21 +388,21 @@
   uint32_t stream_id = buffer.stream_id;
   auto pending_buffers_it = stream_pending_buffers_map_.find(stream_id);
   if (pending_buffers_it == stream_pending_buffers_map_.end()) {
-    ALOGE("%s: Cannot find the pending buffer for stream %u", __FUNCTION__,
-          stream_id);
+    ALOGE("[%s] %s: Cannot find the pending buffer for stream %u",
+          name_.c_str(), __FUNCTION__, stream_id);
     return NAME_NOT_FOUND;
   }
 
   auto pending_buffer_it = pending_buffers_it->second.find(frame_number);
   if (pending_buffer_it == pending_buffers_it->second.end()) {
-    ALOGE("%s: Cannot find the pending buffer for stream %u for frame %u",
-          __FUNCTION__, stream_id, frame_number);
+    ALOGE("[%s] %s: Cannot find the pending buffer for stream %u for frame %u",
+          name_.c_str(), __FUNCTION__, stream_id, frame_number);
     return NAME_NOT_FOUND;
   }
 
   if (pending_buffer_it->second.ready) {
-    ALOGE("%s: Already received a buffer for stream %u for frame %u",
-          __FUNCTION__, stream_id, frame_number);
+    ALOGE("[%s] %s: Already received a buffer for stream %u for frame %u",
+          name_.c_str(), __FUNCTION__, stream_id, frame_number);
     return ALREADY_EXISTS;
   }
 
@@ -391,8 +413,11 @@
 }
 
 void ResultDispatcher::NotifyCallbackThreadLoop() {
-  // max thread name len = 16
-  pthread_setname_np(pthread_self(), "ResDispatcher");
+  // '\0' counts toward the 16-character restriction.
+  constexpr int kPthreadNameLenMinusOne = 16 - 1;
+  pthread_setname_np(
+      pthread_self(),
+      name_.substr(/*pos=*/0, /*count=*/kPthreadNameLenMinusOne).c_str());
 
   while (1) {
     NotifyShutters();
@@ -401,7 +426,8 @@
 
     std::unique_lock<std::mutex> lock(notify_callback_lock_);
     if (notify_callback_thread_exiting_) {
-      ALOGV("%s: NotifyCallbackThreadLoop exits.", __FUNCTION__);
+      ALOGV("[%s] %s: NotifyCallbackThreadLoop exits.", name_.c_str(),
+            __FUNCTION__);
       return;
     }
     if (!is_result_shutter_updated_) {
@@ -418,19 +444,20 @@
 void ResultDispatcher::PrintTimeoutMessages() {
   std::lock_guard<std::mutex> lock(result_lock_);
   for (auto& [frame_number, shutter] : pending_shutters_) {
-    ALOGW("%s: pending shutter for frame %u ready %d", __FUNCTION__,
-          frame_number, shutter.ready);
+    ALOGW("[%s] %s: pending shutter for frame %u ready %d", name_.c_str(),
+          __FUNCTION__, frame_number, shutter.ready);
   }
 
   for (auto& [frame_number, final_metadata] : pending_final_metadata_) {
-    ALOGW("%s: pending final result metadaata for frame %u ready %d",
-          __FUNCTION__, frame_number, final_metadata.ready);
+    ALOGW("[%s] %s: pending final result metadaata for frame %u ready %d",
+          name_.c_str(), __FUNCTION__, frame_number, final_metadata.ready);
   }
 
   for (auto& [stream_id, pending_buffers] : stream_pending_buffers_map_) {
     for (auto& [frame_number, pending_buffer] : pending_buffers) {
-      ALOGW("%s: pending buffer of stream %d for frame %u ready %d",
-            __FUNCTION__, stream_id, frame_number, pending_buffer.ready);
+      ALOGW("[%s] %s: pending buffer of stream %d for frame %u ready %d",
+            name_.c_str(), __FUNCTION__, stream_id, frame_number,
+            pending_buffer.ready);
     }
   }
 }
@@ -438,7 +465,7 @@
 status_t ResultDispatcher::GetReadyShutterMessage(NotifyMessage* message) {
   ATRACE_CALL();
   if (message == nullptr) {
-    ALOGE("%s: message is nullptr", __FUNCTION__);
+    ALOGE("[%s] %s: message is nullptr", name_.c_str(), __FUNCTION__);
     return BAD_VALUE;
   }
 
@@ -451,6 +478,8 @@
   message->type = MessageType::kShutter;
   message->message.shutter.frame_number = shutter_it->first;
   message->message.shutter.timestamp_ns = shutter_it->second.timestamp_ns;
+  message->message.shutter.readout_timestamp_ns =
+      shutter_it->second.readout_timestamp_ns;
   pending_shutters_.erase(shutter_it);
 
   return OK;
@@ -464,9 +493,11 @@
     if (GetReadyShutterMessage(&message) != OK) {
       break;
     }
-    ALOGV("%s: Notify shutter for frame %u timestamp %" PRIu64, __FUNCTION__,
-          message.message.shutter.frame_number,
-          message.message.shutter.timestamp_ns);
+    ALOGV("[%s] %s: Notify shutter for frame %u timestamp %" PRIu64
+          " readout_timestamp %" PRIu64,
+          name_.c_str(), __FUNCTION__, message.message.shutter.frame_number,
+          message.message.shutter.timestamp_ns,
+          message.message.shutter.readout_timestamp_ns);
     notify_(message);
   }
 }
@@ -476,8 +507,8 @@
     std::vector<PhysicalCameraMetadata>* physical_metadata) {
   ATRACE_CALL();
   if (final_metadata == nullptr || frame_number == nullptr) {
-    ALOGE("%s: final_metadata (%p) or frame_number (%p) is nullptr",
-          __FUNCTION__, final_metadata, frame_number);
+    ALOGE("[%s] %s: final_metadata (%p) or frame_number (%p) is nullptr",
+          name_.c_str(), __FUNCTION__, final_metadata, frame_number);
     return BAD_VALUE;
   }
 
@@ -506,7 +537,8 @@
 
   while (GetReadyFinalMetadata(&frame_number, &final_metadata,
                                &physical_metadata) == OK) {
-    ALOGV("%s: Notify final metadata for frame %u", __FUNCTION__, frame_number);
+    ALOGV("[%s] %s: Notify final metadata for frame %u", name_.c_str(),
+          __FUNCTION__, frame_number);
     NotifyResultMetadata(frame_number, std::move(final_metadata),
                          std::move(physical_metadata), kPartialResultCount);
   }
@@ -517,7 +549,7 @@
   ATRACE_CALL();
   std::lock_guard<std::mutex> lock(result_lock_);
   if (result == nullptr) {
-    ALOGE("%s: result is nullptr.", __FUNCTION__);
+    ALOGE("[%s] %s: result is nullptr.", name_.c_str(), __FUNCTION__);
     return BAD_VALUE;
   }
 
@@ -555,7 +587,7 @@
 
   while (GetReadyBufferResult(&result) == OK) {
     if (result == nullptr) {
-      ALOGE("%s: result is nullptr", __FUNCTION__);
+      ALOGE("[%s] %s: result is nullptr", name_.c_str(), __FUNCTION__);
       return;
     }
     std::lock_guard<std::mutex> lock(process_capture_result_lock_);
diff --git a/common/hal/utils/result_dispatcher.h b/common/hal/utils/result_dispatcher.h
index 0d94ec8..d610249 100644
--- a/common/hal/utils/result_dispatcher.h
+++ b/common/hal/utils/result_dispatcher.h
@@ -18,6 +18,8 @@
 #define HARDWARE_GOOGLE_CAMERA_HAL_UTILS_RESULT_DISPATCHER_H_
 
 #include <map>
+#include <string>
+#include <string_view>
 #include <thread>
 
 #include "hal_types.h"
@@ -40,7 +42,8 @@
   // notify is the function to notify shutter messages.
   static std::unique_ptr<ResultDispatcher> Create(
       uint32_t partial_result_count,
-      ProcessCaptureResultFunc process_capture_result, NotifyFunc notify);
+      ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
+      std::string_view name = "ResultDispatcher");
 
   virtual ~ResultDispatcher();
 
@@ -56,7 +59,8 @@
   // Add a shutter for a frame number. If the frame number doesn't belong to a
   // pending request that was previously added via AddPendingRequest(), an error
   // will be returned.
-  status_t AddShutter(uint32_t frame_number, int64_t timestamp_ns);
+  status_t AddShutter(uint32_t frame_number, int64_t timestamp_ns,
+                      int64_t readout_timestamp_ns);
 
   // Add an error notification for a frame number. When this is called, we no
   // longer wait for a shutter message or result metadata for the given frame.
@@ -67,7 +71,8 @@
 
   ResultDispatcher(uint32_t partial_result_count,
                    ProcessCaptureResultFunc process_capture_result,
-                   NotifyFunc notify);
+                   NotifyFunc notify,
+                   std::string_view name = "ResultDispatcher");
 
  private:
   static constexpr uint32_t kCallbackThreadTimeoutMs = 500;
@@ -77,6 +82,7 @@
   // called.
   struct PendingShutter {
     int64_t timestamp_ns = 0;
+    int64_t readout_timestamp_ns = 0;
     bool ready = false;
   };
 
@@ -158,6 +164,9 @@
 
   void PrintTimeoutMessages();
 
+  // Name used for debugging purpose to disambiguate multiple ResultDispatchers.
+  std::string name_;
+
   std::mutex result_lock_;
 
   // Maps from frame numbers to pending shutters.
diff --git a/common/hal/utils/stream_buffer_cache_manager.cc b/common/hal/utils/stream_buffer_cache_manager.cc
index f0f9bea..2333a9d 100644
--- a/common/hal/utils/stream_buffer_cache_manager.cc
+++ b/common/hal/utils/stream_buffer_cache_manager.cc
@@ -223,7 +223,7 @@
 }
 
 void StreamBufferCacheManager::WorkloadThreadLoop() {
-  if (property_get_bool(kRaiseBufAllocationPriority, false)) {
+  if (property_get_bool(kRaiseBufAllocationPriority, true)) {
     pid_t tid = gettid();
     setpriority(PRIO_PROCESS, tid, -20);
   }
diff --git a/common/hal/utils/utils.cc b/common/hal/utils/utils.cc
index 7a41889..751713e 100644
--- a/common/hal/utils/utils.cc
+++ b/common/hal/utils/utils.cc
@@ -486,6 +486,44 @@
   return libs;
 }
 
+bool IsStreamUseCaseSupported(const StreamConfiguration& stream_config,
+                              const std::set<int64_t>& stream_use_cases,
+                              bool log_if_not_supported) {
+  for (const auto& stream : stream_config.streams) {
+    if (stream_use_cases.find(stream.use_case) == stream_use_cases.end()) {
+      if (log_if_not_supported) {
+        ALOGE("Stream use case %d not in set of supported use cases",
+              stream.use_case);
+      }
+      return false;
+    }
+  }
+  return true;
+}
+
+status_t GetStreamUseCases(const HalCameraMetadata* static_metadata,
+                           std::set<int64_t>* stream_use_cases) {
+  if (static_metadata == nullptr || stream_use_cases == nullptr) {
+    return BAD_VALUE;
+  }
+
+  camera_metadata_ro_entry entry;
+  status_t ret =
+      static_metadata->Get(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
+  if (ret != OK) {
+    ALOGV("%s: No available stream use cases!", __FUNCTION__);
+    stream_use_cases->insert(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+    return OK;
+  }
+  stream_use_cases->insert(entry.data.i64, entry.data.i64 + entry.count);
+
+  return OK;
+}
+
+bool IsSecuredStream(const Stream& stream) {
+  return (stream.usage & GRALLOC_USAGE_PROTECTED) != 0u;
+}
+
 }  // namespace utils
 }  // namespace google_camera_hal
 }  // namespace android
diff --git a/common/hal/utils/utils.h b/common/hal/utils/utils.h
index a43e614..c3b0612 100644
--- a/common/hal/utils/utils.h
+++ b/common/hal/utils/utils.h
@@ -19,6 +19,7 @@
 
 #include <log/log.h>
 
+#include <set>
 #include <utility>
 
 #include "hal_types.h"
@@ -37,6 +38,7 @@
 bool IsDepthStream(const Stream& stream);
 bool IsOutputZslStream(const Stream& stream);
 bool IsSoftwareDenoiseEligibleSnapshotStream(const Stream& stream);
+bool IsSecuredStream(const Stream& stream);
 
 bool HasCapability(const HalCameraMetadata* metadata, uint8_t capability);
 
@@ -77,6 +79,13 @@
 status_t UpdateThreadSched(pthread_t thread, int32_t policy,
                            struct sched_param* param);
 
+status_t GetStreamUseCases(const HalCameraMetadata* static_metadata,
+                           std::set<int64_t>* stream_use_cases);
+
+bool IsStreamUseCaseSupported(const StreamConfiguration& stream_config,
+                              const std::set<int64_t>& stream_use_cases,
+                              bool log_if_not_supported = true);
+
 // Map the rectangle to the coordination of HAL.
 void ConvertZoomRatio(float zoom_ratio, const Dimension& active_array_dimension,
                       int32_t* left, int32_t* top, int32_t* width,
diff --git a/common/hal/utils/zsl_result_dispatcher.cc b/common/hal/utils/zsl_result_dispatcher.cc
index 3b5baa4..6389041 100644
--- a/common/hal/utils/zsl_result_dispatcher.cc
+++ b/common/hal/utils/zsl_result_dispatcher.cc
@@ -63,17 +63,17 @@
   notify_ = NotifyFunc(
       [this](const NotifyMessage& message) { NotifyHalMessage(message); });
 
-  normal_result_dispatcher_ =
-      std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
-          partial_result_count, process_capture_result_, notify_));
+  normal_result_dispatcher_ = std::unique_ptr<ResultDispatcher>(
+      new ResultDispatcher(partial_result_count, process_capture_result_,
+                           notify_, "ZslNormalDispatcher"));
   if (normal_result_dispatcher_ == nullptr) {
     ALOGE("%s: Creating normal_result_dispatcher_ failed.", __FUNCTION__);
     return BAD_VALUE;
   }
 
-  zsl_result_dispatcher_ =
-      std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
-          partial_result_count, process_capture_result_, notify_));
+  zsl_result_dispatcher_ = std::unique_ptr<ResultDispatcher>(
+      new ResultDispatcher(partial_result_count, process_capture_result_,
+                           notify_, "ZslZslDispatcher"));
   if (zsl_result_dispatcher_ == nullptr) {
     ALOGE("%s: Creating zsl_result_dispatcher_ failed.", __FUNCTION__);
     return BAD_VALUE;
@@ -143,13 +143,16 @@
 }
 
 status_t ZslResultDispatcher::AddShutter(uint32_t frame_number,
-                                         int64_t timestamp_ns) {
+                                         int64_t timestamp_ns,
+                                         int64_t readout_timestamp_ns) {
   ATRACE_CALL();
   bool is_zsl_request = IsZslFrame(frame_number);
   if (is_zsl_request) {
-    return zsl_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
+    return zsl_result_dispatcher_->AddShutter(frame_number, timestamp_ns,
+                                              readout_timestamp_ns);
   } else {
-    return normal_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
+    return normal_result_dispatcher_->AddShutter(frame_number, timestamp_ns,
+                                                 readout_timestamp_ns);
   }
 }
 
diff --git a/common/hal/utils/zsl_result_dispatcher.h b/common/hal/utils/zsl_result_dispatcher.h
index 6297b6b..562ba38 100644
--- a/common/hal/utils/zsl_result_dispatcher.h
+++ b/common/hal/utils/zsl_result_dispatcher.h
@@ -63,7 +63,8 @@
   // Add a shutter for a frame number. If the frame number doesn't belong to a
   // pending request that was previously added via AddPendingRequest(), an error
   // will be returned.
-  status_t AddShutter(uint32_t frame_number, int64_t timestamp_ns);
+  status_t AddShutter(uint32_t frame_number, int64_t timestamp_ns,
+                      int64_t readout_timestamp_ns);
 
   // Add an error notification for a frame number. When this is called, we no
   // longer wait for a shutter message or result metadata for the given frame.
diff --git a/common/profiler/profiler.cc b/common/profiler/profiler.cc
index 31fdaa6..689ef35 100644
--- a/common/profiler/profiler.cc
+++ b/common/profiler/profiler.cc
@@ -95,8 +95,11 @@
   void SetFpsPrintInterval(int32_t interval_seconds) override final;
 
   // Get the latency associated with the name
-  int64_t GetLatencyInNanoseconds(const std::string& name,
-                                  int request_id) override final;
+  std::list<std::pair<std::string, float>> GetLatencyData() override final;
+
+  std::string GetUseCase() const override final {
+    return use_case_;
+  }
 
  protected:
   // A structure to hold start time, end time, and count of profiling code
@@ -496,19 +499,26 @@
 }
 
 // Get the latency associated with the name
-int64_t ProfilerImpl::GetLatencyInNanoseconds(const std::string& name,
-                                              int request_id) {
-  // Will use name to add various TraceInt64 here
-  int valid_request_id = (request_id == kInvalidRequestId) ? 0 : request_id + 1;
-  int64_t latency_ns = 0;
-  {
-    std::lock_guard<std::mutex> lk(lock_);
-    if (static_cast<std::size_t>(valid_request_id) < timing_map_[name].size()) {
-      TimeSlot& slot = timing_map_[name][valid_request_id];
-      latency_ns = slot.end - slot.start;
+std::list<std::pair<std::string, float>> ProfilerImpl::GetLatencyData() {
+  std::list<std::pair<std::string, TimeSlot>> time_results;
+  std::list<std::pair<std::string, float>> latency_data;
+  for (const auto& [node_name, time_series] : timing_map_) {
+    for (const auto& slot : time_series) {
+      if (slot.count > 0 && time_results.size() < time_results.max_size()) {
+        time_results.push_back({node_name, slot});
+      }
     }
   }
-  return latency_ns;
+  time_results.sort(
+      [](const auto& a, const auto& b) { return a.second.end < b.second.end; });
+
+  for (const auto& [node_name, slot] : time_results) {
+    if (slot.count > 0) {
+      float elapsed = (slot.end - slot.start) * kNanoToMilli;
+      latency_data.push_back({node_name, elapsed});
+    }
+  }
+  return latency_data;
 }
 
 class ProfilerStopwatchImpl : public ProfilerImpl {
@@ -588,8 +598,11 @@
   void PrintResult() override final{};
   void ProfileFrameRate(const std::string&) override final{};
   void SetFpsPrintInterval(int32_t) override final{};
-  int64_t GetLatencyInNanoseconds(const std::string&, int) override final {
-    return 0;
+  std::list<std::pair<std::string, float>> GetLatencyData() override final {
+    return {};
+  }
+  std::string GetUseCase() const override final {
+    return "";
   }
 };
 
diff --git a/common/profiler/profiler.h b/common/profiler/profiler.h
index 9e8f16f..8788e59 100644
--- a/common/profiler/profiler.h
+++ b/common/profiler/profiler.h
@@ -20,6 +20,7 @@
 #include <cutils/properties.h>
 
 #include <limits>
+#include <list>
 #include <memory>
 #include <string>
 
@@ -207,8 +208,9 @@
   // The interval unit is second and interval_seconds must >= 1
   virtual void SetFpsPrintInterval(int32_t interval_seconds) = 0;
 
-  virtual int64_t GetLatencyInNanoseconds(const std::string& name,
-                                          int request_id) = 0;
+  virtual std::list<std::pair<std::string, float>> GetLatencyData() = 0;
+
+  virtual std::string GetUseCase() const = 0;
 
  protected:
   Profiler() = default;
diff --git a/common/sensor_listener/goog_sensor_motion.cc b/common/sensor_listener/goog_sensor_motion.cc
index f312ced..b12ea8e 100644
--- a/common/sensor_listener/goog_sensor_motion.cc
+++ b/common/sensor_listener/goog_sensor_motion.cc
@@ -147,6 +147,13 @@
   event_arrival_timestamps->clear();
 
   std::lock_guard<std::mutex> l(event_buffer_lock_);
+
+  event_timestamps->reserve(event_buffer_.size());
+  motion_vector_x->reserve(event_buffer_.size());
+  motion_vector_y->reserve(event_buffer_.size());
+  motion_vector_z->reserve(event_buffer_.size());
+  event_arrival_timestamps->reserve(event_buffer_.size());
+
   for (const auto& event : event_buffer_) {
     int64_t event_time = event.sensor_event.timestamp;
     if (event_time <= start_time || event_time > end_time) {
diff --git a/devices/EmulatedCamera/OWNERS b/devices/EmulatedCamera/OWNERS
new file mode 100644
index 0000000..f57f3f5
--- /dev/null
+++ b/devices/EmulatedCamera/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 41727
+include platform/frameworks/av:/camera/OWNERS
\ No newline at end of file
diff --git a/devices/EmulatedCamera/hwl/Android.bp b/devices/EmulatedCamera/hwl/Android.bp
index cf276ec..fad5ef0 100644
--- a/devices/EmulatedCamera/hwl/Android.bp
+++ b/devices/EmulatedCamera/hwl/Android.bp
@@ -14,13 +14,8 @@
         "EmulatedLogicalRequestState.cpp",
         "EmulatedRequestProcessor.cpp",
         "EmulatedRequestState.cpp",
-        "EmulatedScene.cpp",
-        "EmulatedSensor.cpp",
         "EmulatedTorchState.cpp",
-        "JpegCompressor.cpp",
-        "utils/ExifUtils.cpp",
-        "utils/HWLUtils.cpp",
-        "utils/StreamConfigurationMap.cpp",
+        "GrallocSensorBuffer.cpp",
     ],
     cflags: [
         "-Werror",
@@ -56,6 +51,7 @@
     ],
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
+        "libgooglecamerahwl_sensor_impl",
     ],
     include_dirs: [
         "system/media/private/camera/include",
@@ -78,3 +74,52 @@
     // Never installed to /vendor, only used inside an APEX.
     installable: false,
 }
+
+cc_library_static {
+    name: "libgooglecamerahwl_sensor_impl",
+    owner: "google",
+    proprietary: true,
+    host_supported: true,
+
+    srcs: [
+        "EmulatedScene.cpp",
+        "EmulatedSensor.cpp",
+        "JpegCompressor.cpp",
+        "utils/ExifUtils.cpp",
+        "utils/HWLUtils.cpp",
+        "utils/StreamConfigurationMap.cpp",
+    ],
+
+    header_libs: [
+        "libhardware_headers",
+    ],
+
+    shared_libs: [
+        "libcamera_metadata",
+        "libcutils",
+        "libexif",
+        "libjpeg",
+        "liblog",
+        "libyuv",
+    ],
+
+    static_libs: [
+        "android.hardware.graphics.common@1.1",
+        "android.hardware.graphics.common@1.2",
+    ],
+
+    include_dirs: [
+        "system/media/private/camera/include",
+        "hardware/google/camera/common/hal/common",
+        "hardware/google/camera/common/hal/hwl_interface",
+        "hardware/google/camera/common/hal/utils",
+    ],
+
+    export_include_dirs: ["."],
+
+    cflags: [
+        "-Werror",
+        "-Wextra",
+        "-Wall",
+    ],
+}
diff --git a/devices/EmulatedCamera/hwl/Base.h b/devices/EmulatedCamera/hwl/Base.h
index 883b61a..c6722a5 100644
--- a/devices/EmulatedCamera/hwl/Base.h
+++ b/devices/EmulatedCamera/hwl/Base.h
@@ -21,12 +21,11 @@
 
 #include <memory>
 
-#include "HandleImporter.h"
+#include "android/hardware/graphics/common/1.1/types.h"
 #include "hwl_types.h"
 
 namespace android {
 
-using android::hardware::camera::common::V1_0::helper::HandleImporter;
 using android::hardware::graphics::common::V1_1::PixelFormat;
 using google_camera_hal::HwlPipelineCallback;
 using google_camera_hal::StreamBuffer;
@@ -55,7 +54,6 @@
   PixelFormat format;
   android_dataspace_t dataSpace;
   StreamBuffer stream_buffer;
-  std::shared_ptr<HandleImporter> importer;
   HwlPipelineCallback callback;
   int acquire_fence_fd;
   bool is_input;
@@ -66,7 +64,7 @@
     YCbCrPlanes img_y_crcb;
   } plane;
 
-  SensorBuffer(std::shared_ptr<HandleImporter> handle_importer)
+  SensorBuffer()
       : width(0),
         height(0),
         frame_number(0),
@@ -74,7 +72,6 @@
         camera_id(0),
         format(PixelFormat::RGBA_8888),
         dataSpace(HAL_DATASPACE_UNKNOWN),
-        importer(handle_importer),
         acquire_fence_fd(-1),
         is_input(false),
         is_failed_request(false),
@@ -83,59 +80,13 @@
 
   SensorBuffer(const SensorBuffer&) = delete;
   SensorBuffer& operator=(const SensorBuffer&) = delete;
+
+  virtual ~SensorBuffer() {
+  }
 };
 
 typedef std::vector<std::unique_ptr<SensorBuffer>> Buffers;
 
 }  // namespace android
 
-using android::google_camera_hal::BufferStatus;
-using android::google_camera_hal::ErrorCode;
-using android::google_camera_hal::HwlPipelineResult;
-using android::google_camera_hal::MessageType;
-using android::google_camera_hal::NotifyMessage;
-
-template <>
-struct std::default_delete<android::SensorBuffer> {
-  inline void operator()(android::SensorBuffer* buffer) const {
-    if (buffer != nullptr) {
-      if (buffer->stream_buffer.buffer != nullptr) {
-        buffer->importer->unlock(buffer->stream_buffer.buffer);
-      }
-
-      if (buffer->acquire_fence_fd >= 0) {
-        buffer->importer->closeFence(buffer->acquire_fence_fd);
-      }
-
-      if ((buffer->stream_buffer.status != BufferStatus::kOk) &&
-          (buffer->callback.notify != nullptr) && (!buffer->is_failed_request)) {
-        NotifyMessage msg = {
-            .type = MessageType::kError,
-            .message.error = {.frame_number = buffer->frame_number,
-                              .error_stream_id = buffer->stream_buffer.stream_id,
-                              .error_code = ErrorCode::kErrorBuffer}};
-        buffer->callback.notify(buffer->pipeline_id, msg);
-      }
-
-      if (buffer->callback.process_pipeline_result != nullptr) {
-        auto result = std::make_unique<HwlPipelineResult>();
-        result->camera_id = buffer->camera_id;
-        result->pipeline_id = buffer->pipeline_id;
-        result->frame_number = buffer->frame_number;
-        result->partial_result = 0;
-
-        buffer->stream_buffer.acquire_fence =
-            buffer->stream_buffer.release_fence = nullptr;
-        if (buffer->is_input) {
-          result->input_buffers.push_back(buffer->stream_buffer);
-        } else {
-          result->output_buffers.push_back(buffer->stream_buffer);
-        }
-        buffer->callback.process_pipeline_result(std::move(result));
-      }
-      delete buffer;
-    }
-  }
-};
-
 #endif
diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp
index f6ffaee..75a55af 100644
--- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp
@@ -99,6 +99,9 @@
       return ret;
     }
   }
+
+  default_torch_strength_level_ = GetDefaultTorchStrengthLevel();
+  maximum_torch_strength_level_ = GetMaximumTorchStrengthLevel();
   return OK;
 }
 
@@ -151,9 +154,46 @@
     return INVALID_OPERATION;
   }
 
+  // If torch strength control is supported, reset the torch strength level to
+  // default level whenever the torch is turned OFF.
+  if (maximum_torch_strength_level_ > 1) {
+    torch_state_->InitializeTorchDefaultLevel(default_torch_strength_level_);
+    torch_state_->InitializeSupportTorchStrengthLevel(true);
+  }
+
   return torch_state_->SetTorchMode(mode);
 }
 
+status_t EmulatedCameraDeviceHwlImpl::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
+  if (torch_state_.get() == nullptr) {
+    return UNKNOWN_TRANSACTION;
+  }
+
+  // This API is supported if the maximum level is set to greater than 1.
+  if (maximum_torch_strength_level_ <= 1) {
+    ALOGE("Torch strength control feature is not supported.");
+    return UNKNOWN_TRANSACTION;
+  }
+  // Validate that the torch_strength is within the range.
+  if (torch_strength > maximum_torch_strength_level_ || torch_strength < 1) {
+    ALOGE("Torch strength value should be within the range.");
+    return BAD_VALUE;
+  }
+
+  return torch_state_->TurnOnTorchWithStrengthLevel(torch_strength);
+}
+
+status_t EmulatedCameraDeviceHwlImpl::GetTorchStrengthLevel(int32_t& torch_strength) const {
+  if (default_torch_strength_level_ < 1 && maximum_torch_strength_level_ <= 1) {
+    ALOGE("Torch strength control feature is not supported.");
+    return UNKNOWN_TRANSACTION;
+  }
+
+  torch_strength = torch_state_->GetTorchStrengthLevel();
+  ALOGV("Current torch strength level is: %d", torch_strength);
+  return OK;
+}
+
 status_t EmulatedCameraDeviceHwlImpl::DumpState(int /*fd*/) {
   return OK;
 }
@@ -192,4 +232,26 @@
       physical_stream_configuration_map_max_resolution_, sensor_chars_);
 }
 
+int32_t EmulatedCameraDeviceHwlImpl::GetDefaultTorchStrengthLevel() const {
+  camera_metadata_ro_entry entry;
+  int32_t default_level = 0;
+  auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
+  if (ret == OK && (entry.count == 1)) {
+     default_level = *entry.data.i32;
+     ALOGV("Default torch strength level is %d", default_level);
+  }
+  return default_level;
+}
+
+int32_t EmulatedCameraDeviceHwlImpl::GetMaximumTorchStrengthLevel() const {
+  camera_metadata_ro_entry entry;
+  int32_t max_level = 0;
+  auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &entry);
+  if (ret == OK && (entry.count == 1)) {
+     max_level = *entry.data.i32;
+     ALOGV("Maximum torch strength level is %d", max_level);
+  }
+  return max_level;
+}
+
 }  // namespace android
diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h
index c88b804..08c6ba3 100644
--- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h
+++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h
@@ -58,6 +58,10 @@
 
   status_t SetTorchMode(TorchMode mode) override;
 
+  status_t TurnOnTorchWithStrengthLevel(int32_t torch_strength) override;
+
+  status_t GetTorchStrengthLevel(int32_t& torch_strength) const override;
+
   status_t DumpState(int fd) override;
 
   status_t CreateCameraDeviceSessionHwl(
@@ -77,6 +81,9 @@
 
   status_t Initialize();
 
+  int32_t GetDefaultTorchStrengthLevel() const;
+  int32_t GetMaximumTorchStrengthLevel() const;
+
   const uint32_t camera_id_ = 0;
 
   std::unique_ptr<HalCameraMetadata> static_metadata_;
@@ -87,6 +94,9 @@
   PhysicalDeviceMapPtr physical_device_map_;
   std::shared_ptr<EmulatedTorchState> torch_state_;
   LogicalCharacteristics sensor_chars_;
+  int32_t default_torch_strength_level_ = 0;
+  int32_t maximum_torch_strength_level_ = 0;
+
 };
 
 }  // namespace android
diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp
index ee6461b..fb46544 100644
--- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp
@@ -18,11 +18,14 @@
 
 #include "EmulatedCameraDeviceSessionHWLImpl.h"
 
+#include <android/hardware/graphics/common/1.2/types.h>
 #include <hardware/gralloc.h>
 #include <inttypes.h>
 #include <log/log.h>
 #include <utils/Trace.h>
 
+#include <memory>
+
 #include "EmulatedSensor.h"
 #include "utils.h"
 #include "utils/HWLUtils.h"
@@ -33,6 +36,7 @@
 using google_camera_hal::utils::GetSensorActiveArraySize;
 using google_camera_hal::utils::HasCapability;
 
+using android::hardware::graphics::common::V1_2::Dataspace;
 std::unique_ptr<EmulatedCameraZoomRatioMapperHwlImpl>
 EmulatedCameraZoomRatioMapperHwlImpl::Create(
     const std::unordered_map<uint32_t, std::pair<Dimension, Dimension>>& dims) {
@@ -202,9 +206,11 @@
     return ret;
   }
 
-  request_processor_ = std::make_unique<EmulatedRequestProcessor>(
+  request_processor_ = std::make_shared<EmulatedRequestProcessor>(
       camera_id_, emulated_sensor, session_callback_);
 
+  request_processor_->InitializeSensorQueue(request_processor_);
+
   return request_processor_->Initialize(
       HalCameraMetadata::Clone(static_metadata_.get()),
       ClonePhysicalDeviceMap(physical_device_map_));
@@ -274,20 +280,29 @@
             {{.id = stream.id,
               .override_format =
                   is_input ? stream.format
-                           : EmulatedSensor::OverrideFormat(stream.format),
+                           : EmulatedSensor::OverrideFormat(
+                                 stream.format, stream.dynamic_profile),
               .producer_usage = is_input ? 0
                                          : GRALLOC_USAGE_HW_CAMERA_WRITE |
                                                GRALLOC_USAGE_HW_CAMERA_READ,
               .consumer_usage = 0,
               .max_buffers = max_pipeline_depth_,
-              .override_data_space = stream.data_space,
+              .override_data_space =
+                  (stream.dynamic_profile ==
+                   ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10) &&
+                          (stream.format ==
+                           HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
+                      ? static_cast<android_dataspace_t>(
+                            Dataspace::BT2020_ITU_HLG)
+                      : stream.data_space,
               .is_physical_camera_stream = stream.is_physical_camera_stream,
               .physical_camera_id = stream.physical_camera_id},
              .width = stream.width,
              .height = stream.height,
              .buffer_size = stream.buffer_size,
              .is_input = is_input,
-             .group_id = stream.group_id}));
+             .group_id = stream.group_id,
+             .use_case = stream.use_case}));
 
     if (stream.group_id != -1 && stream.is_physical_camera_stream) {
       // TODO: For quad bayer camera, the logical camera id should be used if
diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h
index 52a4920..81631cf 100644
--- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h
+++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h
@@ -19,6 +19,7 @@
 
 #include <camera_device_session_hwl.h>
 
+#include <memory>
 #include <set>
 
 #include "EmulatedCameraDeviceHWLImpl.h"
@@ -203,7 +204,7 @@
   bool has_raw_stream_ = false;
   std::unique_ptr<HalCameraMetadata> static_metadata_;
   std::vector<EmulatedPipeline> pipelines_;
-  std::unique_ptr<EmulatedRequestProcessor> request_processor_;
+  std::shared_ptr<EmulatedRequestProcessor> request_processor_;
   std::unique_ptr<StreamConfigurationMap> stream_configuration_map_;
   PhysicalStreamConfigurationMap physical_stream_configuration_map_;
   PhysicalStreamConfigurationMap physical_stream_configuration_map_max_resolution_;
diff --git a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h
index 1a7edfc..adedc21 100644
--- a/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h
+++ b/devices/EmulatedCamera/hwl/EmulatedLogicalRequestState.h
@@ -32,6 +32,7 @@
   size_t buffer_size;
   bool is_input;
   int32_t group_id;
+  int64_t use_case;
 };
 
 struct EmulatedPipeline {
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp
index 8c7f24d..05f3263 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp
@@ -26,9 +26,17 @@
 #include <utils/Timers.h>
 #include <utils/Trace.h>
 
+#include <memory>
+
+#include "GrallocSensorBuffer.h"
+
 namespace android {
 
+using ::android::frameworks::sensorservice::V1_0::ISensorManager;
+using ::android::frameworks::sensorservice::V1_0::Result;
 using android::hardware::camera::common::V1_0::helper::HandleImporter;
+using ::android::hardware::sensors::V1_0::SensorInfo;
+using ::android::hardware::sensors::V1_0::SensorType;
 using google_camera_hal::ErrorCode;
 using google_camera_hal::HwlPipelineResult;
 using google_camera_hal::MessageType;
@@ -56,6 +64,12 @@
     ALOGE("%s: Failed during sensor shutdown %s (%d)", __FUNCTION__,
           strerror(-ret), ret);
   }
+
+  if (sensor_event_queue_.get() != nullptr) {
+    sensor_event_queue_->disableSensor(sensor_handle_);
+    sensor_event_queue_.clear();
+    sensor_event_queue_ = nullptr;
+  }
 }
 
 status_t EmulatedRequestProcessor::ProcessPipelineRequests(
@@ -327,13 +341,14 @@
     uint32_t pipeline_id, HwlPipelineCallback callback,
     StreamBuffer stream_buffer, int32_t override_width,
     int32_t override_height) {
-  auto buffer = std::make_unique<SensorBuffer>(importer_);
+  auto buffer = std::make_unique<GrallocSensorBuffer>(importer_);
 
   auto stream = emulated_stream;
   // Make sure input stream formats are correctly mapped here
   if (stream.is_input) {
-    stream.override_format =
-        EmulatedSensor::OverrideFormat(stream.override_format);
+    stream.override_format = EmulatedSensor::OverrideFormat(
+        stream.override_format,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
   }
   if (override_width > 0 && override_height > 0) {
     buffer->width = override_width;
@@ -454,6 +469,13 @@
           if (ret == OK) {
             auto result = request_state_->InitializeLogicalResult(pipeline_id,
                                                                   frame_number);
+            // The screen rotation will be the same for all logical and physical devices
+            uint32_t screen_rotation = screen_rotation_;
+            for (auto it = logical_settings->begin();
+                 it != logical_settings->end(); it++) {
+              it->second.screen_rotation = screen_rotation;
+            }
+
             sensor_->SetCurrentRequest(
                 std::move(logical_settings), std::move(result),
                 std::move(input_buffers), std::move(output_buffers));
@@ -510,4 +532,84 @@
   return request_state_->GetDefaultRequest(type, default_settings);
 }
 
+Return<void> EmulatedRequestProcessor::SensorHandler::onEvent(const Event& e) {
+  auto processor = processor_.lock();
+  if (processor.get() == nullptr) {
+    return Void();
+  }
+
+  if (e.sensorType == SensorType::ACCELEROMETER) {
+    // Heuristic approach for deducing the screen
+    // rotation depending on the reported
+    // accelerometer readings. We switch
+    // the screen rotation when one of the
+    // x/y axis gets close enough to the earth
+    // acceleration.
+    const uint32_t earth_accel = 9;  // Switch threshold [m/s^2]
+    uint32_t x_accel = e.u.vec3.x;
+    uint32_t y_accel = e.u.vec3.y;
+    if (x_accel == earth_accel) {
+      processor->screen_rotation_ = 270;
+    } else if (x_accel == -earth_accel) {
+      processor->screen_rotation_ = 90;
+    } else if (y_accel == -earth_accel) {
+      processor->screen_rotation_ = 180;
+    } else {
+      processor->screen_rotation_ = 0;
+    }
+  } else {
+    ALOGE("%s: unexpected event received type: %d", __func__, e.sensorType);
+  }
+  return Void();
+}
+
+void EmulatedRequestProcessor::InitializeSensorQueue(
+    std::weak_ptr<EmulatedRequestProcessor> processor) {
+  if (sensor_event_queue_.get() != nullptr) {
+    return;
+  }
+
+  sp<ISensorManager> manager = ISensorManager::getService();
+  if (manager == nullptr) {
+    ALOGE("%s: Cannot get ISensorManager", __func__);
+  } else {
+    bool sensor_found = false;
+    manager->getSensorList([&](const auto& list, auto result) {
+      if (result != Result::OK) {
+        ALOGE("%s: Failed to retrieve sensor list!", __func__);
+      } else {
+        for (const SensorInfo& it : list) {
+          if (it.type == SensorType::ACCELEROMETER) {
+            sensor_found = true;
+            sensor_handle_ = it.sensorHandle;
+          }
+        }
+      }
+    });
+    if (sensor_found) {
+      manager->createEventQueue(
+          new SensorHandler(processor), [&](const auto& q, auto result) {
+            if (result != Result::OK) {
+              ALOGE("%s: Cannot create event queue", __func__);
+              return;
+            }
+            sensor_event_queue_ = q;
+          });
+
+      if (sensor_event_queue_.get() != nullptr) {
+        auto res = sensor_event_queue_->enableSensor(
+            sensor_handle_,
+            ns2us(EmulatedSensor::kSupportedFrameDurationRange[0]),
+            0 /*maxBatchReportLatencyUs*/);
+        if (res.isOk()) {
+        } else {
+          ALOGE("%s: Failed to enable sensor", __func__);
+        }
+      } else {
+        ALOGE("%s: Failed to create event queue", __func__);
+      }
+    }
+  }
+}
+
 }  // namespace android
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h
index 4f47e89..f931e35 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h
@@ -18,16 +18,26 @@
 #define EMULATOR_CAMERA_HAL_HWL_REQUEST_PROCESSOR_H
 
 #include <condition_variable>
+#include <memory>
 #include <mutex>
 #include <queue>
 #include <thread>
 
 #include "EmulatedLogicalRequestState.h"
 #include "EmulatedSensor.h"
+#include "HandleImporter.h"
+#include "android/frameworks/sensorservice/1.0/ISensorManager.h"
+#include "android/frameworks/sensorservice/1.0/types.h"
 #include "hwl_types.h"
 
 namespace android {
 
+using ::android::frameworks::sensorservice::V1_0::IEventQueue;
+using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using android::hardware::camera::common::V1_0::helper::HandleImporter;
+using ::android::hardware::sensors::V1_0::Event;
 using google_camera_hal::HalCameraMetadata;
 using google_camera_hal::HwlPipelineRequest;
 using google_camera_hal::HwlSessionCallback;
@@ -62,10 +72,28 @@
 
   status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta,
                       PhysicalDeviceMapPtr physical_devices);
+  void InitializeSensorQueue(std::weak_ptr<EmulatedRequestProcessor> processor);
 
   void SetSessionCallback(const HwlSessionCallback& hwl_session_callback);
 
  private:
+  class SensorHandler : public IEventQueueCallback {
+   public:
+    SensorHandler(std::weak_ptr<EmulatedRequestProcessor> processor)
+        : processor_(processor) {
+    }
+
+    // IEventQueueCallback interface
+    Return<void> onEvent(const Event& e) override;
+
+   private:
+    std::weak_ptr<EmulatedRequestProcessor> processor_;
+  };
+
+  int32_t sensor_handle_;
+  sp<IEventQueue> sensor_event_queue_;
+  std::atomic_uint32_t screen_rotation_;
+
   void RequestProcessorLoop();
 
   std::thread request_thread_;
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
index e7c62f9..f5f1f2b 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
@@ -41,7 +41,9 @@
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING,
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA,
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING,
-    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR};
+    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR,
+    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT,
+    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE};
 
 const std::set<uint8_t> EmulatedRequestState::kSupportedHWLevels = {
     ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
@@ -49,6 +51,14 @@
     ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3,
 };
 
+const std::vector<int64_t> EmulatedRequestState::kSupportedUseCases = {
+    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW,
+    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE,
+    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD,
+    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL,
+    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL};
+
 template <typename T>
 T GetClosestValue(T val, T min, T max) {
   if ((min > max) || ((val >= min) && (val <= max))) {
@@ -2741,8 +2751,12 @@
           config_map.GetValidOutputFormatsForInput(input_format);
       for (const auto& output_format : output_formats) {
         if (!EmulatedSensor::IsReprocessPathSupported(
-                EmulatedSensor::OverrideFormat(input_format),
-                EmulatedSensor::OverrideFormat(output_format))) {
+                EmulatedSensor::OverrideFormat(
+                    input_format,
+                    ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
+                EmulatedSensor::OverrideFormat(
+                    output_format,
+                    ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD))) {
           ALOGE(
               "%s: Input format: 0x%x to output format: 0x%x reprocess is"
               " currently not supported!",
@@ -2832,12 +2846,31 @@
       ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
   is_raw_capable_ =
       SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
+  supports_stream_use_case_ =
+      SupportsCapability(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE);
 
   if (supports_manual_sensor_) {
     auto templateIdx = static_cast<size_t>(RequestTemplate::kManual);
     default_requests_[templateIdx] = HalCameraMetadata::Create(1, 10);
   }
 
+  if (supports_stream_use_case_) {
+    ret = static_metadata_->Get(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+                                &entry);
+    if (ret != OK) {
+      ALOGE("%s: No available stream use cases!", __FUNCTION__);
+      return BAD_VALUE;
+    }
+    for (int64_t useCase : kSupportedUseCases) {
+      if (std::find(entry.data.i64, entry.data.i64 + entry.count, useCase) ==
+          entry.data.i64 + entry.count) {
+        ALOGE("%s: Mandatory stream use case %" PRId64 " not found!",
+              __FUNCTION__, useCase);
+        return BAD_VALUE;
+      }
+    }
+  }
+
   for (size_t templateIdx = 0; templateIdx < kTemplateCount; templateIdx++) {
     switch (static_cast<RequestTemplate>(templateIdx)) {
       case RequestTemplate::kPreview:
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.h b/devices/EmulatedCamera/hwl/EmulatedRequestState.h
index 1987bfa..8bf5408 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestState.h
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.h
@@ -96,6 +96,7 @@
   static const std::set<uint8_t> kSupportedCapabilites;
   static const std::set<uint8_t> kSupportedHWLevels;
   std::unique_ptr<HalCameraMetadata> static_metadata_;
+  static const std::vector<int64_t> kSupportedUseCases;
 
   // android.blacklevel.*
   uint8_t black_level_lock_ = ANDROID_BLACK_LEVEL_LOCK_ON;
@@ -128,6 +129,7 @@
   bool supports_private_reprocessing_ = false;
   bool supports_yuv_reprocessing_ = false;
   bool supports_remosaic_reprocessing_ = false;
+  bool supports_stream_use_case_ = false;
 
   // android.control.*
   struct SceneOverride {
diff --git a/devices/EmulatedCamera/hwl/EmulatedScene.cpp b/devices/EmulatedCamera/hwl/EmulatedScene.cpp
index 965b3b5..800eacb 100644
--- a/devices/EmulatedCamera/hwl/EmulatedScene.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedScene.cpp
@@ -29,11 +29,6 @@
 
 namespace android {
 
-using ::android::frameworks::sensorservice::V1_0::ISensorManager;
-using ::android::frameworks::sensorservice::V1_0::Result;
-using ::android::hardware::sensors::V1_0::SensorInfo;
-using ::android::hardware::sensors::V1_0::SensorType;
-
 // Define single-letter shortcuts for scene definition, for directly indexing
 // mCurrentColors
 #define G (EmulatedScene::GRASS * EmulatedScene::NUM_CHANNELS)
@@ -89,8 +84,7 @@
 EmulatedScene::EmulatedScene(int sensor_width_px, int sensor_height_px,
                              float sensor_sensitivity, int sensor_orientation,
                              bool is_front_facing)
-    : sensor_handle_(-1),
-      screen_rotation_(0),
+    : screen_rotation_(0),
       current_scene_(scene_rot0_),
       sensor_orientation_(sensor_orientation),
       is_front_facing_(is_front_facing),
@@ -115,11 +109,6 @@
 }
 
 EmulatedScene::~EmulatedScene() {
-  if (sensor_event_queue_.get() != nullptr) {
-    sensor_event_queue_->disableSensor(sensor_handle_);
-    sensor_event_queue_.clear();
-    sensor_event_queue_ = nullptr;
-  }
 }
 
 void EmulatedScene::Initialize(int sensor_width_px, int sensor_height_px,
@@ -140,37 +129,6 @@
 
 }
 
-Return<void> EmulatedScene::SensorHandler::onEvent(const Event& e) {
-  auto scene = scene_.promote();
-  if (scene.get() == nullptr) {
-    return Void();
-  }
-
-  if (e.sensorType == SensorType::ACCELEROMETER) {
-    // Heuristic approach for deducing the screen
-    // rotation depending on the reported
-    // accelerometer readings. We switch
-    // the screen rotation when one of the
-    // x/y axis gets close enough to the earth
-    // acceleration.
-    const uint32_t earth_accel = 9; // Switch threshold [m/s^2]
-    uint32_t x_accel = e.u.vec3.x;
-    uint32_t y_accel = e.u.vec3.y;
-    if (x_accel == earth_accel) {
-      scene->screen_rotation_ = 270;
-    } else if (x_accel == -earth_accel) {
-      scene->screen_rotation_ = 90;
-    } else if (y_accel == -earth_accel) {
-      scene->screen_rotation_ = 180;
-    } else {
-      scene->screen_rotation_ = 0;
-    }
-  } else {
-    ALOGE("%s: unexpected event received type: %d", __func__, e.sensorType);
-  }
-  return Void();
-}
-
 void EmulatedScene::SetColorFilterXYZ(float rX, float rY, float rZ, float grX,
                                       float grY, float grZ, float gbX, float gbY,
                                       float gbZ, float bX, float bY, float bZ) {
@@ -197,6 +155,10 @@
   return hour_;
 }
 
+void EmulatedScene::SetScreenRotation(uint32_t screen_rotation) {
+  screen_rotation_ = screen_rotation;
+}
+
 void EmulatedScene::SetExposureDuration(float seconds) {
   exposure_duration_ = seconds;
 }
@@ -389,24 +351,21 @@
     handshake_y_ /= handshake_divider;
   }
 
-  if (sensor_event_queue_.get() != nullptr) {
-    int32_t sensor_orientation = is_front_facing_ ? -sensor_orientation_ : sensor_orientation_;
-    int32_t scene_rotation = ((screen_rotation_ + 360) + sensor_orientation) % 360;
-    switch (scene_rotation) {
-      case 90:
-        current_scene_ = scene_rot90_;
-        break;
-      case 180:
-        current_scene_ = scene_rot180_;
-        break;
-      case 270:
-        current_scene_ = scene_rot270_;
-        break;
-      default:
-        current_scene_ = scene_rot0_;
-    }
-  } else {
-    current_scene_ = scene_rot0_;
+  int32_t sensor_orientation =
+      is_front_facing_ ? -sensor_orientation_ : sensor_orientation_;
+  int32_t scene_rotation = ((screen_rotation_ + 360) + sensor_orientation) % 360;
+  switch (scene_rotation) {
+    case 90:
+      current_scene_ = scene_rot90_;
+      break;
+    case 180:
+      current_scene_ = scene_rot180_;
+      break;
+    case 270:
+      current_scene_ = scene_rot270_;
+      break;
+    default:
+      current_scene_ = scene_rot0_;
   }
 
   // Set starting pixel
@@ -446,52 +405,6 @@
   }
 }
 
-void EmulatedScene::InitializeSensorQueue() {
-  if (sensor_event_queue_.get() != nullptr) {
-    return;
-  }
-
-  sp<ISensorManager> manager = ISensorManager::getService();
-  if (manager == nullptr) {
-    ALOGE("%s: Cannot get ISensorManager", __func__);
-  } else {
-    bool sensor_found = false;
-    manager->getSensorList(
-        [&] (const auto& list, auto result) {
-        if (result != Result::OK) {
-          ALOGE("%s: Failed to retrieve sensor list!", __func__);
-        } else {
-          for (const SensorInfo& it : list) {
-            if (it.type == SensorType::ACCELEROMETER) {
-              sensor_found = true;
-              sensor_handle_ = it.sensorHandle;
-            }
-          }
-        }});
-    if (sensor_found) {
-      manager->createEventQueue(
-          new SensorHandler(this), [&](const auto& q, auto result) {
-            if (result != Result::OK) {
-              ALOGE("%s: Cannot create event queue", __func__);
-              return;
-            }
-            sensor_event_queue_ = q;
-          });
-
-      if (sensor_event_queue_.get() != nullptr) {
-        auto res = sensor_event_queue_->enableSensor(sensor_handle_,
-            ns2us(EmulatedSensor::kSupportedFrameDurationRange[0]), 0/*maxBatchReportLatencyUs*/);
-        if (res.isOk()) {
-        } else {
-          ALOGE("%s: Failed to enable sensor", __func__);
-        }
-      } else {
-        ALOGE("%s: Failed to create event queue", __func__);
-      }
-    }
-  }
-}
-
 void EmulatedScene::SetReadoutPixel(int x, int y) {
   current_x_ = x;
   current_y_ = y;
diff --git a/devices/EmulatedCamera/hwl/EmulatedScene.h b/devices/EmulatedCamera/hwl/EmulatedScene.h
index 0334a58..0672422 100644
--- a/devices/EmulatedCamera/hwl/EmulatedScene.h
+++ b/devices/EmulatedCamera/hwl/EmulatedScene.h
@@ -26,27 +26,17 @@
 #ifndef HW_EMULATOR_CAMERA2_SCENE_H
 #define HW_EMULATOR_CAMERA2_SCENE_H
 
-#include "android/frameworks/sensorservice/1.0/ISensorManager.h"
-#include "android/frameworks/sensorservice/1.0/types.h"
 #include "utils/Timers.h"
 
 namespace android {
 
-using ::android::frameworks::sensorservice::V1_0::IEventQueue;
-using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback;
-using ::android::hardware::sensors::V1_0::Event;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-
-class EmulatedScene : public RefBase {
+class EmulatedScene {
  public:
   EmulatedScene(int sensor_width_px, int sensor_height_px,
                 float sensor_sensitivity, int sensor_orientation,
                 bool is_front_facing);
   ~EmulatedScene();
 
-  void InitializeSensorQueue();
-
   void Initialize(int sensor_width_px, int sensor_height_px,
                   float sensor_sensitivity);
 
@@ -65,6 +55,8 @@
   // Get current hour
   int GetHour() const;
 
+  void SetScreenRotation(uint32_t screen_rotation);
+
   // Set the duration of exposure for determining luminous exposure.
   // Must be called before calculateScene
   void SetExposureDuration(float seconds);
@@ -99,27 +91,13 @@
   static const int kSceneHeight = 20;
 
  private:
-  class SensorHandler : public IEventQueueCallback {
-   public:
-    SensorHandler(wp<EmulatedScene> scene) : scene_(scene) {
-    }
-
-    // IEventQueueCallback interface
-    Return<void> onEvent(const Event& e) override;
-
-   private:
-    wp<EmulatedScene> scene_;
-  };
-
   void InitiliazeSceneRotation(bool clock_wise);
 
-  int32_t sensor_handle_;
-  sp<IEventQueue> sensor_event_queue_;
-  std::atomic_uint32_t screen_rotation_;
   uint8_t scene_rot0_[kSceneWidth*kSceneHeight];
   uint8_t scene_rot90_[kSceneWidth*kSceneHeight];
   uint8_t scene_rot180_[kSceneWidth*kSceneHeight];
   uint8_t scene_rot270_[kSceneWidth*kSceneHeight];
+  uint32_t screen_rotation_;
   uint8_t *current_scene_;
   int32_t sensor_orientation_;
   bool is_front_facing_;
diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp
index 6b6d678..7d93ded 100644
--- a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp
@@ -16,6 +16,7 @@
 
 //#define LOG_NDEBUG 0
 //#define LOG_NNDEBUG 0
+#include "system/graphics-base-v1.1.h"
 #define LOG_TAG "EmulatedSensor"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 
@@ -25,11 +26,11 @@
 #define ALOGVV(...) ((void)0)
 #endif
 
-#include "EmulatedSensor.h"
-
+#include <android/hardware/graphics/common/1.2/types.h>
 #include <cutils/properties.h>
 #include <inttypes.h>
 #include <libyuv.h>
+#include <memory.h>
 #include <system/camera_metadata.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
@@ -37,15 +38,19 @@
 #include <cmath>
 #include <cstdlib>
 
+#include "EmulatedSensor.h"
 #include "utils/ExifUtils.h"
 #include "utils/HWLUtils.h"
 
 namespace android {
 
+using android::google_camera_hal::ErrorCode;
 using google_camera_hal::HalCameraMetadata;
 using google_camera_hal::MessageType;
 using google_camera_hal::NotifyMessage;
 
+using android::hardware::graphics::common::V1_2::Dataspace;
+
 const uint32_t EmulatedSensor::kRegularSceneHandshake = 1; // Scene handshake divider
 const uint32_t EmulatedSensor::kReducedSceneHandshake = 2; // Scene handshake divider
 
@@ -161,6 +166,17 @@
     return false;
   }
 
+  if (characteristics.is_10bit_dynamic_range_capable) {
+    // We support only HLG10 at the moment
+    const auto& hlg10_entry = characteristics.dynamic_range_profiles.find(
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10);
+    if ((characteristics.dynamic_range_profiles.size() != 1) ||
+        (hlg10_entry == characteristics.dynamic_range_profiles.end())) {
+      ALOGE("%s: Only support for HLG10 is available!", __FUNCTION__);
+      return false;
+    }
+  }
+
   if ((characteristics.exposure_time_range[0] >=
        characteristics.exposure_time_range[1]) ||
       ((characteristics.exposure_time_range[0] < kSupportedExposureTimeRange[0]) ||
@@ -361,6 +377,45 @@
         }
       }
 
+      if (stream.dynamic_profile !=
+          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
+        const SensorCharacteristics& sensor_char =
+            stream.is_physical_camera_stream
+                ? sensor_chars.at(stream.physical_camera_id)
+                : sensor_chars.at(logical_id);
+        if (!sensor_char.is_10bit_dynamic_range_capable) {
+          ALOGE("%s: 10-bit dynamic range output not supported on this device!",
+                __FUNCTION__);
+          return false;
+        }
+
+        if ((stream.format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) &&
+            (static_cast<android_pixel_format_v1_1_t>(stream.format) !=
+             HAL_PIXEL_FORMAT_YCBCR_P010)) {
+          ALOGE(
+              "%s: 10-bit dynamic range profile 0x%x not supported on a non "
+              "10-bit output stream"
+              " pixel format 0x%x",
+              __FUNCTION__, stream.dynamic_profile, stream.format);
+          return false;
+        }
+
+        if ((static_cast<android_pixel_format_v1_1_t>(stream.format) ==
+             HAL_PIXEL_FORMAT_YCBCR_P010) &&
+            ((stream.data_space !=
+              static_cast<android_dataspace_t>(Dataspace::BT2020_ITU_HLG)) &&
+             (stream.data_space !=
+              static_cast<android_dataspace_t>(Dataspace::BT2020_HLG)) &&
+             (stream.data_space !=
+              static_cast<android_dataspace_t>(Dataspace::UNKNOWN)))) {
+          ALOGE(
+              "%s: Unsupported stream data space 0x%x for 10-bit YUV "
+              "output",
+              __FUNCTION__, stream.data_space);
+          return false;
+        }
+      }
+
       switch (stream.format) {
         case HAL_PIXEL_FORMAT_BLOB:
           if ((stream.data_space != HAL_DATASPACE_V0_JFIF) &&
@@ -429,6 +484,35 @@
         return false;
       }
     }
+
+    if (!sensor_chars.at(logical_id).support_stream_use_case) {
+      if (stream.use_case != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+        ALOGE("%s: Camera device doesn't support non-default stream use case!",
+              __FUNCTION__);
+        return false;
+      }
+    } else if (stream.use_case >
+               ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL) {
+      ALOGE("%s: Stream with use case %d is not supported!", __FUNCTION__,
+            stream.use_case);
+      return false;
+    } else if (stream.use_case !=
+               ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+      if (stream.use_case ==
+              ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE) {
+        if (stream.format != HAL_PIXEL_FORMAT_YCBCR_420_888 &&
+            stream.format != HAL_PIXEL_FORMAT_BLOB) {
+          ALOGE("%s: Stream with use case %d isn't compatible with format %d",
+              __FUNCTION__, stream.use_case, stream.format);
+          return false;
+        }
+      } else if (stream.format != HAL_PIXEL_FORMAT_YCBCR_420_888 &&
+                 stream.format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        ALOGE("%s: Stream with use case %d isn't compatible with format %d",
+              __FUNCTION__, stream.use_case, stream.format);
+        return false;
+      }
+    }
   }
 
   for (const auto& raw_count : raw_stream_count) {
@@ -503,11 +587,10 @@
   }
 
   logical_camera_id_ = logical_camera_id;
-  scene_ = new EmulatedScene(
+  scene_ = std::make_unique<EmulatedScene>(
       device_chars->second.full_res_width, device_chars->second.full_res_height,
       kElectronsPerLuxSecond, device_chars->second.orientation,
       device_chars->second.is_front_facing);
-  scene_->InitializeSensorQueue();
   jpeg_compressor_ = std::make_unique<JpegCompressor>();
 
   auto res = run(LOG_TAG, ANDROID_PRIORITY_URGENT_DISPLAY);
@@ -628,9 +711,11 @@
   }
 
   auto frame_duration = EmulatedSensor::kSupportedFrameDurationRange[0];
+  auto exposure_time = EmulatedSensor::kSupportedExposureTimeRange[0];
   // Frame duration must always be the same among all physical devices
   if ((settings.get() != nullptr) && (!settings->empty())) {
     frame_duration = settings->begin()->second.frame_duration;
+    exposure_time = settings->begin()->second.exposure_time;
   }
 
   nsecs_t start_real_time = systemTime();
@@ -642,6 +727,7 @@
    * Stage 2: Capture new image
    */
   next_capture_time_ = frame_end_real_time;
+  next_readout_time_ = frame_end_real_time + exposure_time;
 
   sensor_binning_factor_info_.clear();
 
@@ -660,6 +746,14 @@
         ALOGW("%s: Reprocess timestamp absent!", __FUNCTION__);
       }
 
+      ret = next_result->result_metadata->Get(ANDROID_SENSOR_EXPOSURE_TIME,
+                                              &entry);
+      if ((ret == OK) && (entry.count == 1)) {
+        next_readout_time_ = next_capture_time_ + entry.data.i64[0];
+      } else {
+        next_readout_time_ = next_capture_time_;
+      }
+
       reprocess_request = true;
   }
 
@@ -670,7 +764,9 @@
           .type = MessageType::kShutter,
           .message.shutter = {
               .frame_number = next_buffers->at(0)->frame_number,
-              .timestamp_ns = static_cast<uint64_t>(next_capture_time_)}};
+              .timestamp_ns = static_cast<uint64_t>(next_capture_time_),
+              .readout_timestamp_ns =
+                  static_cast<uint64_t>(next_readout_time_)}};
       callback.notify(next_result->pipeline_id, msg);
     }
     auto b = next_buffers->begin();
@@ -718,10 +814,15 @@
       scene_->SetTestPattern(device_settings->second.test_pattern_mode ==
                              ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR);
       scene_->SetTestPatternData(device_settings->second.test_pattern_data);
+      scene_->SetScreenRotation(device_settings->second.screen_rotation);
 
       uint32_t handshake_divider =
-        (device_settings->second.video_stab == ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON) ?
-        kReducedSceneHandshake : kRegularSceneHandshake;
+          (device_settings->second.video_stab ==
+           ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON) ||
+                  (device_settings->second.video_stab ==
+                   ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION)
+              ? kReducedSceneHandshake
+              : kRegularSceneHandshake;
       scene_->CalculateScene(next_capture_time_, handshake_divider);
 
       (*b)->stream_buffer.status = BufferStatus::kOk;
@@ -1010,9 +1111,6 @@
       ret = nanosleep(&t, &t);
     } while (ret != 0);
   }
-  nsecs_t end_real_time __unused = systemTime();
-  ALOGVV("Frame cycle took %" PRIu64 "  ms, target %" PRIu64 " ms",
-         ns2ms(end_real_time - start_real_time), ns2ms(frame_duration));
 
   ReturnResults(callback, std::move(settings), std::move(next_result),
                 reprocess_request);
diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.h b/devices/EmulatedCamera/hwl/EmulatedSensor.h
index 3141b8b..8c63ae4 100644
--- a/devices/EmulatedCamera/hwl/EmulatedSensor.h
+++ b/devices/EmulatedCamera/hwl/EmulatedSensor.h
@@ -77,11 +77,11 @@
 
 #include <hwl_types.h>
 
+#include <algorithm>
 #include <functional>
 
 #include "Base.h"
 #include "EmulatedScene.h"
-#include "HandleImporter.h"
 #include "JpegCompressor.h"
 #include "utils/Mutex.h"
 #include "utils/StreamConfigurationMap.h"
@@ -90,7 +90,6 @@
 
 namespace android {
 
-using android::hardware::camera::common::V1_0::helper::HandleImporter;
 using google_camera_hal::HwlPipelineCallback;
 using google_camera_hal::HwlPipelineResult;
 using google_camera_hal::StreamConfiguration;
@@ -113,6 +112,12 @@
   float bZ = 1.0570f;
 };
 
+typedef std::unordered_map<
+    camera_metadata_enum_android_request_available_dynamic_range_profiles_map,
+    std::unordered_set<
+        camera_metadata_enum_android_request_available_dynamic_range_profiles_map>>
+    ProfileMap;
+
 struct SensorCharacteristics {
   size_t width = 0;
   size_t height = 0;
@@ -137,6 +142,9 @@
   uint32_t orientation = 0;
   bool is_front_facing = false;
   bool quad_bayer_sensor = false;
+  bool is_10bit_dynamic_range_capable = false;
+  ProfileMap dynamic_range_profiles;
+  bool support_stream_use_case = false;
 };
 
 // Maps logical/physical camera ids to sensor characteristics
@@ -147,9 +155,25 @@
   EmulatedSensor();
   ~EmulatedSensor();
 
-  static android_pixel_format_t OverrideFormat(android_pixel_format_t format) {
-    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
-      return HAL_PIXEL_FORMAT_YCBCR_420_888;
+  static android_pixel_format_t OverrideFormat(
+      android_pixel_format_t format,
+      camera_metadata_enum_android_request_available_dynamic_range_profiles_map
+          profile) {
+    switch (profile) {
+      case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD:
+        if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+          return HAL_PIXEL_FORMAT_YCBCR_420_888;
+        }
+        break;
+      case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
+        if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+          return static_cast<android_pixel_format_t>(
+              HAL_PIXEL_FORMAT_YCBCR_P010);
+        }
+        break;
+      default:
+        ALOGE("%s: Unsupported dynamic range profile 0x%x", __FUNCTION__,
+              profile);
     }
 
     return format;
@@ -216,6 +240,7 @@
     uint8_t sensor_pixel_mode = ANDROID_SENSOR_PIXEL_MODE_DEFAULT;
     uint8_t test_pattern_mode = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
     uint32_t test_pattern_data[4] = {0, 0, 0, 0};
+    uint32_t screen_rotation = 0;
   };
 
   // Maps physical and logical camera ids to individual device settings
@@ -313,6 +338,7 @@
   bool threadLoop() override;
 
   nsecs_t next_capture_time_;
+  nsecs_t next_readout_time_;
 
   struct SensorBinningFactorInfo {
     bool has_raw_stream = false;
@@ -323,7 +349,7 @@
 
   std::map<uint32_t, SensorBinningFactorInfo> sensor_binning_factor_info_;
 
-  sp<EmulatedScene> scene_;
+  std::unique_ptr<EmulatedScene> scene_;
 
   static EmulatedScene::ColorChannels GetQuadBayerColor(uint32_t x, uint32_t y);
 
diff --git a/devices/EmulatedCamera/hwl/EmulatedTorchState.cpp b/devices/EmulatedCamera/hwl/EmulatedTorchState.cpp
index 207a40c..edb6311 100644
--- a/devices/EmulatedCamera/hwl/EmulatedTorchState.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedTorchState.cpp
@@ -32,9 +32,36 @@
     return UNKNOWN_ERROR;
   }
 
+  torch_status_ = (mode == TorchMode::kOn) ? TorchModeStatus::kAvailableOn : TorchModeStatus::kAvailableOff;
+  if (mode == TorchMode::kOff && support_torch_strength_control_) {
+    new_torch_strength_level_ = default_level_;
+    ALOGV("%s: Turning torch OFF so reset the torch strength to default level:%d",
+          __FUNCTION__, default_level_);
+  }
+
   torch_cb_(camera_id_, (mode == TorchMode::kOn)
                             ? TorchModeStatus::kAvailableOn
                             : TorchModeStatus::kAvailableOff);
+  return OK;
+}
+
+status_t EmulatedTorchState::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  if (camera_open_) {
+    ALOGE("%s: Camera device open, torch cannot be controlled using this API!",
+          __FUNCTION__);
+    return UNKNOWN_ERROR;
+  }
+  new_torch_strength_level_ = torch_strength;
+  // If the torch mode is OFF and device is available, torch will be turned ON.
+  // torch_strength value should be greater than 1.
+  if (torch_status_ != TorchModeStatus::kAvailableOn && torch_strength > 1) {
+    torch_status_ = TorchModeStatus::kAvailableOn;
+    ALOGV("Changed the torch status to: %d", torch_status_);
+    torch_cb_(camera_id_, TorchModeStatus::kAvailableOn);
+  }
+
+  ALOGV("%s: Torch strength level successfully set to %d", __FUNCTION__, torch_strength);
 
   return OK;
 }
@@ -51,4 +78,20 @@
   torch_cb_(camera_id_, TorchModeStatus::kAvailableOff);
 }
 
+int32_t EmulatedTorchState::GetTorchStrengthLevel() {
+  std::lock_guard<std::mutex> lock(mutex_);
+  return new_torch_strength_level_;
+}
+
+void EmulatedTorchState::InitializeTorchDefaultLevel(int32_t default_level) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  default_level_ = default_level;
+}
+
+void EmulatedTorchState::InitializeSupportTorchStrengthLevel(bool is_torch_strength_control_supported) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  support_torch_strength_control_ = is_torch_strength_control_supported;
+}
+
+
 }  // namespace android
diff --git a/devices/EmulatedCamera/hwl/EmulatedTorchState.h b/devices/EmulatedCamera/hwl/EmulatedTorchState.h
index de69eab..126e16b 100644
--- a/devices/EmulatedCamera/hwl/EmulatedTorchState.h
+++ b/devices/EmulatedCamera/hwl/EmulatedTorchState.h
@@ -26,6 +26,7 @@
 
 using android::google_camera_hal::HwlTorchModeStatusChangeFunc;
 using android::google_camera_hal::TorchMode;
+using android::google_camera_hal::TorchModeStatus;
 
 class EmulatedTorchState {
  public:
@@ -34,8 +35,13 @@
   }
 
   status_t SetTorchMode(TorchMode mode);
+  status_t TurnOnTorchWithStrengthLevel(int32_t torch_strength);
+
   void AcquireFlashHw();
   void ReleaseFlashHw();
+  int32_t GetTorchStrengthLevel();
+  void InitializeTorchDefaultLevel(int32_t default_level);
+  void InitializeSupportTorchStrengthLevel(bool is_torch_strength_control_supported);
 
  private:
   std::mutex mutex_;
@@ -43,6 +49,10 @@
   uint32_t camera_id_;
   HwlTorchModeStatusChangeFunc torch_cb_;
   bool camera_open_ = false;
+  TorchModeStatus torch_status_;
+  int32_t new_torch_strength_level_ = 0;
+  bool support_torch_strength_control_ = false;
+  int32_t default_level_ = 0;
 
   EmulatedTorchState(const EmulatedTorchState&) = delete;
   EmulatedTorchState& operator=(const EmulatedTorchState&) = delete;
diff --git a/devices/EmulatedCamera/hwl/GrallocSensorBuffer.cpp b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.cpp
new file mode 100644
index 0000000..173d4fc
--- /dev/null
+++ b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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 "GrallocSensorBuffer.h"
+
+namespace android {
+
+GrallocSensorBuffer::~GrallocSensorBuffer() {
+  if (stream_buffer.buffer != nullptr) {
+    importer_->unlock(stream_buffer.buffer);
+  }
+
+  if (acquire_fence_fd >= 0) {
+    importer_->closeFence(acquire_fence_fd);
+  }
+
+  if ((stream_buffer.status != BufferStatus::kOk) &&
+      (callback.notify != nullptr) && (!is_failed_request)) {
+    NotifyMessage msg = {
+        .type = MessageType::kError,
+        .message.error = {.frame_number = frame_number,
+                          .error_stream_id = stream_buffer.stream_id,
+                          .error_code = ErrorCode::kErrorBuffer}};
+    callback.notify(pipeline_id, msg);
+  }
+
+  if (callback.process_pipeline_result != nullptr) {
+    auto result = std::make_unique<HwlPipelineResult>();
+    result->camera_id = camera_id;
+    result->pipeline_id = pipeline_id;
+    result->frame_number = frame_number;
+    result->partial_result = 0;
+
+    stream_buffer.acquire_fence = stream_buffer.release_fence = nullptr;
+    if (is_input) {
+      result->input_buffers.push_back(stream_buffer);
+    } else {
+      result->output_buffers.push_back(stream_buffer);
+    }
+    callback.process_pipeline_result(std::move(result));
+  }
+}
+
+}  // namespace android
diff --git a/devices/EmulatedCamera/hwl/GrallocSensorBuffer.h b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.h
new file mode 100644
index 0000000..3fd9726
--- /dev/null
+++ b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef HW_EMULATOR_GRALLOC_SENSOR_BUFFER_H
+#define HW_EMULATOR_GRALLOC_SENSOR_BUFFER_H
+
+#include <log/log.h>
+
+#include <memory>
+
+#include "Base.h"
+#include "HandleImporter.h"
+
+namespace android {
+
+using android::google_camera_hal::BufferStatus;
+using android::google_camera_hal::ErrorCode;
+using android::google_camera_hal::HwlPipelineResult;
+using android::google_camera_hal::MessageType;
+using android::google_camera_hal::NotifyMessage;
+using android::hardware::camera::common::V1_0::helper::HandleImporter;
+
+class GrallocSensorBuffer : public SensorBuffer {
+ public:
+  GrallocSensorBuffer(std::shared_ptr<HandleImporter> handle_importer)
+      : importer_(handle_importer) {
+  }
+
+  GrallocSensorBuffer(const GrallocSensorBuffer&) = delete;
+  GrallocSensorBuffer& operator=(const GrallocSensorBuffer&) = delete;
+
+  virtual ~GrallocSensorBuffer() override;
+
+ private:
+  std::shared_ptr<HandleImporter> importer_;
+};
+
+}  // namespace android
+
+#endif
diff --git a/devices/EmulatedCamera/hwl/JpegCompressor.cpp b/devices/EmulatedCamera/hwl/JpegCompressor.cpp
index 57530ad..582c92f 100644
--- a/devices/EmulatedCamera/hwl/JpegCompressor.cpp
+++ b/devices/EmulatedCamera/hwl/JpegCompressor.cpp
@@ -19,14 +19,16 @@
 
 #include "JpegCompressor.h"
 
+#include <camera_blob.h>
 #include <cutils/properties.h>
-#include <hardware/camera3.h>
 #include <libyuv.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 
 namespace android {
 
+using google_camera_hal::CameraBlob;
+using google_camera_hal::CameraBlobId;
 using google_camera_hal::ErrorCode;
 using google_camera_hal::MessageType;
 using google_camera_hal::NotifyMessage;
@@ -204,13 +206,12 @@
   }
 
   auto jpeg_header_offset =
-      job->output->plane.img.buffer_size - sizeof(struct camera3_jpeg_blob);
+      job->output->plane.img.buffer_size - sizeof(struct CameraBlob);
   if (jpeg_header_offset > encoded_size) {
-    struct camera3_jpeg_blob* blob =
-        reinterpret_cast<struct camera3_jpeg_blob*>(job->output->plane.img.img +
-                                                    jpeg_header_offset);
-    blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
-    blob->jpeg_size = encoded_size;
+    struct CameraBlob* blob = reinterpret_cast<struct CameraBlob*>(
+        job->output->plane.img.img + jpeg_header_offset);
+    blob->blob_id = CameraBlobId::JPEG;
+    blob->blob_size = encoded_size;
   } else {
     ALOGW("%s: No space for jpeg header at offset: %u and jpeg size: %u",
           __FUNCTION__, static_cast<unsigned>(jpeg_header_offset),
@@ -260,7 +261,7 @@
           dmgr.buffer_size);
   };
 
-  dmgr.empty_output_buffer = [](j_compress_ptr cinfo __unused) {
+  dmgr.empty_output_buffer = [](j_compress_ptr) {
     ALOGE("%s:%d Out of buffer", __FUNCTION__, __LINE__);
     return 0;
   };
diff --git a/devices/EmulatedCamera/hwl/JpegCompressor.h b/devices/EmulatedCamera/hwl/JpegCompressor.h
index 1ebda72..f7379e7 100644
--- a/devices/EmulatedCamera/hwl/JpegCompressor.h
+++ b/devices/EmulatedCamera/hwl/JpegCompressor.h
@@ -25,7 +25,6 @@
 #include <thread>
 
 #include "Base.h"
-#include "HandleImporter.h"
 
 extern "C" {
 #include <jpeglib.h>
@@ -35,7 +34,6 @@
 
 namespace android {
 
-using android::hardware::camera::common::V1_0::helper::HandleImporter;
 using google_camera_hal::BufferStatus;
 using google_camera_hal::HwlPipelineCallback;
 using google_camera_hal::HwlPipelineResult;
diff --git a/devices/EmulatedCamera/hwl/apex/Android.bp b/devices/EmulatedCamera/hwl/apex/Android.bp
index 30f80e3..19a1f52 100644
--- a/devices/EmulatedCamera/hwl/apex/Android.bp
+++ b/devices/EmulatedCamera/hwl/apex/Android.bp
@@ -33,6 +33,13 @@
     installable: false,
 }
 
+prebuilt_etc {
+    name: "com.google.emulated.camera.provider.hal.xml",
+    src: ":android.hardware.camera.provider@2.7-service-google.xml",
+    sub_dir: "vintf",
+    installable: false,
+}
+
 apex_defaults {
     name: "com.google.emulated.camera.provider.hal.defaults",
     manifest: "apex_manifest.json",
@@ -43,6 +50,7 @@
     updatable: false,
     // Install the apex in /vendor/apex
     soc_specific: true,
+    apex_name: "com.google.emulated.camera.provider.hal",
     binaries: [
         "android.hardware.camera.provider@2.7-service-google",
     ],
@@ -54,6 +62,7 @@
     ],
     prebuilts: [
         "com.google.emulated.camera.provider.hal.rc",
+        "com.google.emulated.camera.provider.hal.xml", // vintf fragment
         "android.hardware.camera.concurrent.prebuilt.xml",
         "android.hardware.camera.flash-autofocus.prebuilt.xml",
         "android.hardware.camera.front.prebuilt.xml",
@@ -63,7 +72,6 @@
         "emu_camera_depth.json",
         "emu_camera_front.json",
     ],
-    vintf_fragments: [":android.hardware.camera.provider@2.7-service-google.xml"],
 }
 
 apex {
diff --git a/devices/EmulatedCamera/hwl/apex/apex_manifest.json b/devices/EmulatedCamera/hwl/apex/apex_manifest.json
index 50c09a8..719c4ef 100644
--- a/devices/EmulatedCamera/hwl/apex/apex_manifest.json
+++ b/devices/EmulatedCamera/hwl/apex/apex_manifest.json
@@ -1,4 +1,5 @@
 {
   "name": "com.google.emulated.camera.provider.hal",
-  "version": 1
+  "version": 1,
+  "supportsRebootlessUpdate": true
 }
diff --git a/devices/EmulatedCamera/hwl/apex/com.google.emulated.camera.provider.hal.rc b/devices/EmulatedCamera/hwl/apex/com.google.emulated.camera.provider.hal.rc
index 134cd8f..165c36f 100644
--- a/devices/EmulatedCamera/hwl/apex/com.google.emulated.camera.provider.hal.rc
+++ b/devices/EmulatedCamera/hwl/apex/com.google.emulated.camera.provider.hal.rc
@@ -1,3 +1,7 @@
+# Re-start the service on rebootless-update
+on property:apex.com.google.emulated.camera.provider.hal.ready=true
+    start vendor.camera-provider-2-7-google
+
 service vendor.camera-provider-2-7-google /apex/com.google.emulated.camera.provider.hal/bin/hw/android.hardware.camera.provider@2.7-service-google
     class hal
     user system
diff --git a/devices/EmulatedCamera/hwl/apex/file_contexts b/devices/EmulatedCamera/hwl/apex/file_contexts
index 2f0ab85..62bb905 100644
--- a/devices/EmulatedCamera/hwl/apex/file_contexts
+++ b/devices/EmulatedCamera/hwl/apex/file_contexts
@@ -1,5 +1,5 @@
 (/.*)?                                                             u:object_r:vendor_file:s0
-# Permission XMLs
-/etc/permissions(/.*)?                                             u:object_r:vendor_configs_file:s0
+# Configs (e.g. vintf, permissions)
+/etc(/.*)?                                                         u:object_r:vendor_configs_file:s0
 # Service binary
 /bin/hw/android\.hardware\.camera\.provider@2\.7-service-google    u:object_r:hal_camera_default_exec:s0
diff --git a/devices/EmulatedCamera/hwl/configs/emu_camera_back.json b/devices/EmulatedCamera/hwl/configs/emu_camera_back.json
index 3f1e61e..97318f8 100644
--- a/devices/EmulatedCamera/hwl/configs/emu_camera_back.json
+++ b/devices/EmulatedCamera/hwl/configs/emu_camera_back.json
@@ -73,7 +73,8 @@
  ], 
  "android.control.availableVideoStabilizationModes": [
    "0", 
-   "1"
+   "1",
+   "2"
  ], 
  "android.control.awbAvailableModes": [
   "0", 
@@ -112,7 +113,13 @@
  ], 
  "android.flash.info.available": [
   "TRUE"
- ], 
+ ],
+  "android.flash.info.strengthMaximumLevel": [
+  "10"
+ ],
+  "android.flash.info.strengthDefaultLevel": [
+  "3"
+ ],
  "android.hotPixel.availableHotPixelModes": [
   "0", 
   "1", 
@@ -174,7 +181,9 @@
   "BURST_CAPTURE", 
   "PRIVATE_REPROCESSING", 
   "YUV_REPROCESSING", 
-  "RAW"
+  "RAW", 
+  "DYNAMIC_RANGE_TEN_BIT",
+  "STREAM_USE_CASE"
  ], 
  "android.sensor.referenceIlluminant1": [
   "D50"
@@ -186,6 +195,14 @@
  "android.request.maxNumInputStreams": [
   "1"
  ], 
+ "android.request.availableDynamicRangeProfilesMap": [
+  "2", 
+  "3", 
+  "0"
+ ], 
+ "android.request.recommendedTenBitDynamicRangeProfile": [
+  "2"
+ ], 
  "android.scaler.availableInputOutputFormatsMap": [
   "34", 
   "2", 
@@ -196,6 +213,14 @@
   "33", 
   "35"
  ], 
+ "android.scaler.availableStreamUseCases": [
+  "0",
+  "1",
+  "2",
+  "3",
+  "4",
+  "5",
+ ],
  "android.reprocess.maxCaptureStall": [
   "2"
  ], 
@@ -437,7 +462,7 @@
   "1"
  ], 
  "android.request.pipelineMaxDepth": [
-  "4"
+  "8"
  ], 
  "android.scaler.availableMaxDigitalZoom": [
   "10.00000000"
@@ -456,18 +481,34 @@
   "1856", 
   "1392", 
   "33331760", 
+  "54", 
+  "1856", 
+  "1392", 
+  "33331760", 
   "33", 
   "1280", 
   "720", 
   "33331760", 
+  "54", 
+  "1280", 
+  "720", 
+  "33331760", 
   "34", 
   "160", 
   "120", 
   "33331760", 
+  "54", 
+  "160", 
+  "120", 
+  "33331760", 
   "34", 
   "320", 
   "240", 
   "33331760", 
+  "54", 
+  "320", 
+  "240", 
+  "33331760", 
   "35", 
   "160", 
   "120", 
@@ -492,6 +533,10 @@
   "640", 
   "480", 
   "33331760", 
+  "54", 
+  "640", 
+  "480", 
+  "33331760", 
   "34", 
   "1280", 
   "720", 
@@ -524,6 +569,10 @@
   "176", 
   "144", 
   "33331760", 
+  "54", 
+  "176", 
+  "144", 
+  "33331760", 
   "34", 
   "1024", 
   "768", 
@@ -558,6 +607,10 @@
   "1024", 
   "768", 
   "33331760", 
+  "54", 
+  "1024", 
+  "768", 
+  "0", 
   "34", 
   "160", 
   "120", 
@@ -570,6 +623,10 @@
   "160", 
   "120", 
   "0", 
+  "54", 
+  "160", 
+  "120", 
+  "0", 
   "35", 
   "320", 
   "240", 
@@ -578,6 +635,10 @@
   "320", 
   "240", 
   "0", 
+  "54", 
+  "320", 
+  "240", 
+  "0", 
   "34", 
   "640", 
   "480", 
@@ -590,6 +651,10 @@
   "640", 
   "480", 
   "33331760", 
+  "54", 
+  "640", 
+  "480", 
+  "0", 
   "34", 
   "1280", 
   "720", 
@@ -602,10 +667,18 @@
   "1280", 
   "720", 
   "0", 
+  "54", 
+  "1280", 
+  "720", 
+  "0", 
   "35", 
   "1856", 
   "1392", 
   "0", 
+  "54", 
+  "1856", 
+  "1392", 
+  "0", 
   "1", 
   "1600", 
   "1200", 
@@ -632,10 +705,18 @@
   "160", 
   "120", 
   "OUTPUT", 
+  "54", 
+  "160", 
+  "120", 
+  "OUTPUT", 
   "34", 
   "320", 
   "240", 
   "OUTPUT", 
+  "54", 
+  "320", 
+  "240", 
+  "OUTPUT", 
   "35", 
   "160", 
   "120", 
@@ -660,6 +741,10 @@
   "640", 
   "480", 
   "OUTPUT", 
+  "54", 
+  "640", 
+  "480", 
+  "OUTPUT", 
   "34", 
   "1280", 
   "720", 
@@ -676,6 +761,10 @@
   "1280", 
   "720", 
   "OUTPUT", 
+  "54", 
+  "1280", 
+  "720", 
+  "OUTPUT", 
   "35", 
   "1856", 
   "1392", 
@@ -684,6 +773,10 @@
   "1856", 
   "1392", 
   "OUTPUT", 
+  "54", 
+  "1856", 
+  "1392", 
+  "OUTPUT", 
   "INPUT", 
   "1600", 
   "1200", 
@@ -700,6 +793,10 @@
   "176", 
   "144", 
   "OUTPUT", 
+  "54", 
+  "176", 
+  "144", 
+  "OUTPUT", 
   "34", 
   "1024", 
   "768", 
diff --git a/devices/EmulatedCamera/hwl/configs/emu_camera_front.json b/devices/EmulatedCamera/hwl/configs/emu_camera_front.json
index e406561..88b70e0 100644
--- a/devices/EmulatedCamera/hwl/configs/emu_camera_front.json
+++ b/devices/EmulatedCamera/hwl/configs/emu_camera_front.json
@@ -182,6 +182,12 @@
   "android.flash.info.available": [
    "TRUE"
   ], 
+  "android.flash.info.strengthMaximumLevel": [
+  "10"
+ ],
+  "android.flash.info.strengthDefaultLevel": [
+  "3"
+ ],
   "android.hotPixel.availableHotPixelModes": [
    "0", 
    "1", 
@@ -296,7 +302,16 @@
    "ULTRA_HIGH_RESOLUTION_SENSOR",
    "YUV_REPROCESSING", 
    "RAW",
-   "REMOSAIC_REPROCESSING"
+   "REMOSAIC_REPROCESSING", 
+   "DYNAMIC_RANGE_TEN_BIT"
+  ], 
+  "android.request.availableDynamicRangeProfilesMap": [
+   "2", 
+   "2", 
+   "0"
+  ], 
+  "android.request.recommendedTenBitDynamicRangeProfile": [
+   "2"
   ], 
   "android.request.maxNumInputStreams": [
    "1"
@@ -495,6 +510,7 @@
    "65537", 
    "65539", 
    "65540", 
+   "65538", 
    "65567", 
    "65543", 
    "65544", 
@@ -582,6 +598,66 @@
    "8.00000000"
   ], 
   "android.scaler.availableMinFrameDurations": [
+   "54", 
+   "1920", 
+   "1440", 
+   "33331760", 
+   "54", 
+   "1920", 
+   "1080", 
+   "33331760", 
+   "54", 
+   "1920", 
+   "960", 
+   "33331760", 
+   "54", 
+   "1600", 
+   "1200", 
+   "33331760", 
+   "54", 
+   "1440", 
+   "1080", 
+   "33331760", 
+   "54", 
+   "1280", 
+   "960", 
+   "33331760", 
+   "54", 
+   "1280", 
+   "720", 
+   "33331760", 
+   "54", 
+   "1024", 
+   "768", 
+   "33331760", 
+   "54", 
+   "800", 
+   "600", 
+   "33331760", 
+   "54", 
+   "720", 
+   "480", 
+   "33331760", 
+   "54", 
+   "640", 
+   "480", 
+   "33331760", 
+   "54", 
+   "640", 
+   "360", 
+   "33331760", 
+   "54", 
+   "352", 
+   "288", 
+   "33331760", 
+   "54", 
+   "320", 
+   "240", 
+   "33331760", 
+   "54", 
+   "176", 
+   "144", 
+   "33331760", 
    "32",
    "1920",
    "1440",
@@ -858,6 +934,66 @@
    "287539200"
    ],
   "android.scaler.availableStreamConfigurations": [
+   "54", 
+   "1920", 
+   "1440", 
+   "OUTPUT", 
+   "54", 
+   "1920", 
+   "1080", 
+   "OUTPUT", 
+   "54", 
+   "1920", 
+   "960", 
+   "OUTPUT", 
+   "54", 
+   "1600", 
+   "1200", 
+   "OUTPUT", 
+   "54", 
+   "1440", 
+   "1080", 
+   "OUTPUT", 
+   "54", 
+   "1280", 
+   "960", 
+   "OUTPUT", 
+   "54", 
+   "1280", 
+   "720", 
+   "OUTPUT", 
+   "54", 
+   "1024", 
+   "768", 
+   "OUTPUT", 
+   "54", 
+   "800", 
+   "600", 
+   "OUTPUT", 
+   "54", 
+   "720", 
+   "480", 
+   "OUTPUT", 
+   "54", 
+   "640", 
+   "480", 
+   "OUTPUT", 
+   "54", 
+   "640", 
+   "360", 
+   "OUTPUT", 
+   "54", 
+   "352", 
+   "288", 
+   "OUTPUT", 
+   "54", 
+   "320", 
+   "240", 
+   "OUTPUT", 
+   "54", 
+   "176", 
+   "144", 
+   "OUTPUT", 
    "32",
    "1920",
    "1440",
@@ -1604,7 +1740,16 @@
    "ULTRA_HIGH_RESOLUTION_SENSOR",
    "YUV_REPROCESSING", 
    "RAW",
-   "REMOSAIC_REPROCESSING"
+   "REMOSAIC_REPROCESSING", 
+   "DYNAMIC_RANGE_TEN_BIT"
+  ], 
+  "android.request.availableDynamicRangeProfilesMap": [
+   "2", 
+   "2", 
+   "0"
+  ], 
+  "android.request.recommendedTenBitDynamicRangeProfile": [
+   "2"
   ], 
   "android.request.maxNumInputStreams": [
    "1"
@@ -1807,6 +1952,7 @@
    "65544", 
    "65568", 
    "65547", 
+   "65538", 
    "65570", 
    "65551", 
    "65576", 
@@ -1888,6 +2034,66 @@
    "8.00000000"
   ], 
   "android.scaler.availableMinFrameDurations": [
+   "54", 
+   "1920", 
+   "1440", 
+   "33331760", 
+   "54", 
+   "1920", 
+   "1080", 
+   "33331760", 
+   "54", 
+   "1920", 
+   "960", 
+   "33331760", 
+   "54", 
+   "1600", 
+   "1200", 
+   "33331760", 
+   "54", 
+   "1440", 
+   "1080", 
+   "33331760", 
+   "54", 
+   "1280", 
+   "960", 
+   "33331760", 
+   "54", 
+   "1280", 
+   "720", 
+   "33331760", 
+   "54", 
+   "1024", 
+   "768", 
+   "33331760", 
+   "54", 
+   "800", 
+   "600", 
+   "33331760", 
+   "54", 
+   "720", 
+   "480", 
+   "33331760", 
+   "54", 
+   "640", 
+   "480", 
+   "33331760", 
+   "54", 
+   "640", 
+   "360", 
+   "33331760", 
+   "54", 
+   "352", 
+   "288", 
+   "33331760", 
+   "54", 
+   "320", 
+   "240", 
+   "33331760", 
+   "54", 
+   "176", 
+   "144", 
+   "33331760", 
    "32",
    "1920",
    "1440",
@@ -2164,6 +2370,66 @@
    "287539200"
    ],
   "android.scaler.availableStreamConfigurations": [
+   "54", 
+   "1920", 
+   "1440", 
+   "OUTPUT", 
+   "54", 
+   "1920", 
+   "1080", 
+   "OUTPUT", 
+   "54", 
+   "1920", 
+   "960", 
+   "OUTPUT", 
+   "54", 
+   "1600", 
+   "1200", 
+   "OUTPUT", 
+   "54", 
+   "1440", 
+   "1080", 
+   "OUTPUT", 
+   "54", 
+   "1280", 
+   "960", 
+   "OUTPUT", 
+   "54", 
+   "1280", 
+   "720", 
+   "OUTPUT", 
+   "54", 
+   "1024", 
+   "768", 
+   "OUTPUT", 
+   "54", 
+   "800", 
+   "600", 
+   "OUTPUT", 
+   "54", 
+   "720", 
+   "480", 
+   "OUTPUT", 
+   "54", 
+   "640", 
+   "480", 
+   "OUTPUT", 
+   "54", 
+   "640", 
+   "360", 
+   "OUTPUT", 
+   "54", 
+   "352", 
+   "288", 
+   "OUTPUT", 
+   "54", 
+   "320", 
+   "240", 
+   "OUTPUT", 
+   "54", 
+   "176", 
+   "144", 
+   "OUTPUT", 
    "32",
    "1920",
    "1440",
@@ -2933,7 +3199,16 @@
    "ULTRA_HIGH_RESOLUTION_SENSOR",
    "YUV_REPROCESSING", 
    "RAW",
-   "REMOSAIC_REPROCESSING"
+   "REMOSAIC_REPROCESSING", 
+   "DYNAMIC_RANGE_TEN_BIT"
+  ], 
+  "android.request.availableDynamicRangeProfilesMap": [
+   "2", 
+   "2", 
+   "0"
+  ], 
+  "android.request.recommendedTenBitDynamicRangeProfile": [
+   "2"
   ], 
   "android.request.maxNumInputStreams": [
    "1"
@@ -3134,6 +3409,7 @@
    "65567", 
    "65543", 
    "65544", 
+   "65538", 
    "65568", 
    "65547", 
    "65570", 
@@ -3217,6 +3493,70 @@
    "8.00000000"
   ], 
   "android.scaler.availableMinFrameDurations": [
+   "54", 
+   "2048", 
+   "1536", 
+   "33331760", 
+   "54", 
+   "1920", 
+   "1440", 
+   "33331760", 
+   "54", 
+   "1920", 
+   "1080", 
+   "33331760", 
+   "54", 
+   "1920", 
+   "960", 
+   "33331760", 
+   "54", 
+   "1600", 
+   "1200", 
+   "33331760", 
+   "54", 
+   "1440", 
+   "1080", 
+   "33331760", 
+   "54", 
+   "1280", 
+   "960", 
+   "33331760", 
+   "54", 
+   "1280", 
+   "720", 
+   "33331760", 
+   "54", 
+   "1024", 
+   "768", 
+   "33331760", 
+   "54", 
+   "800", 
+   "600", 
+   "33331760", 
+   "54", 
+   "720", 
+   "480", 
+   "33331760", 
+   "54", 
+   "640", 
+   "480", 
+   "33331760", 
+   "54", 
+   "640", 
+   "360", 
+   "33331760", 
+   "54", 
+   "352", 
+   "288", 
+   "33331760", 
+   "54", 
+   "320", 
+   "240", 
+   "33331760", 
+   "54", 
+   "176", 
+   "144", 
+   "33331760", 
    "32",
    "2048",
    "1536",
@@ -3517,6 +3857,70 @@
    "287539200"
    ],
   "android.scaler.availableStreamConfigurations": [
+   "54", 
+   "2048", 
+   "1536", 
+   "OUTPUT", 
+   "54", 
+   "1920", 
+   "1440", 
+   "OUTPUT", 
+   "54", 
+   "1920", 
+   "1080", 
+   "OUTPUT", 
+   "54", 
+   "1920", 
+   "960", 
+   "OUTPUT", 
+   "54", 
+   "1600", 
+   "1200", 
+   "OUTPUT", 
+   "54", 
+   "1440", 
+   "1080", 
+   "OUTPUT", 
+   "54", 
+   "1280", 
+   "960", 
+   "OUTPUT", 
+   "54", 
+   "1280", 
+   "720", 
+   "OUTPUT", 
+   "54", 
+   "1024", 
+   "768", 
+   "OUTPUT", 
+   "54", 
+   "800", 
+   "600", 
+   "OUTPUT", 
+   "54", 
+   "720", 
+   "480", 
+   "OUTPUT", 
+   "54", 
+   "640", 
+   "480", 
+   "OUTPUT", 
+   "54", 
+   "640", 
+   "360", 
+   "OUTPUT", 
+   "54", 
+   "352", 
+   "288", 
+   "OUTPUT", 
+   "54", 
+   "320", 
+   "240", 
+   "OUTPUT", 
+   "54", 
+   "176", 
+   "144", 
+   "OUTPUT", 
    "34", 
    "2048", 
    "1536", 
diff --git a/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp b/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp
index c50297e..b444465 100644
--- a/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp
+++ b/devices/EmulatedCamera/hwl/utils/HWLUtils.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <unordered_set>
 #define LOG_TAG "HWLUtils"
 #include "HWLUtils.h"
 #include <log/log.h>
@@ -61,6 +62,46 @@
   sensor_chars->max_processed_streams = entry.data.i32[1];
   sensor_chars->max_stalling_streams = entry.data.i32[2];
 
+  if (HasCapability(
+          metadata,
+          ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT)) {
+    ret = metadata->Get(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP,
+                        &entry);
+    if ((ret != OK) || ((entry.count % 3) != 0)) {
+      ALOGE("%s: Invalid ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP!",
+            __FUNCTION__);
+      return BAD_VALUE;
+    }
+
+    for (size_t i = 0; i < entry.count; i += 3) {
+      sensor_chars->dynamic_range_profiles.emplace(
+          static_cast<
+              camera_metadata_enum_android_request_available_dynamic_range_profiles_map>(
+              entry.data.i64[i]),
+          std::unordered_set<
+              camera_metadata_enum_android_request_available_dynamic_range_profiles_map>());
+      const auto profile_end =
+          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO
+          << 1;
+      uint64_t current_profile =
+          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+      for (; current_profile != profile_end; current_profile <<= 1) {
+        if (entry.data.i64[i + 1] & current_profile) {
+          sensor_chars->dynamic_range_profiles
+              .at(static_cast<
+                  camera_metadata_enum_android_request_available_dynamic_range_profiles_map>(
+                  entry.data.i64[i]))
+              .emplace(
+                  static_cast<
+                      camera_metadata_enum_android_request_available_dynamic_range_profiles_map>(
+                      current_profile));
+        }
+      }
+    }
+
+    sensor_chars->is_10bit_dynamic_range_capable = true;
+  }
+
   if (HasCapability(metadata,
                     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
     ret = metadata->Get(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, &entry);
@@ -213,6 +254,14 @@
     ALOGE("%s: Lens facing absent!", __FUNCTION__);
     return BAD_VALUE;
   }
+
+  if (HasCapability(metadata,
+                    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE)) {
+    sensor_chars->support_stream_use_case = true;
+  } else {
+    sensor_chars->support_stream_use_case = false;
+  }
+
   return ret;
 }