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

Commit 3a780328 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Ice087a6f,I52fa9bd3,I1a375ab2 into main

* changes:
  Fix proto converter and support VUR.
  Overwrite enableVUR to false if not supported.
  Implement VUR in SubscriptionManager.
parents 3c464673 edb969a9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,9 @@
          "include-filter": "com.android.car.hal.fakevhal.FakeVehicleStubUnitTest"
        }
      ]
    },
    {
      "name": "VehicleHalProtoMessageConverterTest"
    }
  ]
}
+8 −2
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ void aidlToProto(const aidl_vehicle::VehiclePropConfig& in, proto::VehiclePropCo
                protoACfg->add_supported_enum_values(supportedEnumValue);
            }
        }
        protoACfg->set_support_variable_update_rate(areaConfig.supportVariableUpdateRate);
    }
}

@@ -100,9 +101,14 @@ void protoToAidl(const proto::VehiclePropConfig& in, aidl_vehicle::VehiclePropCo
                .maxInt64Value = protoAcfg.max_int64_value(),
                .minFloatValue = protoAcfg.min_float_value(),
                .maxFloatValue = protoAcfg.max_float_value(),
                .supportVariableUpdateRate = protoAcfg.support_variable_update_rate(),
        };
        if (protoAcfg.supported_enum_values().size() != 0) {
            vehicleAreaConfig.supportedEnumValues = std::vector<int64_t>();
            COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoAcfg, supported_enum_values, (&vehicleAreaConfig),
                                           supportedEnumValues.value());
        }

        return vehicleAreaConfig;
    };
    CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, area_configs, out, areaConfigs, cast_to_acfg);
+41 −15
Original line number Diff line number Diff line
@@ -117,18 +117,53 @@ class IVehicleHardware {
        return std::chrono::nanoseconds(0);
    }

    // A [propId, areaId] is newly subscribed or the update rate is changed.
    // A [propId, areaId] is newly subscribed or the subscribe options are changed.
    //
    // The 'options' contains the property ID, area ID and sample rate in Hz.
    // The subscribe options contain sample rate in Hz or enable/disable variable update rate.
    //
    // For continuous property, the sample rate is never 0 and indicates the new sample rate (or
    // the initial sample rate if this property was not subscribed before).
    // For continuous properties:
    //
    // For on-change property, the sample rate is always 0 and must be ignored.
    // The sample rate is never 0 and indicates the desired polling rate for this property. The
    // sample rate is guaranteed to be within supported {@code minSampleRate} and
    // {@code maxSampleRate} as specified in {@code VehiclePropConfig}.
    //
    // If the specified sample rate is not supported, e.g. vehicle bus only supports 5hz and 10hz
    // polling rate but the sample rate is 8hz, impl must choose the higher polling rate (10hz).
    //
    // Whether variable update rate is enabled is specified by {@code enableVariableUpdateRate} in
    // {@code SubscribeOptions}. If variable update rate is not supported for the
    // [propId, areaId], impl must ignore this option and always treat it as disabled.
    //
    // If variable update rate is disabled/not supported, impl must report all the property events
    // for this [propId, areaId] through {@code propertyChangeCallback} according to the sample
    // rate. E.g. a sample rate of 10hz must generate at least 10 property change events per second.
    //
    // If variable update rate is enabled AND supported, impl must only report property events
    // when the [propId, areaId]'s value or status changes (a.k.a same as on-change property).
    // The sample rate still guides the polling rate, but duplicate property events must be dropped
    // and not reported via {@code propertyChangeCallback}.
    //
    // Async property set error events are not affected by variable update rate and must always
    // be reported.
    //
    // If the impl is always polling at {@code maxSampleRate} for all continuous [propId, areaId]s,
    // and do not support variable update rate for any [propId, areaId], then this function can be a
    // no-op.
    //
    // For on-change properties:
    //
    // The sample rate is always 0 and must be ignored. If the impl is always subscribing to all
    // on-change properties, then this function can be no-op.
    //
    // For all properties:
    //
    // It is recommended to only deliver the subscribed property events to DefaultVehicleHal to
    // improve performance. However, even if unsubscribed property events are delivered, they
    // will be filtered out by DefaultVehicleHal.
    //
    // A subscription from VHAL client might not necessarily trigger this function.
    // DefaultVehicleHal will aggregate all the subscriptions from all the clients and notify
    // IVehicleHardware if new subscriptions are required or sample rate is updated.
    // IVehicleHardware if new subscriptions are required or subscribe options are updated.
    //
    // For example:
    // 1. VHAL initially have no subscriber for speed.
