Only access lazy HAL feature when clients do
This was causing some excess kernel logs.
Fixes: 123769263
Test: hwservicemanager_test
HidlServiceLazyTest ClientWithoutLazy (now passes)
Test: internal 'lazy_hidl_test' fuzzing health storage HAL, for sanity
Change-Id: Ie47c9e085c6f251a9fe1806d7f7f70865e6f5f12
diff --git a/HidlService.cpp b/HidlService.cpp
index 6d020a4..e56579f 100644
--- a/HidlService.cpp
+++ b/HidlService.cpp
@@ -105,9 +105,13 @@
}
void HidlService::addClientCallback(const sp<IClientCallback>& callback) {
- handleClientCallbacks(false /* isCalledOnInterval */);
+ if (mHasClients) {
+ // we have this kernel feature, so make sure we're in an updated state
+ forceHandleClientCallbacks(false /*onInterval*/);
+ }
if (mHasClients) {
+ // make sure this callback is in the same state as all of the rest
sendClientCallbackNotification(callback, true /*hasClients*/);
}
@@ -130,6 +134,14 @@
}
ssize_t HidlService::handleClientCallbacks(bool isCalledOnInterval) {
+ if (!mClientCallbacks.empty()) {
+ return forceHandleClientCallbacks(isCalledOnInterval);
+ }
+
+ return -1;
+}
+
+ssize_t HidlService::forceHandleClientCallbacks(bool isCalledOnInterval) {
ssize_t count = getNodeStrongRefCount();
// binder driver doesn't support this feature
diff --git a/HidlService.h b/HidlService.h
index 426df8e..4214d00 100644
--- a/HidlService.h
+++ b/HidlService.h
@@ -71,10 +71,14 @@
void addClientCallback(const sp<IClientCallback>& callback);
bool removeClientCallback(const sp<IClientCallback>& callback);
- // return is number of clients (-1 means this is not implemented)
+ // return is number of clients (-1 means this is not implemented or we didn't check)
// count includes one held by hwservicemanager
ssize_t handleClientCallbacks(bool isCalledOnInterval);
+ // Updates client callbacks (even if mClientCallbacks is emtpy)
+ // see handleClientCallbacks
+ ssize_t forceHandleClientCallbacks(bool isCalledOnInterval);
+
// when giving out a handle to a client, but the kernel might not know this yet
void guaranteeClient();
diff --git a/ServiceManager.cpp b/ServiceManager.cpp
index ac142f5..9f45801 100644
--- a/ServiceManager.cpp
+++ b/ServiceManager.cpp
@@ -654,7 +654,7 @@
return false;
}
- int clients = registered->handleClientCallbacks(false /* isCalledOnInterval */);
+ int clients = registered->forceHandleClientCallbacks(false /* isCalledOnInterval */);
// clients < 0: feature not implemented or other error. Assume clients.
// Otherwise:
diff --git a/test_lazy.cpp b/test_lazy.cpp
index df42329..21108ba 100644
--- a/test_lazy.cpp
+++ b/test_lazy.cpp
@@ -51,21 +51,32 @@
// Note that this should include one count for hwservicemanager. A count of
// 1 indicates that hwservicemanager is the only process holding the service.
void setReportedClientCount(ssize_t count) {
- mInjectedReportCount = count;
+ mState.mInjectedReportCount = count;
+ }
+
+ // Essentially, the number of times the kernel API would be called
+ size_t getNumTimesReported() {
+ return mState.mInjectedTimes;
}
std::unique_ptr<HidlService> makeService() {
auto service = std::make_unique<NiceMock<MockHidlService>>();
- ON_CALL(*service, getNodeStrongRefCount()).WillByDefault(Invoke([&]() { return mInjectedReportCount; }));
+ ON_CALL(*service, getNodeStrongRefCount()).WillByDefault(Invoke([&]() {
+ mState.mInjectedTimes++;
+ return mState.mInjectedReportCount;
+ }));
return service;
}
protected:
void SetUp() override {
- mInjectedReportCount = -1;
+ mState = TestState();
}
- ssize_t mInjectedReportCount = -1;
+ struct TestState {
+ ssize_t mInjectedReportCount = -1;
+ size_t mInjectedTimes = 0;
+ } mState;
};
TEST_F(HidlServiceLazyTest, NoChange) {
@@ -197,3 +208,13 @@
ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
ASSERT_THAT(laterCb->stream, ElementsAre(true, false)); // reported only after two intervals
}
+
+TEST_F(HidlServiceLazyTest, ClientWithoutLazy) {
+ std::unique_ptr<HidlService> service = makeService();
+
+ setReportedClientCount(2);
+ service->handleClientCallbacks(false /*onInterval*/);
+
+ // kernel API should not be called
+ EXPECT_EQ(0u, getNumTimesReported());
+}