Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e5bb7f1 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

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: default avatarMike Lockwood <lockwood@android.com>
parent d12ba5e0
Loading
Loading
Loading
Loading
+30 −1
Original line number Diff line number Diff line
@@ -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();
                }
            }
        }