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

Commit 09652ac1 authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Allow phone to enter suspend with positive proximity." into klp-dev

parents 88ee0dac ec083213
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -450,6 +450,13 @@
         The default is false. -->
    <bool name="config_lidControlsSleep">false</bool>

    <!-- Indicate whether to allow the device to suspend when the screen is off
         due to the proximity sensor.  This resource should only be set to true
         if the sensor HAL correctly handles the proximity sensor as a wake-up source.
         Otherwise, the device may fail to wake out of suspend reliably.
         The default is false. -->
    <bool name="config_suspendWhenScreenOffDueToProximity">false</bool>

    <!-- Control the behavior when the user long presses the power button.
            0 - Nothing
            1 - Global actions menu
+1 −0
Original line number Diff line number Diff line
@@ -260,6 +260,7 @@
  <java-symbol type="bool" name="config_sip_wifi_only" />
  <java-symbol type="bool" name="config_sms_capable" />
  <java-symbol type="bool" name="config_sms_utf8_support" />
  <java-symbol type="bool" name="config_suspendWhenScreenOffDueToProximity" />
  <java-symbol type="bool" name="config_swipeDisambiguation" />
  <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
  <java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
+71 −29
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.SystemSensorManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -119,7 +118,7 @@ final class DisplayPowerController {

    // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
    private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
    private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 500;
    private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;

    // Trigger proximity if distance is less than 5 cm.
    private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
@@ -164,6 +163,10 @@ final class DisplayPowerController {
    // Notifier for sending asynchronous notifications.
    private final Notifier mNotifier;

    // The display suspend blocker.
    // Held while there are pending state change notifications.
    private final SuspendBlocker mDisplaySuspendBlocker;

    // The display blanker.
    private final DisplayBlanker mDisplayBlanker;

@@ -271,7 +274,7 @@ final class DisplayPowerController {

    // The raw non-debounced proximity sensor state.
    private int mPendingProximity = PROXIMITY_UNKNOWN;
    private long mPendingProximityDebounceTime;
    private long mPendingProximityDebounceTime = -1; // -1 if fully debounced

    // True if the screen was turned off because of the proximity sensor.
    // When the screen turns on again, we report user activity to the power manager.
@@ -346,10 +349,11 @@ final class DisplayPowerController {
    public DisplayPowerController(Looper looper, Context context, Notifier notifier,
            LightsService lights, TwilightService twilight, SensorManager sensorManager,
            DisplayManagerService displayManager,
            DisplayBlanker displayBlanker,
            SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker,
            Callbacks callbacks, Handler callbackHandler) {
        mHandler = new DisplayControllerHandler(looper);
        mNotifier = notifier;
        mDisplaySuspendBlocker = displaySuspendBlocker;
        mDisplayBlanker = displayBlanker;
        mCallbacks = callbacks;
        mCallbackHandler = callbackHandler;
@@ -601,7 +605,7 @@ final class DisplayPowerController {
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE) {
                    mScreenOffBecauseOfProximity = true;
                    sendOnProximityPositive();
                    sendOnProximityPositiveWithWakelock();
                    setScreenOn(false);
                }
            } else if (mWaitingForNegativeProximity
@@ -616,7 +620,7 @@ final class DisplayPowerController {
            if (mScreenOffBecauseOfProximity
                    && mProximity != PROXIMITY_POSITIVE) {
                mScreenOffBecauseOfProximity = false;
                sendOnProximityNegative();
                sendOnProximityNegativeWithWakelock();
            }
        } else {
            mWaitingForNegativeProximity = false;
@@ -737,7 +741,7 @@ final class DisplayPowerController {
                    }
                }
            }
            sendOnStateChanged();
            sendOnStateChangedWithWakelock();
        }
    }

@@ -810,22 +814,28 @@ final class DisplayPowerController {
    private void setProximitySensorEnabled(boolean enable) {
        if (enable) {
            if (!mProximitySensorEnabled) {
                // Register the listener.
                // Proximity sensor state already cleared initially.
                mProximitySensorEnabled = true;
                mPendingProximity = PROXIMITY_UNKNOWN;
                mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
                        SensorManager.SENSOR_DELAY_NORMAL, mHandler);
            }
        } else {
            if (mProximitySensorEnabled) {
                // Unregister the listener.
                // Clear the proximity sensor state for next time.
                mProximitySensorEnabled = false;
                mProximity = PROXIMITY_UNKNOWN;
                mPendingProximity = PROXIMITY_UNKNOWN;
                mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
                mSensorManager.unregisterListener(mProximitySensorListener);
                clearPendingProximityDebounceTime(); // release wake lock (must be last)
            }
        }
    }

    private void handleProximitySensorEvent(long time, boolean positive) {
        if (mProximitySensorEnabled) {
            if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
                return; // no change
            }
@@ -834,25 +844,37 @@ final class DisplayPowerController {
            }

            // Only accept a proximity sensor reading if it remains
        // stable for the entire debounce delay.
            // stable for the entire debounce delay.  We hold a wake lock while
            // debouncing the sensor.
            mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
            if (positive) {
                mPendingProximity = PROXIMITY_POSITIVE;
            mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
                setPendingProximityDebounceTime(
                        time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
            } else {
                mPendingProximity = PROXIMITY_NEGATIVE;
            mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
                setPendingProximityDebounceTime(
                        time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
            }

            // Debounce the new sensor reading.
            debounceProximitySensor();
        }
    }

    private void debounceProximitySensor() {
        if (mPendingProximity != PROXIMITY_UNKNOWN) {
        if (mProximitySensorEnabled
                && mPendingProximity != PROXIMITY_UNKNOWN
                && mPendingProximityDebounceTime >= 0) {
            final long now = SystemClock.uptimeMillis();
            if (mPendingProximityDebounceTime <= now) {
                // Sensor reading accepted.  Apply the change then release the wake lock.
                mProximity = mPendingProximity;
                sendUpdatePowerState();
                updatePowerState();
                clearPendingProximityDebounceTime(); // release wake lock (must be last)
            } else {
                // Need to wait a little longer.
                // Debounce again later.  We continue holding a wake lock while waiting.
                Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
                msg.setAsynchronous(true);
                mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
@@ -860,6 +882,20 @@ final class DisplayPowerController {
        }
    }

    private void clearPendingProximityDebounceTime() {
        if (mPendingProximityDebounceTime >= 0) {
            mPendingProximityDebounceTime = -1;
            mDisplaySuspendBlocker.release(); // release wake lock
        }
    }

    private void setPendingProximityDebounceTime(long debounceTime) {
        if (mPendingProximityDebounceTime < 0) {
            mDisplaySuspendBlocker.acquire(); // acquire wake lock
        }
        mPendingProximityDebounceTime = debounceTime;
    }

    private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) {
        if (enable) {
            if (!mLightSensorEnabled) {
@@ -1120,7 +1156,8 @@ final class DisplayPowerController {
        return x + (y - x) * alpha;
    }

    private void sendOnStateChanged() {
    private void sendOnStateChangedWithWakelock() {
        mDisplaySuspendBlocker.acquire();
        mCallbackHandler.post(mOnStateChangedRunnable);
    }

@@ -1128,10 +1165,12 @@ final class DisplayPowerController {
        @Override
        public void run() {
            mCallbacks.onStateChanged();
            mDisplaySuspendBlocker.release();
        }
    };

    private void sendOnProximityPositive() {
    private void sendOnProximityPositiveWithWakelock() {
        mDisplaySuspendBlocker.acquire();
        mCallbackHandler.post(mOnProximityPositiveRunnable);
    }

@@ -1139,10 +1178,12 @@ final class DisplayPowerController {
        @Override
        public void run() {
            mCallbacks.onProximityPositive();
            mDisplaySuspendBlocker.release();
        }
    };

    private void sendOnProximityNegative() {
    private void sendOnProximityNegativeWithWakelock() {
        mDisplaySuspendBlocker.acquire();
        mCallbackHandler.post(mOnProximityNegativeRunnable);
    }

@@ -1150,6 +1191,7 @@ final class DisplayPowerController {
        @Override
        public void run() {
            mCallbacks.onProximityNegative();
            mDisplaySuspendBlocker.release();
        }
    };

+49 −9
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ import android.util.TimeUtils;
import android.view.WindowManagerPolicy;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

@@ -287,6 +286,9 @@ public final class PowerManagerService extends IPowerManager.Stub
    // True if the device should wake up when plugged or unplugged.
    private boolean mWakeUpWhenPluggedOrUnpluggedConfig;

    // True if the device should suspend when the screen is off due to proximity.
    private boolean mSuspendWhenScreenOffDueToProximityConfig;

    // True if dreams are supported on this device.
    private boolean mDreamsSupportedConfig;

@@ -447,7 +449,7 @@ public final class PowerManagerService extends IPowerManager.Stub
            // own handler thread to ensure timely operation.
            mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
                    mContext, mNotifier, mLightsService, twilight, sensorManager,
                    mDisplayManagerService, mDisplayBlanker,
                    mDisplayManagerService, mDisplaySuspendBlocker, mDisplayBlanker,
                    mDisplayPowerControllerCallbacks, mHandler);

            mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
@@ -514,6 +516,8 @@ public final class PowerManagerService extends IPowerManager.Stub

        mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
                com.android.internal.R.bool.config_unplugTurnsOnScreen);
        mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
                com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
        mDreamsSupportedConfig = resources.getBoolean(
                com.android.internal.R.bool.config_dreamsSupported);
        mDreamsEnabledByDefaultConfig = resources.getBoolean(
@@ -639,6 +643,7 @@ public final class PowerManagerService extends IPowerManager.Stub
        }
    }

    @SuppressWarnings("deprecation")
    private static boolean isScreenLock(final WakeLock wakeLock) {
        switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
            case PowerManager.FULL_WAKE_LOCK:
@@ -817,6 +822,7 @@ public final class PowerManagerService extends IPowerManager.Stub
        }
    }

    @SuppressWarnings("deprecation")
    private boolean isWakeLockLevelSupportedInternal(int level) {
        synchronized (mLock) {
            switch (level) {
@@ -1005,6 +1011,7 @@ public final class PowerManagerService extends IPowerManager.Stub
        }
    }

    @SuppressWarnings("deprecation")
    private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
        if (DEBUG_SPEW) {
            Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
@@ -1261,6 +1268,7 @@ public final class PowerManagerService extends IPowerManager.Stub
     *
     * This function must have no other side-effects.
     */
    @SuppressWarnings("deprecation")
    private void updateWakeLockSummaryLocked(int dirty) {
        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
            mWakeLockSummary = 0;
@@ -1299,7 +1307,7 @@ public final class PowerManagerService extends IPowerManager.Stub
                        break;
                    case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
                            mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
                        }
                        break;
                }
@@ -1458,7 +1466,11 @@ public final class PowerManagerService extends IPowerManager.Stub

    /**
     * Returns true if the device is being kept awake by a wake lock, user activity
     * or the stay on while powered setting.
     * or the stay on while powered setting.  We also keep the phone awake when
     * the proximity sensor returns a positive result so that the device does not
     * lock while in a phone call.  This function only controls whether the device
     * will go to sleep or dream which is independent of whether it will be allowed
     * to suspend.
     */
    private boolean isBeingKeptAwakeLocked() {
        return mStayOn
@@ -1749,10 +1761,8 @@ public final class PowerManagerService extends IPowerManager.Stub
     * This function must have no other side-effects.
     */
    private void updateSuspendBlockerLocked() {
        final boolean needWakeLockSuspendBlocker = (mWakeLockSummary != 0);
        final boolean needDisplaySuspendBlocker = (mUserActivitySummary != 0
                || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
                || !mDisplayReady || !mBootCompleted);
        final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
        final boolean needDisplaySuspendBlocker = needDisplaySuspendBlocker();

        // First acquire suspend blockers if needed.
        if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
@@ -1775,6 +1785,27 @@ public final class PowerManagerService extends IPowerManager.Stub
        }
    }

    /**
     * Return true if we must keep a suspend blocker active on behalf of the display.
     * We do so if the screen is on or is in transition between states.
     */
    private boolean needDisplaySuspendBlocker() {
        if (!mDisplayReady) {
            return true;
        }
        if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
            // If we asked for the screen to be on but it is off due to the proximity
            // sensor then we may suspend but only if the configuration allows it.
            // On some hardware it may not be safe to suspend because the proximity
            // sensor may not be correctly configured as a wake-up source.
            if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
                    || !mSuspendWhenScreenOffDueToProximityConfig) {
                return true;
            }
        }
        return false;
    }

    @Override // Binder call
    public boolean isScreenOn() {
        final long ident = Binder.clearCallingIdentity();
@@ -2115,7 +2146,7 @@ public final class PowerManagerService extends IPowerManager.Stub
     *
     * @param brightness The overridden brightness.
     *
     * @see Settings.System#SCREEN_BRIGHTNESS
     * @see android.provider.Settings.System#SCREEN_BRIGHTNESS
     */
    @Override // Binder call
    public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
@@ -2255,7 +2286,16 @@ public final class PowerManagerService extends IPowerManager.Stub

            pw.println();
            pw.println("Settings and Configuration:");
            pw.println("  mWakeUpWhenPluggedOrUnpluggedConfig="
                    + mWakeUpWhenPluggedOrUnpluggedConfig);
            pw.println("  mSuspendWhenScreenOffDueToProximityConfig="
                    + mSuspendWhenScreenOffDueToProximityConfig);
            pw.println("  mDreamsSupportedConfig=" + mDreamsSupportedConfig);
            pw.println("  mDreamsEnabledByDefaultConfig=" + mDreamsEnabledByDefaultConfig);
            pw.println("  mDreamsActivatedOnSleepByDefaultConfig="
                    + mDreamsActivatedOnSleepByDefaultConfig);
            pw.println("  mDreamsActivatedOnDockByDefaultConfig="
                    + mDreamsActivatedOnDockByDefaultConfig);
            pw.println("  mDreamsEnabledSetting=" + mDreamsEnabledSetting);
            pw.println("  mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
            pw.println("  mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);