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