@@ -144,15 +179,6 @@ class IVehicleHardware {
    // 5. The second subscriber is removed, 'unsubscribe' is called.
    //    The impl can optionally disable the polling for vehicle speed.
    //
    // It is recommended to only deliver the subscribed property events to DefaultVehicleHal to
    // improve performance. However, even if unsubscribed property events are delivered, they
    // will be filtered out by DefaultVehicleHal.
    //
    // For continuous property, if the impl is always polling at {@code maxSampleRate} as specified
    // in config, then this function can be a no-op.
    //
    // For on-change property, if the impl is always subscribing to all on-change properties, then
    // this function can be no-op.
    virtual aidl::android::hardware::automotive::vehicle::StatusCode subscribe(
            [[maybe_unused]] aidl::android::hardware::automotive::vehicle::SubscribeOptions
                    options) {
+39 −9
Original line number Diff line number Diff line
@@ -36,20 +36,29 @@ namespace hardware {
namespace automotive {
namespace vehicle {

// A structure to represent subscription config for one subscription client.
struct SubConfig {
    float sampleRateHz;
    bool enableVur;
};

// A class to represent all the subscription configs for a continuous [propId, areaId].
class ContSubConfigs final {
  public:
    using ClientIdType = const AIBinder*;

    void addClient(const ClientIdType& clientId, float sampleRateHz);
    void addClient(const ClientIdType& clientId, float sampleRateHz, bool enableVur);
    void removeClient(const ClientIdType& clientId);
    float getMaxSampleRateHz() const;
    bool isVurEnabled() const;
    bool isVurEnabledForClient(const ClientIdType& clientId);

  private:
    float mMaxSampleRateHz = 0.;
    std::unordered_map<ClientIdType, float> mSampleRateHzByClient;
    bool mEnableVur;
    std::unordered_map<ClientIdType, SubConfig> mConfigByClient;

    void refreshMaxSampleRateHz();
    void refreshCombinedConfig();
};

// A thread-safe subscription manager that manages all VHAL subscriptions.
@@ -58,6 +67,7 @@ class SubscriptionManager final {
    using ClientIdType = const AIBinder*;
    using CallbackType =
            std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
    using VehiclePropValue = aidl::android::hardware::automotive::vehicle::VehiclePropValue;

    explicit SubscriptionManager(IVehicleHardware* vehicleHardware);
    ~SubscriptionManager();
@@ -92,11 +102,8 @@ class SubscriptionManager final {
    // 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<CallbackType,
                       std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
    getSubscribedClients(
            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
                    updatedValues);
    std::unordered_map<CallbackType, std::vector<VehiclePropValue>> getSubscribedClients(
            std::vector<VehiclePropValue>&& updatedValues);

    // For a list of set property error events, returns a map that maps clients subscribing to the
    // properties to a list of errors for each client.
@@ -116,6 +123,21 @@ class SubscriptionManager final {

    IVehicleHardware* mVehicleHardware;

    struct VehiclePropValueHashPropIdAreaId {
        inline size_t operator()(const VehiclePropValue& vehiclePropValue) const {
            size_t res = 0;
            hashCombine(res, vehiclePropValue.prop);
            hashCombine(res, vehiclePropValue.areaId);
            return res;
        }
    };

    struct VehiclePropValueEqualPropIdAreaId {
        inline bool operator()(const VehiclePropValue& left, const VehiclePropValue& right) const {
            return left.prop == right.prop && left.areaId == right.areaId;
        }
    };

    mutable std::mutex mLock;
    std::unordered_map<PropIdAreaId, std::unordered_map<ClientIdType, CallbackType>,
                       PropIdAreaIdHash>
@@ -124,10 +146,15 @@ class SubscriptionManager final {
            mSubscribedPropsByClient GUARDED_BY(mLock);
    std::unordered_map<PropIdAreaId, ContSubConfigs, PropIdAreaIdHash> mContSubConfigsByPropIdArea
            GUARDED_BY(mLock);
    std::unordered_map<CallbackType,
                       std::unordered_set<VehiclePropValue, VehiclePropValueHashPropIdAreaId,
                                          VehiclePropValueEqualPropIdAreaId>>
            mContSubValuesByCallback GUARDED_BY(mLock);

    VhalResult<void> addContinuousSubscriberLocked(const ClientIdType& clientId,
                                                   const PropIdAreaId& propIdAreaId,
                                                   float sampleRateHz) REQUIRES(mLock);
                                                   float sampleRateHz, bool enableVur)
            REQUIRES(mLock);
    VhalResult<void> addOnChangeSubscriberLocked(const PropIdAreaId& propIdAreaId) REQUIRES(mLock);
    // Removes the subscription client for the continuous [propId, areaId].
    VhalResult<void> removeContinuousSubscriberLocked(const ClientIdType& clientId,
@@ -147,6 +174,9 @@ class SubscriptionManager final {
    // Checks whether the manager is empty. For testing purpose.
    bool isEmpty();

    bool isValueUpdatedLocked(const CallbackType& callback, const VehiclePropValue& value)
            REQUIRES(mLock);

    // Get the interval in nanoseconds accroding to sample rate.
    static android::base::Result<int64_t> getIntervalNanos(float sampleRateHz);
};
+33 −1
Original line number Diff line number Diff line
@@ -695,7 +695,39 @@ ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
        if (config.changeMode == VehiclePropertyChangeMode::CONTINUOUS) {
            optionCopy.sampleRate = getDefaultSampleRateHz(
                    optionCopy.sampleRate, config.minSampleRate, config.maxSampleRate);
            if (!optionCopy.enableVariableUpdateRate) {
                continuousSubscriptions.push_back(std::move(optionCopy));
            } else {
                // If clients enables to VUR, we need to check whether VUR is supported for the
                // specific [propId, areaId] and overwrite the option to disable if not supported.
                std::vector<int32_t> areasVurEnabled;
                std::vector<int32_t> areasVurDisabled;
                for (int32_t areaId : optionCopy.areaIds) {
                    const VehicleAreaConfig* areaConfig = getAreaConfig(propId, areaId, config);
                    if (areaConfig == nullptr) {
                        areasVurDisabled.push_back(areaId);
                        continue;
                    }
                    if (!areaConfig->supportVariableUpdateRate) {
                        areasVurDisabled.push_back(areaId);
                        continue;
                    }
                    areasVurEnabled.push_back(areaId);
                }
                if (!areasVurEnabled.empty()) {
                    SubscribeOptions optionVurEnabled = optionCopy;
                    optionVurEnabled.areaIds = areasVurEnabled;
                    optionVurEnabled.enableVariableUpdateRate = true;
                    continuousSubscriptions.push_back(std::move(optionVurEnabled));
                }

                if (!areasVurDisabled.empty()) {
                    // We use optionCopy for areas with VUR disabled.
                    optionCopy.areaIds = areasVurDisabled;
                    optionCopy.enableVariableUpdateRate = false;
                    continuousSubscriptions.push_back(std::move(optionCopy));
                }
            }
        } else {
            onChangeSubscriptions.push_back(std::move(optionCopy));
        }
Loading