Fix resource mgmt bug in SubscriptionManager.
The subscription information map is not correctly cleared during
unsubscription.
Flag: EXEMPT HAL
Test: atest DefaultVehicleHalTest SubscriptionManagerTest
Bug: 38256329
Change-Id: I78968aec54eda291932a34e5ef6c3f3d0e194295
diff --git a/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
index 42902fe..d360be0 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
@@ -219,7 +219,7 @@
// mBinderEvents.
void onBinderDiedUnlinkedHandler();
- size_t countSubscribeClients();
+ size_t countClients();
// Handles the property change events in batch.
void handleBatchedPropertyEvents(std::vector<aidlvhal::VehiclePropValue>&& batchedEvents);
diff --git a/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h b/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
index fa438ec..f4e6ced 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
+++ b/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
@@ -146,6 +146,7 @@
private:
// Friend class for testing.
friend class DefaultVehicleHalTest;
+ friend class SubscriptionManagerTest;
IVehicleHardware* mVehicleHardware;
diff --git a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
index 050f88d..ea0c215 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
@@ -1336,15 +1336,19 @@
dprintf(fd, "Containing %zu property configs\n", configsByPropIdCopy.size());
dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
- dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients());
+ dprintf(fd, "Currently have %zu subscribe clients\n",
+ mSubscriptionManager->countPropertyChangeClients());
dprintf(fd, "Currently have %zu supported values change subscribe clients\n",
mSubscriptionManager->countSupportedValueChangeClients());
}
return STATUS_OK;
}
-size_t DefaultVehicleHal::countSubscribeClients() {
- return mSubscriptionManager->countPropertyChangeClients();
+size_t DefaultVehicleHal::countClients() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return mGetValuesClients.size() + mSetValuesClients.size() +
+ mSubscriptionManager->countPropertyChangeClients() +
+ mSubscriptionManager->countSupportedValueChangeClients();
}
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
index 946c217..64c46c9 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
@@ -414,7 +414,6 @@
std::scoped_lock<std::mutex> lockGuard(mLock);
ClientIdType clientId = callback->asBinder().get();
- ALOGE("ClientId: %p", clientId);
// It is possible that some of the [propId, areaId]s are already subscribed, IVehicleHardware
// will ignore them.
@@ -479,7 +478,7 @@
mSupportedValueChangeClientsByPropIdAreaId.end()) {
mSupportedValueChangeClientsByPropIdAreaId[propIdAreaId].erase(clientId);
}
- if (mSupportedValueChangeClientsByPropIdAreaId.empty()) {
+ if (mSupportedValueChangeClientsByPropIdAreaId[propIdAreaId].empty()) {
mSupportedValueChangeClientsByPropIdAreaId.erase(propIdAreaId);
}
mSupportedValueChangePropIdAreaIdsByClient[clientId].erase(propIdAreaId);
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
index 90b34c4..ab5f667 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
@@ -445,11 +445,7 @@
size_t countPendingRequests() { return mVhal->mPendingRequestPool->countPendingRequests(); }
- size_t countClients() {
- std::scoped_lock<std::mutex> lockGuard(mVhal->mLock);
- return mVhal->mGetValuesClients.size() + mVhal->mSetValuesClients.size() +
- mVhal->countSubscribeClients();
- }
+ size_t countClients() { return mVhal->countClients(); }
std::shared_ptr<PendingRequestPool> getPool() { return mVhal->mPendingRequestPool; }
@@ -2575,8 +2571,10 @@
ASSERT_TRUE(status.isOk()) << "Get non-okay status from unregisterSupportedValueChangeCallback"
<< status.getMessage();
- ASSERT_TRUE(getHardware()->getSubscribedSupportedValueChangePropIdAreaIds().empty())
+ EXPECT_TRUE(getHardware()->getSubscribedSupportedValueChangePropIdAreaIds().empty())
<< "All registered [propId, areaId]s must be unregistered";
+ EXPECT_EQ(countClients(), static_cast<size_t>(0)) << "subscribe clients must be cleared";
+ EXPECT_TRUE(hasNoSubscriptions()) << "subscribe clients must be cleared";
}
TEST_F(DefaultVehicleHalTest, testUnregisterSupportedValueChangeCallback_errorFromHardware) {
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
index 6d0844a..d624cce 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
@@ -124,6 +124,8 @@
std::shared_ptr<MockVehicleHardware> getHardware() { return mHardware; }
+ bool isEmpty() { return mManager->isEmpty(); }
+
private:
std::unique_ptr<SubscriptionManager> mManager;
std::shared_ptr<PropertyCallback> mCallback;
@@ -946,6 +948,19 @@
<< "Incorrect supported value change events for client1";
ASSERT_THAT(clients[client2], UnorderedElementsAre(propIdAreaId2))
<< "Incorrect supported value change events for client2";
+
+ result = getManager()->unsubscribeSupportedValueChange(binder2.get(), {propIdAreaId2});
+
+ ASSERT_TRUE(result.ok()) << "failed to call unsubscribeSupportedValueChange"
+ << result.error().message();
+
+ result = getManager()->unsubscribeSupportedValueChange(binder1.get(), {propIdAreaId1});
+
+ ASSERT_TRUE(result.ok()) << "failed to call unsubscribeSupportedValueChange"
+ << result.error().message();
+
+ EXPECT_EQ(getManager()->countSupportedValueChangeClients(), 0u) << "All clients cleared";
+ EXPECT_TRUE(isEmpty()) << "All clients cleared";
}
} // namespace vehicle