blob: 3195c55b0b36085f83a939328a90e9f2139a9128 [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 Saneb6ed0eb2024-06-25 14:38:42 +000043// A service name which is in the static list of cachable services
44const String16 kCachedServiceName = String16("isub");
45
46#define EXPECT_OK(status) \
47 do { \
48 binder::Status stat = (status); \
49 EXPECT_TRUE(stat.isOk()) << stat; \
50 } while (false)
51
52const String16 kServerName = String16("binderCacheUnitTest");
53
54class FooBar : public BBinder {
55public:
56 status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t) {
57 // exit the server
58 std::thread([] { exit(EXIT_FAILURE); }).detach();
59 return OK;
60 }
61 void killServer(sp<IBinder> binder) {
62 Parcel data, reply;
63 binder->transact(0, data, &reply, 0);
64 }
65};
66
67class MockAidlServiceManager : public os::IServiceManagerDefault {
68public:
69 MockAidlServiceManager() : innerSm() {}
70
71 binder::Status checkService(const ::std::string& name, os::Service* _out) override {
72 sp<IBinder> binder = innerSm.getService(String16(name.c_str()));
73 *_out = os::Service::make<os::Service::Tag::binder>(binder);
74 return binder::Status::ok();
75 }
76
77 binder::Status addService(const std::string& name, const sp<IBinder>& service,
78 bool allowIsolated, int32_t dumpPriority) override {
79 return binder::Status::fromStatusT(
80 innerSm.addService(String16(name.c_str()), service, allowIsolated, dumpPriority));
81 }
82
Parth Sanedc207542024-11-14 11:49:08 +000083 void clearServices() { innerSm.clear(); }
84
Parth Saneb6ed0eb2024-06-25 14:38:42 +000085 FakeServiceManager innerSm;
86};
87
Parth Sanedc207542024-11-14 11:49:08 +000088class LibbinderCacheAddServiceTest : public ::testing::Test {
89protected:
90 void SetUp() override {
91 fakeServiceManager = sp<MockAidlServiceManager>::make();
92 mServiceManager = getServiceManagerShimFromAidlServiceManagerForTests(fakeServiceManager);
93 mServiceManager->enableAddServiceCache(true);
94 }
95
96 void TearDown() override {}
97
98public:
99 void cacheAddServiceAndConfirmCacheHit(const sp<IBinder>& binder1) {
100 // Add a service. This also caches it.
101 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder1));
102 // remove services from fakeservicemanager
103 fakeServiceManager->clearServices();
104
105 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
106 if (kUseCacheInAddService && kUseLibbinderCache) {
107 // If cache is enabled, we should get the binder.
108 EXPECT_EQ(binder1, result);
109 } else {
110 // If cache is disabled, then we should get the null binder
111 EXPECT_EQ(nullptr, result);
112 }
113 }
114 sp<MockAidlServiceManager> fakeServiceManager;
115 sp<android::IServiceManager> mServiceManager;
116};
117
118TEST_F(LibbinderCacheAddServiceTest, AddLocalServiceAndConfirmCacheHit) {
119 sp<IBinder> binder1 = sp<BBinder>::make();
120 cacheAddServiceAndConfirmCacheHit(binder1);
121}
122
123TEST_F(LibbinderCacheAddServiceTest, AddRemoteServiceAndConfirmCacheHit) {
124 sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
125 ASSERT_NE(binder1, nullptr);
126 cacheAddServiceAndConfirmCacheHit(binder1);
127}
128
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000129class LibbinderCacheTest : public ::testing::Test {
130protected:
131 void SetUp() override {
Parth Sanedc207542024-11-14 11:49:08 +0000132 fakeServiceManager = sp<MockAidlServiceManager>::make();
133 mServiceManager = getServiceManagerShimFromAidlServiceManagerForTests(fakeServiceManager);
134 mServiceManager->enableAddServiceCache(false);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000135 }
136
137 void TearDown() override {}
138
139public:
140 void cacheAndConfirmCacheHit(const sp<IBinder>& binder1, const sp<IBinder>& binder2) {
141 // Add a service
142 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder1));
143 // Get the service. This caches it.
144 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
145 ASSERT_EQ(binder1, result);
146
147 // Add the different binder and replace the service.
148 // The cache should still hold the original binder.
149 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder2));
150
151 result = mServiceManager->checkService(kCachedServiceName);
152 if (kUseLibbinderCache) {
153 // If cache is enabled, we should get the binder to Service Manager.
154 EXPECT_EQ(binder1, result);
155 } else {
156 // If cache is disabled, then we should get the newer binder
157 EXPECT_EQ(binder2, result);
158 }
159 }
160
Parth Sanedc207542024-11-14 11:49:08 +0000161 sp<MockAidlServiceManager> fakeServiceManager;
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000162 sp<android::IServiceManager> mServiceManager;
163};
164
165TEST_F(LibbinderCacheTest, AddLocalServiceAndConfirmCacheHit) {
166 sp<IBinder> binder1 = sp<BBinder>::make();
167 sp<IBinder> binder2 = sp<BBinder>::make();
168
169 cacheAndConfirmCacheHit(binder1, binder2);
170}
171
172TEST_F(LibbinderCacheTest, AddRemoteServiceAndConfirmCacheHit) {
173 sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
174 ASSERT_NE(binder1, nullptr);
175 sp<IBinder> binder2 = IInterface::asBinder(mServiceManager);
176
177 cacheAndConfirmCacheHit(binder1, binder2);
178}
179
180TEST_F(LibbinderCacheTest, RemoveFromCacheOnServerDeath) {
181 sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
182 FooBar foo = FooBar();
183
184 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder1));
185
186 // Check Service, this caches the binder
187 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
188 ASSERT_EQ(binder1, result);
189
190 // Kill the server, this should remove from cache.
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000191 pid_t pid;
192 ASSERT_EQ(OK, binder1->getDebugPid(&pid));
Parth Sane9dc99842024-09-17 18:07:22 +0000193 foo.killServer(binder1);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000194 system(("kill -9 " + std::to_string(pid)).c_str());
195
196 sp<IBinder> binder2 = sp<BBinder>::make();
197
198 // Add new service with the same name.
199 // This will replace the service in FakeServiceManager.
200 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder2));
201
202 // Confirm that new service is returned instead of old.
Parth Sane3e865362024-10-02 13:40:40 +0000203 int retry_count = 20;
Parth Saned73a5102024-09-30 17:47:28 +0000204 sp<IBinder> result2;
205 do {
206 std::this_thread::sleep_for(std::chrono::milliseconds(50));
207 if (retry_count-- == 0) {
208 break;
209 }
210 result2 = mServiceManager->checkService(kCachedServiceName);
211 } while (result2 != binder2);
212
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000213 ASSERT_EQ(binder2, result2);
214}
215
216TEST_F(LibbinderCacheTest, NullBinderNotCached) {
217 sp<IBinder> binder1 = nullptr;
218 sp<IBinder> binder2 = sp<BBinder>::make();
219
220 // Check for a cacheble service which isn't registered.
221 // FakeServiceManager should return nullptr.
222 // This shouldn't be cached.
223 sp<IBinder> result = mServiceManager->checkService(kCachedServiceName);
224 ASSERT_EQ(binder1, result);
225
226 // Add the same service
227 EXPECT_EQ(OK, mServiceManager->addService(kCachedServiceName, binder2));
228
229 // This should return the newly added service.
230 result = mServiceManager->checkService(kCachedServiceName);
231 EXPECT_EQ(binder2, result);
232}
233
234TEST_F(LibbinderCacheTest, DoNotCacheServiceNotInList) {
235 sp<IBinder> binder1 = sp<BBinder>::make();
236 sp<IBinder> binder2 = sp<BBinder>::make();
237 String16 serviceName = String16("NewLibbinderCacheTest");
238 // Add a service
239 EXPECT_EQ(OK, mServiceManager->addService(serviceName, binder1));
240 // Get the service. This shouldn't caches it.
241 sp<IBinder> result = mServiceManager->checkService(serviceName);
242 ASSERT_EQ(binder1, result);
243
244 // Add the different binder and replace the service.
245 EXPECT_EQ(OK, mServiceManager->addService(serviceName, binder2));
246
247 // Confirm that we get the new service
248 result = mServiceManager->checkService(serviceName);
249 EXPECT_EQ(binder2, result);
250}
251
252int main(int argc, char** argv) {
253 ::testing::InitGoogleTest(&argc, argv);
254
255 if (fork() == 0) {
256 prctl(PR_SET_PDEATHSIG, SIGHUP);
257
258 // Start a FooBar service and add it to the servicemanager.
259 sp<IBinder> server = new FooBar();
260 defaultServiceManager()->addService(kServerName, server);
261
262 IPCThreadState::self()->joinThreadPool(true);
263 exit(1); // should not reach
264 }
265
266 status_t err = ProcessState::self()->setThreadPoolMaxThreadCount(3);
267 ProcessState::self()->startThreadPool();
268 CHECK_EQ(ProcessState::self()->isThreadPoolStarted(), true);
269 CHECK_GT(ProcessState::self()->getThreadPoolMaxTotalThreadCount(), 0);
270
271 auto binder = defaultServiceManager()->waitForService(kServerName);
272 CHECK_NE(nullptr, binder.get());
273 return RUN_ALL_TESTS();
274}