mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Use IBinder to identify callbacks in VHAL" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2e25e562fa
@@ -78,6 +78,8 @@ struct HalClientValues {
|
||||
std::list<VehiclePropValue *> values;
|
||||
};
|
||||
|
||||
using ClientId = uint64_t;
|
||||
|
||||
class SubscriptionManager {
|
||||
public:
|
||||
using OnPropertyUnsubscribed = std::function<void(int32_t)>;
|
||||
@@ -100,7 +102,8 @@ public:
|
||||
* Updates subscription. Returns the vector of properties subscription that
|
||||
* 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,
|
||||
std::list<SubscribeOptions>* outUpdatedOptions);
|
||||
|
||||
@@ -119,7 +122,7 @@ public:
|
||||
* If there are no clients subscribed to given properties than callback function provided
|
||||
* in the constructor will be called.
|
||||
*/
|
||||
void unsubscribe(const sp<IVehicleCallback>& callback, int32_t propId);
|
||||
void unsubscribe(ClientId clientId, int32_t propId);
|
||||
private:
|
||||
std::list<sp<HalClient>> getSubscribedClientsLocked(int32_t propId,
|
||||
int32_t area,
|
||||
@@ -131,7 +134,8 @@ private:
|
||||
|
||||
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);
|
||||
|
||||
@@ -160,7 +164,7 @@ private:
|
||||
|
||||
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, SubscribeOptions> mHalEventSubscribeOptions;
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ private:
|
||||
static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
|
||||
static float checkSampleRate(const VehiclePropConfig& config,
|
||||
float sampleRate);
|
||||
static ClientId getClientId(const sp<IVehicleCallback>& callback);
|
||||
private:
|
||||
VehicleHal* mHal;
|
||||
std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
|
||||
|
||||
@@ -97,6 +97,7 @@ std::vector<int32_t> HalClient::getSubscribedProperties() const {
|
||||
}
|
||||
|
||||
StatusCode SubscriptionManager::addOrUpdateSubscription(
|
||||
ClientId clientId,
|
||||
const sp<IVehicleCallback> &callback,
|
||||
const hidl_vec<SubscribeOptions> &optionList,
|
||||
std::list<SubscribeOptions>* outUpdatedSubscriptions) {
|
||||
@@ -106,7 +107,7 @@ StatusCode SubscriptionManager::addOrUpdateSubscription(
|
||||
|
||||
ALOGI("SubscriptionManager::addOrUpdateSubscription, callback: %p", callback.get());
|
||||
|
||||
const sp<HalClient>& client = getOrCreateHalClientLocked(callback);
|
||||
const sp<HalClient>& client = getOrCreateHalClientLocked(clientId, callback);
|
||||
if (client.get() == nullptr) {
|
||||
return StatusCode::INTERNAL_ERROR;
|
||||
}
|
||||
@@ -221,10 +222,11 @@ sp<HalClientVector> SubscriptionManager::getClientsForPropertyLocked(
|
||||
}
|
||||
|
||||
sp<HalClient> SubscriptionManager::getOrCreateHalClientLocked(
|
||||
const sp<IVehicleCallback>& callback) {
|
||||
auto it = mClients.find(callback);
|
||||
ClientId clientId, const sp<IVehicleCallback>& callback) {
|
||||
auto it = mClients.find(clientId);
|
||||
|
||||
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);
|
||||
auto res = callback->linkToDeath(mCallbackDeathRecipient, cookie);
|
||||
if (!res.isOk()) { // Client is already dead?
|
||||
@@ -234,18 +236,18 @@ sp<HalClient> SubscriptionManager::getOrCreateHalClientLocked(
|
||||
}
|
||||
|
||||
sp<HalClient> client = new HalClient(callback);
|
||||
mClients.emplace(callback, client);
|
||||
mClients.insert({clientId, client});
|
||||
return client;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void SubscriptionManager::unsubscribe(const sp<IVehicleCallback>& callback,
|
||||
void SubscriptionManager::unsubscribe(ClientId clientId,
|
||||
int32_t propId) {
|
||||
MuxGuard g(mLock);
|
||||
auto propertyClients = getClientsForPropertyLocked(propId);
|
||||
auto clientIter = mClients.find(callback);
|
||||
auto clientIter = mClients.find(clientId);
|
||||
if (clientIter == mClients.end()) {
|
||||
ALOGW("Unable to unsubscribe: no callback found, propId: 0x%x", propId);
|
||||
} else {
|
||||
@@ -285,12 +287,12 @@ void SubscriptionManager::unsubscribe(const sp<IVehicleCallback>& callback,
|
||||
|
||||
void SubscriptionManager::onCallbackDead(uint64_t cookie) {
|
||||
ALOGI("%s, cookie: 0x%" PRIx64, __func__, cookie);
|
||||
IVehicleCallback* callback = reinterpret_cast<IVehicleCallback*>(cookie);
|
||||
ClientId clientId = cookie;
|
||||
|
||||
std::vector<int32_t> props;
|
||||
{
|
||||
MuxGuard g(mLock);
|
||||
const auto& it = mClients.find(callback);
|
||||
const auto& it = mClients.find(clientId);
|
||||
if (it == mClients.end()) {
|
||||
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) {
|
||||
unsubscribe(callback, propId);
|
||||
unsubscribe(clientId, propId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <fstream>
|
||||
|
||||
#include <android/log.h>
|
||||
#include <android/hardware/automotive/vehicle/2.0/BpHwVehicleCallback.h>
|
||||
|
||||
#include "VehicleUtils.h"
|
||||
|
||||
@@ -154,7 +155,8 @@ Return<StatusCode> VehicleHalManager::subscribe(const sp<IVehicleCallback> &call
|
||||
}
|
||||
|
||||
std::list<SubscribeOptions> updatedOptions;
|
||||
auto res = mSubscriptionManager.addOrUpdateSubscription(callback, verifiedOptions,
|
||||
auto res = mSubscriptionManager.addOrUpdateSubscription(getClientId(callback),
|
||||
callback, verifiedOptions,
|
||||
&updatedOptions);
|
||||
if (StatusCode::OK != 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,
|
||||
int32_t propId) {
|
||||
mSubscriptionManager.unsubscribe(callback, propId);
|
||||
mSubscriptionManager.unsubscribe(getClientId(callback), propId);
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
@@ -341,6 +343,18 @@ void VehicleHalManager::onAllClientsUnsubscribed(int32_t 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 vehicle
|
||||
} // namespace automotive
|
||||
|
||||
@@ -119,8 +119,10 @@ private:
|
||||
|
||||
TEST_F(SubscriptionManagerTest, multipleClients) {
|
||||
std::list<SubscribeOptions> updatedOptions;
|
||||
ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
|
||||
ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb2, subscrToProp1, &updatedOptions));
|
||||
ASSERT_EQ(StatusCode::OK,
|
||||
manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
|
||||
ASSERT_EQ(StatusCode::OK,
|
||||
manager.addOrUpdateSubscription(2, cb2, subscrToProp1, &updatedOptions));
|
||||
|
||||
auto clients = manager.getSubscribedClients(
|
||||
PROP1,
|
||||
@@ -132,7 +134,8 @@ TEST_F(SubscriptionManagerTest, multipleClients) {
|
||||
|
||||
TEST_F(SubscriptionManagerTest, negativeCases) {
|
||||
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
|
||||
auto clients = manager.getSubscribedClients(
|
||||
@@ -158,7 +161,8 @@ TEST_F(SubscriptionManagerTest, negativeCases) {
|
||||
|
||||
TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
|
||||
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(
|
||||
PROP1,
|
||||
@@ -169,7 +173,7 @@ TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
|
||||
|
||||
// Same property, but different zone, to make sure we didn't unsubscribe
|
||||
// from previous zone.
|
||||
ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, {
|
||||
ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(1, cb1, {
|
||||
SubscribeOptions {
|
||||
.propId = PROP1,
|
||||
.vehicleAreas = toInt(VehicleAreaZone::ROW_2),
|
||||
@@ -190,15 +194,17 @@ TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
|
||||
|
||||
TEST_F(SubscriptionManagerTest, unsubscribe) {
|
||||
std::list<SubscribeOptions> updatedOptions;
|
||||
ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb1, subscrToProp1, &updatedOptions));
|
||||
ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb2, subscrToProp2, &updatedOptions));
|
||||
ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(cb3, subscrToProp1and2,
|
||||
&updatedOptions));
|
||||
ASSERT_EQ(StatusCode::OK,
|
||||
manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
|
||||
ASSERT_EQ(StatusCode::OK,
|
||||
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()));
|
||||
|
||||
manager.unsubscribe(cb1, PROP1);
|
||||
manager.unsubscribe(1, PROP1);
|
||||
assertOnPropertyUnsubscribedNotCalled();
|
||||
ASSERT_ALL_EXISTS({cb3}, extractCallbacks(clientsToProp1()));
|
||||
|
||||
@@ -206,20 +212,20 @@ TEST_F(SubscriptionManagerTest, unsubscribe) {
|
||||
ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
|
||||
|
||||
// No one subscribed to PROP1, subscription for PROP2 is not affected.
|
||||
manager.unsubscribe(cb3, PROP1);
|
||||
manager.unsubscribe(3, PROP1);
|
||||
assertLastUnsubscribedProperty(PROP1);
|
||||
ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
|
||||
|
||||
manager.unsubscribe(cb3, PROP2);
|
||||
manager.unsubscribe(3, PROP2);
|
||||
assertOnPropertyUnsubscribedNotCalled();
|
||||
ASSERT_ALL_EXISTS({cb2}, extractCallbacks(clientsToProp2()));
|
||||
|
||||
// The last client unsubscribed from this property.
|
||||
manager.unsubscribe(cb2, PROP2);
|
||||
manager.unsubscribe(2, PROP2);
|
||||
assertLastUnsubscribedProperty(PROP2);
|
||||
|
||||
// No one subscribed anymore
|
||||
manager.unsubscribe(cb1, PROP1);
|
||||
manager.unsubscribe(1, PROP1);
|
||||
assertLastUnsubscribedProperty(PROP1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user