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
This commit is contained in:
Henrik Baard
2017-08-09 14:45:05 +02:00
committed by Jeff Sharkey
parent efed687188
commit 8d475ca058

View File

@@ -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--;
}