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

Commit a95ee9f5 authored by Danesh M's avatar Danesh M Committed by Zhao Wei Liew
Browse files

PowerManager: Add proximity check on wake

This consists of the following patches:

ProximityWake : Add support for checking proximity when waking device

Change-Id: Ia5ff446d88435773acccc7467e66009000dc20cb

Be sure to shutdown the proximity sensor after display wake

This fixes:
http://review.cyanogenmod.org/#/c/66657/



Change-Id: I1768f13cb48c3e056d0e137642690fc3d650c4ab

PowerManager : Make proximity check opt-in

Change-Id: I7cf64a82530da2e655018e43683ba7a5584d54f8

Framework : Fix proximity wakeup reference

Change-Id: Ia40ca6fbf6e37fbb3996f2384f725c30b88c2131

[1/2] Frameworks: let InCallUI handle proximity sensor for incoming calls

Fixes "while 'prevent accidental wake-up' is on, proximity sensor
doesn't control screen state on incoming call. Must manually
turn on screen to see who's calling."

Change-Id: I738b3bbd328992c8a8010a0c8d9aa1e444cfa9f9

power: Fix locking for wakeup proximity check

 * Often I'm noticing high power consumption due to the proximity sensor
   never turning off. Add synchronization around this code to ensure
   ordering.

Change-Id: I8ccf3152166cd896e0ce2551c01b8ac8f501d782

add config for proximity check on screen on default value

Change-Id: I7e6ae08e23ee147a37986aa6aa9b3176b301a09e

Services : Ensure proximity check is taken into consideration

Only do the proximity check if explicitly being asked to do so.
This is a patch that was never ported from cm-11.0 :
2293e60c

issue-id: CYNGNOS-1223

Change-Id: Id1be619e638de6a45252d8390eab6e38bd5de5a7

services: button brightness should check proximity

Change-Id: I10a72fa6d8b520e86cfef3d7ded489fd7fa936d2

powermanager: Initialize SensorManager in systemReady()

 * Service startup ordering is different on M and the sensor service
   is not ready during construction of the PowerManager. This was
   causing a hang on boot. Move it to systemReady instead.

Change-Id: I9e0293484e1aaaf9f82f9c75680bec558607c54d

fw: Move proximitycheck to CMSettings.

Change-Id: Ie80166c990363d3846925b189a1f7001a7fd56f8

PowerManagerService: Log when proximity blocks wake

There is currently no indication when the proximity sensor
is allowed to prevent the system from waking up.  This can
make it hard to debug weird failed wakes.  Add a log to
facilitate debugging wakup problems.

Change-Id: I7df34e13b1268a4e7211fb06ccd88f2053c0af0a
(cherry picked from commit 21ddba54)

base: Fix proximity check on power key

To test, enable "Settings >> Display >> Prevent accidental wakeup",
hold your hand over the proximity sensor and turn your phone on.

Prior to this change, it will wake up the phone and after the change
it will not.

Change-Id: Ied300108cebb31dedf228e85510abebb3e8a4152

base: Fix proximity check on non power key

To test, enable "Settings >> Display >> Prevent accidental wake-up"
and "Settings >> Buttons >> Home button Wake up device", hold your
hand over the proximity sensor and turn your phone on by home key.

Prior to this change, it will wake up the phone and after the change
it will not.

Change-Id: Ifd14ff2ad9cd2cbc64209b9cf19e3c0ee0b6f40f

only use proximity checks on wakeup keys

The power button should always wake the screen regardless of the
proximity; only check proximity when the wake up key code is WAKEUP.

Ticket: CYNGNOS-2579

Change-Id: I686ad22d513a3d939be3a0a5c3b752339b2383d3
Signed-off-by: default avatarRoman Birg <roman@cyngn.com>

Disable proximity check on power key properly

Change-Id: If1ca0fa02805ce2fbe5a9ac1ab56a5e62beca4e1

The change-id below is so that Gerrit won't be confused.
Change-Id: Ia5ff446d88435773acccc7467e66009000dc20cb
parent cac7ffc9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -74,4 +74,5 @@ interface IPowerManager

    void setKeyboardLight(boolean on, int key);

    void wakeUpWithProximityCheck(long time, String reason, String opPackageName);
}
+16 −0
Original line number Diff line number Diff line
@@ -715,6 +715,22 @@ public final class PowerManager {
        }
    }

    /**
     * Forces the device to wake up from sleep only if
     * nothing is blocking the proximity sensor
     *
     * @see #wakeUp
     *
     * @hide
     */
    public void wakeUpWithProximityCheck(long time, String reason) {
        try {
            mService.wakeUpWithProximityCheck(time, reason, mContext.getOpPackageName());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Forces the device to start napping.
     * <p>
+14 −3
Original line number Diff line number Diff line
@@ -6113,7 +6113,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        if (isValidGlobalKey(keyCode)
                && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
            if (isWakeKey) {
                wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
                wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
                       "android.policy:KEY", true);
            }
            return result;
        }
@@ -6505,7 +6506,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        if (isWakeKey) {
            wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
            wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY",
                    event.getKeyCode() == KeyEvent.KEYCODE_WAKEUP); // Check prox only on wake key
        }

        return result;
