From 0e5bb7f1c9558bcf76af4f31dd5a11e78bcbdc9d Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Sat, 14 Nov 2009 06:36:31 -0500 Subject: [PATCH 1/2] PowerManagerService: Hold a wakelock while mProximityTask is queued This prevents the device from sleeping while a deferred proximity sensor event is pending. Fixes b/2260005 (Proximity sensor can fail due to missing wakelock) Change-Id: Ia4825f548b5b7d8a0b184f720b32c2f21b77b96e Signed-off-by: Mike Lockwood --- .../android/server/PowerManagerService.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index e1425d444c345..73527b75da1f5 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -185,6 +185,7 @@ class PowerManagerService extends IPowerManager.Stub private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock; private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock; private UnsynchronizedWakeLock mPreventScreenOnPartialLock; + private UnsynchronizedWakeLock mProximityPartialLock; private HandlerThread mHandlerThread; private Handler mHandler; private TimeoutTask mTimeoutTask = new TimeoutTask(); @@ -283,6 +284,7 @@ class PowerManagerService extends IPowerManager.Stub IBinder mToken; int mCount = 0; boolean mRefCounted; + boolean mHeld; UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) { mFlags = flags; @@ -297,6 +299,7 @@ class PowerManagerService extends IPowerManager.Stub try { PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken, MY_UID, mTag); + mHeld = true; } finally { Binder.restoreCallingIdentity(ident); } @@ -306,15 +309,21 @@ class PowerManagerService extends IPowerManager.Stub public void release() { if (!mRefCounted || --mCount == 0) { PowerManagerService.this.releaseWakeLockLocked(mToken, false); + mHeld = false; } if (mCount < 0) { throw new RuntimeException("WakeLock under-locked " + mTag); } } + public boolean isHeld() + { + return mHeld; + } + public String toString() { return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags) - + " mCount=" + mCount + ")"; + + " mCount=" + mCount + " mHeld=" + mHeld + ")"; } } @@ -443,6 +452,8 @@ class PowerManagerService extends IPowerManager.Stub PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false); mPreventScreenOnPartialLock = new UnsynchronizedWakeLock( PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false); + mProximityPartialLock = new UnsynchronizedWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false); mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -907,6 +918,7 @@ class PowerManagerService extends IPowerManager.Stub pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock); pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock); pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock); + pw.println(" mProximityPartialLock=" + mProximityPartialLock); pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount); pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); pw.println(" mProximitySensorActive=" + mProximitySensorActive); @@ -1951,6 +1963,9 @@ class PowerManagerService extends IPowerManager.Stub proximityChangedLocked(mProximityPendingValue == 1); mProximityPendingValue = -1; } + if (mProximityPartialLock.isHeld()) { + mProximityPartialLock.release(); + } } } }; @@ -2412,6 +2427,9 @@ class PowerManagerService extends IPowerManager.Stub try { mSensorManager.unregisterListener(mProximityListener); mHandler.removeCallbacks(mProximityTask); + if (mProximityPartialLock.isHeld()) { + mProximityPartialLock.release(); + } mProximitySensorEnabled = false; } finally { Binder.restoreCallingIdentity(identity); @@ -2478,6 +2496,7 @@ class PowerManagerService extends IPowerManager.Stub long timeSinceLastEvent = milliseconds - mLastProximityEventTime; mLastProximityEventTime = milliseconds; mHandler.removeCallbacks(mProximityTask); + boolean proximityTaskQueued = false; // compare against getMaximumRange to support sensors that only return 0 or 1 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD && @@ -2490,11 +2509,21 @@ class PowerManagerService extends IPowerManager.Stub // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing mProximityPendingValue = (active ? 1 : 0); mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent); + proximityTaskQueued = true; } else { // process the value immediately mProximityPendingValue = -1; proximityChangedLocked(active); } + + // update mProximityPartialLock state + boolean held = mProximityPartialLock.isHeld(); + if (!held && proximityTaskQueued) { + // hold wakelock until mProximityTask runs + mProximityPartialLock.acquire(); + } else if (held && !proximityTaskQueued) { + mProximityPartialLock.release(); + } } } From e090281428cbd1114f4ae2f10755013cea09cdb5 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Sat, 14 Nov 2009 21:02:56 -0500 Subject: [PATCH 2/2] Fix a race condition that resulted in the screen coming on without the brightness set to the correct value. Do not cancel screen brightness animation in forceUserActivityLocked unless screen is turning off. Also not turn the screen on if PowerManager.preventScreenOn(false) is called while proximity sensor is active. Fixes b/2254818 (dim display) where due to a race condition the screen is stuck in a dim state. Change-Id: If6f805609c8d463631b9e22805e5242714ce34c0 Signed-off-by: Mike Lockwood --- services/java/com/android/server/PowerManagerService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 73527b75da1f5..bde03f3f9b5bf 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -1266,7 +1266,7 @@ class PowerManagerService extends IPowerManager.Stub // Forcibly turn on the screen if it's supposed to be on. (This // handles the case where the screen is currently off because of // a prior preventScreenOn(true) call.) - if ((mPowerState & SCREEN_ON_BIT) != 0) { + if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) { if (mSpew) { Log.d(TAG, "preventScreenOn: turning on after a prior preventScreenOn(true)!"); @@ -1847,8 +1847,10 @@ class PowerManagerService extends IPowerManager.Stub } private void forceUserActivityLocked() { - // cancel animation so userActivity will succeed - mScreenBrightness.animating = false; + if (isScreenTurningOffLocked()) { + // cancel animation so userActivity will succeed + mScreenBrightness.animating = false; + } boolean savedActivityAllowed = mUserActivityAllowed; mUserActivityAllowed = true; userActivity(SystemClock.uptimeMillis(), false);