xref: /aosp_15_r20/system/hwservicemanager/test_lazy.cpp (revision ee3b7b6295061e544d3520b965ea91a90424af41)
1*ee3b7b62SAndroid Build Coastguard Worker /*
2*ee3b7b62SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*ee3b7b62SAndroid Build Coastguard Worker  *
4*ee3b7b62SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ee3b7b62SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ee3b7b62SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ee3b7b62SAndroid Build Coastguard Worker  *
8*ee3b7b62SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ee3b7b62SAndroid Build Coastguard Worker  *
10*ee3b7b62SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ee3b7b62SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ee3b7b62SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ee3b7b62SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ee3b7b62SAndroid Build Coastguard Worker  * limitations under the License.
15*ee3b7b62SAndroid Build Coastguard Worker  */
16*ee3b7b62SAndroid Build Coastguard Worker 
17*ee3b7b62SAndroid Build Coastguard Worker #include <HidlService.h>
18*ee3b7b62SAndroid Build Coastguard Worker 
19*ee3b7b62SAndroid Build Coastguard Worker #include <android/hidl/manager/1.2/IClientCallback.h>
20*ee3b7b62SAndroid Build Coastguard Worker #include <gmock/gmock.h>
21*ee3b7b62SAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*ee3b7b62SAndroid Build Coastguard Worker 
23*ee3b7b62SAndroid Build Coastguard Worker using ::android::hardware::Return;
24*ee3b7b62SAndroid Build Coastguard Worker using ::android::hardware::Void;
25*ee3b7b62SAndroid Build Coastguard Worker using ::android::hidl::base::V1_0::IBase;
26*ee3b7b62SAndroid Build Coastguard Worker using ::android::hidl::manager::implementation::HidlService;
27*ee3b7b62SAndroid Build Coastguard Worker using ::android::hidl::manager::V1_2::IClientCallback;
28*ee3b7b62SAndroid Build Coastguard Worker using ::android::sp;
29*ee3b7b62SAndroid Build Coastguard Worker using ::testing::ElementsAre;
30*ee3b7b62SAndroid Build Coastguard Worker using ::testing::Invoke;
31*ee3b7b62SAndroid Build Coastguard Worker using ::testing::NiceMock;
32*ee3b7b62SAndroid Build Coastguard Worker 
33*ee3b7b62SAndroid Build Coastguard Worker class RecordingClientCallback : public IClientCallback {
34*ee3b7b62SAndroid Build Coastguard Worker public:
onClients(const sp<IBase> &,bool clients)35*ee3b7b62SAndroid Build Coastguard Worker     Return<void> onClients(const sp<IBase>& /*base*/, bool clients) override {
36*ee3b7b62SAndroid Build Coastguard Worker         stream.push_back(clients);
37*ee3b7b62SAndroid Build Coastguard Worker         return Void();
38*ee3b7b62SAndroid Build Coastguard Worker     }
39*ee3b7b62SAndroid Build Coastguard Worker 
40*ee3b7b62SAndroid Build Coastguard Worker     std::vector<bool> stream;
41*ee3b7b62SAndroid Build Coastguard Worker };
42*ee3b7b62SAndroid Build Coastguard Worker 
43*ee3b7b62SAndroid Build Coastguard Worker class MockHidlService : public HidlService {
44*ee3b7b62SAndroid Build Coastguard Worker public:
MockHidlService()45*ee3b7b62SAndroid Build Coastguard Worker     MockHidlService() : HidlService("fqname", "instance") {}
46*ee3b7b62SAndroid Build Coastguard Worker     MOCK_METHOD0(getNodeStrongRefCount, ssize_t());
47*ee3b7b62SAndroid Build Coastguard Worker };
48*ee3b7b62SAndroid Build Coastguard Worker 
49*ee3b7b62SAndroid Build Coastguard Worker class HidlServiceLazyTest : public ::testing::Test {
50*ee3b7b62SAndroid Build Coastguard Worker public:
51*ee3b7b62SAndroid Build Coastguard Worker     // Note that this should include one count for hwservicemanager. A count of
52*ee3b7b62SAndroid Build Coastguard Worker     // 1 indicates that hwservicemanager is the only process holding the service.
setReportedClientCount(ssize_t count)53*ee3b7b62SAndroid Build Coastguard Worker     void setReportedClientCount(ssize_t count) {
54*ee3b7b62SAndroid Build Coastguard Worker         mState.mInjectedReportCount = count;
55*ee3b7b62SAndroid Build Coastguard Worker     }
56*ee3b7b62SAndroid Build Coastguard Worker 
57*ee3b7b62SAndroid Build Coastguard Worker     // Essentially, the number of times the kernel API would be called
getNumTimesReported()58*ee3b7b62SAndroid Build Coastguard Worker     size_t getNumTimesReported() {
59*ee3b7b62SAndroid Build Coastguard Worker         return mState.mInjectedTimes;
60*ee3b7b62SAndroid Build Coastguard Worker     }
61*ee3b7b62SAndroid Build Coastguard Worker 
makeService()62*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> makeService() {
63*ee3b7b62SAndroid Build Coastguard Worker         auto service = std::make_unique<NiceMock<MockHidlService>>();
64*ee3b7b62SAndroid Build Coastguard Worker         ON_CALL(*service, getNodeStrongRefCount()).WillByDefault(Invoke([&]() {
65*ee3b7b62SAndroid Build Coastguard Worker             mState.mInjectedTimes++;
66*ee3b7b62SAndroid Build Coastguard Worker             return mState.mInjectedReportCount;
67*ee3b7b62SAndroid Build Coastguard Worker         }));
68*ee3b7b62SAndroid Build Coastguard Worker         return service;
69*ee3b7b62SAndroid Build Coastguard Worker     }
70*ee3b7b62SAndroid Build Coastguard Worker 
71*ee3b7b62SAndroid Build Coastguard Worker protected:
SetUp()72*ee3b7b62SAndroid Build Coastguard Worker     void SetUp() override {
73*ee3b7b62SAndroid Build Coastguard Worker         mState = TestState();
74*ee3b7b62SAndroid Build Coastguard Worker     }
75*ee3b7b62SAndroid Build Coastguard Worker 
76*ee3b7b62SAndroid Build Coastguard Worker     struct TestState {
77*ee3b7b62SAndroid Build Coastguard Worker         ssize_t mInjectedReportCount = -1;
78*ee3b7b62SAndroid Build Coastguard Worker         size_t mInjectedTimes = 0;
79*ee3b7b62SAndroid Build Coastguard Worker     } mState;
80*ee3b7b62SAndroid Build Coastguard Worker };
81*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,NoChange)82*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, NoChange) {
83*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> cb = new RecordingClientCallback;
84*ee3b7b62SAndroid Build Coastguard Worker 
85*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
86*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(cb, 1 /*knownClients*/);
87*ee3b7b62SAndroid Build Coastguard Worker 
88*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(1);
89*ee3b7b62SAndroid Build Coastguard Worker 
90*ee3b7b62SAndroid Build Coastguard Worker     for (size_t i = 0; i < 100; i++) {
91*ee3b7b62SAndroid Build Coastguard Worker         service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
92*ee3b7b62SAndroid Build Coastguard Worker     }
93*ee3b7b62SAndroid Build Coastguard Worker 
94*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre());
95*ee3b7b62SAndroid Build Coastguard Worker }
96*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,NoChangeWithKnownClients)97*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, NoChangeWithKnownClients) {
98*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> cb = new RecordingClientCallback;
99*ee3b7b62SAndroid Build Coastguard Worker 
100*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
101*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(cb, 2 /*knownClients*/);
102*ee3b7b62SAndroid Build Coastguard Worker 
103*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(2);
104*ee3b7b62SAndroid Build Coastguard Worker 
105*ee3b7b62SAndroid Build Coastguard Worker     for (size_t i = 0; i < 100; i++) {
106*ee3b7b62SAndroid Build Coastguard Worker         service->handleClientCallbacks(true /*onInterval*/, 2 /*knownClients*/);
107*ee3b7b62SAndroid Build Coastguard Worker     }
108*ee3b7b62SAndroid Build Coastguard Worker 
109*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre());
110*ee3b7b62SAndroid Build Coastguard Worker }
111*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,GetAndDrop)112*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, GetAndDrop) {
113*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> cb = new RecordingClientCallback;
114*ee3b7b62SAndroid Build Coastguard Worker 
115*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
116*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(cb, 1 /*knownClients*/);
117*ee3b7b62SAndroid Build Coastguard Worker 
118*ee3b7b62SAndroid Build Coastguard Worker     // some other process has the service
119*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(2);
120*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
121*ee3b7b62SAndroid Build Coastguard Worker 
122*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
123*ee3b7b62SAndroid Build Coastguard Worker 
124*ee3b7b62SAndroid Build Coastguard Worker     // just hwservicemanager has the service
125*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(1);
126*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
127*ee3b7b62SAndroid Build Coastguard Worker 
128*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
129*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
130*ee3b7b62SAndroid Build Coastguard Worker 
131*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
132*ee3b7b62SAndroid Build Coastguard Worker }
133*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,GetGuarantee)134*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, GetGuarantee) {
135*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> cb = new RecordingClientCallback;
136*ee3b7b62SAndroid Build Coastguard Worker 
137*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
138*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(cb, 1 /*knownClients*/);
139*ee3b7b62SAndroid Build Coastguard Worker 
140*ee3b7b62SAndroid Build Coastguard Worker     service->guaranteeClient();
141*ee3b7b62SAndroid Build Coastguard Worker 
142*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(1);
143*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/);
144*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
145*ee3b7b62SAndroid Build Coastguard Worker 
146*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
147*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
148*ee3b7b62SAndroid Build Coastguard Worker 
149*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
150*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
151*ee3b7b62SAndroid Build Coastguard Worker }
152*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,ManyUpdatesOffInterval)153*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, ManyUpdatesOffInterval) {
154*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> cb = new RecordingClientCallback;
155*ee3b7b62SAndroid Build Coastguard Worker 
156*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
157*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(cb, 1 /*knownClients*/);
158*ee3b7b62SAndroid Build Coastguard Worker 
159*ee3b7b62SAndroid Build Coastguard Worker     // Clients can appear and dissappear as many times as necessary, but they are only considered
160*ee3b7b62SAndroid Build Coastguard Worker     // dropped when the fixed interval stops.
161*ee3b7b62SAndroid Build Coastguard Worker     for (size_t i = 0; i < 100; i++) {
162*ee3b7b62SAndroid Build Coastguard Worker         setReportedClientCount(2);
163*ee3b7b62SAndroid Build Coastguard Worker         service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/);
164*ee3b7b62SAndroid Build Coastguard Worker         setReportedClientCount(1);
165*ee3b7b62SAndroid Build Coastguard Worker         service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/);
166*ee3b7b62SAndroid Build Coastguard Worker     }
167*ee3b7b62SAndroid Build Coastguard Worker 
168*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
169*ee3b7b62SAndroid Build Coastguard Worker 
170*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
171*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
172*ee3b7b62SAndroid Build Coastguard Worker 
173*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
174*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
175*ee3b7b62SAndroid Build Coastguard Worker }
176*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,AcquisitionAfterGuarantee)177*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, AcquisitionAfterGuarantee) {
178*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> cb = new RecordingClientCallback;
179*ee3b7b62SAndroid Build Coastguard Worker 
180*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
181*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(cb, 1 /*knownClients*/);
182*ee3b7b62SAndroid Build Coastguard Worker 
183*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(2);
184*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/);
185*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
186*ee3b7b62SAndroid Build Coastguard Worker 
187*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(1);
188*ee3b7b62SAndroid Build Coastguard Worker     service->guaranteeClient();
189*ee3b7b62SAndroid Build Coastguard Worker 
190*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/);
191*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
192*ee3b7b62SAndroid Build Coastguard Worker 
193*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
194*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
195*ee3b7b62SAndroid Build Coastguard Worker 
196*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
197*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
198*ee3b7b62SAndroid Build Coastguard Worker }
199*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,NotificationSentForNewClientCallback)200*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, NotificationSentForNewClientCallback) {
201*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> cb = new RecordingClientCallback;
202*ee3b7b62SAndroid Build Coastguard Worker 
203*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
204*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(cb, 1 /*knownClients*/);
205*ee3b7b62SAndroid Build Coastguard Worker 
206*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(2);
207*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/);
208*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
209*ee3b7b62SAndroid Build Coastguard Worker 
210*ee3b7b62SAndroid Build Coastguard Worker     sp<RecordingClientCallback> laterCb = new RecordingClientCallback;
211*ee3b7b62SAndroid Build Coastguard Worker     service->addClientCallback(laterCb, 1 /*knownClients*/);
212*ee3b7b62SAndroid Build Coastguard Worker 
213*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
214*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(laterCb->stream, ElementsAre(true));
215*ee3b7b62SAndroid Build Coastguard Worker 
216*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(1);
217*ee3b7b62SAndroid Build Coastguard Worker 
218*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
219*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true));
220*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(laterCb->stream, ElementsAre(true));
221*ee3b7b62SAndroid Build Coastguard Worker 
222*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/);
223*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
224*ee3b7b62SAndroid Build Coastguard Worker     ASSERT_THAT(laterCb->stream, ElementsAre(true, false)); // reported only after two intervals
225*ee3b7b62SAndroid Build Coastguard Worker }
226*ee3b7b62SAndroid Build Coastguard Worker 
TEST_F(HidlServiceLazyTest,ClientWithoutLazy)227*ee3b7b62SAndroid Build Coastguard Worker TEST_F(HidlServiceLazyTest, ClientWithoutLazy) {
228*ee3b7b62SAndroid Build Coastguard Worker     std::unique_ptr<HidlService> service = makeService();
229*ee3b7b62SAndroid Build Coastguard Worker 
230*ee3b7b62SAndroid Build Coastguard Worker     setReportedClientCount(2);
231*ee3b7b62SAndroid Build Coastguard Worker     service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/);
232*ee3b7b62SAndroid Build Coastguard Worker 
233*ee3b7b62SAndroid Build Coastguard Worker     // kernel API should not be called
234*ee3b7b62SAndroid Build Coastguard Worker     EXPECT_EQ(0u, getNumTimesReported());
235*ee3b7b62SAndroid Build Coastguard Worker }
236