Motivation:
-This should help migrate code that relied on old
acquire/release_wake_lock() methods to new API.
-Being able to release a lock before the end of the scope is consistent
with other "lock" constructs (e.g. unique_lock, shared_lock).
Bug:
78888165
Test: SystemSuspendV1_0UnitTest
Change-Id: Ibb654f523b9c255df68d93407b593deac006920b
/**
* Allocating an IWakeLock instance must block system suspend. Deallocating an
- * IWakeLock must initiate system suspend if no other wake lock is allocated.
+ * IWakeLock must unblock system suspend in a manner equivalent to calling
+ * IWakeLock::release().
*/
-interface IWakeLock {};
+interface IWakeLock {
+ /**
+ * Releases IWakeLock instance. This method only has effect first time its
+ * called. Subsequent calls must result in no-ops. If no unreleased wake
+ * lock is present, system is allowed to suspend.
+ */
+ oneway release();
+};
return IPCThreadState::self()->getCallingPid();
}
-WakeLock::WakeLock(SystemSuspend* systemSuspend) : mSystemSuspend(systemSuspend) {
+WakeLock::WakeLock(SystemSuspend* systemSuspend) : mReleased(), mSystemSuspend(systemSuspend) {
mSystemSuspend->incSuspendCounter();
}
WakeLock::~WakeLock() {
- mSystemSuspend->decSuspendCounter();
- mSystemSuspend->deleteWakeLockStatsEntry(reinterpret_cast<uint64_t>(this));
+ releaseOnce();
+}
+
+Return<void> WakeLock::release() {
+ releaseOnce();
+ return Void();
+}
+
+void WakeLock::releaseOnce() {
+ std::call_once(mReleased, [this]() {
+ mSystemSuspend->decSuspendCounter();
+ mSystemSuspend->deleteWakeLockStatsEntry(reinterpret_cast<uint64_t>(this));
+ });
}
SystemSuspend::SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd)
WakeLock(SystemSuspend* systemSuspend);
~WakeLock();
+ Return<void> release();
+
private:
+ inline void releaseOnce();
+ std::once_flag mReleased;
+
SystemSuspend* mSystemSuspend;
};
ASSERT_FALSE(isSystemSuspendBlocked());
}
+// Tests that upon WakeLock::release() SystemSuspend HAL is unblocked.
+TEST_F(SystemSuspendTest, WakeLockRelease) {
+ sp<IWakeLock> wl = acquireWakeLock();
+ ASSERT_NE(wl, nullptr);
+ unblockSystemSuspendFromWakeupCount();
+ ASSERT_TRUE(isSystemSuspendBlocked());
+ wl->release();
+ ASSERT_FALSE(isSystemSuspendBlocked());
+}
+
// Tests that multiple WakeLocks correctly block SystemSuspend HAL.
TEST_F(SystemSuspendTest, MultipleWakeLocks) {
{
for (int i = 0; i < numThreads; i++) {
tds[i] = std::thread([this] {
for (int i = 0; i < numLocks; i++) {
- sp<IWakeLock> wl = acquireWakeLock();
+ sp<IWakeLock> wl1 = acquireWakeLock();
+ sp<IWakeLock> wl2 = acquireWakeLock();
+ wl2->release();
}
});
}