Snap for 11889377 from 8c1e63c8c945add66ee1507287495114eb91f4fe to 24Q3-release

Change-Id: Ib5205f9c9001cdd47d473c5fffee4bbfb63158bc
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 250b30c..fa2a310 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -42,10 +42,11 @@
 namespace automotive {
 namespace vehicle {
 
-class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehicle::BnVehicle {
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+class DefaultVehicleHal final : public aidlvhal::BnVehicle {
   public:
-    using CallbackType =
-            std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
+    using CallbackType = std::shared_ptr<aidlvhal::IVehicleCallback>;
 
     explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
 
@@ -54,26 +55,16 @@
 
     ~DefaultVehicleHal();
 
-    ndk::ScopedAStatus getAllPropConfigs(
-            aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
-            override;
-    ndk::ScopedAStatus getValues(
-            const CallbackType& callback,
-            const aidl::android::hardware::automotive::vehicle::GetValueRequests& requests)
-            override;
-    ndk::ScopedAStatus setValues(
-            const CallbackType& callback,
-            const aidl::android::hardware::automotive::vehicle::SetValueRequests& requests)
-            override;
-    ndk::ScopedAStatus getPropConfigs(
-            const std::vector<int32_t>& props,
-            aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
-            override;
-    ndk::ScopedAStatus subscribe(
-            const CallbackType& callback,
-            const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
-                    options,
-            int32_t maxSharedMemoryFileCount) override;
+    ndk::ScopedAStatus getAllPropConfigs(aidlvhal::VehiclePropConfigs* returnConfigs) override;
+    ndk::ScopedAStatus getValues(const CallbackType& callback,
+                                 const aidlvhal::GetValueRequests& requests) override;
+    ndk::ScopedAStatus setValues(const CallbackType& callback,
+                                 const aidlvhal::SetValueRequests& requests) override;
+    ndk::ScopedAStatus getPropConfigs(const std::vector<int32_t>& props,
+                                      aidlvhal::VehiclePropConfigs* returnConfigs) override;
+    ndk::ScopedAStatus subscribe(const CallbackType& callback,
+                                 const std::vector<aidlvhal::SubscribeOptions>& options,
+                                 int32_t maxSharedMemoryFileCount) override;
     ndk::ScopedAStatus unsubscribe(const CallbackType& callback,
                                    const std::vector<int32_t>& propIds) override;
     ndk::ScopedAStatus returnSharedMemory(const CallbackType& callback,
@@ -86,12 +77,8 @@
     // friend class for unit testing.
     friend class DefaultVehicleHalTest;
 
-    using GetValuesClient =
-            GetSetValuesClient<aidl::android::hardware::automotive::vehicle::GetValueResult,
-                               aidl::android::hardware::automotive::vehicle::GetValueResults>;
-    using SetValuesClient =
-            GetSetValuesClient<aidl::android::hardware::automotive::vehicle::SetValueResult,
-                               aidl::android::hardware::automotive::vehicle::SetValueResults>;
+    using GetValuesClient = GetSetValuesClient<aidlvhal::GetValueResult, aidlvhal::GetValueResults>;
+    using SetValuesClient = GetSetValuesClient<aidlvhal::SetValueResult, aidlvhal::SetValueResults>;
 
     // A wrapper for binder lifecycle operations to enable stubbing for test.
     class BinderLifecycleInterface {
@@ -137,28 +124,27 @@
     bool mShouldRefreshPropertyConfigs;
     std::unique_ptr<IVehicleHardware> mVehicleHardware;
 
-    // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
-    // lock guard them.
-    std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
-            mConfigsByPropId;
-    // Only modified in constructor, so thread-safe.
-    std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile;
     // PendingRequestPool is thread-safe.
     std::shared_ptr<PendingRequestPool> mPendingRequestPool;
     // SubscriptionManager is thread-safe.
     std::shared_ptr<SubscriptionManager> mSubscriptionManager;
     // ConcurrentQueue is thread-safe.
-    std::shared_ptr<ConcurrentQueue<aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
-            mBatchedEventQueue;
+    std::shared_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>> mBatchedEventQueue;
     // BatchingConsumer is thread-safe.
-    std::shared_ptr<
-            BatchingConsumer<aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
+    std::shared_ptr<BatchingConsumer<aidlvhal::VehiclePropValue>>
             mPropertyChangeEventsBatchingConsumer;
     // Only set once during initialization.
     std::chrono::nanoseconds mEventBatchingWindow;
     // Only used for testing.
     int32_t mTestInterfaceVersion = 0;
 
+    // mConfigsByPropId and mConfigFile is lazy initialized.
+    mutable std::mutex mConfigInitLock;
+    mutable bool mConfigInit GUARDED_BY(mConfigInitLock) = false;
+    mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId
+            GUARDED_BY(mConfigInitLock);
+    mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigInitLock);
+
     std::mutex mLock;
     std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
             GUARDED_BY(mLock);
@@ -182,32 +168,23 @@
     // A thread to handle onBinderDied or onBinderUnlinked event.
     std::thread mOnBinderDiedUnlinkedHandlerThread;
 
-    android::base::Result<void> checkProperty(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
+    android::base::Result<void> checkProperty(const aidlvhal::VehiclePropValue& propValue);
 
     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
-            const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>&
-                    requests);
+            const std::vector<aidlvhal::GetValueRequest>& requests);
 
     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
-            const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
-                    requests);
-    VhalResult<void> checkSubscribeOptions(
-            const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
-                    options);
+            const std::vector<aidlvhal::SetValueRequest>& requests);
+    VhalResult<void> checkSubscribeOptions(const std::vector<aidlvhal::SubscribeOptions>& options);
 
-    VhalResult<void> checkPermissionHelper(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
-            aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess accessToTest) const;
+    VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value,
+                                           aidlvhal::VehiclePropertyAccess accessToTest) const;
 
-    VhalResult<void> checkReadPermission(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
+    VhalResult<void> checkReadPermission(const aidlvhal::VehiclePropValue& value) const;
 
-    VhalResult<void> checkWritePermission(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
+    VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const;
 
-    android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*>
-    getConfig(int32_t propId) const;
+    android::base::Result<const aidlvhal::VehiclePropConfig*> getConfig(int32_t propId) const;
 
     void onBinderDiedWithContext(const AIBinder* clientId);
 
@@ -219,7 +196,7 @@
 
     bool checkDumpPermission();
 
-    bool getAllPropConfigsFromHardware();
+    bool getAllPropConfigsFromHardwareLocked() const REQUIRES(mConfigInitLock);
 
     // The looping handler function to process all onBinderDied or onBinderUnlinked events in
     // mBinderEvents.
@@ -228,19 +205,19 @@
     size_t countSubscribeClients();
 
     // Handles the property change events in batch.
-    void handleBatchedPropertyEvents(
-            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
-                    batchedEvents);
+    void handleBatchedPropertyEvents(std::vector<aidlvhal::VehiclePropValue>&& batchedEvents);
 
-    int32_t getVhalInterfaceVersion();
+    int32_t getVhalInterfaceVersion() const;
+
+    // Gets mConfigsByPropId, lazy init it if necessary.
+    const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& getConfigsByPropId() const;
+    // Gets mConfigFile, lazy init it if necessary.
+    const ndk::ScopedFileDescriptor* getConfigFile() const;
 
     // Puts the property change events into a queue so that they can handled in batch.
     static void batchPropertyChangeEvent(
-            const std::weak_ptr<ConcurrentQueue<
-                    aidl::android::hardware::automotive::vehicle::VehiclePropValue>>&
-                    batchedEventQueue,
-            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
-                    updatedValues);
+            const std::weak_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>>& batchedEventQueue,
+            std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
 
     // Gets or creates a {@code T} object for the client to or from {@code clients}.
     template <class T>
@@ -248,10 +225,8 @@
             std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
             const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);
 
-    static void onPropertyChangeEvent(
-            const std::weak_ptr<SubscriptionManager>& subscriptionManager,
-            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
-                    updatedValues);
+    static void onPropertyChangeEvent(const std::weak_ptr<SubscriptionManager>& subscriptionManager,
+                                      std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
 
     static void onPropertySetErrorEvent(
             const std::weak_ptr<SubscriptionManager>& subscriptionManager,
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index a29861f..9dc039d 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -24,6 +24,7 @@
 #include <VehicleUtils.h>
 #include <VersionForVehicleProperty.h>
 
+#include <android-base/logging.h>
 #include <android-base/result.h>
 #include <android-base/stringprintf.h>
 #include <android/binder_ibinder.h>
@@ -71,6 +72,7 @@
 
 using ::ndk::ScopedAIBinder_DeathRecipient;
 using ::ndk::ScopedAStatus;
+using ::ndk::ScopedFileDescriptor;
 
 std::string toString(const std::unordered_set<int64_t>& values) {
     std::string str = "";
@@ -103,10 +105,7 @@
     : mVehicleHardware(std::move(vehicleHardware)),
       mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)),
       mTestInterfaceVersion(testInterfaceVersion) {
-    if (!getAllPropConfigsFromHardware()) {
-        return;
-    }
-
+    ALOGD("DefaultVehicleHal init");
     IVehicleHardware* vehicleHardwarePtr = mVehicleHardware.get();
     mSubscriptionManager = std::make_shared<SubscriptionManager>(vehicleHardwarePtr);
     mEventBatchingWindow = mVehicleHardware->getPropertyOnChangeEventBatchingWindow();
@@ -319,16 +318,18 @@
     mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano);
 }
 
-int32_t DefaultVehicleHal::getVhalInterfaceVersion() {
+int32_t DefaultVehicleHal::getVhalInterfaceVersion() const {
     if (mTestInterfaceVersion != 0) {
         return mTestInterfaceVersion;
     }
     int32_t myVersion = 0;
-    getInterfaceVersion(&myVersion);
+    // getInterfaceVersion is in-reality a const method.
+    const_cast<DefaultVehicleHal*>(this)->getInterfaceVersion(&myVersion);
     return myVersion;
 }
 
-bool DefaultVehicleHal::getAllPropConfigsFromHardware() {
+bool DefaultVehicleHal::getAllPropConfigsFromHardwareLocked() const {
+    ALOGD("Get all property configs from hardware");
     auto configs = mVehicleHardware->getAllPropertyConfigs();
     std::vector<VehiclePropConfig> filteredConfigs;
     int32_t myVersion = getVhalInterfaceVersion();
@@ -373,22 +374,46 @@
     return true;
 }
 
+const ScopedFileDescriptor* DefaultVehicleHal::getConfigFile() const {
+    std::scoped_lock lockGuard(mConfigInitLock);
+    if (!mConfigInit) {
+        CHECK(getAllPropConfigsFromHardwareLocked())
+                << "Failed to get property configs from hardware";
+        mConfigInit = true;
+    }
+    return mConfigFile.get();
+}
+
+const std::unordered_map<int32_t, VehiclePropConfig>& DefaultVehicleHal::getConfigsByPropId()
+        const {
+    std::scoped_lock lockGuard(mConfigInitLock);
+    if (!mConfigInit) {
+        CHECK(getAllPropConfigsFromHardwareLocked())
+                << "Failed to get property configs from hardware";
+        mConfigInit = true;
+    }
+    return mConfigsByPropId;
+}
+
 ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
-    if (mConfigFile != nullptr) {
+    const ScopedFileDescriptor* configFile = getConfigFile();
+    const auto& configsByPropId = getConfigsByPropId();
+    if (configFile != nullptr) {
         output->payloads.clear();
-        output->sharedMemoryFd.set(dup(mConfigFile->get()));
+        output->sharedMemoryFd.set(dup(configFile->get()));
         return ScopedAStatus::ok();
     }
-    output->payloads.reserve(mConfigsByPropId.size());
-    for (const auto& [_, config] : mConfigsByPropId) {
+    output->payloads.reserve(configsByPropId.size());
+    for (const auto& [_, config] : configsByPropId) {
         output->payloads.push_back(config);
     }
     return ScopedAStatus::ok();
 }
 
 Result<const VehiclePropConfig*> DefaultVehicleHal::getConfig(int32_t propId) const {
-    auto it = mConfigsByPropId.find(propId);
-    if (it == mConfigsByPropId.end()) {
+    const auto& configsByPropId = getConfigsByPropId();
+    auto it = configsByPropId.find(propId);
+    if (it == configsByPropId.end()) {
         return Error() << "no config for property, ID: " << propId;
     }
     return &(it->second);
@@ -634,9 +659,11 @@
 ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props,
                                                 VehiclePropConfigs* output) {
     std::vector<VehiclePropConfig> configs;
+    const auto& configsByPropId = getConfigsByPropId();
     for (int32_t prop : props) {
-        if (mConfigsByPropId.find(prop) != mConfigsByPropId.end()) {
-            configs.push_back(mConfigsByPropId[prop]);
+        auto it = configsByPropId.find(prop);
+        if (it != configsByPropId.end()) {
+            configs.push_back(it->second);
         } else {
             return ScopedAStatus::fromServiceSpecificErrorWithMessage(
                     toInt(StatusCode::INVALID_ARG),
@@ -665,13 +692,15 @@
 
 VhalResult<void> DefaultVehicleHal::checkSubscribeOptions(
         const std::vector<SubscribeOptions>& options) {
+    const auto& configsByPropId = getConfigsByPropId();
     for (const auto& option : options) {
         int32_t propId = option.propId;
-        if (mConfigsByPropId.find(propId) == mConfigsByPropId.end()) {
+        auto it = configsByPropId.find(propId);
+        if (it == configsByPropId.end()) {
             return StatusError(StatusCode::INVALID_ARG)
                    << StringPrintf("no config for property, ID: %" PRId32, propId);
         }
-        const VehiclePropConfig& config = mConfigsByPropId[propId];
+        const VehiclePropConfig& config = it->second;
         std::vector<VehicleAreaConfig> areaConfigs;
         if (option.areaIds.empty()) {
             areaConfigs = config.areaConfigs;
@@ -744,10 +773,11 @@
     }
     std::vector<SubscribeOptions> onChangeSubscriptions;
     std::vector<SubscribeOptions> continuousSubscriptions;
+    const auto& configsByPropId = getConfigsByPropId();
     for (const auto& option : options) {
         int32_t propId = option.propId;
         // We have already validate config exists.
-        const VehiclePropConfig& config = mConfigsByPropId[propId];
+        const VehiclePropConfig& config = configsByPropId.at(propId);
 
         SubscribeOptions optionCopy = option;
         // If areaIds is empty, subscribe to all areas.
@@ -871,7 +901,7 @@
         (areaConfig == nullptr || !hasRequiredAccess(areaConfig->access, accessToTest))) {
         return StatusError(StatusCode::ACCESS_DENIED)
                << StringPrintf("Property %" PRId32 " does not have the following access: %" PRId32,
-                               propId, accessToTest);
+                               propId, static_cast<int32_t>(accessToTest));
     }
     return {};
 }
@@ -936,17 +966,19 @@
     }
     DumpResult result = mVehicleHardware->dump(options);
     if (result.refreshPropertyConfigs) {
-        getAllPropConfigsFromHardware();
+        std::scoped_lock lockGuard(mConfigInitLock);
+        getAllPropConfigsFromHardwareLocked();
     }
     dprintf(fd, "%s", (result.buffer + "\n").c_str());
     if (!result.callerShouldDumpState) {
         return STATUS_OK;
     }
     dprintf(fd, "Vehicle HAL State: \n");
+    const auto& configsByPropId = getConfigsByPropId();
     {
         std::scoped_lock<std::mutex> lockGuard(mLock);
         dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion());
-        dprintf(fd, "Containing %zu property configs\n", mConfigsByPropId.size());
+        dprintf(fd, "Containing %zu property configs\n", configsByPropId.size());
         dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
         dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
         dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients());
diff --git a/bluetooth/audio/flags/btaudiohal.aconfig b/bluetooth/audio/flags/btaudiohal.aconfig
index 4c1500a..13e2116 100644
--- a/bluetooth/audio/flags/btaudiohal.aconfig
+++ b/bluetooth/audio/flags/btaudiohal.aconfig
@@ -7,3 +7,10 @@
     description: "Flag for DSA Over LEA"
     bug: "270987427"
 }
+
+flag {
+    name: "leaudio_report_broadcast_ac_to_hal"
+    namespace: "pixel_bluetooth"
+    description: "Flag for reporting lea broadcast audio config to HAL"
+    bug: "321168976"
+}
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index 67ba93c..d0f2a26 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -121,18 +121,41 @@
 
 void BluetoothAudioSession::ReportAudioConfigChanged(
     const AudioConfiguration& audio_config) {
-  if (session_type_ !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
-      session_type_ !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
-    return;
-  }
-
   std::lock_guard<std::recursive_mutex> guard(mutex_);
-  if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
-    LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
-               << toString(session_type_);
-    return;
+  if (com::android::btaudio::hal::flags::leaudio_report_broadcast_ac_to_hal()) {
+    if (session_type_ ==
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+        session_type_ ==
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+      if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+        LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                  << toString(session_type_);
+        return;
+      }
+    } else if (session_type_ ==
+            SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+      if (audio_config.getTag() != AudioConfiguration::leAudioBroadcastConfig) {
+        LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                  << toString(session_type_);
+        return;
+      }
+    } else {
+      LOG(ERROR) << __func__ << " invalid SessionType ="
+                 << toString(session_type_);
+      return;
+    }
+  } else {
+    if (session_type_ !=
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+        session_type_ !=
+            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+      return;
+    }
+    if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+      LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+                 << toString(session_type_);
+      return;
+    }
   }
 
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);