OSDN Git Service

Add IWakeLock::release() method.
authorTri Vo <trong@google.com>
Wed, 29 Aug 2018 20:44:37 +0000 (13:44 -0700)
committerTri Vo <trong@google.com>
Thu, 30 Aug 2018 16:32:55 +0000 (09:32 -0700)
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

suspend/1.0/IWakeLock.hal
suspend/1.0/default/SystemSuspend.cpp
suspend/1.0/default/SystemSuspend.h
suspend/1.0/default/SystemSuspendUnitTest.cpp

index fd11bea..ead935d 100644 (file)
@@ -18,6 +18,14 @@ package android.system.suspend@1.0;
 
 /**
  * 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();
+};
index c27081f..14800a8 100644 (file)
@@ -57,13 +57,24 @@ static inline int getCallingPid() {
     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)
index 5c148fd..d5f2ea1 100644 (file)
@@ -45,7 +45,12 @@ class WakeLock : public IWakeLock {
     WakeLock(SystemSuspend* systemSuspend);
     ~WakeLock();
 
+    Return<void> release();
+
    private:
+    inline void releaseOnce();
+    std::once_flag mReleased;
+
     SystemSuspend* mSystemSuspend;
 };
 
index 122fb02..4c85968 100644 (file)
@@ -183,6 +183,16 @@ TEST_F(SystemSuspendTest, WakeLockDestructor) {
     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) {
     {
@@ -248,7 +258,9 @@ TEST_F(SystemSuspendTest, WakeLockStressTest) {
     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();
             }
         });
     }