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

Commit f2395597 authored by Yu Shan's avatar Yu Shan Committed by Android (Google) Code Review
Browse files

Merge changes I473360d8,I7ec791b1 into main

* changes:
  Address minor comments.
  Add set supported value debug command.
parents 38e3a6db 2d68d3ee
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -100,6 +100,9 @@ class FakeVehicleHardware : public IVehicleHardware {
    void registerOnPropertySetErrorEvent(
            std::unique_ptr<const PropertySetErrorCallback> callback) override;

    void registerSupportedValueChangeCallback(
            std::unique_ptr<const SupportedValueChangeCallback> callback) 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;
@@ -177,6 +180,7 @@ class FakeVehicleHardware : public IVehicleHardware {
    // Only allowed to set once.
    std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback;
    std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback;
    std::unique_ptr<const SupportedValueChangeCallback> mOnSupportedValueChangeCallback;

    std::mutex mLock;
    std::unordered_map<PropIdAreaId, RefreshInfo, PropIdAreaIdHash> mRefreshInfoByPropIdAreaId
@@ -185,6 +189,10 @@ class FakeVehicleHardware : public IVehicleHardware {
    std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
            mSavedProps GUARDED_BY(mLock);
    std::unordered_set<PropIdAreaId, PropIdAreaIdHash> mSubOnChangePropIdAreaIds GUARDED_BY(mLock);
    int32_t mMinSupportedValueForTestIntProp GUARDED_BY(mLock) = 0;
    int32_t mMaxSupportedValueForTestIntProp GUARDED_BY(mLock) = 10;
    std::vector<int32_t> mSupportedValuesListForTestIntProp GUARDED_BY(mLock) = {0, 2, 4, 6, 8, 10};

    // PendingRequestHandler is thread-safe.
    mutable PendingRequestHandler<GetValuesCallback,
                                  aidl::android::hardware::automotive::vehicle::GetValueRequest>
@@ -281,6 +289,8 @@ class FakeVehicleHardware : public IVehicleHardware {
    std::string dumpRestoreProperty(const std::vector<std::string>& options);
    std::string dumpInjectEvent(const std::vector<std::string>& options);
    std::string dumpSubscriptions();
    std::string dumpSetSupportedValues(const std::vector<std::string>& options);
    std::string dumpSetMinMaxValue(const std::vector<std::string>& options);

    std::vector<std::string> getOptionValues(const std::vector<std::string>& options,
                                             size_t* index);
@@ -310,6 +320,9 @@ class FakeVehicleHardware : public IVehicleHardware {
                               float sampleRateHz) REQUIRES(mLock);
    void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
    void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
    void triggerSupportedValueChange(
            const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config)
            EXCLUDES(mLock);

    static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
            aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
+109 −10
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ 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;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
@@ -1372,6 +1373,10 @@ DumpResult FakeVehicleHardware::dump(const std::vector<std::string>& options) {
        result.buffer = "successfully restored vendor configs";
    } else if (EqualsIgnoreCase(option, "--dumpSub")) {
        result.buffer = dumpSubscriptions();
    } else if (EqualsIgnoreCase(option, "--set-minmaxvalue")) {
        result.buffer = dumpSetMinMaxValue(options);
    } else if (EqualsIgnoreCase(option, "--set-supportedvalues")) {
        result.buffer = dumpSetSupportedValues(options);
    } else {
        result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
    }
@@ -1794,6 +1799,88 @@ std::string FakeVehicleHardware::dumpSubscriptions() {
    return result;
}

std::string FakeVehicleHardware::dumpSetMinMaxValue(const std::vector<std::string>& options) {
    if (auto result = checkArgumentsSize(options, /*minSize=*/3); !result.ok()) {
        return getErrorMsg(result);
    }
    int testPropId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY);
    auto configResult = mServerSidePropStore->getPropConfig(testPropId);
    if (!configResult.ok()) {
        return "Failed to set min/max supported value: VENDOR_EXTENSION_INT_PROPERTY not supported";
    }
    int32_t values[2];
    for (size_t i = 1; i < 3; i++) {
        auto int32Result = safelyParseInt<int32_t>(i, options[i]);
        if (!int32Result.ok()) {
            return StringPrintf(
                    "Failed to set min/max supported value: Value: \"%s\" is not a valid int: %s\n",
                    options[i].c_str(), getErrorMsg(int32Result).c_str());
        }
        values[i - 1] = int32Result.value();
    }
    int32_t minValue = values[0];
    int32_t maxValue = values[1];
    if (minValue > maxValue) {
        return StringPrintf("Failed to set min/max supported value: MinValue: %" PRId32
                            " must not > MaxValue: %" PRId32,
                            minValue, maxValue);
    }
    {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        mMinSupportedValueForTestIntProp = minValue;
        mMaxSupportedValueForTestIntProp = maxValue;
    }
    triggerSupportedValueChange(configResult.value());
    return "Min/Max supported value for VENDOR_EXTENSION_INT_PROPERTY set";
}

std::string FakeVehicleHardware::dumpSetSupportedValues(const std::vector<std::string>& options) {
    if (auto result = checkArgumentsSize(options, /*minSize=*/2); !result.ok()) {
        return getErrorMsg(result);
    }
    int testPropId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY);
    auto configResult = mServerSidePropStore->getPropConfig(testPropId);
    if (!configResult.ok()) {
        return "Failed to set min/max supported value: VENDOR_EXTENSION_INT_PROPERTY not supported";
    }
    std::vector<int32_t> values;
    for (size_t i = 1; i < options.size(); i++) {
        auto int32Result = safelyParseInt<int32_t>(i, options[i]);
        if (!int32Result.ok()) {
            return StringPrintf(
                    "Failed to set supported values: Value: \"%s\" is not a valid int: %s\n",
                    options[i].c_str(), getErrorMsg(int32Result).c_str());
        }
        values.push_back(int32Result.value());
    }

    {
        std::scoped_lock<std::mutex> lockGuard(mLock);
        mSupportedValuesListForTestIntProp = values;
    }
    triggerSupportedValueChange(configResult.value());
    return "Supported values list for VENDOR_EXTENSION_INT_PROPERTY set";
}

// Triggers supported value change for all areaIds that specify hasSupportedValueInfo.
void FakeVehicleHardware::triggerSupportedValueChange(const VehiclePropConfig& config) {
    if (mOnSupportedValueChangeCallback == nullptr) {
        ALOGE("onSupportedValueChangeCallback is not registered, ignore event");
        return;
    }

    std::vector<PropIdAreaId> propIdAreaIds;
    for (const VehicleAreaConfig& areaConfig : config.areaConfigs) {
        if (areaConfig.hasSupportedValueInfo != std::nullopt) {
            propIdAreaIds.push_back({
                    .propId = config.prop,
                    .areaId = areaConfig.areaId,
            });
        }
    }
    (*mOnSupportedValueChangeCallback)(std::move(propIdAreaIds));
}

std::string FakeVehicleHardware::dumpHelp() {
    return "Usage: \n\n"
           "[no args]: dumps (id and value) all supported properties \n"
@@ -1805,6 +1892,10 @@ std::string FakeVehicleHardware::dumpHelp() {
           "The value arguments constructs a VehiclePropValue used in the getValue request. \n"
           "--set <PROP_ID> [ValueArguments]: sets the value of property PROP_ID, the value "
           "arguments constructs a VehiclePropValue used in the setValue request. \n"
           "--set-minmaxvalue <MIN_VALUE(int)> <MAX_VALUE(int)>: sets the min max supported value "
           "for VENDOR_EXTENSION_INT_PROPERTY\n"
           "--set-supportedvalues <VALUE_1(int)> [VALUE_2(int) ...]: sets the supported values list"
           "for VENDOR_EXTENSION_INT_PROPERTY\n"
           "--save-prop <PROP_ID> [-a AREA_ID]: saves the current value for PROP_ID, integration "
           "tests that modify prop value must call this before test and restore-prop after test. \n"
           "--restore-prop <PROP_ID> [-a AREA_ID]: restores a previously saved property value. \n"
@@ -2280,6 +2371,15 @@ void FakeVehicleHardware::registerOnPropertySetErrorEvent(
    mOnPropertySetErrorCallback = std::move(callback);
}

void FakeVehicleHardware::registerSupportedValueChangeCallback(
        std::unique_ptr<const SupportedValueChangeCallback> callback) {
    if (mOnSupportedValueChangeCallback != nullptr) {
        ALOGE("registerOnPropertyChangeEvent must only be called once");
        return;
    }
    mOnSupportedValueChangeCallback = std::move(callback);
}

StatusCode FakeVehicleHardware::subscribe(SubscribeOptions options) {
    int32_t propId = options.propId;

@@ -2303,6 +2403,7 @@ StatusCode FakeVehicleHardware::subscribe(SubscribeOptions options) {

std::vector<MinMaxSupportedValueResult> FakeVehicleHardware::getMinMaxSupportedValues(
        const std::vector<PropIdAreaId>& propIdAreaIds) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    std::vector<MinMaxSupportedValueResult> results;
    // We only support VENDOR_EXTENSION_INT_PROPERTY
    for (const auto& propIdAreaId : propIdAreaIds) {
@@ -2318,11 +2419,11 @@ std::vector<MinMaxSupportedValueResult> FakeVehicleHardware::getMinMaxSupportedV
                .status = StatusCode::OK,
                .minSupportedValue =
                        RawPropValues{
                                .int32Values = {0},
                                .int32Values = {mMinSupportedValueForTestIntProp},
                        },
                .maxSupportedValue =
                        RawPropValues{
                                .int32Values = {10},
                                .int32Values = {mMaxSupportedValueForTestIntProp},
                        },
        });
    }
@@ -2331,6 +2432,7 @@ std::vector<MinMaxSupportedValueResult> FakeVehicleHardware::getMinMaxSupportedV

std::vector<SupportedValuesListResult> FakeVehicleHardware::getSupportedValuesLists(
        const std::vector<PropIdAreaId>& propIdAreaIds) {
    std::scoped_lock<std::mutex> lockGuard(mLock);
    std::vector<SupportedValuesListResult> results;
    // We only support VENDOR_EXTENSION_INT_PROPERTY
    for (const auto& propIdAreaId : propIdAreaIds) {
@@ -2342,16 +2444,13 @@ std::vector<SupportedValuesListResult> FakeVehicleHardware::getSupportedValuesLi
            });
            continue;
        }
        std::vector<std::optional<RawPropValues>> supportedValuesList;
        for (int32_t value : mSupportedValuesListForTestIntProp) {
            supportedValuesList.push_back(RawPropValues{.int32Values = {value}});
        }
        results.push_back(SupportedValuesListResult{
                .status = StatusCode::OK,
                .supportedValuesList = std::vector<std::optional<RawPropValues>>({
                        RawPropValues{.int32Values = {0}},
                        RawPropValues{.int32Values = {2}},
                        RawPropValues{.int32Values = {4}},
                        RawPropValues{.int32Values = {6}},
                        RawPropValues{.int32Values = {8}},
                        RawPropValues{.int32Values = {10}},
                }),
                .supportedValuesList = supportedValuesList,
        });
    }
    return results;
+80 −0
Original line number Diff line number Diff line
@@ -2759,6 +2759,86 @@ TEST_F(FakeVehicleHardwareTest, testDumpFakeUserHal) {
                              "response\nNo SetUserIdentificationAssociation response\n"));
}

TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue) {
    std::vector<std::string> options = {"--set-minmaxvalue", "1", "100"};
    std::vector<PropIdAreaId> changedPropIdAreaIds;

    getHardware()->registerSupportedValueChangeCallback(
            std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
                    [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
                        changedPropIdAreaIds = propIdAreaIds;
                    }));

    DumpResult result = getHardware()->dump(options);
    ASSERT_FALSE(result.callerShouldDumpState);
    ASSERT_THAT(result.buffer, ContainsRegex("Min/Max supported value .* set"));

    ASSERT_EQ(changedPropIdAreaIds.size(), 1u);

    auto results = getHardware()->getMinMaxSupportedValues({PropIdAreaId{
            .propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY), .areaId = 0}});

    ASSERT_EQ(results.size(), 1u);
    EXPECT_EQ(results[0].status, StatusCode::OK);
    EXPECT_EQ(results[0].minSupportedValue.value(), RawPropValues{.int32Values = {1}});
    EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.int32Values = {100}});
}

TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_invalidInt) {
    std::vector<std::string> options = {"--set-minmaxvalue", "abc", "100"};

    DumpResult result = getHardware()->dump(options);
    ASSERT_THAT(result.buffer, ContainsRegex("Failed"));

    options = {"--set-minmaxvalue", "1", "abc"};

    result = getHardware()->dump(options);
    ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
}

TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_minLargerThanMax) {
    std::vector<std::string> options = {"--set-minmaxvalue", "2", "1"};

    DumpResult result = getHardware()->dump(options);
    ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
}

TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues) {
    std::vector<std::string> options = {"--set-supportedvalues", "1", "2", "3"};
    std::vector<PropIdAreaId> changedPropIdAreaIds;

    getHardware()->registerSupportedValueChangeCallback(
            std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
                    [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
                        changedPropIdAreaIds = propIdAreaIds;
                    }));

    DumpResult result = getHardware()->dump(options);
    ASSERT_FALSE(result.callerShouldDumpState);
    ASSERT_THAT(result.buffer, ContainsRegex("Supported values list .* set"));

    ASSERT_EQ(changedPropIdAreaIds.size(), 1u);

    auto results = getHardware()->getSupportedValuesLists({PropIdAreaId{
            .propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY), .areaId = 0}});

    ASSERT_EQ(results.size(), 1u);
    EXPECT_EQ(results[0].status, StatusCode::OK);
    EXPECT_NE(results[0].supportedValuesList, std::nullopt);
    EXPECT_EQ(results[0].supportedValuesList.value(), std::vector<std::optional<RawPropValues>>({
                                                              RawPropValues{.int32Values = {1}},
                                                              RawPropValues{.int32Values = {2}},
                                                              RawPropValues{.int32Values = {3}},
                                                      }));
}

TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_invalidInt) {
    std::vector<std::string> options = {"--set-supportedvalues", "1", "2", "ab", "3"};

    DumpResult result = getHardware()->dump(options);
    ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
}

struct SetPropTestCase {
    std::string test_name;
    std::vector<std::string> options;
+1 −1
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ class SubscriptionClient {

    // Invokes onSupportedValueChange callback.
    static void sendSupportedValueChangeEvents(CallbackType callback,
                                               std::vector<PropIdAreaId> propIdAreaIds);
                                               const std::vector<PropIdAreaId>& propIdAreaIds);
};

}  // namespace vehicle
+4 −4
Original line number Diff line number Diff line
@@ -306,8 +306,9 @@ void SubscriptionClient::sendPropertySetErrors(std::shared_ptr<IVehicleCallback>
    }
}

void SubscriptionClient::sendSupportedValueChangeEvents(std::shared_ptr<IVehicleCallback> callback,
                                                        std::vector<PropIdAreaId> propIdAreaIds) {
void SubscriptionClient::sendSupportedValueChangeEvents(
        std::shared_ptr<IVehicleCallback> callback,
        const std::vector<PropIdAreaId>& propIdAreaIds) {
    if (propIdAreaIds.empty()) {
        return;
    }
@@ -323,8 +324,7 @@ void SubscriptionClient::sendSupportedValueChangeEvents(std::shared_ptr<IVehicle
    if (ScopedAStatus callbackStatus = callback->onSupportedValueChange(vhalPropIdAreaIds);
        !callbackStatus.isOk()) {
        ALOGE("subscribe: failed to call onSupportedValueChange callback, client ID: %p, error: "
              "%s, "
              "exception: %d, service specific error: %d",
              "%s, exception: %d, service specific error: %d",
              callback->asBinder().get(), callbackStatus.getMessage(),
              callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
    }
Loading