1 /*
2 * Copyright 2018 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 <android-base/file.h>
18 #include <android-base/logging.h>
19 #include <android-base/result.h>
20 #include <android-base/unique_fd.h>
21 #include <android/binder_manager.h>
22 #include <android/binder_stability.h>
23 #include <android/system/suspend/BnSuspendCallback.h>
24 #include <android/system/suspend/BnWakelockCallback.h>
25 #include <binder/IPCThreadState.h>
26 #include <binder/IServiceManager.h>
27 #include <binder/ProcessState.h>
28 #include <cutils/native_handle.h>
29 #include <ftw.h>
30 #include <gmock/gmock.h>
31 #include <gtest/gtest.h>
32 #include <hidl/HidlTransportSupport.h>
33 #include <suspend_service_flags.h>
34 #include <sys/poll.h>
35 #include <sys/socket.h>
36 #include <sys/types.h>
37
38 #include <chrono>
39 #include <cmath>
40 #include <csignal>
41 #include <cstdlib>
42 #include <future>
43 #include <string>
44 #include <thread>
45
46 #include "SuspendControlService.h"
47 #include "SystemSuspend.h"
48 #include "SystemSuspendAidl.h"
49 #include "WakeupList.h"
50
51 using aidl::android::system::suspend::ISystemSuspend;
52 using aidl::android::system::suspend::IWakeLock;
53 using aidl::android::system::suspend::SystemSuspendAidl;
54 using aidl::android::system::suspend::WakeLockType;
55 using android::sp;
56 using android::base::Result;
57 using android::base::Socketpair;
58 using android::base::unique_fd;
59 using android::base::WriteStringToFd;
60 using android::base::WriteStringToFile;
61 using android::hardware::configureRpcThreadpool;
62 using android::hardware::joinRpcThreadpool;
63 using android::hardware::Return;
64 using android::hardware::Void;
65 using android::system::suspend::BnSuspendCallback;
66 using android::system::suspend::BnWakelockCallback;
67 using android::system::suspend::ISuspendControlService;
68 using android::system::suspend::internal::ISuspendControlServiceInternal;
69 using android::system::suspend::internal::WakeLockInfo;
70 using android::system::suspend::internal::WakeupInfo;
71 using android::system::suspend::V1_0::readFd;
72 using android::system::suspend::V1_0::SleepTimeConfig;
73 using android::system::suspend::V1_0::SuspendControlService;
74 using android::system::suspend::V1_0::SuspendControlServiceInternal;
75 using android::system::suspend::V1_0::SuspendStats;
76 using android::system::suspend::V1_0::SystemSuspend;
77 using android::system::suspend::V1_0::TimestampType;
78 using android::system::suspend::V1_0::WakeupList;
79 using namespace std::chrono_literals;
80
81 namespace android {
82
83 static constexpr char kServiceName[] = "TestService";
84 static constexpr char kControlServiceName[] = "TestControlService";
85 static constexpr char kControlServiceInternalName[] = "TestControlServiceInternal";
86
isReadBlocked(int fd,int timeout_ms=20)87 static bool isReadBlocked(int fd, int timeout_ms = 20) {
88 struct pollfd pfd {
89 .fd = fd, .events = POLLIN,
90 };
91 return poll(&pfd, 1, timeout_ms) == 0;
92 }
93
94 class SystemSuspendTest : public ::testing::Test {
95 protected:
registerTestService()96 static void registerTestService() {
97 std::thread testService([] {
98 configureRpcThreadpool(1, true /* callerWillJoin */);
99
100 sp<SuspendControlService> suspendControl = new SuspendControlService();
101 auto controlStatus = ::android::defaultServiceManager()->addService(
102 android::String16(kControlServiceName), suspendControl);
103 if (android::OK != controlStatus) {
104 LOG(FATAL) << "Unable to register service " << kControlServiceName << controlStatus;
105 }
106
107 sp<SuspendControlServiceInternal> suspendControlInternal =
108 new SuspendControlServiceInternal();
109 controlStatus = ::android::defaultServiceManager()->addService(
110 android::String16(kControlServiceInternalName), suspendControlInternal);
111 if (android::OK != controlStatus) {
112 LOG(FATAL) << "Unable to register service " << kControlServiceInternalName
113 << controlStatus;
114 }
115
116 // Create non-HW binder threadpool for SuspendControlService.
117 sp<android::ProcessState> ps{android::ProcessState::self()};
118 ps->startThreadPool();
119
120 wakeupReasonsFd =
121 unique_fd(TEMP_FAILURE_RETRY(open(wakeupReasonsFile.path, O_CLOEXEC | O_RDONLY)));
122
123 suspendTimeFd =
124 unique_fd(TEMP_FAILURE_RETRY(open(suspendTimeFile.path, O_CLOEXEC | O_RDONLY)));
125
126 systemSuspend = new SystemSuspend(
127 std::move(wakeupCountFds[1]), std::move(stateFds[1]),
128 unique_fd(-1) /*suspendStatsFd*/, 1 /* maxNativeStatsEntries */,
129 unique_fd(-1) /* kernelWakelockStatsFd */, std::move(wakeupReasonsFd),
130 std::move(suspendTimeFd), kSleepTimeConfig, suspendControl, suspendControlInternal);
131
132 std::shared_ptr<SystemSuspendAidl> suspendAidl =
133 ndk::SharedRefBase::make<SystemSuspendAidl>(systemSuspend.get());
134 auto aidlBinder = suspendAidl->asBinder();
135 AIBinder_forceDowngradeToLocalStability(aidlBinder.get());
136 auto aidlStatus = AServiceManager_addService(aidlBinder.get(), kServiceName);
137 CHECK(aidlStatus == STATUS_OK);
138
139 joinRpcThreadpool();
140 });
141 testService.detach();
142 }
143
SetUpTestSuite()144 static void SetUpTestSuite() {
145 Socketpair(SOCK_STREAM, &wakeupCountFds[0], &wakeupCountFds[1]);
146 Socketpair(SOCK_STREAM, &stateFds[0], &stateFds[1]);
147
148 wakeupCountFd = wakeupCountFds[0];
149 stateFd = stateFds[0];
150
151 registerTestService();
152 std::shared_ptr<ISystemSuspend> suspendService = ISystemSuspend::fromBinder(
153 ndk::SpAIBinder(AServiceManager_waitForService(kServiceName)));
154 ASSERT_NE(suspendService, nullptr) << "failed to get suspend service";
155
156 sp<IBinder> control =
157 android::defaultServiceManager()->getService(android::String16(kControlServiceName));
158 ASSERT_NE(control, nullptr) << "failed to get the suspend control service";
159 sp<ISuspendControlService> controlService = interface_cast<ISuspendControlService>(control);
160
161 sp<IBinder> controlInternal = android::defaultServiceManager()->getService(
162 android::String16(kControlServiceInternalName));
163 ASSERT_NE(controlInternal, nullptr) << "failed to get the suspend control internal service";
164 sp<ISuspendControlServiceInternal> controlServiceInternal =
165 interface_cast<ISuspendControlServiceInternal>(controlInternal);
166
167 // Start auto-suspend.
168 bool enabled = false;
169 controlServiceInternal->enableAutosuspend(new BBinder(), &enabled);
170 ASSERT_EQ(enabled, true) << "failed to start autosuspend";
171 }
172
TearDownTestSuite()173 static void TearDownTestSuite() {
174 unblockSystemSuspendFromWakeupCount();
175 systemSuspend->disableAutosuspend();
176 }
177
178 public:
SetUp()179 virtual void SetUp() override {
180 suspendService = ISystemSuspend::fromBinder(
181 ndk::SpAIBinder(AServiceManager_waitForService(kServiceName)));
182 ASSERT_NE(suspendService, nullptr) << "failed to get suspend service";
183
184 sp<IBinder> control =
185 android::defaultServiceManager()->getService(android::String16(kControlServiceName));
186 ASSERT_NE(control, nullptr) << "failed to get the suspend control service";
187 controlService = interface_cast<ISuspendControlService>(control);
188
189 sp<IBinder> controlInternal = android::defaultServiceManager()->getService(
190 android::String16(kControlServiceInternalName));
191 ASSERT_NE(controlInternal, nullptr) << "failed to get the suspend control internal service";
192 controlServiceInternal = interface_cast<ISuspendControlServiceInternal>(controlInternal);
193
194 systemSuspend->enableAutosuspend(new BBinder());
195
196 // SystemSuspend HAL should not have written back to wakeupCountFd or stateFd yet.
197 ASSERT_TRUE(isReadBlocked(wakeupCountFd));
198 ASSERT_TRUE(isReadBlocked(stateFd));
199 }
200
TearDown()201 virtual void TearDown() override {
202 // Allow some time for the autosuspend loop to happen, if unblocked
203 std::this_thread::sleep_for(100ms);
204
205 if (!isReadBlocked(wakeupCountFd)) readFd(wakeupCountFd);
206 if (!isReadBlocked(stateFd)) readFd(stateFd);
207
208 ASSERT_TRUE(isReadBlocked(wakeupCountFd));
209 ASSERT_TRUE(isReadBlocked(stateFd));
210 }
211
unblockSystemSuspendFromWakeupCount()212 static void unblockSystemSuspendFromWakeupCount() {
213 std::string wakeupCount = std::to_string(rand());
214 ASSERT_TRUE(WriteStringToFd(wakeupCount, wakeupCountFd));
215 }
216
isSystemSuspendBlocked(int timeout_ms=20)217 bool isSystemSuspendBlocked(int timeout_ms = 20) {
218 // Allow some time for the autosuspend loop to happen, if unblocked
219 std::this_thread::sleep_for(100ms);
220
221 return isReadBlocked(stateFd, timeout_ms);
222 }
223
acquireWakeLock(const std::string & name="TestLock")224 std::shared_ptr<IWakeLock> acquireWakeLock(const std::string& name = "TestLock") {
225 std::shared_ptr<IWakeLock> wl = nullptr;
226 auto status = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name, &wl);
227 return wl;
228 }
229
getActiveWakeLockCount()230 size_t getActiveWakeLockCount() {
231 std::vector<WakeLockInfo> wlStats;
232 controlServiceInternal->getWakeLockStatsFiltered(
233 ISuspendControlServiceInternal::WAKE_LOCK_INFO_ACTIVE_COUNT, &wlStats);
234 return count_if(wlStats.begin(), wlStats.end(), [](auto entry) { return entry.isActive; });
235 }
236
237 // Wait for wakelock's active count to reach a certain value.
waitForActiveCount(const std::string & wl_name,int expectedCount,std::chrono::milliseconds timeout=std::chrono::milliseconds (100),std::chrono::milliseconds pollingInterval=std::chrono::milliseconds (10))238 bool waitForActiveCount(
239 const std::string& wl_name, int expectedCount,
240 std::chrono::milliseconds timeout = std::chrono::milliseconds(100),
241 std::chrono::milliseconds pollingInterval = std::chrono::milliseconds(10)) {
242 std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
243 while (std::chrono::steady_clock::now() - start_time < timeout) {
244 std::vector<WakeLockInfo> wlStats = getWakelockStats();
245 WakeLockInfo wlInfo;
246 if (findWakeLockInfoByName(wlStats, wl_name, &wlInfo) &&
247 wlInfo.activeCount == expectedCount) {
248 return true;
249 }
250 std::this_thread::sleep_for(pollingInterval);
251 }
252 return false;
253 }
254
checkLoop(int numIter)255 void checkLoop(int numIter) {
256 for (int i = 0; i < numIter; i++) {
257 // Mock value for /sys/power/wakeup_count.
258 std::string wakeupCount = std::to_string(rand());
259 ASSERT_TRUE(WriteStringToFd(wakeupCount, wakeupCountFd));
260 ASSERT_EQ(readFd(wakeupCountFd), wakeupCount)
261 << "wakeup count value written by SystemSuspend is not equal to value given to it";
262 ASSERT_EQ(readFd(stateFd), "mem")
263 << "SystemSuspend failed to write correct sleep state.";
264 }
265 }
266
checkWakelockLoop(int numIter,const std::string name)267 void checkWakelockLoop(int numIter, const std::string name) {
268 for (int i = 0; i < numIter; i++) {
269 std::shared_ptr<IWakeLock> testLock = acquireWakeLock(name);
270 testLock->release();
271 }
272 }
273
suspendFor(std::chrono::milliseconds suspendTime,int numberOfSuspends)274 void suspendFor(std::chrono::milliseconds suspendTime, int numberOfSuspends) {
275 std::string suspendStr =
276 "0.001 " /* placeholder */ +
277 std::to_string(
278 std::chrono::duration_cast<std::chrono::duration<double>>(suspendTime).count());
279 ASSERT_TRUE(WriteStringToFile(suspendStr, suspendTimeFile.path));
280 checkLoop(numberOfSuspends);
281 }
282
checkSleepTime(std::chrono::milliseconds expected)283 void checkSleepTime(std::chrono::milliseconds expected) {
284 // There is a race window where sleepTime can be checked in the tests,
285 // before it is updated in autoSuspend
286 while (!isReadBlocked(wakeupCountFd)) {
287 }
288 std::chrono::milliseconds actual = systemSuspend->getSleepTime();
289 ASSERT_EQ(actual.count(), expected.count()) << "incorrect sleep time";
290 }
291
findWakeLockInfoByName(const std::vector<WakeLockInfo> & wlStats,const std::string & name,WakeLockInfo * info)292 bool findWakeLockInfoByName(const std::vector<WakeLockInfo>& wlStats, const std::string& name,
293 WakeLockInfo* info) {
294 auto it = std::find_if(wlStats.begin(), wlStats.end(),
295 [&name](const auto& x) { return x.name == name; });
296 if (it != wlStats.end()) {
297 *info = *it;
298 return true;
299 }
300 return false;
301 }
302
getWakelockStats()303 std::vector<WakeLockInfo> getWakelockStats() {
304 std::vector<WakeLockInfo> wlStats;
305 controlServiceInternal->getWakeLockStats(&wlStats);
306 return wlStats;
307 }
308
309 std::shared_ptr<ISystemSuspend> suspendService;
310 sp<ISuspendControlService> controlService;
311 sp<ISuspendControlServiceInternal> controlServiceInternal;
312 static sp<SystemSuspend> systemSuspend;
313 static unique_fd wakeupCountFds[2];
314 static unique_fd stateFds[2];
315 static unique_fd wakeupReasonsFd;
316 static unique_fd suspendTimeFd;
317 static int wakeupCountFd;
318 static int stateFd;
319 static TemporaryFile wakeupReasonsFile;
320 static TemporaryFile suspendTimeFile;
321
322 static constexpr SleepTimeConfig kSleepTimeConfig = {
323 .baseSleepTime = 100ms,
324 .maxSleepTime = 400ms,
325 .sleepTimeScaleFactor = 1.9,
326 .backoffThreshold = 1,
327 .shortSuspendThreshold = 100ms,
328 .failedSuspendBackoffEnabled = true,
329 .shortSuspendBackoffEnabled = true,
330 };
331 };
332
333 // SystemSuspendTest test suite resources
334 sp<SystemSuspend> SystemSuspendTest::systemSuspend;
335 unique_fd SystemSuspendTest::wakeupCountFds[2];
336 unique_fd SystemSuspendTest::stateFds[2];
337 unique_fd SystemSuspendTest::wakeupReasonsFd;
338 unique_fd SystemSuspendTest::suspendTimeFd;
339 int SystemSuspendTest::wakeupCountFd;
340 int SystemSuspendTest::stateFd;
341 TemporaryFile SystemSuspendTest::wakeupReasonsFile;
342 TemporaryFile SystemSuspendTest::suspendTimeFile;
343
344 // Tests that autosuspend thread can only be enabled once.
TEST_F(SystemSuspendTest,OnlyOneEnableAutosuspend)345 TEST_F(SystemSuspendTest, OnlyOneEnableAutosuspend) {
346 bool enabled = false;
347 controlServiceInternal->enableAutosuspend(new BBinder(), &enabled);
348 ASSERT_EQ(enabled, false);
349 }
350
351 // Tests that autosuspend thread can only enabled again after its been disabled.
TEST_F(SystemSuspendTest,EnableAutosuspendAfterDisableAutosuspend)352 TEST_F(SystemSuspendTest, EnableAutosuspendAfterDisableAutosuspend) {
353 bool enabled = false;
354
355 checkLoop(1);
356 controlServiceInternal->enableAutosuspend(new BBinder(), &enabled);
357 ASSERT_FALSE(enabled);
358
359 systemSuspend->disableAutosuspend();
360 unblockSystemSuspendFromWakeupCount();
361
362 controlServiceInternal->enableAutosuspend(new BBinder(), &enabled);
363 ASSERT_TRUE(enabled);
364 }
365
TEST_F(SystemSuspendTest,DisableAutosuspendBlocksSuspend)366 TEST_F(SystemSuspendTest, DisableAutosuspendBlocksSuspend) {
367 checkLoop(1);
368 systemSuspend->disableAutosuspend();
369 unblockSystemSuspendFromWakeupCount();
370 ASSERT_TRUE(isSystemSuspendBlocked());
371
372 // Re-enable autosuspend
373 bool enabled = false;
374 controlServiceInternal->enableAutosuspend(new BBinder(), &enabled);
375 ASSERT_TRUE(enabled);
376 }
377
TEST_F(SystemSuspendTest,BlockAutosuspendIfBinderIsDead)378 TEST_F(SystemSuspendTest, BlockAutosuspendIfBinderIsDead) {
379 class DeadBinder : public BBinder {
380 android::status_t pingBinder() override { return android::UNKNOWN_ERROR; }
381 };
382
383 auto token = sp<DeadBinder>::make();
384
385 systemSuspend->disableAutosuspend();
386 unblockSystemSuspendFromWakeupCount();
387 ASSERT_TRUE(isSystemSuspendBlocked());
388
389 bool enabled = false;
390 controlServiceInternal->enableAutosuspend(token, &enabled);
391 unblockSystemSuspendFromWakeupCount();
392
393 ASSERT_TRUE(isSystemSuspendBlocked(150));
394 }
395
TEST_F(SystemSuspendTest,UnresponsiveClientDoesNotBlockAcquireRelease)396 TEST_F(SystemSuspendTest, UnresponsiveClientDoesNotBlockAcquireRelease) {
397 static std::mutex _lock;
398 static std::condition_variable inPingBinderCondVar;
399 static bool inPingBinder = false;
400
401 class UnresponsiveBinder : public BBinder {
402 android::status_t pingBinder() override {
403 auto lock = std::unique_lock(_lock);
404 inPingBinder = true;
405 inPingBinderCondVar.notify_all();
406
407 // Block pingBinder until test finishes and releases its lock
408 inPingBinderCondVar.wait(lock);
409 return android::UNKNOWN_ERROR;
410 }
411 };
412
413 systemSuspend->disableAutosuspend();
414 unblockSystemSuspendFromWakeupCount();
415 ASSERT_TRUE(isSystemSuspendBlocked());
416
417 auto token = sp<UnresponsiveBinder>::make();
418 bool enabled = false;
419 controlServiceInternal->enableAutosuspend(token, &enabled);
420 unblockSystemSuspendFromWakeupCount();
421
422 auto lock = std::unique_lock(_lock);
423 // wait until pingBinder has been called.
424 if (!inPingBinder) {
425 inPingBinderCondVar.wait(lock);
426 }
427 // let pingBinder finish once we release the test lock
428 inPingBinderCondVar.notify_all();
429
430 std::condition_variable wakeLockAcquired;
431 std::thread(
432 [this](std::condition_variable& wakeLockAcquired) {
433 std::shared_ptr<IWakeLock> testLock = acquireWakeLock("testLock");
434 testLock->release();
435 wakeLockAcquired.notify_all();
436 },
437 std::ref(wakeLockAcquired))
438 .detach();
439
440 std::mutex _acquireReleaseLock;
441 auto acquireReleaseLock = std::unique_lock(_acquireReleaseLock);
442 bool timedOut = wakeLockAcquired.wait_for(acquireReleaseLock, 200ms) == std::cv_status::timeout;
443
444 ASSERT_FALSE(timedOut);
445 }
446
TEST_F(SystemSuspendTest,AutosuspendLoop)447 TEST_F(SystemSuspendTest, AutosuspendLoop) {
448 checkLoop(5);
449 }
450
451 // Tests that upon WakeLock destruction SystemSuspend HAL is unblocked.
TEST_F(SystemSuspendTest,WakeLockDestructor)452 TEST_F(SystemSuspendTest, WakeLockDestructor) {
453 {
454 std::shared_ptr<IWakeLock> wl = acquireWakeLock();
455 ASSERT_NE(wl, nullptr);
456 unblockSystemSuspendFromWakeupCount();
457 ASSERT_TRUE(isSystemSuspendBlocked());
458 }
459 ASSERT_FALSE(isSystemSuspendBlocked());
460 }
461
462 // Tests that upon WakeLock::release() SystemSuspend HAL is unblocked.
TEST_F(SystemSuspendTest,WakeLockRelease)463 TEST_F(SystemSuspendTest, WakeLockRelease) {
464 std::shared_ptr<IWakeLock> wl = acquireWakeLock();
465 ASSERT_NE(wl, nullptr);
466 unblockSystemSuspendFromWakeupCount();
467 ASSERT_TRUE(isSystemSuspendBlocked());
468 wl->release();
469 ASSERT_FALSE(isSystemSuspendBlocked());
470 }
471
472 // Tests that multiple WakeLocks correctly block SystemSuspend HAL.
TEST_F(SystemSuspendTest,MultipleWakeLocks)473 TEST_F(SystemSuspendTest, MultipleWakeLocks) {
474 {
475 std::shared_ptr<IWakeLock> wl1 = acquireWakeLock();
476 ASSERT_NE(wl1, nullptr);
477 ASSERT_TRUE(isSystemSuspendBlocked());
478 {
479 std::shared_ptr<IWakeLock> wl2 = acquireWakeLock();
480 ASSERT_NE(wl2, nullptr);
481 unblockSystemSuspendFromWakeupCount();
482 ASSERT_TRUE(isSystemSuspendBlocked());
483 }
484 ASSERT_TRUE(isSystemSuspendBlocked());
485 }
486 ASSERT_FALSE(isSystemSuspendBlocked());
487 }
488
489 // Tests that upon thread deallocation WakeLock is destructed and SystemSuspend HAL is unblocked.
TEST_F(SystemSuspendTest,ThreadCleanup)490 TEST_F(SystemSuspendTest, ThreadCleanup) {
491 std::thread clientThread([this] {
492 std::shared_ptr<IWakeLock> wl = acquireWakeLock();
493 ASSERT_NE(wl, nullptr);
494 unblockSystemSuspendFromWakeupCount();
495 ASSERT_TRUE(isSystemSuspendBlocked());
496 });
497 clientThread.join();
498 ASSERT_FALSE(isSystemSuspendBlocked());
499 }
500
501 // Test that binder driver correctly deallocates acquired WakeLocks, even if the client processs
502 // is terminated without ability to do clean up.
TEST_F(SystemSuspendTest,CleanupOnAbort)503 TEST_F(SystemSuspendTest, CleanupOnAbort) {
504 ASSERT_EXIT(
505 {
506 std::shared_ptr<IWakeLock> wl = acquireWakeLock();
507 ASSERT_NE(wl, nullptr);
508 std::abort();
509 },
510 ::testing::KilledBySignal(SIGABRT), "");
511 ASSERT_TRUE(isSystemSuspendBlocked());
512 unblockSystemSuspendFromWakeupCount();
513 // Timing of the wake lock clean-up after process death is scheduler-dependent.
514 // Increase the timeout to avoid flakes.
515 ASSERT_FALSE(isSystemSuspendBlocked(200));
516 }
517
518 // Stress test acquiring/releasing WakeLocks.
TEST_F(SystemSuspendTest,WakeLockStressTest)519 TEST_F(SystemSuspendTest, WakeLockStressTest) {
520 // numThreads threads will acquire/release numLocks locks each.
521 constexpr int numThreads = 10;
522 constexpr int numLocks = 10000;
523 std::thread tds[numThreads];
524
525 for (int i = 0; i < numThreads; i++) {
526 tds[i] = std::thread([this] {
527 for (int j = 0; j < numLocks; j++) {
528 std::shared_ptr<IWakeLock> wl1 = acquireWakeLock();
529 std::shared_ptr<IWakeLock> wl2 = acquireWakeLock();
530 wl2->release();
531 }
532 });
533 }
534 for (int i = 0; i < numThreads; i++) {
535 tds[i].join();
536 }
537 ASSERT_EQ(getActiveWakeLockCount(), 0);
538 }
539
TEST_F(SystemSuspendTest,SuspendBackoffLongSuspendTest)540 TEST_F(SystemSuspendTest, SuspendBackoffLongSuspendTest) {
541 // Sleep time shall be set to base sleep time after a long suspend
542 suspendFor(10000ms, 1);
543 checkSleepTime(kSleepTimeConfig.baseSleepTime);
544 }
545
TEST_F(SystemSuspendTest,BackoffThresholdTest)546 TEST_F(SystemSuspendTest, BackoffThresholdTest) {
547 // Sleep time shall be set to base sleep time after a long suspend
548 suspendFor(10000ms, 1);
549 checkSleepTime(kSleepTimeConfig.baseSleepTime);
550
551 // Sleep time shall back off after the configured backoff threshold
552 std::chrono::milliseconds expectedSleepTime = std::chrono::round<std::chrono::milliseconds>(
553 kSleepTimeConfig.baseSleepTime * kSleepTimeConfig.sleepTimeScaleFactor);
554 suspendFor(10ms, kSleepTimeConfig.backoffThreshold);
555 checkSleepTime(kSleepTimeConfig.baseSleepTime);
556 suspendFor(10ms, 1);
557 checkSleepTime(expectedSleepTime);
558
559 // Sleep time shall return to base sleep time after a long suspend
560 suspendFor(10000ms, 1);
561 checkSleepTime(kSleepTimeConfig.baseSleepTime);
562 }
563
TEST_F(SystemSuspendTest,SuspendBackoffMaxTest)564 TEST_F(SystemSuspendTest, SuspendBackoffMaxTest) {
565 // Sleep time shall be set to base sleep time after a long suspend
566 suspendFor(10000ms, 1);
567 checkSleepTime(kSleepTimeConfig.baseSleepTime);
568
569 // Sleep time shall be capped at the configured maximum
570 suspendFor(10ms, 3 + kSleepTimeConfig.backoffThreshold);
571 checkSleepTime(kSleepTimeConfig.maxSleepTime);
572
573 // Sleep time shall return to base sleep time after a long suspend
574 suspendFor(10000ms, 1);
575 checkSleepTime(kSleepTimeConfig.baseSleepTime);
576 }
577
578 // Callbacks are passed around as sp<>. However, mock expectations are verified when mock objects
579 // are destroyed, i.e. the test needs to control lifetime of the mock object.
580 // MockCallbackImpl can be destroyed independently of its wrapper MockCallback which is passed to
581 // SystemSuspend.
582 struct MockCallbackImpl {
notifyWakeupandroid::MockCallbackImpl583 binder::Status notifyWakeup([[maybe_unused]] bool success,
584 const std::vector<std::string>& wakeupReasons) {
585 mWakeupReasons = wakeupReasons;
586 mNumWakeups++;
587 return binder::Status::ok();
588 }
589
590 std::vector<std::string> mWakeupReasons;
591 int mNumWakeups = 0;
592 };
593
594 class MockCallback : public BnSuspendCallback {
595 public:
MockCallback(MockCallbackImpl * impl)596 MockCallback(MockCallbackImpl* impl) : mImpl(impl), mDisabled(false) {}
notifyWakeup(bool x,const std::vector<std::string> & wakeupReasons)597 binder::Status notifyWakeup(bool x, const std::vector<std::string>& wakeupReasons) {
598 return mDisabled ? binder::Status::ok() : mImpl->notifyWakeup(x, wakeupReasons);
599 }
600 // In case we pull the rug from under MockCallback, but SystemSuspend still has an sp<> to the
601 // object.
disable()602 void disable() { mDisabled = true; }
603
604 private:
605 MockCallbackImpl* mImpl;
606 bool mDisabled;
607 };
608
609 // Tests that nullptr can't be registered as callbacks.
TEST_F(SystemSuspendTest,RegisterInvalidCallback)610 TEST_F(SystemSuspendTest, RegisterInvalidCallback) {
611 bool retval = false;
612 controlService->registerCallback(nullptr, &retval);
613 ASSERT_FALSE(retval);
614 }
615
616 // Tests that SystemSuspend HAL correctly notifies wakeup events.
TEST_F(SystemSuspendTest,CallbackNotifyWakeup)617 TEST_F(SystemSuspendTest, CallbackNotifyWakeup) {
618 constexpr int numWakeups = 5;
619 MockCallbackImpl impl;
620 sp<MockCallback> cb = new MockCallback(&impl);
621 bool retval = false;
622 controlService->registerCallback(cb, &retval);
623 ASSERT_TRUE(retval);
624 checkLoop(numWakeups + 1);
625 cb->disable();
626 // SystemSuspend should suspend numWakeup + 1 times. However, it might
627 // only be able to notify numWakeup times. The test case might have
628 // finished by the time last notification completes.
629 ASSERT_GE(impl.mNumWakeups, numWakeups);
630 }
631
632 // Tests that SystemSuspend HAL correctly notifies wakeup subscribers with wakeup reasons.
TEST_F(SystemSuspendTest,CallbackNotifyWakeupReason)633 TEST_F(SystemSuspendTest, CallbackNotifyWakeupReason) {
634 int i;
635 const std::string wakeupReason0 = "";
636 const std::string wakeupReason1 = " ";
637 const std::string wakeupReason2 = "\n\n";
638 const std::string wakeupReason3 = "100 :android,wakeup-reason-1";
639 const std::string wakeupReason4 = "Abort: android,wakeup-reason-2\n";
640 const std::string wakeupReason5 =
641 "999 :android,wakeup-reason-3\nAbort: android,wakeup-reason-3\n";
642 const std::string referenceWakeupUnknown = "unknown";
643 const std::string referenceWakeupReason3 = "100 :android,wakeup-reason-1";
644 const std::string referenceWakeupReason4 = "Abort: android,wakeup-reason-2";
645 const std::vector<std::string> referenceWakeupReason5 = {"999 :android,wakeup-reason-3",
646 "Abort: android,wakeup-reason-3"};
647
648 unique_fd wakeupReasonsWriteFd = unique_fd(
649 TEMP_FAILURE_RETRY(open(SystemSuspendTest::wakeupReasonsFile.path, O_CLOEXEC | O_WRONLY)));
650
651 MockCallbackImpl impl;
652 sp<MockCallback> cb = new MockCallback(&impl);
653
654 bool retval = false;
655 controlService->registerCallback(cb, &retval);
656 ASSERT_TRUE(retval);
657
658 // wakeupReason0 empty wakeup reason
659 // Following assert check may happen before a callback been executed, iterate few checkLoop to
660 // make sure at least one callback been finished.
661 checkLoop(3);
662 ASSERT_EQ(impl.mWakeupReasons.size(), 1);
663 ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupUnknown);
664
665 // wakeupReason1 single invalid wakeup reason with only space.
666 ASSERT_TRUE(WriteStringToFd(wakeupReason1, wakeupReasonsWriteFd));
667 checkLoop(3);
668 ASSERT_EQ(impl.mWakeupReasons.size(), 1);
669 ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupUnknown);
670
671 // wakeupReason2 two empty wakeup reasons.
672 lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
673 ASSERT_TRUE(WriteStringToFd(wakeupReason2, wakeupReasonsWriteFd));
674 checkLoop(3);
675 ASSERT_EQ(impl.mWakeupReasons.size(), 1);
676 ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupUnknown);
677
678 // wakeupReason3 single wakeup reasons.
679 lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
680 ASSERT_TRUE(WriteStringToFd(wakeupReason3, wakeupReasonsWriteFd));
681 checkLoop(3);
682 ASSERT_EQ(impl.mWakeupReasons.size(), 1);
683 ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupReason3);
684
685 // wakeupReason4 two wakeup reasons with one empty.
686 lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
687 ASSERT_TRUE(WriteStringToFd(wakeupReason4, wakeupReasonsWriteFd));
688 checkLoop(3);
689 ASSERT_EQ(impl.mWakeupReasons.size(), 1);
690 ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupReason4);
691
692 // wakeupReason5 two wakeup reasons.
693 lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
694 ASSERT_TRUE(WriteStringToFd(wakeupReason5, wakeupReasonsWriteFd));
695 checkLoop(3);
696 ASSERT_EQ(impl.mWakeupReasons.size(), 2);
697 i = 0;
698 for (auto wakeupReason : impl.mWakeupReasons) {
699 ASSERT_EQ(wakeupReason, referenceWakeupReason5[i++]);
700 }
701 cb->disable();
702 }
703
704 // Tests that SystemSuspend HAL correctly deals with a dead callback.
TEST_F(SystemSuspendTest,DeadCallback)705 TEST_F(SystemSuspendTest, DeadCallback) {
706 ASSERT_EXIT(
707 {
708 sp<MockCallback> cb = new MockCallback(nullptr);
709 bool retval = false;
710 controlService->registerCallback(cb, &retval);
711 ASSERT_TRUE(retval);
712 std::exit(0);
713 },
714 ::testing::ExitedWithCode(0), "");
715
716 // Dead process callback must still be dealt with either by unregistering it
717 // or checking isOk() on every call.
718 checkLoop(3);
719 }
720
721 // Callback that registers another callback.
722 class CbRegisteringCb : public BnSuspendCallback {
723 public:
CbRegisteringCb(sp<ISuspendControlService> controlService)724 CbRegisteringCb(sp<ISuspendControlService> controlService) : mControlService(controlService) {}
notifyWakeup(bool x,const std::vector<std::string> & wakeupReasons)725 binder::Status notifyWakeup([[maybe_unused]] bool x,
726 [[maybe_unused]] const std::vector<std::string>& wakeupReasons) {
727 sp<MockCallback> cb = new MockCallback(nullptr);
728 cb->disable();
729 bool retval = false;
730 mControlService->registerCallback(cb, &retval);
731 return binder::Status::ok();
732 }
733
734 private:
735 sp<ISuspendControlService> mControlService;
736 };
737
738 // Tests that callback registering another callback doesn't result in a deadlock.
TEST_F(SystemSuspendTest,CallbackRegisterCallbackNoDeadlock)739 TEST_F(SystemSuspendTest, CallbackRegisterCallbackNoDeadlock) {
740 sp<CbRegisteringCb> cb = new CbRegisteringCb(controlService);
741 bool retval = false;
742 controlService->registerCallback(cb, &retval);
743 ASSERT_TRUE(retval);
744 checkLoop(3);
745 }
746
747 struct MockWakelockCallbackImpl {
748 MOCK_METHOD0(notifyAcquired, binder::Status());
749 MOCK_METHOD0(notifyReleased, binder::Status());
750 };
751
752 class MockWakelockCallback : public BnWakelockCallback {
753 public:
MockWakelockCallback(MockWakelockCallbackImpl * impl)754 MockWakelockCallback(MockWakelockCallbackImpl* impl) : mImpl(impl), mDisabled(false) {}
notifyAcquired(void)755 binder::Status notifyAcquired(void) {
756 return mDisabled ? binder::Status::ok() : mImpl->notifyAcquired();
757 }
notifyReleased(void)758 binder::Status notifyReleased(void) {
759 return mDisabled ? binder::Status::ok() : mImpl->notifyReleased();
760 }
761 // In case we pull the rug from under MockWakelockCallback, but SystemSuspend still has an sp<>
762 // to the object.
disable()763 void disable() { mDisabled = true; }
764
765 private:
766 MockWakelockCallbackImpl* mImpl;
767 bool mDisabled;
768 };
769
770 // Tests that nullptr can't be registered as wakelock callbacks.
TEST_F(SystemSuspendTest,RegisterInvalidWakelockCallback)771 TEST_F(SystemSuspendTest, RegisterInvalidWakelockCallback) {
772 bool retval = false;
773 controlService->registerWakelockCallback(nullptr, "testLock", &retval);
774 ASSERT_FALSE(retval);
775 }
776
777 // Tests that the a callback cannot be registeed with a wakelock twice.
TEST_F(SystemSuspendTest,RegisterCallbackTwice)778 TEST_F(SystemSuspendTest, RegisterCallbackTwice) {
779 bool retval = false;
780 MockWakelockCallbackImpl impl;
781 sp<MockWakelockCallback> cb = new MockWakelockCallback(&impl);
782
783 controlService->registerWakelockCallback(cb, "testLock", &retval);
784 ASSERT_TRUE(retval);
785 controlService->registerWakelockCallback(cb, "testLock", &retval);
786 ASSERT_FALSE(retval);
787
788 cb->disable();
789 }
790
791 // Tests that the same callback can be registered with two wakelocks.
TEST_F(SystemSuspendTest,RegisterSameCallbackForTwoWakelocks)792 TEST_F(SystemSuspendTest, RegisterSameCallbackForTwoWakelocks) {
793 bool retval = false;
794 MockWakelockCallbackImpl impl;
795 sp<MockWakelockCallback> cb = new MockWakelockCallback(&impl);
796
797 controlService->registerWakelockCallback(cb, "testLock1", &retval);
798 ASSERT_TRUE(retval);
799 controlService->registerWakelockCallback(cb, "testLock2", &retval);
800 ASSERT_TRUE(retval);
801
802 cb->disable();
803 }
804
805 // Tests that the two callbacks can be registered with the same wakelock.
TEST_F(SystemSuspendTest,RegisterTwoCallbacksForSameWakelock)806 TEST_F(SystemSuspendTest, RegisterTwoCallbacksForSameWakelock) {
807 bool retval = false;
808 MockWakelockCallbackImpl impl;
809 sp<MockWakelockCallback> cb1 = new MockWakelockCallback(&impl);
810 sp<MockWakelockCallback> cb2 = new MockWakelockCallback(&impl);
811
812 controlService->registerWakelockCallback(cb1, "testLock", &retval);
813 ASSERT_TRUE(retval);
814 controlService->registerWakelockCallback(cb2, "testLock", &retval);
815 ASSERT_TRUE(retval);
816
817 cb1->disable();
818 cb2->disable();
819 }
820
821 // Tests that SystemSuspend HAL correctly deals with a dead wakelock callback.
TEST_F(SystemSuspendTest,DeadWakelockCallback)822 TEST_F(SystemSuspendTest, DeadWakelockCallback) {
823 ASSERT_EXIT(
824 {
825 sp<MockWakelockCallback> cb = new MockWakelockCallback(nullptr);
826 bool retval = false;
827 controlService->registerWakelockCallback(cb, "testLock", &retval);
828 ASSERT_TRUE(retval);
829 std::exit(0);
830 },
831 ::testing::ExitedWithCode(0), "");
832
833 // Dead process callback must still be dealt with either by unregistering it
834 // or checking isOk() on every call.
835 std::shared_ptr<IWakeLock> testLock = acquireWakeLock("testLock");
836 ASSERT_TRUE(testLock->release().isOk());
837 }
838
839 // Wakelock callback that registers another callback.
840 class WakelockCbRegisteringCb : public BnWakelockCallback {
841 public:
WakelockCbRegisteringCb(sp<ISuspendControlService> controlService)842 WakelockCbRegisteringCb(sp<ISuspendControlService> controlService)
843 : mControlService(controlService) {}
notifyAcquired(void)844 binder::Status notifyAcquired(void) {
845 sp<MockWakelockCallback> cb = new MockWakelockCallback(nullptr);
846 cb->disable();
847 bool retval = false;
848 mControlService->registerWakelockCallback(cb, "testLock", &retval);
849 return binder::Status::ok();
850 }
notifyReleased(void)851 binder::Status notifyReleased(void) {
852 sp<MockWakelockCallback> cb = new MockWakelockCallback(nullptr);
853 cb->disable();
854 bool retval = false;
855 mControlService->registerWakelockCallback(cb, "testLock", &retval);
856 return binder::Status::ok();
857 }
858
859 private:
860 sp<ISuspendControlService> mControlService;
861 };
862
TEST_F(SystemSuspendTest,WakelockCallbackRegisterCallbackNoDeadlock)863 TEST_F(SystemSuspendTest, WakelockCallbackRegisterCallbackNoDeadlock) {
864 sp<WakelockCbRegisteringCb> cb = new WakelockCbRegisteringCb(controlService);
865 bool retval = false;
866 controlService->registerWakelockCallback(cb, "testLock", &retval);
867 ASSERT_TRUE(retval);
868
869 checkWakelockLoop(3, "testLock");
870 }
871
872 // Tests that SystemSuspend HAL correctly notifies wakelock events.
TEST_F(SystemSuspendTest,CallbackNotifyWakelock)873 TEST_F(SystemSuspendTest, CallbackNotifyWakelock) {
874 bool retval = false;
875 MockWakelockCallbackImpl impl1;
876 MockWakelockCallbackImpl impl2;
877 sp<MockWakelockCallback> cb1 = new MockWakelockCallback(&impl1);
878 sp<MockWakelockCallback> cb2 = new MockWakelockCallback(&impl2);
879
880 controlService->registerWakelockCallback(cb1, "testLock1", &retval);
881 ASSERT_TRUE(retval);
882 controlService->registerWakelockCallback(cb2, "testLock2", &retval);
883 ASSERT_TRUE(retval);
884
885 EXPECT_CALL(impl1, notifyAcquired).Times(4);
886 EXPECT_CALL(impl1, notifyReleased).Times(4);
887 EXPECT_CALL(impl2, notifyAcquired).Times(3);
888 EXPECT_CALL(impl2, notifyReleased).Times(3);
889
890 checkWakelockLoop(4, "testLock1");
891 checkWakelockLoop(3, "testLock2");
892
893 cb1->disable();
894 cb2->disable();
895 }
896
897 // Tests for a potential race condition in wakelock stats updates.
898 // This checks wakelock accounting when a wakelock is acquired and released, and a re-acquire
899 // happens immediately.
TEST_F(SystemSuspendTest,WakeLockStatsRaceConditionTest)900 TEST_F(SystemSuspendTest, WakeLockStatsRaceConditionTest) {
901 constexpr int kNumRetries = 100;
902
903 for (int i = 0; i < kNumRetries; i++) {
904 std::string testLockName = "testLock" + std::to_string(i + 1);
905
906 std::shared_ptr<IWakeLock> wlA = acquireWakeLock(testLockName);
907 ASSERT_NE(wlA, nullptr);
908
909 // Release the wakelock. This executes async as 'release()' is marked oneway.
910 wlA->release();
911
912 // Immediately re-acquire the wakelock.
913 std::shared_ptr<IWakeLock> wlB = acquireWakeLock(testLockName);
914 ASSERT_NE(wlB, nullptr);
915
916 // Let the release operation complete.
917 EXPECT_TRUE(waitForActiveCount(testLockName, 1))
918 << "Timeout waiting for activeCount to reach 1 (retry: " << i << ")";
919
920 std::vector<WakeLockInfo> wlStats = getWakelockStats();
921 WakeLockInfo wlInfo;
922 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
923 EXPECT_TRUE(wlInfo.isActive);
924 EXPECT_EQ(wlInfo.activeCount, 1);
925
926 wlB->release();
927 EXPECT_TRUE(waitForActiveCount(testLockName, 0))
928 << "Timeout waiting for activeCount to reach 0 (retry: " << i << ")";
929
930 wlStats = getWakelockStats();
931 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
932 EXPECT_FALSE(wlInfo.isActive);
933 EXPECT_EQ(wlInfo.activeCount, 0);
934 EXPECT_EQ(wlInfo.activeTime, 0);
935 }
936 }
937
938 // Tests for correctness of the wakelock active count, active status and active time when multiple
939 // wakelocks of the same name are acquired and released sequentially.
940 // Order tested: Acq A -> Acq B -> Rel A -> Rel B.
TEST_F(SystemSuspendTest,WakeLockStatsActiveCountDecrementCheck)941 TEST_F(SystemSuspendTest, WakeLockStatsActiveCountDecrementCheck) {
942 std::string testLockName = "testLock";
943
944 std::shared_ptr<IWakeLock> wlA = acquireWakeLock(testLockName);
945 ASSERT_NE(wlA, nullptr);
946
947 std::vector<WakeLockInfo> wlStats = getWakelockStats();
948 WakeLockInfo wlInfo;
949 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
950 EXPECT_TRUE(wlInfo.isActive);
951 EXPECT_EQ(wlInfo.activeCount, 1);
952
953 std::shared_ptr<IWakeLock> wlB = acquireWakeLock(testLockName);
954 ASSERT_NE(wlB, nullptr);
955
956 wlStats = getWakelockStats();
957 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
958 EXPECT_TRUE(wlInfo.isActive);
959 EXPECT_EQ(wlInfo.activeCount, 2);
960
961 wlA->release();
962 // Let the release operation complete.
963 EXPECT_TRUE(waitForActiveCount(testLockName, 1))
964 << "Timeout waiting for activeCount to reach 1";
965 // Sleep for 5ms to test activeTime update later.
966 std::this_thread::sleep_for(5ms);
967
968 wlStats = getWakelockStats();
969 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
970 // wlB of the same name is yet to be released.
971 EXPECT_TRUE(wlInfo.isActive);
972 EXPECT_EQ(wlInfo.activeCount, 1);
973 EXPECT_GE(wlInfo.activeTime, 5);
974
975 wlB->release();
976 EXPECT_TRUE(waitForActiveCount(testLockName, 0))
977 << "Timeout waiting for activeCount to reach 0";
978
979 wlStats = getWakelockStats();
980 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
981 EXPECT_FALSE(wlInfo.isActive);
982 EXPECT_EQ(wlInfo.activeCount, 0);
983 EXPECT_EQ(wlInfo.activeTime, 0);
984 }
985
986 // Tests for correctness of the wakelock active count, active status and active time when multiple
987 // wakelocks are acquired and released sequentially.
988 // Order tested: Acq A -> Acq B -> Rel B -> Rel A.
TEST_F(SystemSuspendTest,WakeLockStatsAcquiredReleasedInLIFOOrder)989 TEST_F(SystemSuspendTest, WakeLockStatsAcquiredReleasedInLIFOOrder) {
990 std::string testLockName = "testLock";
991
992 std::shared_ptr<IWakeLock> wlA = acquireWakeLock(testLockName);
993 ASSERT_NE(wlA, nullptr);
994
995 std::vector<WakeLockInfo> wlStats = getWakelockStats();
996 WakeLockInfo wlInfo;
997 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
998 EXPECT_TRUE(wlInfo.isActive);
999 EXPECT_EQ(wlInfo.activeCount, 1);
1000
1001 std::shared_ptr<IWakeLock> wlB = acquireWakeLock(testLockName);
1002 ASSERT_NE(wlB, nullptr);
1003
1004 wlStats = getWakelockStats();
1005 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
1006 EXPECT_TRUE(wlInfo.isActive);
1007 EXPECT_EQ(wlInfo.activeCount, 2);
1008
1009 wlB->release();
1010 // Let the release operation complete.
1011 EXPECT_TRUE(waitForActiveCount(testLockName, 1))
1012 << "Timeout waiting for activeCount to reach 1";
1013 // Sleep for 5ms to test activeTime update later.
1014 std::this_thread::sleep_for(5ms);
1015
1016 wlStats = getWakelockStats();
1017 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
1018 // wlB of the same name is yet to be released.
1019 EXPECT_TRUE(wlInfo.isActive);
1020 EXPECT_EQ(wlInfo.activeCount, 1);
1021 EXPECT_GE(wlInfo.activeTime, 5);
1022
1023 wlA->release();
1024 EXPECT_TRUE(waitForActiveCount(testLockName, 0))
1025 << "Timeout waiting for activeCount to reach 0";
1026
1027 wlStats = getWakelockStats();
1028 ASSERT_TRUE(findWakeLockInfoByName(wlStats, testLockName, &wlInfo));
1029 EXPECT_FALSE(wlInfo.isActive);
1030 EXPECT_EQ(wlInfo.activeCount, 0);
1031 EXPECT_EQ(wlInfo.activeTime, 0);
1032 }
1033
1034 class SystemSuspendSameThreadTest : public ::testing::Test {
1035 public:
acquireWakeLock(const std::string & name="TestLock")1036 std::shared_ptr<IWakeLock> acquireWakeLock(const std::string& name = "TestLock") {
1037 std::shared_ptr<IWakeLock> wl = nullptr;
1038 auto status = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name, &wl);
1039 return wl;
1040 }
1041
1042 /**
1043 * Returns true if wake lock is found else false.
1044 */
findWakeLockInfoByName(const std::vector<WakeLockInfo> & wlStats,const std::string & name,WakeLockInfo * info)1045 bool findWakeLockInfoByName(const std::vector<WakeLockInfo>& wlStats, const std::string& name,
1046 WakeLockInfo* info) {
1047 auto it = std::find_if(wlStats.begin(), wlStats.end(),
1048 [&name](const auto& x) { return x.name == name; });
1049 if (it != wlStats.end()) {
1050 *info = *it;
1051 return true;
1052 }
1053 return false;
1054 }
1055
writeStatToFile(int statDirFd,const std::string & fileName,const std::string & stat)1056 bool writeStatToFile(int statDirFd, const std::string& fileName, const std::string& stat) {
1057 unique_fd statFd{TEMP_FAILURE_RETRY(
1058 openat(statDirFd, fileName.c_str(), O_CREAT | O_CLOEXEC | O_RDWR, S_IRWXU))};
1059 if (statFd < 0) {
1060 PLOG(ERROR) << "SystemSuspend: Error opening " << fileName;
1061 return false;
1062 }
1063
1064 if (!WriteStringToFd(stat, statFd.get())) {
1065 PLOG(ERROR) << "SystemSuspend: Error writing stat to " << fileName;
1066 return false;
1067 }
1068
1069 return true;
1070 }
1071
writeStatToFile(int statDirFd,const std::string & fileName,int64_t stat)1072 bool writeStatToFile(int statDirFd, const std::string& fileName, int64_t stat) {
1073 return writeStatToFile(statDirFd, fileName, std::to_string(stat));
1074 }
1075
1076 /**
1077 * Creates a kernel wakelock directory and stats files.
1078 * Returns true on success else false.
1079 */
addKernelWakelock(const std::string & name,int64_t activeCount=42,int64_t activeTime=42,int64_t eventCount=42,int64_t expireCount=42,int64_t lastChange=42,int64_t maxTime=42,int64_t preventSuspendTime=42,int64_t totalTime=42,int64_t wakeupCount=42)1080 bool addKernelWakelock(const std::string& name, int64_t activeCount = 42,
1081 int64_t activeTime = 42, int64_t eventCount = 42,
1082 int64_t expireCount = 42, int64_t lastChange = 42, int64_t maxTime = 42,
1083 int64_t preventSuspendTime = 42, int64_t totalTime = 42,
1084 int64_t wakeupCount = 42) {
1085 static int id = 0;
1086 std::string kwlId = "wakeup" + std::to_string(id++);
1087
1088 if ((mkdirat(kernelWakelockStatsFd, kwlId.c_str(), S_IRWXU)) < 0) {
1089 PLOG(ERROR) << "SystemSuspend: Error creating directory for " << kwlId;
1090 return false;
1091 }
1092
1093 unique_fd kernelWakelockFd{TEMP_FAILURE_RETRY(
1094 openat(kernelWakelockStatsFd, kwlId.c_str(), O_DIRECTORY | O_CLOEXEC | O_RDONLY))};
1095 if (kernelWakelockFd < 0) {
1096 PLOG(ERROR) << "SystemSuspend: Error opening " << kwlId;
1097 return false;
1098 }
1099
1100 int fd = kernelWakelockFd.get();
1101
1102 return writeStatToFile(fd, "name", name) &&
1103 writeStatToFile(fd, "active_count", activeCount) &&
1104 writeStatToFile(fd, "active_time_ms", activeTime) &&
1105 writeStatToFile(fd, "event_count", eventCount) &&
1106 writeStatToFile(fd, "expire_count", expireCount) &&
1107 writeStatToFile(fd, "last_change_ms", lastChange) &&
1108 writeStatToFile(fd, "max_time_ms", maxTime) &&
1109 writeStatToFile(fd, "prevent_suspend_time_ms", preventSuspendTime) &&
1110 writeStatToFile(fd, "total_time_ms", totalTime) &&
1111 writeStatToFile(fd, "wakeup_count", wakeupCount);
1112 }
1113
1114 /**
1115 * Adds Suspend stats files to suspendStatDir.
1116 * Returns true on success else false.
1117 */
addSuspendStats(int64_t success=42,int64_t fail=42,int64_t failedFreeze=42,int64_t failedPrepare=42,int64_t failedSuspend=42,int64_t failedSuspendLate=42,int64_t failedSuspendNoirq=42,int64_t failedResume=42,int64_t failedResumeEarly=42,int64_t failedResumeNoirq=42,const std::string & lastFailedDev="fakeDev",int64_t lastFailedErrno=-42,const std::string & lastFailedStep="fakeStep",uint64_t lastHwSleep=42,uint64_t totalHwSleep=42,uint64_t maxHwSleep=523986009990)1118 bool addSuspendStats(int64_t success = 42, int64_t fail = 42, int64_t failedFreeze = 42,
1119 int64_t failedPrepare = 42, int64_t failedSuspend = 42,
1120 int64_t failedSuspendLate = 42, int64_t failedSuspendNoirq = 42,
1121 int64_t failedResume = 42, int64_t failedResumeEarly = 42,
1122 int64_t failedResumeNoirq = 42,
1123 const std::string& lastFailedDev = "fakeDev",
1124 int64_t lastFailedErrno = -42,
1125 const std::string& lastFailedStep = "fakeStep", uint64_t lastHwSleep = 42,
1126 uint64_t totalHwSleep = 42, uint64_t maxHwSleep = 523986009990) {
1127 int fd = suspendStatsFd.get();
1128
1129 return writeStatToFile(fd, "success", success) && writeStatToFile(fd, "fail", fail) &&
1130 writeStatToFile(fd, "failed_freeze", failedFreeze) &&
1131 writeStatToFile(fd, "failed_prepare", failedPrepare) &&
1132 writeStatToFile(fd, "failed_suspend", failedSuspend) &&
1133 writeStatToFile(fd, "failed_suspend_late", failedSuspendLate) &&
1134 writeStatToFile(fd, "failed_suspend_noirq", failedSuspendNoirq) &&
1135 writeStatToFile(fd, "failed_resume", failedResume) &&
1136 writeStatToFile(fd, "failed_resume_early", failedResumeEarly) &&
1137 writeStatToFile(fd, "failed_resume_noirq", failedResumeNoirq) &&
1138 writeStatToFile(fd, "last_failed_dev", lastFailedDev) &&
1139 writeStatToFile(fd, "last_failed_errno", lastFailedErrno) &&
1140 writeStatToFile(fd, "last_failed_step", lastFailedStep) &&
1141 writeStatToFile(fd, "last_hw_sleep", lastHwSleep) &&
1142 writeStatToFile(fd, "total_hw_sleep", totalHwSleep) &&
1143 writeStatToFile(fd, "max_hw_sleep", maxHwSleep);
1144 }
1145
removeDirectoryEntry(const std::string & path)1146 bool removeDirectoryEntry(const std::string& path) {
1147 auto callback = [](const char* child, const struct stat*, int file_type,
1148 struct FTW*) -> int {
1149 switch (file_type) {
1150 case FTW_D:
1151 case FTW_DP:
1152 case FTW_DNR:
1153 if (rmdir(child) == -1) {
1154 PLOG(ERROR) << "rmdir " << child;
1155 }
1156 break;
1157 case FTW_NS:
1158 default:
1159 if (rmdir(child) != -1) break;
1160 // FALLTHRU (for gcc, lint, pcc, etc; and following for clang)
1161 FALLTHROUGH_INTENDED;
1162 case FTW_F:
1163 case FTW_SL:
1164 case FTW_SLN:
1165 if (unlink(child) == -1) {
1166 PLOG(ERROR) << "unlink " << child;
1167 }
1168 break;
1169 }
1170 return 0;
1171 };
1172 return nftw(path.c_str(), callback, 128, FTW_DEPTH | FTW_MOUNT | FTW_PHYS) == 0;
1173 }
1174
1175 /**
1176 * Removes all entries from directory.
1177 * Returns true on success else false.
1178 */
clearDirectory(const std::string & dirPath)1179 bool clearDirectory(const std::string& dirPath) {
1180 std::unique_ptr<DIR, decltype(&closedir)> dp(opendir(dirPath.c_str()), &closedir);
1181 if (!dp) {
1182 return false;
1183 }
1184
1185 rewinddir(dp.get());
1186 struct dirent* de;
1187 while ((de = readdir(dp.get()))) {
1188 std::string name(de->d_name);
1189 if ((name == ".") || (name == "..")) {
1190 continue;
1191 }
1192 if (!removeDirectoryEntry(dirPath + "/" + name)) {
1193 PLOG(ERROR) << "SystemSuspend: Failed to remove " << name;
1194 return false;
1195 }
1196 }
1197
1198 return true;
1199 }
1200
1201 /**
1202 * Returns wakelock stats.
1203 */
getWakelockStats(int32_t selectBitmap=ISuspendControlServiceInternal::WAKE_LOCK_INFO_ALL_FIELDS)1204 std::vector<WakeLockInfo> getWakelockStats(
1205 int32_t selectBitmap = ISuspendControlServiceInternal::WAKE_LOCK_INFO_ALL_FIELDS) {
1206 std::vector<WakeLockInfo> wlStats;
1207 controlServiceInternal->getWakeLockStatsFiltered(selectBitmap, &wlStats);
1208 return wlStats;
1209 }
1210
1211 /**
1212 * Returns suspend stats.
1213 */
getSuspendStats()1214 Result<SuspendStats> getSuspendStats() { return systemSuspend->getSuspendStats(); }
1215
SetUp()1216 virtual void SetUp() override {
1217 kernelWakelockStatsFd = unique_fd(TEMP_FAILURE_RETRY(
1218 open(kernelWakelockStatsDir.path, O_DIRECTORY | O_CLOEXEC | O_RDONLY)));
1219 if (kernelWakelockStatsFd < 0) {
1220 PLOG(FATAL) << "SystemSuspend: Failed to open kernel wakelock stats directory";
1221 }
1222
1223 suspendStatsFd = unique_fd(
1224 TEMP_FAILURE_RETRY(open(suspendStatsDir.path, O_DIRECTORY | O_CLOEXEC | O_RDONLY)));
1225 if (suspendStatsFd < 0) {
1226 PLOG(FATAL) << "SystemSuspend: Failed to open suspend_stats directory";
1227 }
1228
1229 // Set up same thread suspend services
1230 sp<SuspendControlService> suspendControl = new SuspendControlService();
1231 sp<SuspendControlServiceInternal> suspendControlInternal =
1232 new SuspendControlServiceInternal();
1233 controlService = suspendControl;
1234 controlServiceInternal = suspendControlInternal;
1235 systemSuspend = new SystemSuspend(
1236 unique_fd(-1) /* wakeupCountFd */, unique_fd(-1) /* stateFd */,
1237 unique_fd(dup(suspendStatsFd)), 1 /* maxNativeStatsEntries */,
1238 unique_fd(dup(kernelWakelockStatsFd.get())), unique_fd(-1) /* wakeupReasonsFd */,
1239 unique_fd(-1) /* suspendTimeFd */, kSleepTimeConfig, suspendControl,
1240 suspendControlInternal);
1241
1242 suspendService = ndk::SharedRefBase::make<SystemSuspendAidl>(systemSuspend.get());
1243 }
1244
TearDown()1245 virtual void TearDown() override {
1246 systemSuspend->disableAutosuspend();
1247 ASSERT_TRUE(clearDirectory(kernelWakelockStatsDir.path));
1248 ASSERT_TRUE(clearDirectory(suspendStatsDir.path));
1249 }
1250
1251 sp<SystemSuspend> systemSuspend;
1252 std::shared_ptr<ISystemSuspend> suspendService;
1253 sp<ISuspendControlService> controlService;
1254 sp<ISuspendControlServiceInternal> controlServiceInternal;
1255 unique_fd kernelWakelockStatsFd;
1256 unique_fd suspendStatsFd;
1257 TemporaryDir kernelWakelockStatsDir;
1258 TemporaryDir suspendStatsDir;
1259
1260 const SleepTimeConfig kSleepTimeConfig = {
1261 .baseSleepTime = 100ms,
1262 .maxSleepTime = 400ms,
1263 .sleepTimeScaleFactor = 1.9,
1264 .backoffThreshold = 1,
1265 .shortSuspendThreshold = 100ms,
1266 .failedSuspendBackoffEnabled = true,
1267 .shortSuspendBackoffEnabled = true,
1268 };
1269 };
1270
1271 class mock_flag_provider_interface : public suspend_service::flags::flag_provider_interface {
1272 public:
1273 MOCK_METHOD(bool, fast_kernel_wakelock_reporting, (), (override));
1274 };
1275
1276 class ParameterizedSystemSuspendSameThreadTest : public SystemSuspendSameThreadTest,
1277 public ::testing::WithParamInterface<bool> {
1278 protected:
SetUp()1279 void SetUp() override {
1280 auto mock_flag_provider = std::make_unique<mock_flag_provider_interface>();
1281 ON_CALL(*mock_flag_provider, fast_kernel_wakelock_reporting())
1282 .WillByDefault(::testing::Return(GetParam()));
1283 suspend_service::flags::provider_ = std::move(mock_flag_provider);
1284
1285 SystemSuspendSameThreadTest::SetUp();
1286 }
1287 };
1288
1289 // Test that getWakeLockStats has correct information about Native WakeLocks.
TEST_F(SystemSuspendSameThreadTest,GetNativeWakeLockStats)1290 TEST_F(SystemSuspendSameThreadTest, GetNativeWakeLockStats) {
1291 std::string fakeWlName = "FakeLock";
1292 {
1293 std::shared_ptr<IWakeLock> fakeLock = acquireWakeLock(fakeWlName);
1294 std::vector<WakeLockInfo> wlStats = getWakelockStats();
1295 ASSERT_EQ(wlStats.size(), 1);
1296
1297 WakeLockInfo nwlInfo;
1298 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeWlName, &nwlInfo));
1299 ASSERT_EQ(nwlInfo.name, fakeWlName);
1300 ASSERT_EQ(nwlInfo.activeCount, 1);
1301 ASSERT_EQ(nwlInfo.isActive, true);
1302 ASSERT_FALSE(nwlInfo.isKernelWakelock);
1303
1304 ASSERT_EQ(nwlInfo.pid, getpid());
1305
1306 ASSERT_EQ(nwlInfo.eventCount, 0);
1307 ASSERT_EQ(nwlInfo.expireCount, 0);
1308 ASSERT_EQ(nwlInfo.preventSuspendTime, 0);
1309 ASSERT_EQ(nwlInfo.wakeupCount, 0);
1310
1311 // We sleep so that the wake lock stats entry get updated with a different timestamp.
1312 std::this_thread::sleep_for(1s);
1313 }
1314 std::vector<WakeLockInfo> wlStats = getWakelockStats();
1315 ASSERT_EQ(wlStats.size(), 1);
1316
1317 WakeLockInfo nwlInfo;
1318 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeWlName, &nwlInfo));
1319 ASSERT_EQ(nwlInfo.name, fakeWlName);
1320 ASSERT_EQ(nwlInfo.activeCount, 0);
1321 ASSERT_GE(nwlInfo.maxTime, 1000);
1322 ASSERT_GE(nwlInfo.totalTime, 1000);
1323 ASSERT_EQ(nwlInfo.isActive, false);
1324 ASSERT_EQ(nwlInfo.activeTime, 0); // No longer active
1325 ASSERT_FALSE(nwlInfo.isKernelWakelock);
1326
1327 ASSERT_EQ(nwlInfo.pid, getpid());
1328
1329 ASSERT_EQ(nwlInfo.eventCount, 0);
1330 ASSERT_EQ(nwlInfo.expireCount, 0);
1331 ASSERT_EQ(nwlInfo.preventSuspendTime, 0);
1332 ASSERT_EQ(nwlInfo.wakeupCount, 0);
1333 }
1334
1335 INSTANTIATE_TEST_SUITE_P(ParameterizedSystemSuspendSameThreadTest,
1336 ParameterizedSystemSuspendSameThreadTest, ::testing::Bool());
1337
1338 // Test that getWakeLockStats has correct information about Kernel WakeLocks.
TEST_P(ParameterizedSystemSuspendSameThreadTest,GetKernelWakeLockStats)1339 TEST_P(ParameterizedSystemSuspendSameThreadTest, GetKernelWakeLockStats) {
1340 std::string fakeKwlName1 = "fakeKwl1";
1341 std::string fakeKwlName2 = "fakeKwl2";
1342 addKernelWakelock(fakeKwlName1);
1343 addKernelWakelock(fakeKwlName2, 10 /* activeCount */);
1344
1345 std::vector<WakeLockInfo> wlStats = getWakelockStats();
1346
1347 ASSERT_EQ(wlStats.size(), 2);
1348
1349 WakeLockInfo kwlInfo1;
1350 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeKwlName1, &kwlInfo1));
1351 ASSERT_EQ(kwlInfo1.name, fakeKwlName1);
1352 ASSERT_EQ(kwlInfo1.activeCount, 42);
1353 ASSERT_EQ(kwlInfo1.lastChange, 42);
1354 ASSERT_EQ(kwlInfo1.maxTime, 42);
1355 ASSERT_EQ(kwlInfo1.totalTime, 42);
1356 ASSERT_EQ(kwlInfo1.isActive, true);
1357 ASSERT_EQ(kwlInfo1.activeTime, 42);
1358 ASSERT_TRUE(kwlInfo1.isKernelWakelock);
1359
1360 ASSERT_EQ(kwlInfo1.pid, -1);
1361
1362 ASSERT_EQ(kwlInfo1.eventCount, 42);
1363 ASSERT_EQ(kwlInfo1.expireCount, 42);
1364 ASSERT_EQ(kwlInfo1.preventSuspendTime, 42);
1365 ASSERT_EQ(kwlInfo1.wakeupCount, 42);
1366
1367 WakeLockInfo kwlInfo2;
1368 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeKwlName2, &kwlInfo2));
1369 ASSERT_EQ(kwlInfo2.name, fakeKwlName2);
1370 ASSERT_EQ(kwlInfo2.activeCount, 10);
1371 ASSERT_EQ(kwlInfo2.lastChange, 42);
1372 ASSERT_EQ(kwlInfo2.maxTime, 42);
1373 ASSERT_EQ(kwlInfo2.totalTime, 42);
1374 ASSERT_EQ(kwlInfo2.isActive, true);
1375 ASSERT_EQ(kwlInfo2.activeTime, 42);
1376 ASSERT_TRUE(kwlInfo2.isKernelWakelock);
1377
1378 ASSERT_EQ(kwlInfo2.pid, -1);
1379
1380 ASSERT_EQ(kwlInfo2.eventCount, 42);
1381 ASSERT_EQ(kwlInfo2.expireCount, 42);
1382 ASSERT_EQ(kwlInfo2.preventSuspendTime, 42);
1383 ASSERT_EQ(kwlInfo2.wakeupCount, 42);
1384 }
1385
1386 // Test that getWakeLockStats has correct information about Native AND Kernel WakeLocks.
TEST_P(ParameterizedSystemSuspendSameThreadTest,GetNativeAndKernelWakeLockStats)1387 TEST_P(ParameterizedSystemSuspendSameThreadTest, GetNativeAndKernelWakeLockStats) {
1388 std::string fakeNwlName = "fakeNwl";
1389 std::string fakeKwlName = "fakeKwl";
1390
1391 addKernelWakelock(fakeKwlName);
1392
1393 {
1394 std::shared_ptr<IWakeLock> fakeLock = acquireWakeLock(fakeNwlName);
1395 std::vector<WakeLockInfo> wlStats = getWakelockStats();
1396 ASSERT_EQ(wlStats.size(), 2);
1397
1398 // Native Wakelock Stats
1399 WakeLockInfo nwlInfo;
1400 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeNwlName, &nwlInfo));
1401 ASSERT_EQ(nwlInfo.name, fakeNwlName);
1402 ASSERT_EQ(nwlInfo.activeCount, 1);
1403 ASSERT_EQ(nwlInfo.isActive, true);
1404 ASSERT_FALSE(nwlInfo.isKernelWakelock);
1405
1406 ASSERT_EQ(nwlInfo.pid, getpid());
1407
1408 ASSERT_EQ(nwlInfo.eventCount, 0);
1409 ASSERT_EQ(nwlInfo.expireCount, 0);
1410 ASSERT_EQ(nwlInfo.preventSuspendTime, 0);
1411 ASSERT_EQ(nwlInfo.wakeupCount, 0);
1412
1413 // Kernel Wakelock Stats
1414 WakeLockInfo kwlInfo;
1415 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeKwlName, &kwlInfo));
1416 ASSERT_EQ(kwlInfo.name, fakeKwlName);
1417 ASSERT_EQ(kwlInfo.activeCount, 42);
1418 ASSERT_EQ(kwlInfo.lastChange, 42);
1419 ASSERT_EQ(kwlInfo.maxTime, 42);
1420 ASSERT_EQ(kwlInfo.totalTime, 42);
1421 ASSERT_EQ(kwlInfo.isActive, true);
1422 ASSERT_EQ(kwlInfo.activeTime, 42);
1423 ASSERT_TRUE(kwlInfo.isKernelWakelock);
1424
1425 ASSERT_EQ(kwlInfo.pid, -1);
1426
1427 ASSERT_EQ(kwlInfo.eventCount, 42);
1428 ASSERT_EQ(kwlInfo.expireCount, 42);
1429 ASSERT_EQ(kwlInfo.preventSuspendTime, 42);
1430 ASSERT_EQ(kwlInfo.wakeupCount, 42);
1431
1432 // We sleep so that the wake lock stats entry get updated with a different timestamp.
1433 std::this_thread::sleep_for(1s);
1434 }
1435 std::vector<WakeLockInfo> wlStats = getWakelockStats();
1436 ASSERT_EQ(wlStats.size(), 2);
1437
1438 // Native Wakelock Stats
1439 WakeLockInfo nwlInfo;
1440 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeNwlName, &nwlInfo));
1441 ASSERT_EQ(nwlInfo.name, fakeNwlName);
1442 ASSERT_EQ(nwlInfo.activeCount, 0);
1443 ASSERT_GE(nwlInfo.maxTime, 1000);
1444 ASSERT_GE(nwlInfo.totalTime, 1000);
1445 ASSERT_EQ(nwlInfo.isActive, false);
1446 ASSERT_EQ(nwlInfo.activeTime, 0); // No longer active
1447 ASSERT_FALSE(nwlInfo.isKernelWakelock);
1448
1449 ASSERT_EQ(nwlInfo.pid, getpid());
1450
1451 ASSERT_EQ(nwlInfo.eventCount, 0);
1452 ASSERT_EQ(nwlInfo.expireCount, 0);
1453 ASSERT_EQ(nwlInfo.preventSuspendTime, 0);
1454 ASSERT_EQ(nwlInfo.wakeupCount, 0);
1455
1456 // Kernel Wakelock Stats (No changes expected here)
1457 WakeLockInfo kwlInfo;
1458 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeKwlName, &kwlInfo));
1459 ASSERT_EQ(kwlInfo.name, fakeKwlName);
1460 ASSERT_EQ(kwlInfo.activeCount, 42);
1461 ASSERT_EQ(kwlInfo.lastChange, 42);
1462 ASSERT_EQ(kwlInfo.maxTime, 42);
1463 ASSERT_EQ(kwlInfo.totalTime, 42);
1464 ASSERT_EQ(kwlInfo.isActive, true);
1465 ASSERT_EQ(kwlInfo.activeTime, 42);
1466 ASSERT_TRUE(kwlInfo.isKernelWakelock);
1467
1468 ASSERT_EQ(kwlInfo.pid, -1);
1469
1470 ASSERT_EQ(kwlInfo.eventCount, 42);
1471 ASSERT_EQ(kwlInfo.expireCount, 42);
1472 ASSERT_EQ(kwlInfo.preventSuspendTime, 42);
1473 ASSERT_EQ(kwlInfo.wakeupCount, 42);
1474 }
1475
1476 // Test that the least recently used native wake lock stats entry is evicted after a given
1477 // threshold.
TEST_F(SystemSuspendSameThreadTest,NativeWakeLockStatsLruEviction)1478 TEST_F(SystemSuspendSameThreadTest, NativeWakeLockStatsLruEviction) {
1479 std::string fakeWlName1 = "FakeLock1";
1480 std::string fakeWlName2 = "FakeLock2";
1481
1482 acquireWakeLock(fakeWlName1);
1483 acquireWakeLock(fakeWlName2);
1484
1485 std::vector<WakeLockInfo> wlStats = getWakelockStats();
1486
1487 // Max number of native stats entries was set to 1 in SystemSuspend constructor.
1488 ASSERT_EQ(wlStats.size(), 1);
1489 ASSERT_EQ(wlStats.begin()->name, fakeWlName2);
1490
1491 WakeLockInfo wlInfo;
1492 ASSERT_TRUE(findWakeLockInfoByName(wlStats, fakeWlName2, &wlInfo));
1493 ASSERT_FALSE(findWakeLockInfoByName(wlStats, fakeWlName1, &wlInfo)); // Evicted
1494 }
1495
1496 // Test that GetSuspendStats has correct information.
TEST_F(SystemSuspendSameThreadTest,GetSuspendStats)1497 TEST_F(SystemSuspendSameThreadTest, GetSuspendStats) {
1498 addSuspendStats();
1499
1500 Result<SuspendStats> res = getSuspendStats();
1501 ASSERT_RESULT_OK(res);
1502
1503 SuspendStats stats = res.value();
1504
1505 ASSERT_EQ(stats.success, 42);
1506 ASSERT_EQ(stats.fail, 42);
1507 ASSERT_EQ(stats.failedFreeze, 42);
1508 ASSERT_EQ(stats.failedPrepare, 42);
1509 ASSERT_EQ(stats.failedSuspend, 42);
1510 ASSERT_EQ(stats.failedSuspendLate, 42);
1511 ASSERT_EQ(stats.failedSuspendNoirq, 42);
1512 ASSERT_EQ(stats.failedResume, 42);
1513 ASSERT_EQ(stats.failedResumeEarly, 42);
1514 ASSERT_EQ(stats.failedResumeNoirq, 42);
1515 ASSERT_EQ(stats.lastFailedDev, "fakeDev");
1516 ASSERT_EQ(stats.lastFailedErrno, -42);
1517 ASSERT_EQ(stats.lastFailedStep, "fakeStep");
1518 ASSERT_EQ(stats.lastHwSleep, 42);
1519 ASSERT_EQ(stats.totalHwSleep, 42);
1520 ASSERT_EQ(stats.maxHwSleep, 523986009990);
1521 }
1522
1523 class SuspendWakeupTest : public ::testing::Test {
1524 public:
SetUp()1525 virtual void SetUp() override {
1526 Socketpair(SOCK_STREAM, &wakeupCountTestFd, &wakeupCountServiceFd);
1527 Socketpair(SOCK_STREAM, &stateTestFd, &stateServiceFd);
1528
1529 suspendControl = new SuspendControlService();
1530
1531 suspendControlInternal = new SuspendControlServiceInternal();
1532
1533 suspendTimeFd =
1534 unique_fd(TEMP_FAILURE_RETRY(open(suspendTimeFile.path, O_CLOEXEC | O_RDONLY)));
1535
1536 wakeupReasonsFd =
1537 unique_fd(TEMP_FAILURE_RETRY(open(wakeupReasonsFile.path, O_CLOEXEC | O_RDONLY)));
1538
1539 systemSuspend = new SystemSuspend(
1540 std::move(wakeupCountServiceFd), std::move(stateServiceFd),
1541 unique_fd(-1) /* suspendStatsFd */, 100 /* maxStatsEntries */,
1542 unique_fd(-1) /* kernelWakelockStatsFd */, std::move(wakeupReasonsFd),
1543 std::move(suspendTimeFd), kSleepTimeConfig, suspendControl, suspendControlInternal);
1544
1545 // Start auto-suspend.
1546 bool enabled = false;
1547 suspendControlInternal->enableAutosuspend(new BBinder(), &enabled);
1548 ASSERT_EQ(enabled, true) << "failed to start autosuspend";
1549 }
1550
TearDown()1551 virtual void TearDown() override { systemSuspend->disableAutosuspend(); }
1552
acquireWakeLock(const std::string & name="TestLock")1553 std::shared_ptr<IWakeLock> acquireWakeLock(const std::string& name = "TestLock") {
1554 auto suspendService = ndk::SharedRefBase::make<SystemSuspendAidl>(systemSuspend.get());
1555 std::shared_ptr<IWakeLock> wl = nullptr;
1556 auto status = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name, &wl);
1557 return wl;
1558 }
1559
wakeup(std::string wakeupReason)1560 void wakeup(std::string wakeupReason) {
1561 ASSERT_TRUE(WriteStringToFile(wakeupReason, wakeupReasonsFile.path));
1562 checkLoop(1);
1563 }
1564
checkLoop(int numIter)1565 void checkLoop(int numIter) {
1566 for (int i = 0; i < numIter; i++) {
1567 // Mock value for /sys/power/wakeup_count.
1568 std::string wakeupCount = std::to_string(rand());
1569 ASSERT_TRUE(WriteStringToFd(wakeupCount, wakeupCountTestFd));
1570 ASSERT_EQ(readFd(wakeupCountTestFd), wakeupCount)
1571 << "wakeup count value written by SystemSuspend is not equal to value given to it";
1572 ASSERT_EQ(readFd(stateTestFd), "mem")
1573 << "SystemSuspend failed to write correct sleep state.";
1574 // There is a race window where sleepTime can be checked in the tests,
1575 // before it is updated in autoSuspend
1576 while (!isReadBlocked(wakeupCountTestFd)) {
1577 }
1578 }
1579 }
1580
suspendFor(std::chrono::milliseconds suspendTime,std::chrono::milliseconds suspendOverhead,int numberOfSuspends)1581 void suspendFor(std::chrono::milliseconds suspendTime,
1582 std::chrono::milliseconds suspendOverhead, int numberOfSuspends) {
1583 std::string suspendStr =
1584 std::to_string(
1585 std::chrono::duration_cast<std::chrono::duration<double>>(suspendOverhead)
1586 .count()) +
1587 " " +
1588 std::to_string(
1589 std::chrono::duration_cast<std::chrono::duration<double>>(suspendTime).count());
1590 ASSERT_TRUE(WriteStringToFile(suspendStr, suspendTimeFile.path));
1591 checkLoop(numberOfSuspends);
1592 }
1593
checkSuspendInfo(const SuspendInfo & expected)1594 void checkSuspendInfo(const SuspendInfo& expected) {
1595 SuspendInfo actual;
1596 systemSuspend->getSuspendInfo(&actual);
1597
1598 ASSERT_EQ(actual.suspendAttemptCount, expected.suspendAttemptCount);
1599 ASSERT_EQ(actual.failedSuspendCount, expected.failedSuspendCount);
1600 ASSERT_EQ(actual.shortSuspendCount, expected.shortSuspendCount);
1601 ASSERT_EQ(actual.suspendTimeMillis, expected.suspendTimeMillis);
1602 ASSERT_EQ(actual.shortSuspendTimeMillis, expected.shortSuspendTimeMillis);
1603 ASSERT_EQ(actual.suspendOverheadTimeMillis, expected.suspendOverheadTimeMillis);
1604 ASSERT_EQ(actual.failedSuspendOverheadTimeMillis, expected.failedSuspendOverheadTimeMillis);
1605 ASSERT_EQ(actual.newBackoffCount, expected.newBackoffCount);
1606 ASSERT_EQ(actual.backoffContinueCount, expected.backoffContinueCount);
1607 ASSERT_EQ(actual.sleepTimeMillis, expected.sleepTimeMillis);
1608 }
1609
1610 unique_fd wakeupCountServiceFd;
1611 unique_fd stateServiceFd;
1612 unique_fd stateTestFd;
1613 unique_fd wakeupCountTestFd;
1614 unique_fd wakeupReasonsFd;
1615 unique_fd suspendTimeFd;
1616 TemporaryFile wakeupReasonsFile;
1617 TemporaryFile suspendTimeFile;
1618 TemporaryFile stateFile;
1619 TemporaryFile wakeupCountFile;
1620 sp<SuspendControlService> suspendControl;
1621 sp<SuspendControlServiceInternal> suspendControlInternal;
1622 sp<SystemSuspend> systemSuspend;
1623
1624 const SleepTimeConfig kSleepTimeConfig = {
1625 .baseSleepTime = 100ms,
1626 .maxSleepTime = 400ms,
1627 .sleepTimeScaleFactor = 1.9,
1628 .backoffThreshold = 1,
1629 .shortSuspendThreshold = 100ms,
1630 .failedSuspendBackoffEnabled = true,
1631 .shortSuspendBackoffEnabled = true,
1632 };
1633
1634 const int64_t kLongSuspendMillis = 10000; // >= kSleepTimeConfig.shortSuspendThreshold
1635 const int64_t kShortSuspendMillis = 10; // < kSleepTimeConfig.shortSuspendThreshold
1636 const int64_t kSuspendOverheadMillis = 20;
1637 };
1638
TEST_F(SuspendWakeupTest,LongSuspendStat)1639 TEST_F(SuspendWakeupTest, LongSuspendStat) {
1640 suspendFor(std::chrono::milliseconds(kLongSuspendMillis),
1641 std::chrono::milliseconds(kSuspendOverheadMillis), 1);
1642 SuspendInfo expected;
1643 expected.suspendAttemptCount = 1;
1644 expected.suspendTimeMillis = kLongSuspendMillis;
1645 expected.suspendOverheadTimeMillis = kSuspendOverheadMillis;
1646 expected.sleepTimeMillis = kSleepTimeConfig.baseSleepTime.count();
1647 checkSuspendInfo(expected);
1648 }
1649
TEST_F(SuspendWakeupTest,ShortSuspendStat)1650 TEST_F(SuspendWakeupTest, ShortSuspendStat) {
1651 suspendFor(std::chrono::milliseconds(kShortSuspendMillis),
1652 std::chrono::milliseconds(kSuspendOverheadMillis), 1);
1653 SuspendInfo expected;
1654 expected.suspendAttemptCount = 1;
1655 expected.shortSuspendCount = 1;
1656 expected.shortSuspendTimeMillis = kShortSuspendMillis;
1657 expected.suspendTimeMillis = kShortSuspendMillis;
1658 expected.suspendOverheadTimeMillis = kSuspendOverheadMillis;
1659 expected.sleepTimeMillis = kSleepTimeConfig.baseSleepTime.count();
1660 checkSuspendInfo(expected);
1661 }
1662
TEST_F(SuspendWakeupTest,ShortSuspendBackoffStat)1663 TEST_F(SuspendWakeupTest, ShortSuspendBackoffStat) {
1664 suspendFor(std::chrono::milliseconds(kShortSuspendMillis),
1665 std::chrono::milliseconds(kSuspendOverheadMillis), 2);
1666 SuspendInfo expected;
1667 expected.suspendAttemptCount = 2;
1668 expected.shortSuspendCount = 2;
1669 expected.shortSuspendTimeMillis = kShortSuspendMillis * 2;
1670 expected.suspendTimeMillis = kShortSuspendMillis * 2;
1671 expected.suspendOverheadTimeMillis = kSuspendOverheadMillis * 2;
1672 expected.newBackoffCount = 1;
1673 expected.sleepTimeMillis = kSleepTimeConfig.baseSleepTime.count() * 2;
1674 checkSuspendInfo(expected);
1675 }
1676
TEST_F(SuspendWakeupTest,ShortSuspendBackoffContinueStat)1677 TEST_F(SuspendWakeupTest, ShortSuspendBackoffContinueStat) {
1678 suspendFor(std::chrono::milliseconds(kShortSuspendMillis),
1679 std::chrono::milliseconds(kSuspendOverheadMillis), 2);
1680 SuspendInfo expected;
1681 expected.suspendAttemptCount = 2;
1682 expected.shortSuspendCount = 2;
1683 expected.shortSuspendTimeMillis = kShortSuspendMillis * 2;
1684 expected.suspendTimeMillis = kShortSuspendMillis * 2;
1685 expected.suspendOverheadTimeMillis = kSuspendOverheadMillis * 2;
1686 expected.newBackoffCount = 1;
1687 expected.sleepTimeMillis = kSleepTimeConfig.baseSleepTime.count() * 2;
1688 checkSuspendInfo(expected);
1689
1690 suspendFor(std::chrono::milliseconds(kShortSuspendMillis),
1691 std::chrono::milliseconds(kSuspendOverheadMillis), 1);
1692 expected.suspendAttemptCount += 1;
1693 expected.shortSuspendCount += 1;
1694 expected.shortSuspendTimeMillis += kShortSuspendMillis;
1695 expected.suspendTimeMillis += kShortSuspendMillis;
1696 expected.suspendOverheadTimeMillis += kSuspendOverheadMillis;
1697 expected.backoffContinueCount += 1;
1698 expected.sleepTimeMillis +=
1699 std::chrono::round<std::chrono::milliseconds>(kSleepTimeConfig.baseSleepTime *
1700 kSleepTimeConfig.sleepTimeScaleFactor)
1701 .count();
1702 checkSuspendInfo(expected);
1703 }
1704
TEST_F(SuspendWakeupTest,GetSingleWakeupReasonStat)1705 TEST_F(SuspendWakeupTest, GetSingleWakeupReasonStat) {
1706 wakeup("abc");
1707
1708 std::vector<WakeupInfo> wStats;
1709 ASSERT_TRUE(suspendControlInternal->getWakeupStats(&wStats).isOk());
1710 ASSERT_EQ(wStats.size(), 1);
1711 ASSERT_EQ(wStats[0].name, "abc");
1712 ASSERT_EQ(wStats[0].count, 1);
1713 }
1714
TEST_F(SuspendWakeupTest,GetChainedWakeupReasonStat)1715 TEST_F(SuspendWakeupTest, GetChainedWakeupReasonStat) {
1716 wakeup("a\nb");
1717
1718 std::vector<WakeupInfo> wStats;
1719 ASSERT_TRUE(suspendControlInternal->getWakeupStats(&wStats).isOk());
1720 ASSERT_EQ(wStats.size(), 1);
1721 ASSERT_EQ(wStats[0].name, "a;b");
1722 ASSERT_EQ(wStats[0].count, 1);
1723 }
1724
TEST_F(SuspendWakeupTest,GetMultipleWakeupReasonStats)1725 TEST_F(SuspendWakeupTest, GetMultipleWakeupReasonStats) {
1726 wakeup("abc");
1727 wakeup("d\ne");
1728 wakeup("");
1729 wakeup("");
1730 wakeup("wxyz\nabc\n");
1731 wakeup("abc");
1732
1733 std::vector<WakeupInfo> wStats;
1734 ASSERT_TRUE(suspendControlInternal->getWakeupStats(&wStats).isOk());
1735 ASSERT_EQ(wStats.size(), 4);
1736 ASSERT_EQ(wStats[0].name, "abc");
1737 ASSERT_EQ(wStats[0].count, 2);
1738 ASSERT_EQ(wStats[1].name, "wxyz;abc");
1739 ASSERT_EQ(wStats[1].count, 1);
1740 ASSERT_EQ(wStats[2].name, "unknown");
1741 ASSERT_EQ(wStats[2].count, 2);
1742 ASSERT_EQ(wStats[3].name, "d;e");
1743 ASSERT_EQ(wStats[3].count, 1);
1744 }
1745
TEST(WakeupListTest,TestEmpty)1746 TEST(WakeupListTest, TestEmpty) {
1747 WakeupList wakeupList(3);
1748
1749 std::vector<WakeupInfo> wakeups;
1750 wakeupList.getWakeupStats(&wakeups);
1751
1752 ASSERT_TRUE(wakeups.empty());
1753 }
1754
TEST(WakeupListTest,TestNoCapacity)1755 TEST(WakeupListTest, TestNoCapacity) {
1756 WakeupList wakeupList(0);
1757
1758 wakeupList.update({"a"});
1759
1760 std::vector<WakeupInfo> wakeups;
1761 wakeupList.getWakeupStats(&wakeups);
1762
1763 ASSERT_TRUE(wakeups.empty());
1764 }
1765
TEST(WakeupListTest,TestConcat)1766 TEST(WakeupListTest, TestConcat) {
1767 WakeupList wakeupList(3);
1768
1769 wakeupList.update({"a", "b"});
1770
1771 std::vector<WakeupInfo> wakeups;
1772 wakeupList.getWakeupStats(&wakeups);
1773
1774 ASSERT_EQ(wakeups[0].name, "a;b");
1775 ASSERT_EQ(wakeups[0].count, 1);
1776 }
1777
TEST(WakeupListTest,TestNewEntry)1778 TEST(WakeupListTest, TestNewEntry) {
1779 WakeupList wakeupList(3);
1780
1781 wakeupList.update({"a"});
1782 wakeupList.update({"b"});
1783
1784 std::vector<WakeupInfo> wakeups;
1785 wakeupList.getWakeupStats(&wakeups);
1786
1787 ASSERT_EQ(wakeups[1].name, "a");
1788 ASSERT_EQ(wakeups[1].count, 1);
1789 ASSERT_EQ(wakeups[0].name, "b");
1790 ASSERT_EQ(wakeups[0].count, 1);
1791 }
1792
TEST(WakeupListTest,TestIncrement)1793 TEST(WakeupListTest, TestIncrement) {
1794 WakeupList wakeupList(3);
1795
1796 wakeupList.update({"a"});
1797 wakeupList.update({"b"});
1798 wakeupList.update({"a"});
1799
1800 std::vector<WakeupInfo> wakeups;
1801 wakeupList.getWakeupStats(&wakeups);
1802
1803 ASSERT_EQ(wakeups[0].name, "a");
1804 ASSERT_EQ(wakeups[0].count, 2);
1805 ASSERT_EQ(wakeups[1].name, "b");
1806 ASSERT_EQ(wakeups[1].count, 1);
1807 }
1808
TEST(WakeupListTest,TestCapacity)1809 TEST(WakeupListTest, TestCapacity) {
1810 WakeupList wakeupList(3);
1811
1812 wakeupList.update({"a"});
1813 wakeupList.update({"b"});
1814 wakeupList.update({"c"});
1815 wakeupList.update({"d"});
1816
1817 std::vector<WakeupInfo> wakeups;
1818 wakeupList.getWakeupStats(&wakeups);
1819
1820 ASSERT_EQ(wakeups.size(), 3);
1821 ASSERT_EQ(wakeups[0].name, "d");
1822 ASSERT_EQ(wakeups[0].count, 1);
1823 ASSERT_EQ(wakeups[1].name, "c");
1824 ASSERT_EQ(wakeups[1].count, 1);
1825 ASSERT_EQ(wakeups[2].name, "b");
1826 ASSERT_EQ(wakeups[2].count, 1);
1827 }
1828
TEST(WakeupListTest,TestLRUEvict)1829 TEST(WakeupListTest, TestLRUEvict) {
1830 WakeupList wakeupList(3);
1831
1832 wakeupList.update({"a"});
1833 wakeupList.update({"b"});
1834 wakeupList.update({"a"});
1835 wakeupList.update({"c"});
1836 wakeupList.update({"c"});
1837 wakeupList.update({"c"});
1838 wakeupList.update({"d"});
1839
1840 std::vector<WakeupInfo> wakeups;
1841 wakeupList.getWakeupStats(&wakeups);
1842
1843 ASSERT_EQ(wakeups.size(), 3);
1844 ASSERT_EQ(wakeups[0].name, "d");
1845 ASSERT_EQ(wakeups[0].count, 1);
1846 ASSERT_EQ(wakeups[1].name, "c");
1847 ASSERT_EQ(wakeups[1].count, 3);
1848 ASSERT_EQ(wakeups[2].name, "a");
1849 ASSERT_EQ(wakeups[2].count, 2);
1850 }
1851
1852 struct WakeLockInfoField {
1853 int32_t bit = 0;
1854 std::function<int(WakeLockInfo)> getter;
1855 int64_t expectedValue;
1856 };
1857
1858 // Test that selected fields are properly set.
TEST_P(ParameterizedSystemSuspendSameThreadTest,GetKernelWakeLockStatsFiltered)1859 TEST_P(ParameterizedSystemSuspendSameThreadTest, GetKernelWakeLockStatsFiltered) {
1860 using ISCSI = ISuspendControlServiceInternal;
1861 static const WakeLockInfoField FIELDS[] = {
1862 {ISCSI::WAKE_LOCK_INFO_ACTIVE_COUNT, [](WakeLockInfo wl) { return wl.activeCount; }, 1},
1863 {ISCSI::WAKE_LOCK_INFO_LAST_CHANGE, [](WakeLockInfo wl) { return wl.lastChange; }, 2},
1864 {ISCSI::WAKE_LOCK_INFO_MAX_TIME, [](WakeLockInfo wl) { return wl.maxTime; }, 3},
1865 {ISCSI::WAKE_LOCK_INFO_TOTAL_TIME, [](WakeLockInfo wl) { return wl.totalTime; }, 4},
1866 {ISCSI::WAKE_LOCK_INFO_ACTIVE_TIME, [](WakeLockInfo wl) { return wl.activeTime; }, 5},
1867 {ISCSI::WAKE_LOCK_INFO_EVENT_COUNT, [](WakeLockInfo wl) { return wl.eventCount; }, 6},
1868 {ISCSI::WAKE_LOCK_INFO_EXPIRE_COUNT, [](WakeLockInfo wl) { return wl.expireCount; }, 7},
1869 {ISCSI::WAKE_LOCK_INFO_PREVENT_SUSPEND_TIME,
1870 [](WakeLockInfo wl) { return wl.preventSuspendTime; }, 8},
1871 {ISCSI::WAKE_LOCK_INFO_WAKEUP_COUNT, [](WakeLockInfo wl) { return wl.wakeupCount; }, 9},
1872 };
1873
1874 std::string fakeKwlName1 = "fakeKwl1";
1875 addKernelWakelock(fakeKwlName1, /* activeCount = */ 1, /* activeTime = */ 5,
1876 /* eventCount = */ 6,
1877 /* expireCount = */ 7, /* lastChange = */ 2, /* maxTime = */ 3,
1878 /* preventSuspendTime = */ 8, /* totalTime = */ 4, /* wakeupCount = */ 9);
1879 for (auto field : FIELDS) {
1880 std::vector<WakeLockInfo> infos = getWakelockStats(field.bit);
1881 WakeLockInfo wli;
1882 ASSERT_TRUE(findWakeLockInfoByName(infos, fakeKwlName1, &wli));
1883 ASSERT_EQ(field.getter(wli), field.expectedValue)
1884 << "Bit mask " << field.bit << " had unexpected value";
1885 }
1886 }
1887
1888 } // namespace android
1889
main(int argc,char ** argv)1890 int main(int argc, char** argv) {
1891 android::hardware::details::setTrebleTestingOverride(true);
1892 ::testing::InitGoogleMock(&argc, argv);
1893 ::testing::InitGoogleTest(&argc, argv);
1894 return RUN_ALL_TESTS();
1895 }
1896