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