From 8d475ca0586ca7315d0660be429d5eebe114303b Mon Sep 17 00:00:00 2001 From: Henrik Baard Date: Wed, 9 Aug 2017 14:45:05 +0200 Subject: [PATCH] Prevent WakeLock count ending up in an incorrect state WakeLock can end up in a bad state if the following sequence is executed: 1. mWakeLock = mPowerManager.newWakeLock(...) 2. mWakeLock.acquire(TIMEOUT_MS); 3. timeout TIMEOUT_MS occurs before release() is called 4. release is called() [1] mInternalCount = mExternalCount = 0 [2] mInternalCount = 1, mExternalCount = 1 [3] mInternalCount = 0, mExternalCount = 1 [4] mInternalCount = -1, mExternalCount = 0 If acquireLocked is called on the same object after this sequence, mInternalCount is incremented to 0 which results in no wakelock being requested from PowerManagerService. Bug: 64676694 Test: cts-tradefed run commandAndExit cts-dev -m CtsOsTestCases -t android.os.cts.PowerManager_WakeLockTest Change-Id: I133812aefb5d92eec2e2dde1a36f81dc9ffd7625 --- core/java/android/os/PowerManager.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 3726f47093b93..7f4dee6ef2da0 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1412,7 +1412,11 @@ public final class PowerManager { */ public void release(int flags) { synchronized (mToken) { - mInternalCount--; + if (mInternalCount > 0) { + // internal count must only be decreased if it is > 0 or state of + // the WakeLock object is broken. + mInternalCount--; + } if ((flags & RELEASE_FLAG_TIMEOUT) == 0) { mExternalCount--; }