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

Commit 21d7b02a authored by Yu Shan's avatar Yu Shan
Browse files

[RESTRICT AUTOMERGE] Pass property set error to subscribed clients.

Pass the async property set error generated by VehicleHardware layer
to subscribed clients.

Test: atest DefaultVehicleHalTest
Bug: 286384730
Bug: 292001021
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6fe26625db72da7760014d0c71019fb3e847e2d3)
Merged-In: Iadd92e1c0c741ad6450a0508fe9e6301bdfe66c5
Change-Id: Iadd92e1c0c741ad6450a0508fe9e6301bdfe66c5
parent 0bc307a5
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -107,12 +107,18 @@ class SubscriptionClient final : public ConnectedClient {
    // Gets the callback to be called when the request for this client has finished.
    std::shared_ptr<const IVehicleHardware::GetValuesCallback> getResultCallback();

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

  protected:
    // Gets the callback to be called when the request for this client has timeout.
+5 −1
Original line number Diff line number Diff line
@@ -247,10 +247,14 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
            const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);

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

    static void onPropertySetErrorEvent(
            const std::weak_ptr<SubscriptionManager>& subscriptionManager,
            const std::vector<SetValueErrorEvent>& errorEvents);

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

+5 −0
Original line number Diff line number Diff line
@@ -103,6 +103,11 @@ class SubscriptionManager final {
    // property has not been subscribed before or is not a continuous property.
    std::optional<float> getSampleRate(const ClientIdType& clientId, int32_t propId,
                                       int32_t areaId);
    // 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.
    std::unordered_map<CallbackType,
                       std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropError>>
    getSubscribedClientsForErrorEvents(const std::vector<SetValueErrorEvent>& errorEvents);

    // Checks whether the sample rate is valid.
    static bool checkSampleRate(float sampleRate);
+30 −1
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropError;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
using ::android::base::Result;
@@ -300,7 +302,34 @@ void SubscriptionClient::sendUpdatedValues(std::shared_ptr<IVehicleCallback> cal
    if (ScopedAStatus callbackStatus =
                callback->onPropertyEvent(vehiclePropValues, sharedMemoryFileCount);
        !callbackStatus.isOk()) {
        ALOGE("subscribe: failed to call UpdateValues callback, client ID: %p, error: %s, "
        ALOGE("subscribe: failed to call onPropertyEvent callback, client ID: %p, error: %s, "
              "exception: %d, service specific error: %d",
              callback->asBinder().get(), callbackStatus.getMessage(),
              callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
    }
}

void SubscriptionClient::sendPropertySetErrors(std::shared_ptr<IVehicleCallback> callback,
                                               std::vector<VehiclePropError>&& vehiclePropErrors) {
    if (vehiclePropErrors.empty()) {
        return;
    }

    VehiclePropErrors vehiclePropErrorsLargeParcelable;
    ScopedAStatus status = vectorToStableLargeParcelable(std::move(vehiclePropErrors),
                                                         &vehiclePropErrorsLargeParcelable);
    if (!status.isOk()) {
        int statusCode = status.getServiceSpecificError();
        ALOGE("subscribe: failed to marshal result into large parcelable, error: "
              "%s, code: %d",
              status.getMessage(), statusCode);
        return;
    }

    if (ScopedAStatus callbackStatus =
                callback->onPropertySetError(vehiclePropErrorsLargeParcelable);
        !callbackStatus.isOk()) {
        ALOGE("subscribe: failed to call onPropertySetError callback, client ID: %p, error: %s, "
              "exception: %d, service specific error: %d",
              callback->asBinder().get(), callbackStatus.getMessage(),
              callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
+30 −7
Original line number Diff line number Diff line
@@ -156,6 +156,11 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware)
                    [subscriptionManagerCopy](std::vector<VehiclePropValue> updatedValues) {
                        onPropertyChangeEvent(subscriptionManagerCopy, updatedValues);
                    }));
    mVehicleHardware->registerOnPropertySetErrorEvent(
            std::make_unique<IVehicleHardware::PropertySetErrorCallback>(
                    [subscriptionManagerCopy](std::vector<SetValueErrorEvent> errorEvents) {
                        onPropertySetErrorEvent(subscriptionManagerCopy, errorEvents);
                    }));

    // Register heartbeat event.
    mRecurrentAction =
@@ -189,7 +194,7 @@ DefaultVehicleHal::~DefaultVehicleHal() {
}

void DefaultVehicleHal::onPropertyChangeEvent(
        std::weak_ptr<SubscriptionManager> subscriptionManager,
        const std::weak_ptr<SubscriptionManager>& subscriptionManager,
        const std::vector<VehiclePropValue>& updatedValues) {
    auto manager = subscriptionManager.lock();
    if (manager == nullptr) {
@@ -206,6 +211,20 @@ void DefaultVehicleHal::onPropertyChangeEvent(
    }
}

void DefaultVehicleHal::onPropertySetErrorEvent(
        const std::weak_ptr<SubscriptionManager>& subscriptionManager,
        const std::vector<SetValueErrorEvent>& errorEvents) {
    auto manager = subscriptionManager.lock();
    if (manager == nullptr) {
        ALOGW("the SubscriptionManager is destroyed, DefaultVehicleHal is ending");
        return;
    }
    auto vehiclePropErrorsByClient = manager->getSubscribedClientsForErrorEvents(errorEvents);
    for (auto& [callback, vehiclePropErrors] : vehiclePropErrorsByClient) {
        SubscriptionClient::sendPropertySetErrors(callback, std::move(vehiclePropErrors));
    }
}

template <class T>
std::shared_ptr<T> DefaultVehicleHal::getOrCreateClient(
        std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
@@ -669,15 +688,19 @@ ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
        // Create a new SubscriptionClient if there isn't an existing one.
        mSubscriptionClients->maybeAddClient(callback);

        // Since we have already check the sample rates, the following functions must succeed.
        if (!onChangeSubscriptions.empty()) {
            return toScopedAStatus(mSubscriptionManager->subscribe(callback, onChangeSubscriptions,
                                                                   /*isContinuousProperty=*/false));
            auto result = mSubscriptionManager->subscribe(callback, onChangeSubscriptions,
                                                          /*isContinuousProperty=*/false);
            if (!result.ok()) {
                return toScopedAStatus(result);
            }
        }
        if (!continuousSubscriptions.empty()) {
            return toScopedAStatus(mSubscriptionManager->subscribe(callback,
                                                                   continuousSubscriptions,
                                                                   /*isContinuousProperty=*/true));
            auto result = mSubscriptionManager->subscribe(callback, continuousSubscriptions,
                                                          /*isContinuousProperty=*/true);
            if (!result.ok()) {
                return toScopedAStatus(result);
            }
        }
    }
    return ScopedAStatus::ok();
Loading