blob: 19395c2dcd362e671693c2b184e34e20c9988e73 [file] [log] [blame]
Parth Saneb6ed0eb2024-06-25 14:38:42 +00001/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <gtest/gtest.h>
17
18#include <android-base/logging.h>
19#include <android/os/IServiceManager.h>
20#include <binder/IBinder.h>
21#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
23#include <binder/IServiceManagerUnitTestHelper.h>
24#include "fakeservicemanager/FakeServiceManager.h"
25
26#include <sys/prctl.h>
27#include <thread>
28
29using namespace android;
30
31#ifdef LIBBINDER_CLIENT_CACHE
32constexpr bool kUseLibbinderCache = true;
33#else
34constexpr bool kUseLibbinderCache = false;
35#endif
36
Parth Sanedc207542024-11-14 11:49:08 +000037#ifdef LIBBINDER_ADDSERVICE_CACHE
38constexpr bool kUseCacheInAddService = true;
39#else
40constexpr bool kUseCacheInAddService = false;
41#endif
42
Parth Sane5e1b7e12024-11-29 10:40:41 +000043#ifdef LIBBINDER_REMOVE_CACHE_STATIC_LIST
44constexpr bool kRemoveStaticList = true;
45#else
46constexpr bool kRemoveStaticList = false;
47#endif
48
Parth Saneb6ed0eb2024-06-25 14:38:42 +000049// A service name which is in the static list of cachable services
50const String16 kCachedServiceName = String16("isub");
51
52#define EXPECT_OK(status) \
53 do { \
54 binder::Status stat = (status); \
55 EXPECT_TRUE(stat.isOk()) << stat; \
56 } while (false)
57
58const String16 kServerName = String16("binderCacheUnitTest");
59
60class FooBar : public BBinder {
61public:
62 status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t) {
63 // exit the server
64 std::thread([] { exit(EXIT_FAILURE); }).detach();
65 return OK;
66 }
67 void killServer(sp<IBinder> binder) {
68 Parcel data, reply;
69 binder->transact(0, data, &reply, 0);
70 }
71};
72
73class MockAidlServiceManager : public os::IServiceManagerDefault {
74public:
75 MockAidlServiceManager() : innerSm() {}
76
77 binder::Status checkService(const ::std::string& name, os::Service* _out) override {
Parth Sane5e1b7e12024-11-29 10:40:41 +000078 os::ServiceWithMetadata serviceWithMetadata = os::ServiceWithMetadata();
79 serviceWithMetadata.service = innerSm.getService(String16(name.c_str()));
80 serviceWithMetadata.isLazyService = false;
81 *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(serviceWithMetadata);
Parth Saneb6ed0eb2024-06-25 14:38:42 +000082 return binder::Status::ok();
83 }
84
85 binder::Status addService(const std::string& name, const sp<IBinder>& service,
86 bool allowIsolated, int32_t dumpPriority) override {
87 return binder::Status::fromStatusT(
88 innerSm.addService(String16(name.c_str()), service, allowIsolated, dumpPriority));
89 }
90
Parth Sanedc207542024-11-14 11:49:08 +000091 void clearServices() { innerSm.clear(); }
92
Parth Saneb6ed0eb2024-06-25 14:38:42 +000093 FakeServiceManager innerSm;
94};
95
Parth Sane5e1b7e12024-11-29 10:40:41 +000096// Returns services with isLazyService flag as true.
97class MockAidlServiceManager2 : public os::IServiceManagerDefault {
98public:
99 MockAidlServiceManager2() : innerSm() {}
100
101 binder::Status checkService(const ::std::string& name, os::Service* _out) override {
102 os::ServiceWithMetadata serviceWithMetadata = os::ServiceWithMetadata();
103 serviceWithMetadata.service = innerSm.getService(String16(name.c_str()));
104 serviceWithMetadata.isLazyService = true;
105 *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(serviceWithMetadata);
106 return binder::Status::ok();
107 }
108
109 binder::Status addService(const std::string& name, const sp<IBinder>& service,
110 bool allowIsolated, int32_t dumpPriority) override {
111 return binder::Status::fromStatusT(
112 innerSm.addService(String16(name.c_str()), service, allowIsolated, dumpPriority));
113 }
114
115 void clearServices() { innerSm.clear(); }
116
117 FakeServiceManager innerSm;
118};
119
120class LibbinderCacheRemoveStaticList : public ::testing::Test {
121protected:
122 void SetUp() override {
123 fakeServiceManager = sp<MockAidlServiceManager2>::make();
124 mServiceManager = getServiceManagerShimFromAidlServiceManagerForTests(fakeServiceManager);
125 mServiceManager->enableAddServiceCache(true);
126 }
127 void TearDown() override {}
128
129public:
130 void cacheAddServiceAndConfirmCacheMiss(const sp<IBinder>& binder1) {
131 // Add a service. This shouldn't cache it.
132 EXPECT_EQ(OK,
133 mServiceManager->addService(kCachedServiceName, binder1,
134 /*allowIsolated = */ false,
135 android::os::IServiceManager::FLAG_IS_LAZY_SERVICE));
136 // Try to populate cache. Cache shouldn't be updated.
137 EXPECT_EQ(binder1, mServiceManager->checkService(kCachedServiceName));
138 fakeServiceManager->clearServices();
139 EXPECT_EQ(nullptr, mServiceManager->checkService(kCachedServiceName));
140 }
141
142 sp<MockAidlServiceManager2> fakeServiceManager;
143 sp<android::IServiceManager> mServiceManager;
144};
145
146TEST_F(LibbinderCacheRemoveStaticList, AddLocalServiceAndConfirmCacheMiss) {
147 if (!kRemoveStaticList) {
148 GTEST_SKIP() << "Skipping as feature is not enabled";
149 return;
150 }
151 sp<IBinder> binder1 = sp<BBinder>::make();
152 cacheAddServiceAndConfirmCacheMiss(binder1);
153}
154
155TEST_F(LibbinderCacheRemoveStaticList, AddRemoteServiceAndConfirmCacheMiss) {
156 if (!kRemoveStaticList) {
157 GTEST_SKIP() << "Skipping as feature is not enabled";
158 return;
159 }
160 sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
161 ASSERT_NE(binder1, nullptr);
162 cacheAddServiceAndConfirmCacheMiss(binder1);
163}
164
Parth Sanedc207542024-11-14 11:49:08 +0000165class LibbinderCacheAddServiceTest : public ::testing::Test {
166protected:
167 void SetUp() override {
168 fakeServiceManager = sp<MockAidlServiceManager>::make();
169 mServiceManager = getServiceManagerShimFromAidlServiceManagerForTests(fakeServiceManager);
170 mServiceManager->enableAddServiceCache(true);
171 }
172
173 void TearDown() override {}
174
175public:
176 void cacheAddServiceAndConfirmCacheHit(const sp<IBinder>& binder1) {
177 // Add a service. This also caches it.
178 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder1));
179 // remove services from fakeservicemanager
180 fakeServiceManager->clearServices();
181
182 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
183 if (kUseCacheInAddService && kUseLibbinderCache) {
184 // If cache is enabled, we should get the binder.
185 EXPECT_EQ(binder1, result);
186 } else {
187 // If cache is disabled, then we should get the null binder
188 EXPECT_EQ(nullptr, result);
189 }
190 }
191 sp<MockAidlServiceManager> fakeServiceManager;
192 sp<android::IServiceManager> mServiceManager;
193};
194
195TEST_F(LibbinderCacheAddServiceTest, AddLocalServiceAndConfirmCacheHit) {
196 sp<IBinder> binder1 = sp<BBinder>::make();
197 cacheAddServiceAndConfirmCacheHit(binder1);
198}
199
200TEST_F(LibbinderCacheAddServiceTest, AddRemoteServiceAndConfirmCacheHit) {
201 sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
202 ASSERT_NE(binder1, nullptr);
203 cacheAddServiceAndConfirmCacheHit(binder1);
204}
205
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000206class LibbinderCacheTest : public ::testing::Test {
207protected:
208 void SetUp() override {
Parth Sanedc207542024-11-14 11:49:08 +0000209 fakeServiceManager = sp<MockAidlServiceManager>::make();
210 mServiceManager = getServiceManagerShimFromAidlServiceManagerForTests(fakeServiceManager);
211 mServiceManager->enableAddServiceCache(false);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000212 }
213
214 void TearDown() override {}
215
216public:
217 void cacheAndConfirmCacheHit(const sp<IBinder>& binder1, const sp<IBinder>& binder2) {
218 // Add a service
219 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder1));
220 // Get the service. This caches it.
221 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
222 ASSERT_EQ(binder1, result);
223
224 // Add the different binder and replace the service.
225 // The cache should still hold the original binder.
226 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder2));
227
228 result = mServiceManager->checkService(kCachedServiceName);
229 if (kUseLibbinderCache) {
230 // If cache is enabled, we should get the binder to Service Manager.
231 EXPECT_EQ(binder1, result);
232 } else {
233 // If cache is disabled, then we should get the newer binder
234 EXPECT_EQ(binder2, result);
235 }
236 }
237
Parth Sanedc207542024-11-14 11:49:08 +0000238 sp<MockAidlServiceManager> fakeServiceManager;
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000239 sp<android::IServiceManager> mServiceManager;
240};
241
242TEST_F(LibbinderCacheTest, AddLocalServiceAndConfirmCacheHit) {
243 sp<IBinder> binder1 = sp<BBinder>::make();
244 sp<IBinder> binder2 = sp<BBinder>::make();
245
246 cacheAndConfirmCacheHit(binder1, binder2);
247}
248
249TEST_F(LibbinderCacheTest, AddRemoteServiceAndConfirmCacheHit) {
250 sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
251 ASSERT_NE(binder1, nullptr);
252 sp<IBinder> binder2 = IInterface::asBinder(mServiceManager);
253
254 cacheAndConfirmCacheHit(binder1, binder2);
255}
256
257TEST_F(LibbinderCacheTest, RemoveFromCacheOnServerDeath) {
258 sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
259 FooBar foo = FooBar();
260
261 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder1));
262
263 // Check Service, this caches the binder
264 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
265 ASSERT_EQ(binder1, result);
266
267 // Kill the server, this should remove from cache.
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000268 pid_t pid;
269 ASSERT_EQ(OK, binder1->getDebugPid(&pid));
Parth Sane9dc99842024-09-17 18:07:22 +0000270 foo.killServer(binder1);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000271 system(("kill -9 " + std::to_string(pid)).c_str());
272
273 sp<IBinder> binder2 = sp<BBinder>::make();
274
275 // Add new service with the same name.
276 // This will replace the service in FakeServiceManager.
277 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder2));
278
279 // Confirm that new service is returned instead of old.
Parth Sane3e865362024-10-02 13:40:40 +0000280 int retry_count = 20;
Parth Saned73a5102024-09-30 17:47:28 +0000281 sp<IBinder> result2;
282 do {
283 std::this_thread::sleep_for(std::chrono::milliseconds(50));
284 if (retry_count-- == 0) {
285 break;
286 }
287 result2 = mServiceManager->checkService(kCachedServiceName);
288 } while (result2 != binder2);
289
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000290 ASSERT_EQ(binder2, result2);
291}
292
293TEST_F(LibbinderCacheTest, NullBinderNotCached) {
294 sp<IBinder> binder1 = nullptr;
295 sp<IBinder> binder2 = sp<BBinder>::make();
296
297 // Check for a cacheble service which isn't registered.
298 // FakeServiceManager should return nullptr.
299 // This shouldn't be cached.
300 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
301 ASSERT_EQ(binder1, result);
302
303 // Add the same service
304 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder2));
305
306 // This should return the newly added service.
307 result = mServiceManager->checkService(kCachedServiceName);
308 EXPECT_EQ(binder2, result);
309}
310
Parth Sane5e1b7e12024-11-29 10:40:41 +0000311// TODO(b/333854840): Remove this test removing the static list
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000312TEST_F(LibbinderCacheTest, DoNotCacheServiceNotInList) {
Parth Sane5e1b7e12024-11-29 10:40:41 +0000313 if (kRemoveStaticList) {
314 GTEST_SKIP() << "Skipping test as static list is disabled";
315 return;
316 }
317
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000318 sp<IBinder> binder1 = sp<BBinder>::make();
319 sp<IBinder> binder2 = sp<BBinder>::make();
320 String16 serviceName = String16("NewLibbinderCacheTest");
321 // Add a service
322 EXPECT_EQ(OK, mServiceManager->addService(serviceName, binder1));
323 // Get the service. This shouldn't caches it.
324 sp<IBinder> result = mServiceManager->checkService(serviceName);
325 ASSERT_EQ(binder1, result);
326
327 // Add the different binder and replace the service.
328 EXPECT_EQ(OK, mServiceManager->addService(serviceName, binder2));
329
330 // Confirm that we get the new service
331 result = mServiceManager->checkService(serviceName);
332 EXPECT_EQ(binder2, result);
333}
334
335int main(int argc, char** argv) {
336 ::testing::InitGoogleTest(&argc, argv);
337
338 if (fork() == 0) {
339 prctl(PR_SET_PDEATHSIG, SIGHUP);
340
341 // Start a FooBar service and add it to the servicemanager.
342 sp<IBinder> server = new FooBar();
343 defaultServiceManager()->addService(kServerName, server);
344
345 IPCThreadState::self()->joinThreadPool(true);
346 exit(1); // should not reach
347 }
348
349 status_t err = ProcessState::self()->setThreadPoolMaxThreadCount(3);
350 ProcessState::self()->startThreadPool();
351 CHECK_EQ(ProcessState::self()->isThreadPoolStarted(), true);
352 CHECK_GT(ProcessState::self()->getThreadPoolMaxTotalThreadCount(), 0);
353
354 auto binder = defaultServiceManager()->waitForService(kServerName);
355 CHECK_NE(nullptr, binder.get());
356 return RUN_ALL_TESTS();
357}