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