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

Commit db4f577d authored by Yu Shan's avatar Yu Shan
Browse files

Override subscribe/unsubscribe.

Override subscribe/unsubscribe in FakeVehicleHardware, now it will only
generate property change events for subscribed properties.

Test: atest DefaultVehicleHalTest android.car.cts.CarPropertyManagerTest
Bug: 306262618
Change-Id: Ice39f059820d4ec6039acb4daf9975514f2eb22b
parent f4647e03
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -91,9 +91,13 @@ class FakeVehicleHardware : public IVehicleHardware {
    void registerOnPropertySetErrorEvent(
            std::unique_ptr<const PropertySetErrorCallback> callback) override;

    // Update the sample rate for the [propId, areaId] pair.
    aidl::android::hardware::automotive::vehicle::StatusCode updateSampleRate(
            int32_t propId, int32_t areaId, float sampleRate) override;
    // Subscribe to a new [propId, areaId] or change the update rate.
    aidl::android::hardware::automotive::vehicle::StatusCode subscribe(
            aidl::android::hardware::automotive::vehicle::SubscribeOptions options) override;

    // Unsubscribe to a [propId, areaId].
    aidl::android::hardware::automotive::vehicle::StatusCode unsubscribe(int32_t propId,
                                                                         int32_t areaId) override;

  protected:
    // mValuePool is also used in mServerSidePropStore.
@@ -154,6 +158,7 @@ class FakeVehicleHardware : public IVehicleHardware {
            mRecurrentActions GUARDED_BY(mLock);
    std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
            mSavedProps GUARDED_BY(mLock);
    std::unordered_set<PropIdAreaId, PropIdAreaIdHash> mSubOnChangePropIdAreaIds GUARDED_BY(mLock);
    // PendingRequestHandler is thread-safe.
    mutable PendingRequestHandler<GetValuesCallback,
                                  aidl::android::hardware::automotive::vehicle::GetValueRequest>
@@ -176,7 +181,8 @@ class FakeVehicleHardware : public IVehicleHardware {
    void storePropInitialValue(const ConfigDeclaration& config);
    // The callback that would be called when a vehicle property value change happens.
    void onValueChangeCallback(
            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)
            EXCLUDES(mLock);
    // Load the config files in format '*.json' from the directory and parse the config files
    // into a map from property ID to ConfigDeclarations.
    void loadPropConfigsFromDir(const std::string& dirPath,
@@ -262,6 +268,11 @@ class FakeVehicleHardware : public IVehicleHardware {
    void generateVendorConfigs(
            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>&) const;

    aidl::android::hardware::automotive::vehicle::StatusCode subscribePropIdAreaIdLocked(
            int32_t propId, int32_t areaId, float sampleRateHz,
            aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode changeMode)
            REQUIRES(mLock);

    static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
            aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
            int32_t keyCode, int32_t targetDisplay);
+90 −28
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
using ::aidl::android::hardware::automotive::vehicle::toString;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
@@ -67,6 +69,7 @@ using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
@@ -1926,26 +1929,53 @@ void FakeVehicleHardware::registerOnPropertySetErrorEvent(
    mOnPropertySetErrorCallback = std::move(callback);
}

StatusCode FakeVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId, float sampleRate) {
    // DefaultVehicleHal makes sure that sampleRate must be within minSampleRate and maxSampleRate.
    // For fake implementation, we would write the same value with a new timestamp into propStore
    // at sample rate.
StatusCode FakeVehicleHardware::subscribe(SubscribeOptions options) {
    int32_t propId = options.propId;

    auto configResult = mServerSidePropStore->getConfig(propId);
    if (!configResult.ok()) {
        ALOGE("subscribe: property: %" PRId32 " is not supported", propId);
        return StatusCode::INVALID_ARG;
    }

    std::scoped_lock<std::mutex> lockGuard(mLock);
    for (int areaId : options.areaIds) {
        if (StatusCode status = subscribePropIdAreaIdLocked(propId, areaId, options.sampleRate,
                                                            configResult.value()->changeMode);
            status != StatusCode::OK) {
            return status;
        }
    }
    return StatusCode::OK;
}

StatusCode FakeVehicleHardware::subscribePropIdAreaIdLocked(int32_t propId, int32_t areaId,
                                                            float sampleRateHz,
                                                            VehiclePropertyChangeMode changeMode) {
    PropIdAreaId propIdAreaId{
            .propId = propId,
            .areaId = areaId,
    };
    switch (changeMode) {
        case VehiclePropertyChangeMode::STATIC:
            ALOGW("subscribe to a static property, do nothing.");
            return StatusCode::OK;
        case VehiclePropertyChangeMode::ON_CHANGE:
            mSubOnChangePropIdAreaIds.insert(std::move(propIdAreaId));
            return StatusCode::OK;
        case VehiclePropertyChangeMode::CONTINUOUS:
            if (sampleRateHz == 0.f) {
                ALOGE("Must not use sample rate 0 for a continuous property");
                return StatusCode::INTERNAL_ERROR;
            }
            if (mRecurrentActions.find(propIdAreaId) != mRecurrentActions.end()) {
                mRecurrentTimer->unregisterTimerCallback(mRecurrentActions[propIdAreaId]);
            }
    if (sampleRate == 0) {
        return StatusCode::OK;
    }
    int64_t interval = static_cast<int64_t>(1'000'000'000. / sampleRate);
            int64_t intervalInNanos = static_cast<int64_t>(1'000'000'000. / sampleRateHz);
            auto action = std::make_shared<RecurrentTimer::Callback>([this, propId, areaId] {
        // Refresh the property value. In real implementation, this should poll the latest value
        // from vehicle bus. Here, we are just refreshing the existing value with a new timestamp.
                // Refresh the property value. In real implementation, this should poll the latest
                // value from vehicle bus. Here, we are just refreshing the existing value with a
                // new timestamp.
                auto result = getValue(VehiclePropValue{
                        .areaId = areaId,
                        .prop = propId,
@@ -1956,21 +1986,53 @@ StatusCode FakeVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId,
                    return;
                }
                result.value()->timestamp = elapsedRealtimeNano();
        // For continuous properties, we must generate a new onPropertyChange event periodically
        // according to the sample rate.
                // For continuous properties, we must generate a new onPropertyChange event
                // periodically according to the sample rate.
                mServerSidePropStore->writeValue(std::move(result.value()), /*updateStatus=*/true,
                                                 VehiclePropertyStore::EventMode::ALWAYS);
            });
    mRecurrentTimer->registerTimerCallback(interval, action);
            mRecurrentTimer->registerTimerCallback(intervalInNanos, action);
            mRecurrentActions[propIdAreaId] = action;
            return StatusCode::OK;
    }
}

StatusCode FakeVehicleHardware::unsubscribe(int32_t propId, int32_t areaId) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    PropIdAreaId propIdAreaId{
            .propId = propId,
            .areaId = areaId,
    };
    if (mRecurrentActions.find(propIdAreaId) != mRecurrentActions.end()) {
        mRecurrentTimer->unregisterTimerCallback(mRecurrentActions[propIdAreaId]);
        mRecurrentActions.erase(propIdAreaId);
    }
    mSubOnChangePropIdAreaIds.erase(propIdAreaId);
    return StatusCode::OK;
}

void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) {
    if (mOnPropertyChangeCallback == nullptr) {
        return;
    }

    PropIdAreaId propIdAreaId{
            .propId = value.prop,
            .areaId = value.areaId,
    };

    {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        if (mRecurrentActions.find(propIdAreaId) == mRecurrentActions.end() &&
            mSubOnChangePropIdAreaIds.find(propIdAreaId) == mSubOnChangePropIdAreaIds.end()) {
            if (FAKE_VEHICLEHARDWARE_DEBUG) {
                ALOGD("The updated property value: %s is not subscribed, ignore",
                      value.toString().c_str());
            }
            return;
        }
    }

    std::vector<VehiclePropValue> updatedValues;
    updatedValues.push_back(value);
    (*mOnPropertyChangeCallback)(std::move(updatedValues));
+194 −114

File changed.

Preview size limit exceeded, changes collapsed.