@@ -6954,6 +6956,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) {
        return wakeUp(wakeTime, wakeInTheaterMode, reason, false);
    }

    private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason,
            final boolean withProximityCheck) {
        final boolean theaterModeEnabled = isTheaterModeEnabled();
        if (!wakeInTheaterMode && theaterModeEnabled) {
            return false;
@@ -6964,7 +6971,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    Settings.Global.THEATER_MODE_ON, 0);
        }

        if (withProximityCheck) {
            mPowerManager.wakeUpWithProximityCheck(wakeTime, reason);
        } else {
            mPowerManager.wakeUp(wakeTime, reason);
        }
        return true;
    }

+149 −8
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.SystemSensorManager;
import android.hardware.display.DisplayManagerInternal;
@@ -57,6 +60,7 @@ import android.provider.Settings.SettingNotFoundException;
import android.service.dreams.DreamManagerInternal;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.telephony.TelephonyManager;
import android.util.EventLog;
import android.util.Slog;
import android.util.SparseIntArray;
@@ -114,6 +118,8 @@ public final class PowerManagerService extends SystemService
    // Message: Sent when the screen brightness boost expires.
    private static final int MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 3;

    private static final int MSG_WAKE_UP = 5;

    // Dirty bit: mWakeLocks changed
    protected static final int DIRTY_WAKE_LOCKS = 1 << 0;
    // Dirty bit: mWakefulness changed
@@ -186,6 +192,8 @@ public final class PowerManagerService extends SystemService

    private static final int BUTTON_ON_DURATION = 5 * 1000;

    private static final float PROXIMITY_NEAR_THRESHOLD = 5.0f;

    private final Context mContext;
    private final ServiceThread mHandlerThread;
    private final PowerManagerHandler mHandler;
@@ -533,6 +541,17 @@ public final class PowerManagerService extends SystemService

    private boolean mKeyboardVisible = false;

    // Whether proximity check on wake is enabled by default
    private boolean mProximityWakeEnabledByDefaultConfig;

    private boolean mProximityWakeSupported;
    private boolean mProximityWakeEnabled;
    private int mProximityTimeOut;
    private SensorManager mSensorManager;
    private Sensor mProximitySensor;
    private SensorEventListener mProximityListener;
    private android.os.PowerManager.WakeLock mProximityWakeLock;

    public PowerManagerService(Context context) {
        super(context);
        mContext = context;
@@ -634,6 +653,10 @@ public final class PowerManagerService extends SystemService
            mDisplayManagerInternal.initPowerManagement(
                    mDisplayPowerCallbacks, mHandler, sensorManager);

            // Initialize proximity sensor
            mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
            mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

            // Register for broadcasts from other components of the system.
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
@@ -720,6 +743,9 @@ public final class PowerManagerService extends SystemService
            resolver.registerContentObserver(CMSettings.Global.getUriFor(
                    CMSettings.Global.DEV_FORCE_SHOW_NAVBAR),
                    false, mSettingsObserver, UserHandle.USER_ALL);
            resolver.registerContentObserver(CMSettings.System.getUriFor(
                    CMSettings.System.PROXIMITY_ON_WAKE),
                    false, mSettingsObserver, UserHandle.USER_ALL);

            // Go.
            readConfigurationLocked();
@@ -768,6 +794,16 @@ public final class PowerManagerService extends SystemService
                com.android.internal.R.fraction.config_maximumScreenDimRatio, 1, 1);
        mSupportsDoubleTapWakeConfig = resources.getBoolean(
                com.android.internal.R.bool.config_supportDoubleTapWake);
        mProximityWakeSupported = resources.getBoolean(
                org.cyanogenmod.platform.internal.R.bool.config_proximityCheckOnWake);
        mProximityWakeEnabledByDefaultConfig = resources.getBoolean(
                org.cyanogenmod.platform.internal.R.bool.config_proximityCheckOnWakeEnabledByDefault);
        mProximityTimeOut = resources.getInteger(
                org.cyanogenmod.platform.internal.R.integer.config_proximityCheckTimeout);
        if (mProximityWakeSupported) {
            mProximityWakeLock = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE))
                    .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ProximityWakeLock");
        }
    }

    private void updateSettingsLocked() {
@@ -856,6 +892,10 @@ public final class PowerManagerService extends SystemService
                UserHandle.USER_CURRENT);
        mForceNavbar = CMSettings.Global.getIntForUser(resolver,
                CMSettings.Global.DEV_FORCE_SHOW_NAVBAR, 0, UserHandle.USER_CURRENT) == 1;
        mProximityWakeEnabled = CMSettings.System.getInt(resolver,
                CMSettings.System.PROXIMITY_ON_WAKE,
                mProximityWakeEnabledByDefaultConfig ? 1 : 0) == 1;

        mDirty |= DIRTY_SETTINGS;
    }

