Merge "Fix the path to IR HAL" into main
diff --git a/bluetooth/ranging/OWNERS b/bluetooth/ranging/OWNERS
new file mode 100644
index 0000000..3d95624
--- /dev/null
+++ b/bluetooth/ranging/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 27441
+
+include platform/packages/modules/Bluetooth:/OWNERS
+
+chienyuanhuang@google.com
diff --git a/bluetooth/ranging/aidl/vts/Android.bp b/bluetooth/ranging/aidl/vts/Android.bp
new file mode 100644
index 0000000..ead9992
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/Android.bp
@@ -0,0 +1,27 @@
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalBluetoothRangingTargetTest",
+    defaults: [
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalBluetoothRangingTargetTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.ranging-V1-ndk",
+        "libbluetooth-types",
+    ],
+    test_config: "VtsHalBluetoothRangingTargetTest.xml",
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp
new file mode 100644
index 0000000..702df95
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2023 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 <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSoundingSessionCallback.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+using aidl::android::hardware::bluetooth::ranging::
+    BluetoothChannelSoundingParameters;
+using aidl::android::hardware::bluetooth::ranging::
+    BnBluetoothChannelSoundingSessionCallback;
+using aidl::android::hardware::bluetooth::ranging::ChannelSoudingRawData;
+using aidl::android::hardware::bluetooth::ranging::CsSecurityLevel;
+using aidl::android::hardware::bluetooth::ranging::IBluetoothChannelSounding;
+using aidl::android::hardware::bluetooth::ranging::
+    IBluetoothChannelSoundingSession;
+using aidl::android::hardware::bluetooth::ranging::
+    IBluetoothChannelSoundingSessionCallback;
+using aidl::android::hardware::bluetooth::ranging::RangingResult;
+using aidl::android::hardware::bluetooth::ranging::Reason;
+using aidl::android::hardware::bluetooth::ranging::ResultType;
+using aidl::android::hardware::bluetooth::ranging::SessionType;
+using aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
+using ndk::ScopedAStatus;
+
+class BluetoothChannelSoundingSessionCallback
+    : public BnBluetoothChannelSoundingSessionCallback {
+ public:
+  ScopedAStatus onOpened(Reason reason) override;
+  ScopedAStatus onOpenFailed(Reason reason) override;
+  ScopedAStatus onResult(const RangingResult& in_result) override;
+  ScopedAStatus onClose(Reason reason) override;
+  ScopedAStatus onCloseFailed(Reason reason) override;
+};
+
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onOpened(
+    Reason /*reason*/) {
+  return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onOpenFailed(
+    Reason /*reason*/) {
+  return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onResult(
+    const RangingResult& /*in_result*/) {
+  return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onClose(
+    Reason /*reason*/) {
+  return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onCloseFailed(
+    Reason /*reason*/) {
+  return ::ndk::ScopedAStatus::ok();
+}
+
+class BluetoothRangingTest : public ::testing::TestWithParam<std::string> {
+ public:
+  virtual void SetUp() override {
+    ALOGI("SetUp Ranging Test");
+    bluetooth_channel_sounding_ = IBluetoothChannelSounding::fromBinder(
+        ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(bluetooth_channel_sounding_, nullptr);
+  }
+
+  virtual void TearDown() override {
+    ALOGI("TearDown Ranging Test");
+    bluetooth_channel_sounding_ = nullptr;
+    ASSERT_EQ(bluetooth_channel_sounding_, nullptr);
+  }
+
+  ScopedAStatus getVendorSpecificData(
+      std::optional<std::vector<std::optional<VendorSpecificData>>>*
+          _aidl_return);
+  ScopedAStatus getSupportedSessionTypes(
+      std::optional<std::vector<SessionType>>* _aidl_return);
+  ScopedAStatus getMaxSupportedCsSecurityLevel(CsSecurityLevel* _aidl_return);
+  ScopedAStatus openSession(
+      const BluetoothChannelSoundingParameters& in_params,
+      const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+          in_callback,
+      std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return);
+
+  ScopedAStatus initBluetoothChannelSoundingSession(
+      std::shared_ptr<IBluetoothChannelSoundingSession>* session) {
+    BluetoothChannelSoundingParameters params;
+    std::shared_ptr<BluetoothChannelSoundingSessionCallback> callback = nullptr;
+    callback =
+        ndk::SharedRefBase::make<BluetoothChannelSoundingSessionCallback>();
+    ScopedAStatus status = openSession(params, callback, session);
+    return status;
+  }
+
+ private:
+  std::shared_ptr<IBluetoothChannelSounding> bluetooth_channel_sounding_;
+};
+
+ScopedAStatus BluetoothRangingTest::getVendorSpecificData(
+    std::optional<std::vector<std::optional<VendorSpecificData>>>*
+        _aidl_return) {
+  return bluetooth_channel_sounding_->getVendorSpecificData(_aidl_return);
+}
+ScopedAStatus BluetoothRangingTest::getSupportedSessionTypes(
+    std::optional<std::vector<SessionType>>* _aidl_return) {
+  return bluetooth_channel_sounding_->getSupportedSessionTypes(_aidl_return);
+}
+
+ScopedAStatus BluetoothRangingTest::getMaxSupportedCsSecurityLevel(
+    CsSecurityLevel* _aidl_return) {
+  return bluetooth_channel_sounding_->getMaxSupportedCsSecurityLevel(
+      _aidl_return);
+}
+ScopedAStatus BluetoothRangingTest::openSession(
+    const BluetoothChannelSoundingParameters& in_params,
+    const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+        in_callback,
+    std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return) {
+  return bluetooth_channel_sounding_->openSession(in_params, in_callback,
+                                                  _aidl_return);
+}
+
+TEST_P(BluetoothRangingTest, SetupAndTearDown) {}
+
+TEST_P(BluetoothRangingTest, GetVendorSpecificData) {
+  std::optional<std::vector<std::optional<VendorSpecificData>>>
+      vendor_specific_data;
+  ScopedAStatus status = getVendorSpecificData(&vendor_specific_data);
+  ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetSupportedSessionTypes) {
+  std::optional<std::vector<SessionType>> supported_session_types;
+  ScopedAStatus status = getSupportedSessionTypes(&supported_session_types);
+  ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetMaxSupportedCsSecurityLevel) {
+  CsSecurityLevel security_level;
+  ScopedAStatus status = getMaxSupportedCsSecurityLevel(&security_level);
+  ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, OpenSession) {
+  BluetoothChannelSoundingParameters params;
+  std::shared_ptr<BluetoothChannelSoundingSessionCallback> callback = nullptr;
+  callback =
+      ndk::SharedRefBase::make<BluetoothChannelSoundingSessionCallback>();
+  std::shared_ptr<IBluetoothChannelSoundingSession> session;
+  ScopedAStatus status = openSession(params, callback, &session);
+  ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetVendorSpecificReplies) {
+  std::shared_ptr<IBluetoothChannelSoundingSession> session;
+  auto status = initBluetoothChannelSoundingSession(&session);
+  ASSERT_TRUE(status.isOk());
+  if (session != nullptr) {
+    std::optional<std::vector<std::optional<VendorSpecificData>>>
+        vendor_specific_data;
+    status = session->getVendorSpecificReplies(&vendor_specific_data);
+    ASSERT_TRUE(status.isOk());
+  }
+}
+
+TEST_P(BluetoothRangingTest, GetSupportedResultTypes) {
+  std::shared_ptr<IBluetoothChannelSoundingSession> session;
+  auto status = initBluetoothChannelSoundingSession(&session);
+  ASSERT_TRUE(status.isOk());
+  if (session != nullptr) {
+    std::vector<ResultType> supported_result_types;
+    status = session->getSupportedResultTypes(&supported_result_types);
+    ASSERT_TRUE(status.isOk());
+  }
+}
+
+TEST_P(BluetoothRangingTest, IsAbortedProcedureRequired) {
+  std::shared_ptr<IBluetoothChannelSoundingSession> session;
+  auto status = initBluetoothChannelSoundingSession(&session);
+  ASSERT_TRUE(status.isOk());
+  if (session != nullptr) {
+    bool is_abort_procedure_required = true;
+    status = session->isAbortedProcedureRequired(&is_abort_procedure_required);
+    ASSERT_TRUE(status.isOk());
+  }
+}
+
+TEST_P(BluetoothRangingTest, WriteRawData) {
+  std::shared_ptr<IBluetoothChannelSoundingSession> session;
+  auto status = initBluetoothChannelSoundingSession(&session);
+  ASSERT_TRUE(status.isOk());
+  if (session != nullptr) {
+    ChannelSoudingRawData raw_data;
+    status = session->writeRawData(raw_data);
+    ASSERT_TRUE(status.isOk());
+  }
+}
+
+TEST_P(BluetoothRangingTest, CloseSession) {
+  std::shared_ptr<IBluetoothChannelSoundingSession> session;
+  auto status = initBluetoothChannelSoundingSession(&session);
+  ASSERT_TRUE(status.isOk());
+  if (session != nullptr) {
+    status = session->close(Reason::LOCAL_STACK_REQUEST);
+    ASSERT_TRUE(status.isOk());
+  }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothRangingTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothRangingTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothChannelSounding::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  ABinderProcess_startThreadPool();
+  int status = RUN_ALL_TESTS();
+  ALOGI("Test result = %d", status);
+  return status;
+}
\ No newline at end of file
diff --git a/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml
new file mode 100644
index 0000000..624b77e
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml
@@ -0,0 +1,33 @@
+<!--
+  Copyright (C) 2023 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.
+-->
+
+<configuration description="Runs VtsHalBluetoothRangingTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalBluetoothRangingTargetTest->/data/local/tmp/VtsHalBluetoothRangingTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalBluetoothRangingTargetTest" />
+    </test>
+</configuration>
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 98ef773..831cebb 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -265,7 +265,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.health</name>
-        <version>1-2</version>
+        <version>3</version>
         <interface>
             <name>IHealth</name>
             <instance>default</instance>
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index e288f17..4691dd6 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -48,7 +48,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
 
@@ -80,7 +80,7 @@
     name: "android.hardware.health-translate-ndk",
     defaults: ["android.hardware.health-translate-ndk_defaults"],
     shared_libs: [
-        "android.hardware.health-V2-ndk",
+        "android.hardware.health-V3-ndk",
     ],
 }
 
@@ -97,7 +97,7 @@
     name: "android.hardware.health-translate-java",
     srcs: ["android/hardware/health/Translate.java"],
     libs: [
-        "android.hardware.health-V2-java",
+        "android.hardware.health-V3-java",
         "android.hardware.health-V2.0-java",
         "android.hardware.health-V2.1-java",
     ],
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
index 2dd01b1..089c8ac 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
@@ -37,4 +37,6 @@
   long batteryManufacturingDateSeconds;
   long batteryFirstUsageSeconds;
   long batteryStateOfHealth;
+  @nullable String batterySerialNumber;
+  android.hardware.health.BatteryPartStatus batteryPartStatus = android.hardware.health.BatteryPartStatus.UNSUPPORTED;
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
new file mode 100644
index 0000000..e013e31
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.health;
+@Backing(type="int") @VintfStability
+enum BatteryPartStatus {
+  UNSUPPORTED,
+  ORIGINAL,
+  REPLACED,
+}
diff --git a/health/aidl/android/hardware/health/BatteryHealthData.aidl b/health/aidl/android/hardware/health/BatteryHealthData.aidl
index 594bcce..7245298 100644
--- a/health/aidl/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/android/hardware/health/BatteryHealthData.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.health;
 
+import android.hardware.health.BatteryPartStatus;
+
 /*
  * Battery health data
  */
@@ -36,4 +38,14 @@
      * Otherwise, value must be in the range 0 to 100.
      */
     long batteryStateOfHealth;
+    /**
+     * Serial number of the battery. Null if not supported. If supported, a string of at least 6
+     * alphanumeric characters. Characters may either be upper or lower case, but for comparison
+     * and uniqueness purposes, must be treated as case-insensitive.
+     */
+    @nullable String batterySerialNumber;
+    /**
+     * Indicator for part originality of the battery.
+     */
+    BatteryPartStatus batteryPartStatus = BatteryPartStatus.UNSUPPORTED;
 }
diff --git a/health/aidl/android/hardware/health/BatteryPartStatus.aidl b/health/aidl/android/hardware/health/BatteryPartStatus.aidl
new file mode 100644
index 0000000..6c2060a
--- /dev/null
+++ b/health/aidl/android/hardware/health/BatteryPartStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.health;
+
+/**
+ * Possible values for BatteryPartStatus.
+ * Note: These are currently in sync with BatteryManager and must not
+ * be extended / altered.
+ */
+@VintfStability
+@Backing(type="int")
+enum BatteryPartStatus {
+    /**
+     * Device cannot differentiate an original battery from a replaced battery.
+     */
+    UNSUPPORTED = 0,
+    /**
+     * Device has the original battery it was manufactured with.
+     */
+    ORIGINAL = 1,
+    /**
+     * Device has a replaced battery.
+     */
+    REPLACED = 2,
+}
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index b51e4f3..2071f08 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -29,7 +29,7 @@
         "libcutils",
         "liblog",
         "libutils",
-        "android.hardware.health-V2-ndk",
+        "android.hardware.health-V3-ndk",
 
         // TODO(b/177269435): remove when BatteryMonitor works with AIDL HealthInfo.
         "libhidlbase",
@@ -48,7 +48,7 @@
     name: "libhealth_aidl_charger_defaults",
     shared_libs: [
         // common
-        "android.hardware.health-V2-ndk",
+        "android.hardware.health-V3-ndk",
         "libbase",
         "libcutils",
         "liblog",
@@ -195,7 +195,7 @@
         "service_fuzzer_defaults",
     ],
     static_libs: [
-        "android.hardware.health-V2-ndk",
+        "android.hardware.health-V3-ndk",
         "libbase",
         "liblog",
         "fuzz_libhealth_aidl_impl",
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 1d8cc13..8b512c4 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -153,6 +153,8 @@
         !res.isOk()) {
         LOG(WARNING) << "Cannot get Battery_state_of_health: " << res.getDescription();
     }
+    out->batterySerialNumber = std::nullopt;
+    out->batteryPartStatus = BatteryPartStatus::UNSUPPORTED;
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/health/aidl/default/android.hardware.health-service.example.xml b/health/aidl/default/android.hardware.health-service.example.xml
index 1fe9b8d..2acaaba 100644
--- a/health/aidl/default/android.hardware.health-service.example.xml
+++ b/health/aidl/default/android.hardware.health-service.example.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.health</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>IHealth/default</fqname>
     </hal>
 </manifest>
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index b735a87..6d2b530 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -39,7 +39,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.health-V2-ndk",
+        "android.hardware.health-V3-ndk",
         "libgmock",
     ],
     header_libs: [
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 783ce11..9360789 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -84,6 +84,21 @@
     return AnyOfArray(enum_range<T>().begin(), enum_range<T>().end());
 }
 
+MATCHER(IsValidSerialNumber, "") {
+    if (!arg) {
+        return true;
+    }
+    if (arg->size() < 6) {
+        return false;
+    }
+    for (const auto& c : *arg) {
+        if (!isalnum(c)) {
+            return false;
+        }
+    }
+    return true;
+}
+
 class HealthAidl : public testing::TestWithParam<std::string> {
   public:
     void SetUp() override {
@@ -270,7 +285,7 @@
     ASSERT_THAT(static_cast<int>(value), AnyOf(Eq(1), Eq(4)));
 }
 
-MATCHER(IsValidHealthData, "") {
+MATCHER_P(IsValidHealthData, version, "") {
     *result_listener << "value is " << arg.toString() << ".";
     if (!ExplainMatchResult(Ge(-1), arg.batteryManufacturingDateSeconds, result_listener)) {
         *result_listener << " for batteryManufacturingDateSeconds.";
@@ -284,6 +299,15 @@
         *result_listener << " for batteryStateOfHealth.";
         return false;
     }
+    if (!ExplainMatchResult(IsValidSerialNumber(), arg.batterySerialNumber, result_listener)) {
+        *result_listener << " for batterySerialNumber.";
+        return false;
+    }
+    if (!ExplainMatchResult(IsValidEnum<BatteryPartStatus>(), arg.batteryPartStatus,
+                            result_listener)) {
+        *result_listener << " for batteryPartStatus.";
+        return false;
+    }
 
     return true;
 }
@@ -303,7 +327,7 @@
     status = health->getBatteryHealthData(&value);
     ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
     if (!status.isOk()) return;
-    ASSERT_THAT(value, IsValidHealthData());
+    ASSERT_THAT(value, IsValidHealthData(version));
 }
 
 MATCHER(IsValidStorageInfo, "") {
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
index 14c32ae..b0ea743 100644
--- a/health/utils/libhealthshim/Android.bp
+++ b/health/utils/libhealthshim/Android.bp
@@ -34,7 +34,7 @@
         "-Werror",
     ],
     static_libs: [
-        "android.hardware.health-V2-ndk",
+        "android.hardware.health-V3-ndk",
         "android.hardware.health-translate-ndk",
         "android.hardware.health@1.0",
         "android.hardware.health@2.0",
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
index 6a5f512..a5ba919 100644
--- a/health/utils/libhealthshim/shim.cpp
+++ b/health/utils/libhealthshim/shim.cpp
@@ -230,6 +230,7 @@
 ScopedAStatus HealthShim::getBatteryHealthData(BatteryHealthData* out) {
     out->batteryManufacturingDateSeconds = 0;
     out->batteryFirstUsageSeconds = 0;
+    out->batteryPartStatus = BatteryPartStatus::UNSUPPORTED;
     return ResultToStatus(Result::NOT_SUPPORTED);
 }
 
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
index 5631937..62a1bd7 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
@@ -111,6 +111,12 @@
     ErrorCode_UnexpectedServerError: 1,
     ; Indicate the Request was malformed & hence couldnt be served.
     ErrorCode_RequestMalformed: 2,
+    ; Requested Entry not found.
+    ErrorCode_EntryNotFound: 3,
+    ; Error happened while serialization or deserialization.
+    SerializationError: 4,
+    ; Indicates that Dice Policy matching did not succeed & hence access not granted.
+    ErrorCode_DicePolicyError: 5,
 )
 
 ; INCLUDE DicePolicy.cddl for: DicePolicy
\ No newline at end of file
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index 93192e9..def5d5d 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -32,6 +32,7 @@
         "libcoset",
         "libauthgraph_vts_test",
         "libbinder_rs",
+        "libcoset",
         "liblog_rust",
     ],
     require_root: true,
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 8c6b4fe..cc606b1 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -21,8 +21,9 @@
 use secretkeeper_comm::data_types::error::SecretkeeperError;
 use secretkeeper_comm::data_types::request::Request;
 use secretkeeper_comm::data_types::request_response_impl::{
-    GetVersionRequest, GetVersionResponse,
-};
+    GetVersionRequest, GetVersionResponse, GetSecretRequest, GetSecretResponse, StoreSecretRequest,
+    StoreSecretResponse };
+use secretkeeper_comm::data_types::{Id, ID_SIZE, Secret, SECRET_SIZE};
 use secretkeeper_comm::data_types::response::Response;
 use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
@@ -33,6 +34,33 @@
     "android.hardware.security.secretkeeper.ISecretkeeper/nonsecure";
 const CURRENT_VERSION: u64 = 1;
 
+// TODO(b/291238565): This will change once libdice_policy switches to Explicit-key DiceCertChain
+// This is generated by patching libdice_policy such that it dumps an example dice chain &
+// a policy, such that the former matches the latter.
+const HYPOTHETICAL_DICE_POLICY: [u8; 43] = [
+    0x83, 0x01, 0x81, 0x83, 0x01, 0x80, 0xA1, 0x01, 0x00, 0x82, 0x83, 0x01, 0x81, 0x01, 0x73, 0x74,
+    0x65, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x5F, 0x64, 0x69, 0x63, 0x65, 0x5F, 0x70, 0x6F, 0x6C, 0x69,
+    0x63, 0x79, 0x83, 0x02, 0x82, 0x03, 0x18, 0x64, 0x19, 0xE9, 0x75,
+];
+
+// Random bytes (of ID_SIZE/SECRET_SIZE) generated for tests.
+const ID_EXAMPLE: [u8; ID_SIZE] = [
+    0xF1, 0xB2, 0xED, 0x3B, 0xD1, 0xBD, 0xF0, 0x7D, 0xE1, 0xF0, 0x01, 0xFC, 0x61, 0x71, 0xD3, 0x42,
+    0xE5, 0x8A, 0xAF, 0x33, 0x6C, 0x11, 0xDC, 0xC8, 0x6F, 0xAE, 0x12, 0x5C, 0x26, 0x44, 0x6B, 0x86,
+    0xCC, 0x24, 0xFD, 0xBF, 0x91, 0x4A, 0x54, 0x84, 0xF9, 0x01, 0x59, 0x25, 0x70, 0x89, 0x38, 0x8D,
+    0x5E, 0xE6, 0x91, 0xDF, 0x68, 0x60, 0x69, 0x26, 0xBE, 0xFE, 0x79, 0x58, 0xF7, 0xEA, 0x81, 0x7D,
+];
+const ID_NOT_STORED: [u8; ID_SIZE] = [
+    0x56, 0xD0, 0x4E, 0xAA, 0xC1, 0x7B, 0x55, 0x6B, 0xA0, 0x2C, 0x65, 0x43, 0x39, 0x0A, 0x6C, 0xE9,
+    0x1F, 0xD0, 0x0E, 0x20, 0x3E, 0xFB, 0xF5, 0xF9, 0x3F, 0x5B, 0x11, 0x1B, 0x18, 0x73, 0xF6, 0xBB,
+    0xAB, 0x9F, 0xF2, 0xD6, 0xBD, 0xBA, 0x25, 0x68, 0x22, 0x30, 0xF2, 0x1F, 0x90, 0x05, 0xF3, 0x64,
+    0xE7, 0xEF, 0xC6, 0xB6, 0xA0, 0x85, 0xC9, 0x40, 0x40, 0xF0, 0xB4, 0xB9, 0xD8, 0x28, 0xEE, 0x9C,
+];
+const SECRET_EXAMPLE: [u8; SECRET_SIZE] = [
+    0xA9, 0x89, 0x97, 0xFE, 0xAE, 0x97, 0x55, 0x4B, 0x32, 0x35, 0xF0, 0xE8, 0x93, 0xDA, 0xEA, 0x24,
+    0x06, 0xAC, 0x36, 0x8B, 0x3C, 0x95, 0x50, 0x16, 0x67, 0x71, 0x65, 0x26, 0xEB, 0xD0, 0xC3, 0x98,
+];
+
 fn get_connection() -> Option<binder::Strong<dyn ISecretkeeper>> {
     match binder::get_interface(SECRETKEEPER_IDENTIFIER) {
         Ok(sk) => Some(sk),
@@ -161,3 +189,93 @@
     let err = *SecretkeeperError::deserialize_from_packet(response_packet).unwrap();
     assert_eq!(err, SecretkeeperError::RequestMalformed);
 }
+
+#[test]
+fn secret_management_store_get_secret_found() {
+    let secretkeeper = match get_connection() {
+        Some(sk) => sk,
+        None => {
+            warn!("Secretkeeper HAL is unavailable, skipping test");
+            return;
+        }
+    };
+
+    let store_request = StoreSecretRequest {
+        id: Id(ID_EXAMPLE),
+        secret: Secret(SECRET_EXAMPLE),
+        sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
+    };
+
+    let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+    let store_response = secretkeeper
+        .processSecretManagementRequest(&store_request)
+        .unwrap();
+    let store_response = ResponsePacket::from_slice(&store_response).unwrap();
+
+    assert_eq!(
+        store_response.response_type().unwrap(),
+        ResponseType::Success
+    );
+    // Really just checking that the response is indeed StoreSecretResponse
+    let _ = StoreSecretResponse::deserialize_from_packet(store_response).unwrap();
+
+    // Get the secret that was just stored
+    let get_request = GetSecretRequest {
+        id: Id(ID_EXAMPLE),
+        updated_sealing_policy: None,
+    };
+    let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+
+    let get_response = secretkeeper
+        .processSecretManagementRequest(&get_request)
+        .unwrap();
+    let get_response = ResponsePacket::from_slice(&get_response).unwrap();
+    assert_eq!(get_response.response_type().unwrap(), ResponseType::Success);
+    let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
+    assert_eq!(get_response.secret.0, SECRET_EXAMPLE);
+}
+
+#[test]
+fn secret_management_store_get_secret_not_found() {
+    let secretkeeper = match get_connection() {
+        Some(sk) => sk,
+        None => {
+            warn!("Secretkeeper HAL is unavailable, skipping test");
+            return;
+        }
+    };
+
+    // Store a secret (corresponding to an id).
+    let store_request = StoreSecretRequest {
+        id: Id(ID_EXAMPLE),
+        secret: Secret(SECRET_EXAMPLE),
+        sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
+    };
+
+    let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+    let store_response = secretkeeper
+        .processSecretManagementRequest(&store_request)
+        .unwrap();
+    let store_response = ResponsePacket::from_slice(&store_response).unwrap();
+
+    assert_eq!(
+        store_response.response_type().unwrap(),
+        ResponseType::Success
+    );
+
+    // (Try to) Get the secret that was never stored
+    let get_request = GetSecretRequest {
+        id: Id(ID_NOT_STORED),
+        updated_sealing_policy: None,
+    };
+    let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+    let get_response = secretkeeper
+        .processSecretManagementRequest(&get_request)
+        .unwrap();
+
+    // Check that response is `SecretkeeperError::EntryNotFound`
+    let get_response = ResponsePacket::from_slice(&get_response).unwrap();
+    assert_eq!(get_response.response_type().unwrap(), ResponseType::Error);
+    let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
+    assert_eq!(err, SecretkeeperError::EntryNotFound);
+}
diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp
index 6612ea2..08cc67a 100644
--- a/security/secretkeeper/default/Android.bp
+++ b/security/secretkeeper/default/Android.bp
@@ -35,6 +35,7 @@
         "libauthgraph_hal",
         "libbinder_rs",
         "liblog_rust",
+        "libsecretkeeper_comm_nostd",
         "libsecretkeeper_core_nostd",
         "libsecretkeeper_hal",
     ],
diff --git a/security/secretkeeper/default/src/main.rs b/security/secretkeeper/default/src/main.rs
index a291017..c8c1521 100644
--- a/security/secretkeeper/default/src/main.rs
+++ b/security/secretkeeper/default/src/main.rs
@@ -15,17 +15,21 @@
  */
 
 //! Non-secure implementation of the Secretkeeper HAL.
+mod store;
 
-use log::{error, info, Level};
-use std::sync::{Arc, Mutex};
 use authgraph_boringssl as boring;
-use authgraph_core::ta::{Role, AuthGraphTa};
-use authgraph_core::keyexchange::{MAX_OPENED_SESSIONS, AuthGraphParticipant};
+use authgraph_core::keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS};
+use authgraph_core::ta::{AuthGraphTa, Role};
+use authgraph_hal::channel::SerializedChannel;
+use log::{error, info, Level};
 use secretkeeper_core::ta::SecretkeeperTa;
 use secretkeeper_hal::SecretkeeperService;
