• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019, 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 
17 #include <sys/eventfd.h>
18 #include <cstdlib>
19 #include <ctime>
20 #include <iostream>
21 #include <numeric>
22 #include <string>
23 #include <thread>
24 
25 #include <sys/epoll.h>
26 #include <unistd.h>
27 
28 #include <ILazyTestService.h>
29 #include <ILazyTestServiceCb.h>
30 #include <binder/IPCThreadState.h>
31 #include <binder/IServiceManager.h>
32 #include <gtest/gtest.h>
33 #include <utils/String8.h>
34 
35 using ::ILazyTestService;
36 using ::android::DEAD_OBJECT;
37 using ::android::IBinder;
38 using ::android::IPCThreadState;
39 using ::android::IServiceManager;
40 using ::android::OK;
41 using ::android::sp;
42 using ::android::String16;
43 using ::android::base::unique_fd;
44 using ::android::os::ParcelFileDescriptor;
45 
46 std::vector<String16> gServiceNames;
47 static constexpr size_t SHUTDOWN_WAIT_MS = 10000;
48 static constexpr size_t CALLBACK_SHUTDOWN_WAIT_MS = 5000;
49 
waitForService(const String16 & name)50 sp<IBinder> waitForService(const String16& name) {
51   sp<IServiceManager> manager;
52   manager = android::defaultServiceManager();
53   EXPECT_NE(manager, nullptr);
54 
55   return manager->waitForService(name);
56 }
57 
isServiceRunning(const String16 & name)58 bool isServiceRunning(const String16& name) {
59   sp<IServiceManager> manager;
60   manager = android::defaultServiceManager();
61   EXPECT_NE(manager, nullptr);
62 
63   return manager->checkService(name) != nullptr;
64 }
65 
TEST(AidlLazyQuitTest,Quits)66 TEST(AidlLazyQuitTest, Quits) {
67   const String16 quitter = String16("aidl_lazy_test_quit");
68   usleep(SHUTDOWN_WAIT_MS * 1000);
69   ASSERT_FALSE(isServiceRunning(quitter));
70 
71   auto binder = waitForService(quitter);
72 
73   // binder dies. Could also linkToDeath to switch to cond var.
74   for (size_t i = 0; i < 1000; i++) {
75     if (binder->pingBinder() != OK) break;
76     usleep(10000);
77   }
78   EXPECT_EQ(DEAD_OBJECT, binder->pingBinder());
79 
80   // service should quit immediately, but wait a bit before checking
81   // so that servicemanager has time to process the death notification
82   usleep(SHUTDOWN_WAIT_MS * 1000 / 2);
83   ASSERT_FALSE(isServiceRunning(quitter));
84 }
85 
86 class AidlLazyTest : public ::testing::Test {
87  protected:
88   sp<IServiceManager> manager;
89 
SetUp()90   void SetUp() override {
91     manager = android::defaultServiceManager();
92     ASSERT_NE(manager, nullptr);
93 
94     for (size_t i = 0; i < gServiceNames.size(); i++) {
95       ASSERT_FALSE(isServiceRunning(gServiceNames.at(i)))
96           << "Service '" << android::String8(gServiceNames.at(i)) << "' is already running. "
97           << "Please ensure this is implemented as a lazy service, then kill all "
98           << "clients of this service and try again.";
99     }
100   }
101 
TearDown()102   void TearDown() override {
103     std::cout << "Waiting " << SHUTDOWN_WAIT_MS << " milliseconds before checking that the "
104               << "service has shut down." << std::endl;
105     IPCThreadState::self()->flushCommands();
106     usleep(SHUTDOWN_WAIT_MS * 1000);
107     for (size_t i = 0; i < gServiceNames.size(); i++) {
108       ASSERT_FALSE(isServiceRunning(gServiceNames.at(i))) << "Service failed to shut down.";
109     }
110   }
111 };
112 
113 static constexpr size_t NUM_IMMEDIATE_GETS = 100;
TEST_F(AidlLazyTest,GetRelease)114 TEST_F(AidlLazyTest, GetRelease) {
115   size_t nServices = gServiceNames.size();
116 
117   for (size_t i = 0; i < nServices * NUM_IMMEDIATE_GETS; i++) {
118     IPCThreadState::self()->flushCommands();
119     sp<IBinder> service = waitForService(gServiceNames.at(i % nServices));
120     ASSERT_NE(service.get(), nullptr);
121     ASSERT_EQ(service->pingBinder(), android::NO_ERROR);
122   }
123 }
124 
waitMs(size_t numTimes,size_t maxWait)125 static std::vector<size_t> waitMs(size_t numTimes, size_t maxWait) {
126   std::vector<size_t> times(numTimes);
127   for (size_t i = 0; i < numTimes; i++) {
128     times.at(i) = (size_t)(rand() % (maxWait + 1));
129   }
130   return times;
131 }
132 
testWithTimes(const std::vector<size_t> & waitMs,bool beforeGet)133 static void testWithTimes(const std::vector<size_t>& waitMs, bool beforeGet) {
134   size_t nServices = gServiceNames.size();
135   for (size_t i = 0; i < waitMs.size(); i++) {
136     IPCThreadState::self()->flushCommands();
137     if (beforeGet) {
138       std::cout << "Thread waiting " << waitMs.at(i) << " while not holding service." << std::endl;
139       usleep(waitMs.at(i) * 1000);
140     }
141 
142     sp<IBinder> service = waitForService(gServiceNames.at(i % nServices));
143 
144     if (!beforeGet) {
145       std::cout << "Thread waiting " << waitMs.at(i) << " while holding service." << std::endl;
146       usleep(waitMs.at(i) * 1000);
147     }
148 
149     ASSERT_NE(service.get(), nullptr);
150     ASSERT_EQ(service->pingBinder(), android::NO_ERROR);
151   }
152 }
153 
154 static constexpr size_t NUM_TIMES_GET_RELEASE = 5;
155 static constexpr size_t MAX_WAITING_DURATION_MS = 10000;
156 static constexpr size_t NUM_CONCURRENT_THREADS = 3;
testConcurrentThreadsWithDelays(bool delayBeforeGet)157 static void testConcurrentThreadsWithDelays(bool delayBeforeGet) {
158   size_t nServices = gServiceNames.size();
159   std::vector<std::vector<size_t>> threadWaitTimes(NUM_CONCURRENT_THREADS);
160   int maxWait = 0;
161   for (size_t i = 0; i < threadWaitTimes.size(); i++) {
162     threadWaitTimes.at(i) = waitMs(NUM_TIMES_GET_RELEASE * nServices, MAX_WAITING_DURATION_MS);
163     int totalWait = std::accumulate(threadWaitTimes.at(i).begin(), threadWaitTimes.at(i).end(), 0);
164     maxWait = std::max(maxWait, totalWait);
165   }
166   std::cout << "Additional runtime expected from sleeps: " << maxWait << " millisecond(s)."
167             << std::endl;
168 
169   std::vector<std::thread> threads(NUM_CONCURRENT_THREADS);
170   for (size_t i = 0; i < threads.size(); i++) {
171     threads.at(i) = std::thread(testWithTimes, threadWaitTimes.at(i), delayBeforeGet);
172   }
173 
174   for (auto& thread : threads) {
175     thread.join();
176   }
177 }
178 
TEST_F(AidlLazyTest,GetConcurrentWithWaitBefore)179 TEST_F(AidlLazyTest, GetConcurrentWithWaitBefore) {
180   testConcurrentThreadsWithDelays(true);
181 }
182 
TEST_F(AidlLazyTest,GetConcurrentWithWaitAfter)183 TEST_F(AidlLazyTest, GetConcurrentWithWaitAfter) {
184   testConcurrentThreadsWithDelays(false);
185 }
186 
187 class AidlLazyRegistrarTest : public ::testing::Test {
188  protected:
189   const String16 serviceName = String16("aidl_lazy_test_1");
SetUp()190   void SetUp() override {
191     if (std::find(gServiceNames.begin(), gServiceNames.end(), serviceName) == gServiceNames.end()) {
192       GTEST_SKIP() << "Persistence test requires special instance: " << serviceName;
193     }
194   }
195 };
196 
197 template <typename T>
waitForLazyTestService(String16 name)198 sp<T> waitForLazyTestService(String16 name) {
199   sp<T> service = android::waitForService<T>(name);
200   EXPECT_NE(service, nullptr);
201   return service;
202 }
203 
TEST_F(AidlLazyRegistrarTest,ForcedPersistenceTest)204 TEST_F(AidlLazyRegistrarTest, ForcedPersistenceTest) {
205   sp<ILazyTestService> service;
206   for (int i = 0; i < 2; i++) {
207     service = waitForLazyTestService<ILazyTestService>(serviceName);
208     EXPECT_TRUE(service->forcePersist(i == 0).isOk());
209     service = nullptr;
210 
211     std::cout << "Waiting " << SHUTDOWN_WAIT_MS << " milliseconds before checking whether the "
212               << "service is still running." << std::endl;
213     IPCThreadState::self()->flushCommands();
214     usleep(SHUTDOWN_WAIT_MS * 1000);
215 
216     if (i == 0) {
217       ASSERT_TRUE(isServiceRunning(serviceName)) << "Service shut down when it shouldn't have.";
218     } else {
219       ASSERT_FALSE(isServiceRunning(serviceName)) << "Service failed to shut down.";
220     }
221   }
222 }
223 
TEST_F(AidlLazyRegistrarTest,ActiveServicesCountCallbackTest)224 TEST_F(AidlLazyRegistrarTest, ActiveServicesCountCallbackTest) {
225   const String16 cbServiceName = String16("aidl_lazy_cb_test");
226 
227   int efd = eventfd(0, 0);
228   ASSERT_GE(efd, 0) << "Failed to create eventfd";
229 
230   unique_fd uniqueEventFd(efd);
231   ParcelFileDescriptor parcelEventFd(std::move(uniqueEventFd));
232 
233   sp<ILazyTestServiceCb> service;
234   service = waitForLazyTestService<ILazyTestServiceCb>(cbServiceName);
235   ASSERT_TRUE(service->setEventFd(parcelEventFd).isOk());
236   service = nullptr;
237 
238   IPCThreadState::self()->flushCommands();
239 
240   std::cout << "Waiting " << SHUTDOWN_WAIT_MS << " milliseconds for callback completion "
241             << "notification." << std::endl;
242 
243   int epollFd = epoll_create1(EPOLL_CLOEXEC);
244   ASSERT_GE(epollFd, 0) << "Failed to create epoll";
245   unique_fd epollUniqueFd(epollFd);
246 
247   const int EPOLL_MAX_EVENTS = 1;
248   struct epoll_event event, events[EPOLL_MAX_EVENTS];
249 
250   event.events = EPOLLIN;
251   event.data.fd = efd;
252   int rc = epoll_ctl(epollFd, EPOLL_CTL_ADD, efd, &event);
253   ASSERT_GE(rc, 0) << "Failed to add fd to epoll";
254 
255   rc = TEMP_FAILURE_RETRY(epoll_wait(epollFd, events, EPOLL_MAX_EVENTS, SHUTDOWN_WAIT_MS));
256   ASSERT_NE(rc, 0) << "Service shutdown timeout";
257   ASSERT_GT(rc, 0) << "Error waiting for service shutdown notification";
258 
259   eventfd_t counter;
260   rc = TEMP_FAILURE_RETRY(eventfd_read(parcelEventFd.get(), &counter));
261   ASSERT_GE(rc, 0) << "Failed to get callback completion notification from service";
262   ASSERT_EQ(counter, 1);
263 
264   std::cout << "Waiting " << CALLBACK_SHUTDOWN_WAIT_MS
265             << " milliseconds before checking whether the "
266             << "service is still running." << std::endl;
267 
268   usleep(CALLBACK_SHUTDOWN_WAIT_MS * 1000);
269 
270   ASSERT_FALSE(isServiceRunning(serviceName)) << "Service failed to shut down.";
271 }
272 
main(int argc,char ** argv)273 int main(int argc, char** argv) {
274   ::testing::InitGoogleTest(&argc, argv);
275 
276   srand(time(nullptr));
277 
278   if (argc < 2) {
279     // If the user does not specify any service to test, default to these test interfaces
280     gServiceNames.push_back(String16("aidl_lazy_test_1"));
281     gServiceNames.push_back(String16("aidl_lazy_test_2"));
282   } else {
283     for (int i = 1; i < argc; i++) {
284       gServiceNames.push_back(String16(argv[i]));
285     }
286   }
287 
288   android::ProcessState::self()->startThreadPool();
289 
290   return RUN_ALL_TESTS();
291 }
292