@@ -1724,12 +1764,14 @@ public final class PowerManagerService extends SystemService
                                    && now > mLastUserActivityTime + mButtonTimeout) {
                                mButtonsLight.setBrightness(0);
                            } else {
                                if (!mProximityPositive) {
                                    mButtonsLight.setBrightness(buttonBrightness);
                                    if (buttonBrightness != 0 && mButtonTimeout != 0) {
                                        nextTimeout = now + mButtonTimeout;
                                    }
                                }
                            }
                        }
                    } else {
                        nextTimeout = mLastUserActivityTime + screenOffTimeout;
                        if (now < nextTimeout) {
@@ -3091,6 +3133,10 @@ public final class PowerManagerService extends SystemService
                case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
                    handleScreenBrightnessBoostTimeout();
                    break;
                case MSG_WAKE_UP:
                    cleanupProximity();
                    ((Runnable) msg.obj).run();
                    break;
            }
        }
    }
@@ -3462,6 +3508,19 @@ public final class PowerManagerService extends SystemService

        @Override // Binder call
        public void wakeUp(long eventTime, String reason, String opPackageName) {
            wakeUp(eventTime, reason, opPackageName, false);
        }

        @Override // Binder call
        public void wakeUpWithProximityCheck(long eventTime, String reason, String opPackageName) {
            wakeUp(eventTime, reason, opPackageName, true);
        }

        /**
         * @hide
         */
        private void wakeUp(long eventTime, String reason, String opPackageName,
                final boolean checkProximity) {
            if (eventTime > SystemClock.uptimeMillis()) {
                throw new IllegalArgumentException("event time must not be in the future");
            }
@@ -3470,6 +3529,9 @@ public final class PowerManagerService extends SystemService
                    android.Manifest.permission.DEVICE_POWER, null);

            final int uid = Binder.getCallingUid();
            final Runnable r = new Runnable() {
                @Override
                public void run() {
                    final long ident = Binder.clearCallingIdentity();
                    try {
                        wakeUpInternal(eventTime, reason, uid, opPackageName, uid);
@@ -3477,6 +3539,13 @@ public final class PowerManagerService extends SystemService
                        Binder.restoreCallingIdentity(ident);
                    }
                }
            };
            if (checkProximity) {
                runWithProximityCheck(r);
            } else {
                r.run();
            }
        }

        @Override // Binder call
        public void goToSleep(long eventTime, int reason, int flags) {
@@ -3936,4 +4005,76 @@ public final class PowerManagerService extends SystemService
            nativeSetFeature(featureId, data);
        }
    }

    private void cleanupProximity() {
        synchronized (mProximityWakeLock) {
            cleanupProximityLocked();
        }
    }

    private void cleanupProximityLocked() {
        if (mProximityWakeLock.isHeld()) {
            mProximityWakeLock.release();
        }
        if (mProximityListener != null) {
            mSensorManager.unregisterListener(mProximityListener);
            mProximityListener = null;
        }
    }

    private void runWithProximityCheck(final Runnable r) {
        if (mHandler.hasMessages(MSG_WAKE_UP)) {
            // A message is already queued
            return;
        }

        final TelephonyManager tm =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        final boolean hasIncomingCall = tm.getCallState() == TelephonyManager.CALL_STATE_RINGING;

        if (mProximityWakeSupported && mProximityWakeEnabled
                && mProximitySensor != null && !hasIncomingCall) {
            final Message msg = mHandler.obtainMessage(MSG_WAKE_UP);
            msg.obj = r;
            mHandler.sendMessageDelayed(msg, mProximityTimeOut);
            runPostProximityCheck(r);
        } else {
            r.run();
        }
    }

    private void runPostProximityCheck(final Runnable r) {
        if (mSensorManager == null) {
            r.run();
            return;
        }
        synchronized (mProximityWakeLock) {
            mProximityWakeLock.acquire();
            mProximityListener = new SensorEventListener() {
                @Override
                public void onSensorChanged(SensorEvent event) {
                    cleanupProximityLocked();
                    if (!mHandler.hasMessages(MSG_WAKE_UP)) {
                        Slog.w(TAG, "Proximity sensor took too long, wake event already triggered!");
                        return;
                    }
                    mHandler.removeMessages(MSG_WAKE_UP);
                    final float distance = event.values[0];
                    if (distance >= PROXIMITY_NEAR_THRESHOLD ||
                            distance >= mProximitySensor.getMaximumRange()) {
                        r.run();
                    } else {
                        Slog.w(TAG, "Not waking up. Proximity sensor is blocked.");
                    }
                }

                @Override
                public void onAccuracyChanged(Sensor sensor, int accuracy) {
                    // Do nothing
                }
            };
            mSensorManager.registerListener(mProximityListener,
                   mProximitySensor, SensorManager.SENSOR_DELAY_FASTEST);
        }
    }
}