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

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

Guard update timestamp logic with lock.

Guard the logic to update property value timestamp with lock so that
they will not overlap. Otherwise, it is possible that another op will
update the timestamp to a newer value, which causes this op to fail
the timestamp freshness check.

Test: atest --iterations 10 FakeVehicleHardwareTest#testSubscribe_enableVUR
Bug: 308552957
Change-Id: I8f7a6356ba65e4470e851e59c20bb1f678c2d467
parent 57528c13
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -1055,10 +1055,11 @@ VhalResult<void> FakeVehicleHardware::setValue(const VehiclePropValue& value) {
    }

    auto updatedValue = mValuePool->obtain(value);
    int64_t timestamp = elapsedRealtimeNano();
    updatedValue->timestamp = timestamp;

    auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue));
    auto writeResult = mServerSidePropStore->writeValue(
            std::move(updatedValue),
            /*updateStatus=*/false, /*mode=*/VehiclePropertyStore::EventMode::ON_VALUE_CHANGE,
            /*useCurrentTimestamp=*/true);
    if (!writeResult.ok()) {
        return StatusError(getErrorCode(writeResult))
               << StringPrintf("failed to write value into property store, error: %s",
@@ -2091,10 +2092,10 @@ StatusCode FakeVehicleHardware::subscribePropIdAreaIdLocked(
                    // Failed to read current value, skip refreshing.
                    return;
                }
                result.value()->timestamp = elapsedRealtimeNano();

                mServerSidePropStore->writeValue(std::move(result.value()), /*updateStatus=*/true,
                                                 eventMode);
                mServerSidePropStore->writeValue(std::move(result.value()),
                                                 /*updateStatus=*/true, eventMode,
                                                 /*useCurrentTimestamp=*/true);
            });
            mRecurrentTimer->registerTimerCallback(intervalInNanos, action);
            mRecurrentActions[propIdAreaId] = action;
+3 −1
Original line number Diff line number Diff line
@@ -100,9 +100,11 @@ class VehiclePropertyStore final {
    // override an existing value, the status for the existing value would be used for the
    // overridden value.
    // 'EventMode' controls whether the 'OnValueChangeCallback' will be called for this operation.
    // If 'useCurrentTimestamp' is true, the property value will be set to the current timestamp.
    VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
                                bool updateStatus = false,
                                EventMode mode = EventMode::ON_VALUE_CHANGE) EXCLUDES(mLock);
                                EventMode mode = EventMode::ON_VALUE_CHANGE,
                                bool useCurrentTimestamp = false) EXCLUDES(mLock);

    // Remove a given property value from the property store. The 'propValue' would be used to
    // generate the key for the value to remove.
+9 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#define LOG_TAG "VehiclePropertyStore"
#include <utils/Log.h>
#include <utils/SystemClock.h>

#include "VehiclePropertyStore.h"

@@ -107,13 +108,20 @@ void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config,

VhalResult<void> VehiclePropertyStore::writeValue(VehiclePropValuePool::RecyclableType propValue,
                                                  bool updateStatus,
                                                  VehiclePropertyStore::EventMode eventMode) {
                                                  VehiclePropertyStore::EventMode eventMode,
                                                  bool useCurrentTimestamp) {
    bool valueUpdated = true;
    VehiclePropValue updatedValue;
    OnValueChangeCallback onValueChangeCallback = nullptr;
    {
        std::scoped_lock<std::mutex> g(mLock);

        // Must set timestamp inside the lock to make sure no other writeValue will update the
        // the timestamp to a newer one while we are writing this value.
        if (useCurrentTimestamp) {
            propValue->timestamp = elapsedRealtimeNano();
        }

        int32_t propId = propValue->prop;

        VehiclePropertyStore::Record* record = getRecordLocked(propId);