Add binder lifecycle monitor.
Add binder lifecycle monitor for registerSupportedValueChange. If
the client binder dies, we need to call unregister for the client
and clear stored information.
Flag: EXEMPT hal
Test: atest DefaultVehicleHalTest
Bug: 377348572
Change-Id: I7271a609c7eb4cae98eb5fc684d1212ffc921db9
diff --git a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
index 012a430..050f88d 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
@@ -953,7 +953,9 @@
}
{
- // Lock to make sure onBinderDied would not be called concurrently.
+ // Lock to make sure onBinderDied would not be called concurrently
+ // (before subscribe). Without this, we may create a new subscription for an already dead
+ // client which will never be unsubscribed.
std::scoped_lock lockGuard(mLock);
if (!monitorBinderLifeCycleLocked(callback->asBinder().get())) {
return ScopedAStatus::fromExceptionCodeWithMessage(EX_TRANSACTION_FAILED,
@@ -1178,14 +1180,24 @@
if (propIdAreaIdsToSubscribe.empty()) {
return ScopedAStatus::ok();
}
- auto result =
- mSubscriptionManager->subscribeSupportedValueChange(callback, propIdAreaIdsToSubscribe);
- if (!result.ok()) {
- ALOGW("registerSupportedValueChangeCallback: failed to subscribe supported value change"
- " for %s, error: %s",
- fmt::format("{}", propIdAreaIdsToSubscribe).c_str(),
- result.error().message().c_str());
- return toScopedAStatus(result);
+ {
+ // Lock to make sure onBinderDied would not be called concurrently
+ // (before subscribeSupportedValueChange). Without this, we may create a new subscription
+ // for an already dead client which will never be unsubscribed.
+ std::scoped_lock lockGuard(mLock);
+ if (!monitorBinderLifeCycleLocked(callback->asBinder().get())) {
+ return ScopedAStatus::fromExceptionCodeWithMessage(EX_TRANSACTION_FAILED,
+ "client died");
+ }
+ auto result = mSubscriptionManager->subscribeSupportedValueChange(callback,
+ propIdAreaIdsToSubscribe);
+ if (!result.ok()) {
+ ALOGW("registerSupportedValueChangeCallback: failed to subscribe supported value change"
+ " for %s, error: %s",
+ fmt::format("{}", propIdAreaIdsToSubscribe).c_str(),
+ result.error().message().c_str());
+ return toScopedAStatus(result);
+ }
}
return ScopedAStatus::ok();
}
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
index f87e3d7..90b34c4 100644
--- a/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
@@ -272,6 +272,10 @@
void SetUp() override { init(std::make_unique<MockVehicleHardware>()); }
void init(std::unique_ptr<MockVehicleHardware> hardware) {
+ // Default init uses the following static configs to create the mock IVehicleHardware,
+ // individual test case may use setHardware to overwrite the underlying IVehicleHardware
+ // to use a different set of configs.
+
std::vector<VehiclePropConfig> testConfigs;
for (size_t i = 0; i < 10000; i++) {
testConfigs.push_back(VehiclePropConfig{
@@ -420,18 +424,8 @@
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
});
hardware->setPropertyConfigs(testConfigs);
- mHardwarePtr = hardware.get();
- mVhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- mVhalClient = IVehicle::fromBinder(mVhal->asBinder());
- mCallback = ndk::SharedRefBase::make<MockVehicleCallback>();
- // Keep the local binder alive.
- mBinder = mCallback->asBinder();
- mCallbackClient = IVehicleCallback::fromBinder(mBinder);
- // Set the linkToDeath to a fake implementation that always returns OK.
- auto handler = std::make_unique<TestBinderLifecycleHandler>();
- mBinderLifecycleHandler = handler.get();
- mVhal->setBinderLifecycleHandler(std::move(handler));
+ setHardware(std::move(hardware));
}
void TearDown() override {
@@ -548,6 +542,33 @@
return {};
}
+ protected:
+ // Sets the underlying IVehicleHardware and recreates the DefaultVehicleHal objects under test.
+ // If used, caller should call this at the beginning of the test case.
+ void setHardware(std::unique_ptr<MockVehicleHardware> hardware) {
+ setHardware(std::move(hardware), 0);
+ }
+
+ void setHardware(std::unique_ptr<MockVehicleHardware> hardware, int32_t testInterfaceVersion) {
+ mHardwarePtr = hardware.get();
+ if (testInterfaceVersion == 0) {
+ mVhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+ } else {
+ mVhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware),
+ testInterfaceVersion);
+ }
+ // Set the linkToDeath to a fake implementation that always returns OK.
+ auto handler = std::make_unique<TestBinderLifecycleHandler>();
+ mBinderLifecycleHandler = handler.get();
+ mVhal->setBinderLifecycleHandler(std::move(handler));
+
+ mVhalClient = IVehicle::fromBinder(mVhal->asBinder());
+ mCallback = ndk::SharedRefBase::make<MockVehicleCallback>();
+ // Keep the local binder alive.
+ mBinder = mCallback->asBinder();
+ mCallbackClient = IVehicleCallback::fromBinder(mBinder);
+ }
+
private:
class TestBinderLifecycleHandler final : public DefaultVehicleHal::BinderLifecycleInterface {
public:
@@ -588,11 +609,10 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
VehiclePropConfigs output;
- auto status = client->getAllPropConfigs(&output);
+ auto status = getClient()->getAllPropConfigs(&output);
ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
ASSERT_THAT(output.payloads, WhenSortedBy(propConfigCmp, Eq(testConfigs)));
@@ -609,11 +629,10 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
VehiclePropConfigs output;
- auto status = client->getAllPropConfigs(&output);
+ auto status = getClient()->getAllPropConfigs(&output);
ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
ASSERT_TRUE(output.payloads.empty());
@@ -637,12 +656,10 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware),
- /* testInterfaceVersion= */ 2);
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware), /* testInterfaceVersion= */ 2);
VehiclePropConfigs output;
- auto status = client->getAllPropConfigs(&output);
+ auto status = getClient()->getAllPropConfigs(&output);
ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
ASSERT_THAT(output.payloads, ElementsAre(VehiclePropConfig{
@@ -666,15 +683,14 @@
hardware->setPropertyConfigs(testConfigs);
// Store the pointer for testing. We are sure it is valid.
MockVehicleHardware* hardwarePtr = hardware.get();
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
VehiclePropConfigs output;
- auto status = client->getPropConfigs(std::vector<int32_t>({propId1, propId2}), &output);
+ auto status = getClient()->getPropConfigs(std::vector<int32_t>({propId1, propId2}), &output);
ASSERT_TRUE(status.isOk()) << "getPropConfigs failed: " << status.getMessage();
ASSERT_EQ(output.payloads, testConfigs);
- ASSERT_FALSE(hardwarePtr->getAllPropertyConfigsCalled());
+ ASSERT_FALSE(getHardware()->getAllPropertyConfigsCalled());
}
TEST_F(DefaultVehicleHalTest, testGetPropConfigsInvalidArg) {
@@ -689,11 +705,10 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
VehiclePropConfigs output;
- auto status = client->getPropConfigs(
+ auto status = getClient()->getPropConfigs(
std::vector<int32_t>({testInt32VecProp(1), testInt32VecProp(2), testInt32VecProp(3)}),
&output);
@@ -2187,8 +2202,7 @@
auto response = std::vector<SupportedValuesListResult>({resultFromHardware});
hardware->setSupportedValuesListResponse(response);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
SupportedValuesListResults results;
@@ -2196,14 +2210,14 @@
auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
auto propIdAreaId3 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(3), .areaId = 0};
auto propIdAreaId4 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(4), .areaId = 4};
- auto status = vhal->getSupportedValuesLists(
+ auto status = getClient()->getSupportedValuesLists(
std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2, propIdAreaId3,
propIdAreaId4},
&results);
ASSERT_TRUE(status.isOk()) << "Get non-okay status from getSupportedValuesLists"
<< status.getMessage();
- ASSERT_THAT(hardwarePtr->getSupportedValuesListRequest(),
+ ASSERT_THAT(getHardware()->getSupportedValuesListRequest(),
ElementsAre(PropIdAreaId{.propId = testInt32VecWindowProp(4), .areaId = 4}))
<< "Only valid request 4 should get to hardware";
@@ -2250,8 +2264,7 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
SupportedValuesListResults results;
@@ -2260,7 +2273,7 @@
// areaId not valid.
auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(1), .areaId = 2};
- auto status = vhal->getSupportedValuesLists(
+ auto status = getClient()->getSupportedValuesLists(
std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2}, &results);
ASSERT_TRUE(status.isOk()) << "Get non-okay status from getSupportedValuesLists"
@@ -2328,8 +2341,7 @@
auto response = std::vector<MinMaxSupportedValueResult>({resultFromHardware});
hardware->setMinMaxSupportedValueResponse(response);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
MinMaxSupportedValueResults results;
@@ -2337,14 +2349,14 @@
auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
auto propIdAreaId3 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(3), .areaId = 0};
auto propIdAreaId4 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(4), .areaId = 4};
- auto status = vhal->getMinMaxSupportedValue(
+ auto status = getClient()->getMinMaxSupportedValue(
std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2, propIdAreaId3,
propIdAreaId4},
&results);
ASSERT_TRUE(status.isOk()) << "Get non-okay status from getMinMaxSupportedValue"
<< status.getMessage();
- ASSERT_THAT(hardwarePtr->getMinMaxSupportedValueRequest(),
+ ASSERT_THAT(getHardware()->getMinMaxSupportedValueRequest(),
ElementsAre(PropIdAreaId{.propId = testInt32VecWindowProp(4), .areaId = 4}))
<< "Only valid request 4 should get to hardware";
@@ -2396,8 +2408,7 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
MinMaxSupportedValueResults results;
@@ -2406,7 +2417,7 @@
// areaId not valid.
auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(1), .areaId = 2};
- auto status = vhal->getMinMaxSupportedValue(
+ auto status = getClient()->getMinMaxSupportedValue(
std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2}, &results);
ASSERT_TRUE(status.isOk()) << "Get non-okay status from getMinMaxSupportedValue"
@@ -2448,22 +2459,20 @@
}});
auto hardware = std::make_unique<MockVehicleHardware>();
- MockVehicleHardware* hardwarePtr = hardware.get();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
// This request is ignored because it does not have supported value info.
auto propIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from registerSupportedValueChangeCallback"
<< status.getMessage();
ASSERT_THAT(
- hardwarePtr->getSubscribedSupportedValueChangePropIdAreaIds(),
+ getHardware()->getSubscribedSupportedValueChangePropIdAreaIds(),
UnorderedElementsAre(PropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2}));
}
@@ -2478,11 +2487,10 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto propIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId1});
ASSERT_FALSE(status.isOk()) << "registerSupportedValueChangeCallback must return error if one "
@@ -2509,11 +2517,10 @@
hardware->setStatus("subscribeSupportedValueChange", StatusCode::INTERNAL_ERROR);
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto propIdAreaId = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId});
ASSERT_FALSE(status.isOk()) << "registerSupportedValueChangeCallback must return error if "
@@ -2550,27 +2557,25 @@
}});
auto hardware = std::make_unique<MockVehicleHardware>();
- MockVehicleHardware* hardwarePtr = hardware.get();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto propIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from registerSupportedValueChangeCallback"
<< status.getMessage();
- status = client->unregisterSupportedValueChangeCallback(
+ status = getClient()->unregisterSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from unregisterSupportedValueChangeCallback"
<< status.getMessage();
- ASSERT_TRUE(hardwarePtr->getSubscribedSupportedValueChangePropIdAreaIds().empty())
+ ASSERT_TRUE(getHardware()->getSubscribedSupportedValueChangePropIdAreaIds().empty())
<< "All registered [propId, areaId]s must be unregistered";
}
@@ -2591,20 +2596,18 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setStatus("unsubscribeSupportedValueChange", StatusCode::INTERNAL_ERROR);
- MockVehicleHardware* hardwarePtr = hardware.get();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto propIdAreaId = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from registerSupportedValueChangeCallback"
<< status.getMessage();
- status = client->unregisterSupportedValueChangeCallback(
+ status = getClient()->unregisterSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId});
ASSERT_FALSE(status.isOk()) << "unregisterSupportedValueChangeCallback must return error if "
@@ -2641,15 +2644,13 @@
}});
auto hardware = std::make_unique<MockVehicleHardware>();
- MockVehicleHardware* hardwarePtr = hardware.get();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto propIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto propIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
- auto status = client->unregisterSupportedValueChangeCallback(
+ auto status = getClient()->unregisterSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{propIdAreaId1, propIdAreaId2});
ASSERT_TRUE(status.isOk());
@@ -2685,24 +2686,22 @@
}});
auto hardware = std::make_unique<MockVehicleHardware>();
- MockVehicleHardware* hardwarePtr = hardware.get();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto vhalPropIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto vhalPropIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
auto propIdAreaId1 = PropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto propIdAreaId2 = PropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
getCallbackClient(),
std::vector<VhalPropIdAreaId>{vhalPropIdAreaId1, vhalPropIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from registerSupportedValueChangeCallback"
<< status.getMessage();
- hardwarePtr->sendSupportedValueChangeEvent(
+ getHardware()->sendSupportedValueChangeEvent(
std::vector<PropIdAreaId>{propIdAreaId1, propIdAreaId2});
getCallback()->waitForOnSupportedValueChange(/*size=*/2, /*timeoutInNano=*/1'000'000'000);
@@ -2741,17 +2740,15 @@
}});
auto hardware = std::make_unique<MockVehicleHardware>();
- MockVehicleHardware* hardwarePtr = hardware.get();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto vhalPropIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto vhalPropIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
auto propIdAreaId1 = PropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto propIdAreaId2 = PropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
getCallbackClient(),
std::vector<VhalPropIdAreaId>{vhalPropIdAreaId1, vhalPropIdAreaId2});
@@ -2759,13 +2756,13 @@
<< status.getMessage();
// After unregistering for propIdAreaId1, we should no longer receive events for it.
- status = client->unregisterSupportedValueChangeCallback(
+ status = getClient()->unregisterSupportedValueChangeCallback(
getCallbackClient(), std::vector<VhalPropIdAreaId>{vhalPropIdAreaId1});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from unregisterSupportedValueChangeCallback"
<< status.getMessage();
- hardwarePtr->sendSupportedValueChangeEvent(
+ getHardware()->sendSupportedValueChangeEvent(
std::vector<PropIdAreaId>{propIdAreaId1, propIdAreaId2});
getCallback()->waitForOnSupportedValueChange(/*size=*/1, /*timeoutInNano=*/1'000'000'000);
@@ -2804,11 +2801,9 @@
}});
auto hardware = std::make_unique<MockVehicleHardware>();
- MockVehicleHardware* hardwarePtr = hardware.get();
hardware->setPropertyConfigs(testConfigs);
- auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
- std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+ setHardware(std::move(hardware));
auto vhalPropIdAreaId1 = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
auto vhalPropIdAreaId2 = VhalPropIdAreaId{.propId = testInt32VecWindowProp(2), .areaId = 2};
@@ -2821,41 +2816,73 @@
// Keep binder alive to prevent binder reuse.
SpAIBinder binder2 = callback2->asBinder();
- auto status = client->registerSupportedValueChangeCallback(
+ auto status = getClient()->registerSupportedValueChangeCallback(
callback1, std::vector<VhalPropIdAreaId>{vhalPropIdAreaId1, vhalPropIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from registerSupportedValueChangeCallback"
<< status.getMessage();
- status = client->registerSupportedValueChangeCallback(
+ status = getClient()->registerSupportedValueChangeCallback(
callback2, std::vector<VhalPropIdAreaId>{vhalPropIdAreaId1, vhalPropIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from registerSupportedValueChangeCallback"
<< status.getMessage();
- ASSERT_THAT(hardwarePtr->getSubscribedSupportedValueChangePropIdAreaIds(),
+ ASSERT_THAT(getHardware()->getSubscribedSupportedValueChangePropIdAreaIds(),
UnorderedElementsAre(propIdAreaId1, propIdAreaId2));
- status = client->unregisterSupportedValueChangeCallback(
+ status = getClient()->unregisterSupportedValueChangeCallback(
callback1, std::vector<VhalPropIdAreaId>{vhalPropIdAreaId1, vhalPropIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from unregisterSupportedValueChangeCallback"
<< status.getMessage();
- ASSERT_THAT(hardwarePtr->getSubscribedSupportedValueChangePropIdAreaIds(),
+ ASSERT_THAT(getHardware()->getSubscribedSupportedValueChangePropIdAreaIds(),
UnorderedElementsAre(propIdAreaId1, propIdAreaId2))
<< "[propId, areaId] must still be subscribed if one of the two clients unsubscribe";
- status = client->unregisterSupportedValueChangeCallback(
+ status = getClient()->unregisterSupportedValueChangeCallback(
callback2, std::vector<VhalPropIdAreaId>{vhalPropIdAreaId1, vhalPropIdAreaId2});
ASSERT_TRUE(status.isOk()) << "Get non-okay status from unregisterSupportedValueChangeCallback"
<< status.getMessage();
- ASSERT_TRUE(hardwarePtr->getSubscribedSupportedValueChangePropIdAreaIds().empty())
+ ASSERT_TRUE(getHardware()->getSubscribedSupportedValueChangePropIdAreaIds().empty())
<< "All registered [propId, areaId]s must be unregistered";
}
+TEST_F(DefaultVehicleHalTest, testRegisterSupportedValueChange_monitorBinderLifecycle) {
+ auto testConfigs = std::vector<VehiclePropConfig>({VehiclePropConfig{
+ .prop = testInt32VecProp(1),
+ .areaConfigs =
+ {
+ {.areaId = 0,
+ .hasSupportedValueInfo =
+ HasSupportedValueInfo{
+ .hasMinSupportedValue = false,
+ .hasMaxSupportedValue = false,
+ .hasSupportedValuesList = true,
+ }},
+ },
+ }});
+
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ hardware->setPropertyConfigs(testConfigs);
+
+ setHardware(std::move(hardware));
+
+ auto vhalPropIdAreaId = VhalPropIdAreaId{.propId = testInt32VecProp(1), .areaId = 0};
+
+ auto status = getClient()->registerSupportedValueChangeCallback(
+ getCallbackClient(), std::vector<VhalPropIdAreaId>{vhalPropIdAreaId});
+
+ ASSERT_TRUE(status.isOk()) << "Get non-okay status from registerSupportedValueChangeCallback"
+ << status.getMessage();
+
+ ASSERT_EQ(countOnBinderDiedContexts(), static_cast<size_t>(1))
+ << "expect one OnBinderDied context when one client is registered";
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware