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

Commit 6f6af46b authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8105868 from 0e6671e9 to tm-d1-release

Change-Id: Iff96aa41f5061209ad76b06ecc8fdb6c10000504
parents e17bf288 0e6671e9
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -67,24 +67,30 @@ inline constexpr bool isSystemProp(int32_t prop) {
}

inline const ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig* getAreaConfig(
        const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue,
        int32_t propId, int32_t areaId,
        const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config) {
    if (config.areaConfigs.size() == 0) {
        return nullptr;
    }

    if (isGlobalProp(propValue.prop)) {
    if (isGlobalProp(propId)) {
        return &(config.areaConfigs[0]);
    }

    for (const auto& c : config.areaConfigs) {
        if (c.areaId == propValue.areaId) {
        if (c.areaId == areaId) {
            return &c;
        }
    }
    return nullptr;
}

inline const ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig* getAreaConfig(
        const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue,
        const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config) {
    return getAreaConfig(propValue.prop, propValue.areaId, config);
}

inline std::unique_ptr<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>
createVehiclePropValueVec(::aidl::android::hardware::automotive::vehicle::VehiclePropertyType type,
                          size_t vecSize) {
+5 −2
Original line number Diff line number Diff line
@@ -21,9 +21,11 @@

#include <VehicleHalTypes.h>
#include <VehicleUtils.h>
#include <android-base/format.h>
#include <android-base/stringprintf.h>
#include <math/HashCombine.h>

#include <inttypes.h>

namespace android {
namespace hardware {
namespace automotive {
@@ -36,13 +38,14 @@ using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::android::base::Error;
using ::android::base::Result;
using ::android::base::StringPrintf;

bool VehiclePropertyStore::RecordId::operator==(const VehiclePropertyStore::RecordId& other) const {
    return area == other.area && token == other.token;
}

std::string VehiclePropertyStore::RecordId::toString() const {
    return ::fmt::format("RecordID{{.areaId={:d}, .token={:d}}}", area, token);
    return StringPrintf("RecordID{{.areaId=% " PRId32 ", .token=%" PRId64 "}", area, token);
}

size_t VehiclePropertyStore::RecordIdHash::operator()(RecordId const& recordId) const {
+21 −25
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "PendingRequestPool.h"

#include <IVehicleHardware.h>
#include <VehicleHalTypes.h>

#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
@@ -41,24 +42,24 @@ namespace vehicle {
// This class is thread-safe.
class ConnectedClient {
  public:
    ConnectedClient(
            std::shared_ptr<PendingRequestPool> requestPool,
            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
                    callback);
    using CallbackType =
            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>;

    ConnectedClient(std::shared_ptr<PendingRequestPool> requestPool, CallbackType callback);

    virtual ~ConnectedClient() = default;

    // Gets the unique ID for this client.
    const void* id();

    // Add client requests. The requests would be registered as pending requests until
    // Adds client requests. The requests would be registered as pending requests until
    // {@code tryFinishRequests} is called for them.
    // Returns {@code INVALID_ARG} error if any of the requestIds are duplicate with one of the
    // pending request IDs or {@code TRY_AGAIN} error if the pending request pool is full and could
    // no longer add requests.
    ::android::base::Result<void> addRequests(const std::unordered_set<int64_t>& requestIds);

    // Mark the requests as finished. Returns a list of request IDs that was pending and has been
    // Marks the requests as finished. Returns a list of request IDs that was pending and has been
    // finished. It must be a set of the requested request IDs.
    std::unordered_set<int64_t> tryFinishRequests(const std::unordered_set<int64_t>& requestIds);

@@ -67,8 +68,7 @@ class ConnectedClient {
    virtual std::shared_ptr<const PendingRequestPool::TimeoutCallbackFunc> getTimeoutCallback() = 0;

    const std::shared_ptr<PendingRequestPool> mRequestPool;
    const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
            mCallback;
    const CallbackType mCallback;
};

// A class to represent a client that calls {@code IVehicle.setValues} or {@code
@@ -76,10 +76,7 @@ class ConnectedClient {
template <class ResultType, class ResultsType>
class GetSetValuesClient final : public ConnectedClient {
  public:
    GetSetValuesClient(
            std::shared_ptr<PendingRequestPool> requestPool,
            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
                    callback);
    GetSetValuesClient(std::shared_ptr<PendingRequestPool> requestPool, CallbackType callback);

    // Sends the results to this client.
    void sendResults(const std::vector<ResultType>& results);
@@ -104,15 +101,17 @@ class GetSetValuesClient final : public ConnectedClient {
// A class to represent a client that calls {@code IVehicle.subscribe}.
class SubscriptionClient final : public ConnectedClient {
  public:
    SubscriptionClient(
            std::shared_ptr<PendingRequestPool> requestPool,
            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
                    callback);
    SubscriptionClient(std::shared_ptr<PendingRequestPool> requestPool, CallbackType callback);

    // Gets the callback to be called when the request for this client has finished.
    std::shared_ptr<const std::function<
            void(std::vector<::aidl::android::hardware::automotive::vehicle::GetValueResult>)>>
    getResultCallback();
    std::shared_ptr<const IVehicleHardware::GetValuesCallback> getResultCallback();

    // Marshals the updated values into largeParcelable and sents it through {@code onPropertyEvent}
    // callback.
    static void sendUpdatedValues(
            CallbackType callback,
            std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
                    updatedValues);

  protected:
    // Gets the callback to be called when the request for this client has timeout.
@@ -121,14 +120,11 @@ class SubscriptionClient final : public ConnectedClient {
  private:
    // The following members are only initialized during construction.
    std::shared_ptr<const PendingRequestPool::TimeoutCallbackFunc> mTimeoutCallback;
    std::shared_ptr<const std::function<void(
            std::vector<::aidl::android::hardware::automotive::vehicle::GetValueResult>)>>
            mResultCallback;
    std::shared_ptr<const IVehicleHardware::GetValuesCallback> mResultCallback;
    std::shared_ptr<const IVehicleHardware::PropertyChangeCallback> mPropertyChangeCallback;

    static void onGetValueResults(
            const void* clientId,
            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
                    callback,
            const void* clientId, CallbackType callback,
            std::shared_ptr<PendingRequestPool> requestPool,
            std::vector<::aidl::android::hardware::automotive::vehicle::GetValueResult> results);
};
+114 −13
Original line number Diff line number Diff line
@@ -93,11 +93,68 @@ class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::ve
            GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::SetValueResult,
                               ::aidl::android::hardware::automotive::vehicle::SetValueResults>;

    // A thread safe class to maintain an increasing request ID for each subscribe client. This
    // class is safe to pass to async callbacks.
    class SubscribeIdByClient {
      public:
        int64_t getId(const CallbackType& callback);

      private:
        std::mutex mLock;
        std::unordered_map<const AIBinder*, int64_t> mIds GUARDED_BY(mLock);
    };

    // A thread safe class to store all subscribe clients. This class is safe to pass to async
    // callbacks.
    class SubscriptionClients {
      public:
        SubscriptionClients(std::shared_ptr<PendingRequestPool> pool) : mPendingRequestPool(pool) {}

        std::shared_ptr<SubscriptionClient> getClient(const CallbackType& callback);

        void removeClient(const AIBinder* clientId);

        size_t countClients();

      private:
        std::mutex mLock;
        std::unordered_map<const AIBinder*, std::shared_ptr<SubscriptionClient>> mClients
                GUARDED_BY(mLock);
        // PendingRequestPool is thread-safe.
        std::shared_ptr<PendingRequestPool> mPendingRequestPool;
    };

    // A wrapper for linkToDeath to enable stubbing for test.
    class ILinkToDeath {
      public:
        virtual ~ILinkToDeath() = default;

        virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                            void* cookie) = 0;
    };

    // A real implementation for ILinkToDeath.
    class AIBinderLinkToDeathImpl final : public ILinkToDeath {
      public:
        binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                    void* cookie) override;
    };

    // OnBinderDiedContext is a type used as a cookie passed deathRecipient. The deathRecipient's
    // onBinderDied function takes only a cookie as input and we have to store all the contexts
    // as the cookie.
    struct OnBinderDiedContext {
        DefaultVehicleHal* vhal;
        const AIBinder* clientId;
    };

    // The default timeout of get or set value requests is 30s.
    // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe
    // to specify custom timeouts.
    static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000;
    const std::unique_ptr<IVehicleHardware> mVehicleHardware;
    // heart beat event interval: 3s
    static constexpr int64_t HEART_BEAT_INTERVAL_IN_NANO = 3'000'000'000;
    const std::shared_ptr<IVehicleHardware> mVehicleHardware;

    // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
    // lock guard them.
@@ -108,22 +165,24 @@ class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::ve
    // PendingRequestPool is thread-safe.
    std::shared_ptr<PendingRequestPool> mPendingRequestPool;
    // SubscriptionManager is thread-safe.
    std::unique_ptr<SubscriptionManager> mSubscriptionManager;
    std::shared_ptr<SubscriptionManager> mSubscriptionManager;

    std::mutex mLock;
    std::unordered_map<CallbackType, std::shared_ptr<GetValuesClient>> mGetValuesClients
    std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
            GUARDED_BY(mLock);
    std::unordered_map<CallbackType, std::shared_ptr<SetValuesClient>> mSetValuesClients
    std::unordered_map<const AIBinder*, std::shared_ptr<GetValuesClient>> mGetValuesClients
            GUARDED_BY(mLock);
    std::unordered_map<CallbackType, std::shared_ptr<SubscriptionClient>> mSubscriptionClients
    std::unordered_map<const AIBinder*, std::shared_ptr<SetValuesClient>> mSetValuesClients
            GUARDED_BY(mLock);
    // An increasing request ID we keep for subscribe clients.
    std::unordered_map<CallbackType, int64_t> mSubscribeIdByClient GUARDED_BY(mLock);
    // SubscriptionClients is thread-safe.
    std::shared_ptr<SubscriptionClients> mSubscriptionClients;
    // mLinkToDeathImpl is only going to be changed in test.
    std::unique_ptr<ILinkToDeath> mLinkToDeathImpl;

    template <class T>
    std::shared_ptr<T> getOrCreateClient(
            std::unordered_map<CallbackType, std::shared_ptr<T>>* clients,
            const CallbackType& callback) REQUIRES(mLock);
    // RecurrentTimer is thread-safe.
    RecurrentTimer mRecurrentTimer;

    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;

    ::android::base::Result<void> checkProperty(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
@@ -136,13 +195,55 @@ class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::ve
            const std::vector<::aidl::android::hardware::automotive::vehicle::SetValueRequest>&
                    requests);

    void getValueFromHardwareCallCallback(
            const CallbackType& callback,
    ::android::base::Result<void> checkSubscribeOptions(
            const std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
                    options);

    ::android::base::Result<void> checkReadPermission(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;

    ::android::base::Result<void> checkWritePermission(
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;

    ::android::base::Result<
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig*>
    getConfig(int32_t propId) const;

    void onBinderDiedWithContext(const AIBinder* clientId);

    void onBinderUnlinkedWithContext(const AIBinder* clientId);

    void monitorBinderLifeCycle(const CallbackType& callback);

    template <class T>
    static std::shared_ptr<T> getOrCreateClient(
            std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
            const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);

    static void getValueFromHardwareCallCallback(
            std::weak_ptr<IVehicleHardware> vehicleHardware,
            std::shared_ptr<SubscribeIdByClient> subscribeIdByClient,
            std::shared_ptr<SubscriptionClients> subscriptionClients, const CallbackType& callback,
            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);

    static void onPropertyChangeEvent(
            std::weak_ptr<SubscriptionManager> subscriptionManager,
            const std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
                    updatedValues);

    static void checkHealth(std::weak_ptr<IVehicleHardware> hardware,
                            std::weak_ptr<SubscriptionManager> subscriptionManager);

    static void onBinderDied(void* cookie);

    static void onBinderUnlinked(void* cookie);

    // Test-only
    // Set the default timeout for pending requests.
    void setTimeout(int64_t timeoutInNano);

    // Test-only
    void setLinkToDeathImpl(std::unique_ptr<ILinkToDeath> impl);
};

}  // namespace vehicle
+19 −11
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ namespace vehicle {
// A thread-safe subscription manager that manages all VHAL subscriptions.
class SubscriptionManager final {
  public:
    using ClientIdType = const AIBinder*;
    using CallbackType =
            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
    using GetValueFunc = std::function<void(
@@ -59,24 +60,24 @@ class SubscriptionManager final {
                    options,
            bool isContinuousProperty);

    // Unsubscribes from the properties for the callback.
    // Returns error if the callback was not subscribed before or one of the given property was not
    // Unsubscribes from the properties for the client.
    // Returns error if the client was not subscribed before or one of the given property was not
    // subscribed. If error is returned, no property would be unsubscribed.
    // Returns ok if all the requested properties for the callback are unsubscribed.
    ::android::base::Result<void> unsubscribe(const CallbackType& callback,
    // Returns ok if all the requested properties for the client are unsubscribed.
    ::android::base::Result<void> unsubscribe(ClientIdType client,
                                              const std::vector<int32_t>& propIds);

    // Unsubscribes to all the properties for the callback.
    // Returns error if the callback was not subscribed before. If error is returned, no property
    // Unsubscribes from all the properties for the client.
    // Returns error if the client was not subscribed before. If error is returned, no property
    // would be unsubscribed.
    // Returns ok if all the properties for the callback are unsubscribed.
    ::android::base::Result<void> unsubscribe(const CallbackType& callback);
    // Returns ok if all the properties for the client are unsubscribed.
    ::android::base::Result<void> unsubscribe(ClientIdType client);

    // For a list of updated properties, returns a map that maps clients subscribing to
    // the updated properties to a list of updated values. This would only return on-change property
    // clients that should be informed for the given updated values.
    std::unordered_map<
            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>,
            CallbackType,
            std::vector<const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue*>>
    getSubscribedClients(
            const std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
@@ -86,6 +87,9 @@ class SubscriptionManager final {
    static bool checkSampleRate(float sampleRate);

  private:
    // Friend class for testing.
    friend class DefaultVehicleHalTest;

    struct PropIdAreaId {
        int32_t propId;
        int32_t areaId;
@@ -131,9 +135,10 @@ class SubscriptionManager final {
    };

    mutable std::mutex mLock;
    std::unordered_map<PropIdAreaId, std::unordered_set<CallbackType>, PropIdAreaIdHash>
    std::unordered_map<PropIdAreaId, std::unordered_map<ClientIdType, CallbackType>,
                       PropIdAreaIdHash>
            mClientsByPropIdArea GUARDED_BY(mLock);
    std::unordered_map<CallbackType, std::unordered_map<PropIdAreaId, std::unique_ptr<Subscription>,
    std::unordered_map<ClientIdType, std::unordered_map<PropIdAreaId, std::unique_ptr<Subscription>,
                                                        PropIdAreaIdHash>>
            mSubscriptionsByClient GUARDED_BY(mLock);
    // RecurrentTimer is thread-safe.
@@ -141,6 +146,9 @@ class SubscriptionManager final {
    const GetValueFunc mGetValue;

    static ::android::base::Result<int64_t> getInterval(float sampleRate);

    // Checks whether the manager is empty. For testing purpose.
    bool isEmpty();
};

}  // namespace vehicle
Loading