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