Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7360a2df authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11889377 from 8c1e63c8 to 24Q3-release

Change-Id: Ib5205f9c9001cdd47d473c5fffee4bbfb63158bc
parents 15340724 8c1e63c8
Loading
Loading
Loading
Loading
+46 −71
Original line number Diff line number Diff line
@@ -42,10 +42,11 @@ namespace hardware {
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,25 +55,15 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi

    ~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,
    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;
@@ -86,12 +77,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
    // 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 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
    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 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
    // 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 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi

    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 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
    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 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
            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,
+53 −21
Original line number Diff line number Diff line
@@ -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 ::android::base::StringPrintf;

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 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHa
    : 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 @@ void DefaultVehicleHal::setTimeout(int64_t timeoutInNano) {
    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 @@ bool DefaultVehicleHal::getAllPropConfigsFromHardware() {
    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::setValues(const CallbackType& callback,
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 @@ bool areaConfigsHaveRequiredAccess(const std::vector<VehicleAreaConfig>& areaCon

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 @@ ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
    }
    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 @@ VhalResult<void> DefaultVehicleHal::checkPermissionHelper(
        (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 @@ binder_status_t DefaultVehicleHal::dump(int fd, const char** args, uint32_t numA
    }
    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());
+7 −0
Original line number Diff line number Diff line
@@ -7,3 +7,10 @@ flag {
    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
+34 −11
Original line number Diff line number Diff line
@@ -121,19 +121,42 @@ const AudioConfiguration BluetoothAudioSession::GetAudioConfig() {

void BluetoothAudioSession::ReportAudioConfigChanged(
    const AudioConfiguration& audio_config) {
  std::lock_guard<std::recursive_mutex> guard(mutex_);
  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;
    }

  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;
    }
  }

  audio_config_ = std::make_unique<AudioConfiguration>(audio_config);