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