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

Commit decc02b6 authored by Pavel Maltsev's avatar Pavel Maltsev Committed by android-build-merger
Browse files

Merge "Use IBinder to identify callbacks in VHAL" into oc-dev am: 2e25e562

am: 84163bc3

Change-Id: Ifa921d812d63f2833e015201e8a1d111383b10ef
parents d49bb43c 84163bc3
Loading
Loading
Loading
Loading
+8 −4
Original line number Original line Diff line number Diff line
@@ -78,6 +78,8 @@ struct HalClientValues {
    std::list<VehiclePropValue *> values;
    std::list<VehiclePropValue *> values;
};
};


using ClientId = uint64_t;

class SubscriptionManager {
class SubscriptionManager {
public:
public:
    using OnPropertyUnsubscribed = std::function<void(int32_t)>;
    using OnPropertyUnsubscribed = std::function<void(int32_t)>;
@@ -100,7 +102,8 @@ public:
     * Updates subscription. Returns the vector of properties subscription that
     * Updates subscription. Returns the vector of properties subscription that
     * needs to be updated in VehicleHAL.
     * needs to be updated in VehicleHAL.
     */
     */
    StatusCode addOrUpdateSubscription(const sp<IVehicleCallback>& callback,
    StatusCode addOrUpdateSubscription(ClientId clientId,
                                       const sp<IVehicleCallback>& callback,
                                       const hidl_vec<SubscribeOptions>& optionList,
                                       const hidl_vec<SubscribeOptions>& optionList,
                                       std::list<SubscribeOptions>* outUpdatedOptions);
                                       std::list<SubscribeOptions>* outUpdatedOptions);


@@ -119,7 +122,7 @@ public:
     * If there are no clients subscribed to given properties than callback function provided
     * If there are no clients subscribed to given properties than callback function provided
     * in the constructor will be called.
     * in the constructor will be called.
     */
     */
    void unsubscribe(const sp<IVehicleCallback>& callback, int32_t propId);
    void unsubscribe(ClientId clientId, int32_t propId);
private:
private:
    std::list<sp<HalClient>> getSubscribedClientsLocked(int32_t propId,
    std::list<sp<HalClient>> getSubscribedClientsLocked(int32_t propId,
                                                        int32_t area,
                                                        int32_t area,
@@ -131,7 +134,8 @@ private:


    sp<HalClientVector> getClientsForPropertyLocked(int32_t propId) const;
    sp<HalClientVector> getClientsForPropertyLocked(int32_t propId) const;


    sp<HalClient> getOrCreateHalClientLocked(const sp<IVehicleCallback> &callback);
    sp<HalClient> getOrCreateHalClientLocked(ClientId callingPid,
                                             const sp<IVehicleCallback>& callback);


    void onCallbackDead(uint64_t cookie);
    void onCallbackDead(uint64_t cookie);


@@ -160,7 +164,7 @@ private:


    mutable std::mutex mLock;
    mutable std::mutex mLock;


    std::map<sp<IVehicleCallback>, sp<HalClient>> mClients;
    std::map<ClientId, sp<HalClient>> mClients;
    std::map<int32_t, sp<HalClientVector>> mPropToClients;
    std::map<int32_t, sp<HalClientVector>> mPropToClients;
    std::map<int32_t, SubscribeOptions> mHalEventSubscribeOptions;
    std::map<int32_t, SubscribeOptions> mHalEventSubscribeOptions;


+1 −0
Original line number Original line Diff line number Diff line
@@ -101,6 +101,7 @@ private:
    static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
    static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
    static float checkSampleRate(const VehiclePropConfig& config,
    static float checkSampleRate(const VehiclePropConfig& config,
                                 float sampleRate);
                                 float sampleRate);
    static ClientId getClientId(const sp<IVehicleCallback>& callback);
private:
private:
    VehicleHal* mHal;
    VehicleHal* mHal;
    std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
    std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
+12 −10
Original line number Original line Diff line number Diff line
@@ -97,6 +97,7 @@ std::vector<int32_t> HalClient::getSubscribedProperties() const {
}
}


StatusCode SubscriptionManager::addOrUpdateSubscription(
StatusCode SubscriptionManager::addOrUpdateSubscription(
        ClientId clientId,
        const sp<IVehicleCallback> &callback,
        const sp<IVehicleCallback> &callback,
        const hidl_vec<SubscribeOptions> &optionList,
        const hidl_vec<SubscribeOptions> &optionList,
        std::list<SubscribeOptions>* outUpdatedSubscriptions) {
        std::list<SubscribeOptions>* outUpdatedSubscriptions) {
@@ -106,7 +107,7 @@ StatusCode SubscriptionManager::addOrUpdateSubscription(


    ALOGI("SubscriptionManager::addOrUpdateSubscription, callback: %p", callback.get());
    ALOGI("SubscriptionManager::addOrUpdateSubscription, callback: %p", callback.get());


    const sp<HalClient>& client = getOrCreateHalClientLocked(callback);
    const sp<HalClient>& client = getOrCreateHalClientLocked(clientId, callback);
    if (client.get() == nullptr) {
    if (client.get() == nullptr) {
        return StatusCode::INTERNAL_ERROR;
        return StatusCode::INTERNAL_ERROR;
    }
    }
@@ -221,10 +222,11 @@ sp<HalClientVector> SubscriptionManager::getClientsForPropertyLocked(
}
}


sp<HalClient> SubscriptionManager::getOrCreateHalClientLocked(
sp<HalClient> SubscriptionManager::getOrCreateHalClientLocked(
        const sp<IVehicleCallback>& callback) {
        ClientId clientId, const sp<IVehicleCallback>& callback) {
    auto it = mClients.find(callback);
    auto it = mClients.find(clientId);

    if (it == mClients.end()) {
    if (it == mClients.end()) {
        uint64_t cookie = reinterpret_cast<uint64_t>(callback.get());
        uint64_t cookie = reinterpret_cast<uint64_t>(clientId);
        ALOGI("Creating new client and linking to death recipient, cookie: 0x%" PRIx64, cookie);
        ALOGI("Creating new client and linking to death recipient, cookie: 0x%" PRIx64, cookie);
        auto res = callback->linkToDeath(mCallbackDeathRecipient, cookie);
        auto res = callback->linkToDeath(mCallbackDeathRecipient, cookie);
        if (!res.isOk()) {  // Client is already dead?
        if (!res.isOk()) {  // Client is already dead?
@@ -234,18 +236,18 @@ sp<HalClient> SubscriptionManager::getOrCreateHalClientLocked(
        }
        }


        sp<HalClient> client = new HalClient(callback);
        sp<HalClient> client = new HalClient(callback);
        mClients.emplace(callback, client);
        mClients.insert({clientId, client});
        return client;
        return client;
    } else {
    } else {
        return it->second;
        return it->second;
    }
    }
}
}


void SubscriptionManager::unsubscribe(const sp<IVehicleCallback>& callback,
void SubscriptionManager::unsubscribe(ClientId clientId,
                                      int32_t propId) {
                                      int32_t propId) {
    MuxGuard g(mLock);
    MuxGuard g(mLock);
    auto propertyClients = getClientsForPropertyLocked(propId);
    auto propertyClients = getClientsForPropertyLocked(propId);
    auto clientIter = mClients.find(callback);
    auto clientIter = mClients.find(clientId);
    if (clientIter == mClients.end()) {
    if (clientIter == mClients.end()) {
        ALOGW("Unable to unsubscribe: no callback found, propId: 0x%x", propId);
        ALOGW("Unable to unsubscribe: no callback found, propId: 0x%x", propId);
    } else {
    } else {
@@ -285,12 +287,12 @@ void SubscriptionManager::unsubscribe(const sp<IVehicleCallback>& callback,


void SubscriptionManager::onCallbackDead(uint64_t cookie) {
void SubscriptionManager::onCallbackDead(uint64_t cookie) {
    ALOGI("%s, cookie: 0x%" PRIx64, __func__, cookie);
    ALOGI("%s, cookie: 0x%" PRIx64, __func__, cookie);
    IVehicleCallback* callback = reinterpret_cast<IVehicleCallback*>(cookie);
    ClientId clientId = cookie;


    std::vector<int32_t> props;
    std::vector<int32_t> props;
    {
    {
        MuxGuard g(mLock);
        MuxGuard g(mLock);
        const auto& it = mClients.find(callback);
        const auto& it = mClients.find(clientId);
        if (it == mClients.end()) {
        if (it == mClients.end()) {
            return;  // Nothing to do here, client wasn't subscribed to any properties.
            return;  // Nothing to do here, client wasn't subscribed to any properties.
        }
        }
@@ -299,7 +301,7 @@ void SubscriptionManager::onCallbackDead(uint64_t cookie) {
    }
    }


    for (int32_t propId : props) {
    for (int32_t propId : props) {
        unsubscribe(callback, propId);
        unsubscribe(clientId, propId);
    }
    }
}
}


+16 −2
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@
#include <fstream>
#include <fstream>


#include <android/log.h>
#include <android/log.h>
#include <android/hardware/automotive/vehicle/2.0/BpHwVehicleCallback.h>


#include "VehicleUtils.h"
#include "VehicleUtils.h"


@@ -154,7 +155,8 @@ Return<StatusCode> VehicleHalManager::subscribe(const sp<IVehicleCallback> &call
    }
    }


    std::list<SubscribeOptions> updatedOptions;
    std::list<SubscribeOptions> updatedOptions;
    auto res = mSubscriptionManager.addOrUpdateSubscription(callback, verifiedOptions,
    auto res = mSubscriptionManager.addOrUpdateSubscription(getClientId(callback),
                                                            callback, verifiedOptions,
                                                            &updatedOptions);
                                                            &updatedOptions);
    if (StatusCode::OK != res) {
    if (StatusCode::OK != res) {
        ALOGW("%s failed to subscribe, error code: %d", __func__, res);
        ALOGW("%s failed to subscribe, error code: %d", __func__, res);
@@ -170,7 +172,7 @@ Return<StatusCode> VehicleHalManager::subscribe(const sp<IVehicleCallback> &call


Return<StatusCode> VehicleHalManager::unsubscribe(const sp<IVehicleCallback>& callback,
Return<StatusCode> VehicleHalManager::unsubscribe(const sp<IVehicleCallback>& callback,
                                                  int32_t propId) {
                                                  int32_t propId) {
    mSubscriptionManager.unsubscribe(callback, propId);
    mSubscriptionManager.unsubscribe(getClientId(callback), propId);
    return StatusCode::OK;
    return StatusCode::OK;
}
}


@@ -341,6 +343,18 @@ void VehicleHalManager::onAllClientsUnsubscribed(int32_t propertyId) {
    mHal->unsubscribe(propertyId);
    mHal->unsubscribe(propertyId);
}
}


ClientId VehicleHalManager::getClientId(const sp<IVehicleCallback>& callback) {
    //TODO(b/32172906): rework this to get some kind of unique id for callback interface when this
    // feature is ready in HIDL.

    if (callback->isRemote()) {
        BpHwVehicleCallback* hwCallback = static_cast<BpHwVehicleCallback*>(callback.get());
        return static_cast<ClientId>(reinterpret_cast<intptr_t>(hwCallback->onAsBinder()));
    } else {
        return static_cast<ClientId>(reinterpret_cast<intptr_t>(callback.get()));
    }
}

}  // namespace V2_0
}  // namespace V2_0
}  // namespace vehicle
}  // namespace vehicle
}  // namespace automotive
}  // namespace automotive
+22 −16
Original line number Original line Diff line number Diff line
@@ -119,8 +119,10 @@ private:


TEST_F(SubscriptionManagerTest, multipleClients) {
TEST_F(SubscriptionManagerTest, multipleClients) {
    std::list<SubscribeOptions> updatedOptions;
    std::list<SubscribeOptions> updatedOptions;
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
    ASSERT_EQ(StatusCode::OK,
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb2, subscrToProp1, &updatedOptions));
              manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
    ASSERT_EQ(StatusCode::OK,
              manager.addOrUpdateSubscription(2, cb2, subscrToProp1, &updatedOptions));


    auto clients = manager.getSubscribedClients(
    auto clients = manager.getSubscribedClients(
            PROP1,
            PROP1,
@@ -132,7 +134,8 @@ TEST_F(SubscriptionManagerTest, multipleClients) {


TEST_F(SubscriptionManagerTest, negativeCases) {
TEST_F(SubscriptionManagerTest, negativeCases) {
    std::list<SubscribeOptions> updatedOptions;
    std::list<SubscribeOptions> updatedOptions;
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
    ASSERT_EQ(StatusCode::OK,
              manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));


    // Wrong zone
    // Wrong zone
    auto clients = manager.getSubscribedClients(
    auto clients = manager.getSubscribedClients(
@@ -158,7 +161,8 @@ TEST_F(SubscriptionManagerTest, negativeCases) {


TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
    std::list<SubscribeOptions> updatedOptions;
    std::list<SubscribeOptions> updatedOptions;
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(1, cb1, subscrToProp1,
                                                              &updatedOptions));


    auto clients = manager.getSubscribedClients(
    auto clients = manager.getSubscribedClients(
            PROP1,
            PROP1,
@@ -169,7 +173,7 @@ TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {


    // Same property, but different zone, to make sure we didn't unsubscribe
    // Same property, but different zone, to make sure we didn't unsubscribe
    // from previous zone.
    // from previous zone.
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, {
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(1, cb1, {
        SubscribeOptions {
        SubscribeOptions {
                .propId = PROP1,
                .propId = PROP1,
                .vehicleAreas = toInt(VehicleAreaZone::ROW_2),
                .vehicleAreas = toInt(VehicleAreaZone::ROW_2),
@@ -190,15 +194,17 @@ TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {


TEST_F(SubscriptionManagerTest, unsubscribe) {
TEST_F(SubscriptionManagerTest, unsubscribe) {
    std::list<SubscribeOptions> updatedOptions;
    std::list<SubscribeOptions> updatedOptions;
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
    ASSERT_EQ(StatusCode::OK,
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb2, subscrToProp2, &updatedOptions));
              manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
    ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb3, subscrToProp1and2,
    ASSERT_EQ(StatusCode::OK,
                                                              &updatedOptions));
              manager.addOrUpdateSubscription(2, cb2, subscrToProp2, &updatedOptions));
    ASSERT_EQ(StatusCode::OK,
              manager.addOrUpdateSubscription(3, cb3, subscrToProp1and2, &updatedOptions));


    ASSERT_ALL_EXISTS({ cb1, cb3 }, extractCallbacks(clientsToProp1()));
    ASSERT_ALL_EXISTS({ cb1, cb3 }, extractCallbacks(clientsToProp1()));
    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));


    manager.unsubscribe(cb1, PROP1);
    manager.unsubscribe(1, PROP1);
    assertOnPropertyUnsubscribedNotCalled();
    assertOnPropertyUnsubscribedNotCalled();
    ASSERT_ALL_EXISTS({cb3}, extractCallbacks(clientsToProp1()));
    ASSERT_ALL_EXISTS({cb3}, extractCallbacks(clientsToProp1()));


@@ -206,20 +212,20 @@ TEST_F(SubscriptionManagerTest, unsubscribe) {
    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));


    // No one subscribed to PROP1, subscription for PROP2 is not affected.
    // No one subscribed to PROP1, subscription for PROP2 is not affected.
    manager.unsubscribe(cb3, PROP1);
    manager.unsubscribe(3, PROP1);
    assertLastUnsubscribedProperty(PROP1);
    assertLastUnsubscribedProperty(PROP1);
    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));


    manager.unsubscribe(cb3, PROP2);
    manager.unsubscribe(3, PROP2);
    assertOnPropertyUnsubscribedNotCalled();
    assertOnPropertyUnsubscribedNotCalled();
    ASSERT_ALL_EXISTS({cb2}, extractCallbacks(clientsToProp2()));
    ASSERT_ALL_EXISTS({cb2}, extractCallbacks(clientsToProp2()));


    // The last client unsubscribed from this property.
    // The last client unsubscribed from this property.
    manager.unsubscribe(cb2, PROP2);
    manager.unsubscribe(2, PROP2);
    assertLastUnsubscribedProperty(PROP2);
    assertLastUnsubscribedProperty(PROP2);


    // No one subscribed anymore
    // No one subscribed anymore
    manager.unsubscribe(cb1, PROP1);
    manager.unsubscribe(1, PROP1);
    assertLastUnsubscribedProperty(PROP1);
    assertLastUnsubscribedProperty(PROP1);
}
}