-use authgraph_hal::channel::SerializedChannel;
+use std::sync::Arc;
+use std::sync::Mutex;
+use store::InMemoryStore;
+
 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
-    ISecretkeeper, BpSecretkeeper,
+    BpSecretkeeper, ISecretkeeper,
 };
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -53,8 +57,9 @@
         // The TA code expects to run single threaded, so spawn a thread to run it in.
         std::thread::spawn(move || {
             let mut crypto_impls = boring::crypto_trait_impls();
+            let storage_impl = Box::new(InMemoryStore::default());
             let sk_ta = Rc::new(RefCell::new(
-                SecretkeeperTa::new(&mut crypto_impls)
+                SecretkeeperTa::new(&mut crypto_impls, storage_impl)
                     .expect("Failed to create local Secretkeeper TA"),
             ));
             let mut ag_ta = AuthGraphTa::new(
diff --git a/security/secretkeeper/default/src/store.rs b/security/secretkeeper/default/src/store.rs
new file mode 100644
index 0000000..7b2d0b9
--- /dev/null
+++ b/security/secretkeeper/default/src/store.rs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+use secretkeeper_comm::data_types::error::Error;
+use secretkeeper_core::store::KeyValueStore;
+use std::collections::HashMap;
+
+/// An in-memory implementation of KeyValueStore. Please note that this is entirely for
+/// testing purposes. Refer to the documentation of `PolicyGatedStorage` & Secretkeeper HAL for
+/// persistence requirements.
+#[derive(Default)]
+pub struct InMemoryStore(HashMap<Vec<u8>, Vec<u8>>);
+impl KeyValueStore for InMemoryStore {
+    fn store(&mut self, key: &[u8], val: &[u8]) -> Result<(), Error> {
+        // This will overwrite the value if key is already present.
+        let _ = self.0.insert(key.to_vec(), val.to_vec());
+        Ok(())
+    }
+
+    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
+        let optional_val = self.0.get(key);
+        Ok(optional_val.cloned())
+    }
+}
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 384ee97..08ee773 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -23,18 +23,6 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-filegroup {
-    name: "sensors-default.rc",
-    srcs: ["sensors-default.rc"],
-}
-
-prebuilt_etc {
-    name: "sensors-default.xml",
-    src: "sensors-default.xml",
-    sub_dir: "vintf",
-    installable: false,
-}
-
 cc_library_static {
     name: "libsensorsexampleimpl",
     vendor: true,
@@ -59,21 +47,62 @@
 cc_binary {
     name: "android.hardware.sensors-service.example",
     relative_install_path: "hw",
-    init_rc: [":sensors-default.rc"],
-    vintf_fragments: [":sensors-default.xml"],
+    installable: false, // install APEX below
+
     vendor: true,
     shared_libs: [
-        "libbase",
         "libbinder_ndk",
-        "libfmq",
-        "libpower",
-        "libcutils",
         "liblog",
-        "libutils",
-        "android.hardware.sensors-V2-ndk",
     ],
     static_libs: [
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
+        "android.system.suspend-V1-ndk",
+        "libbase",
+        "libcutils",
+        "libfmq",
+        "libpower",
         "libsensorsexampleimpl",
+        "libutils",
     ],
     srcs: ["main.cpp"],
 }
+
+prebuilt_etc {
+    name: "sensors-default.rc",
+    src: "sensors-default.rc",
+    installable: false,
+}
+
+prebuilt_etc {
+    name: "sensors-default.xml",
+    src: "sensors-default.xml",
+    sub_dir: "vintf",
+    installable: false,
+}
+
+// Default vendor APEX for android.hardware.sensors.
+// Custom implementations may use override_apex based on this APEX.
+apex {
+    name: "com.android.hardware.sensors",
+    manifest: "apex_manifest.json",
+    key: "com.android.hardware.key",
+    certificate: ":com.android.hardware.certificate",
+    file_contexts: "file_contexts",
+    updatable: false,
+    vendor: true,
+
+    binaries: ["android.hardware.sensors-service.example"],
+    prebuilts: [
+        "sensors-default.rc", // init rc
+        "sensors-default.xml", // vintf fragment
+        "android.hardware.sensor.ambient_temperature.prebuilt.xml",
+        "android.hardware.sensor.barometer.prebuilt.xml",
+        "android.hardware.sensor.gyroscope.prebuilt.xml",
+        "android.hardware.sensor.hinge_angle.prebuilt.xml",
+        "android.hardware.sensor.light.prebuilt.xml",
+        "android.hardware.sensor.proximity.prebuilt.xml",
+        "android.hardware.sensor.relative_humidity.prebuilt.xml",
+    ],
+}
diff --git a/sensors/aidl/default/apex/Android.bp b/sensors/aidl/default/apex/Android.bp
deleted file mode 100644
index 5482086..0000000
--- a/sensors/aidl/default/apex/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-package {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-genrule {
-    name: "com.android.hardware.sensors.rc-gen",
-    srcs: [":sensors-default.rc"],
-    out: ["com.android.hardware.sensors.rc"],
-    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.sensors/' $(in) > $(out)",
-}
-
-prebuilt_etc {
-    name: "com.android.hardware.sensors.rc",
-    src: ":com.android.hardware.sensors.rc-gen",
-    installable: false,
-}
-
-// Default vendor APEX for android.hardware.sensors.
-// Custom implementations may use override_apex based on this APEX.
-apex {
-    name: "com.android.hardware.sensors",
-    manifest: "apex_manifest.json",
-    key: "com.android.hardware.key",
-    certificate: ":com.android.hardware.certificate",
-    file_contexts: "file_contexts",
-    updatable: false,
-    vendor: true,
-
-    binaries: ["android.hardware.sensors-service.example"],
-    prebuilts: [
-        "com.android.hardware.sensors.rc", // init rc
-        "sensors-default.xml", // vintf fragment
-        "android.hardware.sensor.ambient_temperature.prebuilt.xml",
-        "android.hardware.sensor.barometer.prebuilt.xml",
-        "android.hardware.sensor.gyroscope.prebuilt.xml",
-        "android.hardware.sensor.hinge_angle.prebuilt.xml",
-        "android.hardware.sensor.light.prebuilt.xml",
-        "android.hardware.sensor.proximity.prebuilt.xml",
-        "android.hardware.sensor.relative_humidity.prebuilt.xml",
-    ],
-}
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey b/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
deleted file mode 100644
index 98dfb71..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.pem
deleted file mode 100644
index a2f1833..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.pk8 b/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
deleted file mode 100644
index 7a1cca0..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
+++ /dev/null
Binary files differ
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
deleted file mode 100644
index 20a06f9..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF3TCCA8UCFAbIl4RS714WSLo4k64MHsINz4VEMA0GCSqGSIb3DQEBCwUAMIGp
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
-LmFuZHJvaWQuaGFyZHdhcmUuc2Vuc29yczAgFw0yMTA5MDMxNjEyNDNaGA80NzU5
-MDczMTE2MTI0M1owgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
-MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5oYXJkd2FyZS5zZW5zb3JzMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnluNTPcq4pDEeb5gEYszRYQCawq8czUY
-J+x2b0i7qO2wLidX45CX6BLZ9N7c5veoV3FvC1wMTRR6lGAyg7UbD80vVmPdmr6R
-vw2AdIqrghXinvAEv6gxQQPVQa8UHkCL4lULLXo2gdmoCBM8VJHihjO/2F8ZLsP/
-nKhYx9Nr6w9LEyalmHTkXOgNyrNprpbJwugdk3hDXbAK+j5nF9fsz/iWFoXnPuNe
-oqdWj21YhXKDAbewBXaM6l3qmTdGsVVJL4HmVURGUY2f2UZwMWTEjpy9UDzyfqqg
-CSdH1RLmGVAINyfNI3Zswo0CjnOCf0jW6mq9/6mfGYu8hBCrky/rOH8reDwYZTGe
-H6JbNj0dhEN5HzQcxGEQQ43L1nmH7XlnuPO0xPSsw5binPVuUvURivR3PSsFgpPl
-0Uche62XgLAXCXhNV2uUQtZLVFGug7JcGgS4O3GoKr6w35Q+W9SEXanXFMW6X+wN
-hkbhB4MDSuKTZrjEnZEyxMOLG8ILN9i7osa+yjWONTn9bZc6q3Y9jyu3u84o8kC8
-KDcvr8YZEL63nQsQXO44GiQmqBptuB+ehcAC6uRCKkY9tQ95EQ7laGQ3C85d3gPj
-NcGjT7SSuUir7n+LI9pZsotedd9+rGhiiyT8CM4sVWiYJFnA2UX/bsnkZyAOq9Po
-jz1aMdHc4wUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEATEPN2SZk8pJc4DaWmhyR
-MUklzVeuN0J0Mij1mHuVmID7Q5IhBBXxtVmwRIo208rHSvFLAo7Z4FnuZCV3A/c9
-TlXT3S2t+iYG5eOyXSsoSc/uerJ7kIBcOe27qIrO9GwcK5CQlTaXP+CG1gbLp1nl
-IaqKAT+eb/ji5wmFxMI77wo3uKLPTCfpaptFNaYlRqvxiXdJsCZwCPgmCtXJUeeZ
-R/HKOA4PcS2QB+HwhYePY5kUJPwt6MwJEyno72oenfl49FrGHj0BzVmQ7KMfiYjZ
-eRSB2Wbo50xfiICkPlUcvWD8rRNg7N9CM/Q5O0MW3ivAe42aGap/8qfXUa+L5vu4
-9vaxgQvBVcPXE/pyeCYM8beB84Us+FOYPC7gIUhcctBqGYAQmHzp3sXvIg0DVxz7
-0aqolFGpjRFqbgheS9WRkDHFpYrhR1XMVOQjussHqWEyRcvliqeFlZr8+JNkJNi+
-lmGMdnEAWZs8PL0/AEf+8y0Nr/w0k3Y6IZCDcwpxbpJQOU5pAbkfUzEJHkxMfuvW
-ZshvqIMOaLWCGxZaxlbLRxWGuarWYzfmDY3n9TwJmAIUdMLiswv3UsCmLBJO1XGX
-SUWfgi4fyG1/phfzhdU3efMvmN+XT16/ykMrY8P5S+ghwK12IZ3DgTl0ooLFABUj
-zYeQ8LLz3SP9LNgeLnPP/po=
------END CERTIFICATE-----
diff --git a/sensors/aidl/default/apex/apex_manifest.json b/sensors/aidl/default/apex_manifest.json
similarity index 100%
rename from sensors/aidl/default/apex/apex_manifest.json
rename to sensors/aidl/default/apex_manifest.json
diff --git a/sensors/aidl/default/apex/file_contexts b/sensors/aidl/default/file_contexts
similarity index 100%
rename from sensors/aidl/default/apex/file_contexts
rename to sensors/aidl/default/file_contexts
diff --git a/sensors/aidl/default/sensors-default.rc b/sensors/aidl/default/sensors-default.rc
index 96da85d..e0b0ef0 100644
--- a/sensors/aidl/default/sensors-default.rc
+++ b/sensors/aidl/default/sensors-default.rc
@@ -1,4 +1,4 @@
-service vendor.sensors-default /vendor/bin/hw/android.hardware.sensors-service.example
+service vendor.sensors-default /apex/com.android.hardware.sensors/bin/hw/android.hardware.sensors-service.example
     class hal
     user system
     group system
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
index 8f4411b..954982e 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -15,12 +15,11 @@
  */
 
 #define LOG_TAG "android.hardware.tv.hdmi.connection"
+#include "HdmiConnectionMock.h"
 #include <android-base/logging.h>
 #include <fcntl.h>
 #include <utils/Log.h>
 
-#include "HdmiConnectionMock.h"
-
 using ndk::ScopedAStatus;
 
 namespace android {
@@ -34,6 +33,7 @@
     ALOGE("HdmiConnectionMock died");
     auto hdmi = static_cast<HdmiConnectionMock*>(cookie);
     hdmi->mHdmiThreadRun = false;
+    pthread_join(hdmi->mThreadId, NULL);
 }
 
 ScopedAStatus HdmiConnectionMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
@@ -55,12 +55,15 @@
 ScopedAStatus HdmiConnectionMock::setCallback(
         const std::shared_ptr<IHdmiConnectionCallback>& callback) {
     if (mCallback != nullptr) {
+        stopThread();
         mCallback = nullptr;
     }
-
     if (callback != nullptr) {
         mCallback = callback;
-        AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+        mDeathRecipient =
+                ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+
+        AIBinder_linkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this /* cookie */);
 
         mInputFile = open(HDMI_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
         pthread_create(&mThreadId, NULL, __threadLoop, this);
@@ -153,7 +156,7 @@
     int r = -1;
 
     // Open the input pipe
-    while (mInputFile < 0) {
+    while (mHdmiThreadRun && mInputFile < 0) {
         usleep(1000 * 1000);
         mInputFile = open(HDMI_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
     }
@@ -193,7 +196,21 @@
                      .physicalAddress = mPhysicalAddress};
     mPortConnectionStatus[0] = false;
     mHpdSignal[0] = HpdSignal::HDMI_HPD_PHYSICAL;
-    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+}
+
+void HdmiConnectionMock::stopThread() {
+    if (mCallback != nullptr) {
+        ALOGE("[halimp_aidl] HdmiConnectionMock shutting down.");
+        mCallback = nullptr;
+        mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+        mHdmiThreadRun = false;
+        pthread_join(mThreadId, NULL);
+    }
+}
+
+HdmiConnectionMock::~HdmiConnectionMock() {
+    stopThread();
 }
 
 }  // namespace implementation
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
index c013fdd..8c66f08 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
@@ -41,7 +41,7 @@
 
 struct HdmiConnectionMock : public BnHdmiConnection {
     HdmiConnectionMock();
-
+    ~HdmiConnectionMock();
     ::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
     ::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
     ::ndk::ScopedAStatus setCallback(
@@ -56,6 +56,7 @@
     void threadLoop();
     int readMessageFromFifo(unsigned char* buf, int msgCount);
     void handleHotplugMessage(unsigned char* msgBuf);
+    void stopThread();
 
   private:
     static void serviceDied(void* cookie);