am 09652ac1: Merge "Allow phone to enter suspend with positive proximity." into klp-dev
* commit '09652ac1db59b70de47ff5ea49953773312a171f': Allow phone to enter suspend with positive proximity.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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,49 +814,67 @@ 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 (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
|
||||
return; // no change
|
||||
}
|
||||
if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
|
||||
return; // no change
|
||||
}
|
||||
if (mProximitySensorEnabled) {
|
||||
if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
|
||||
return; // no change
|
||||
}
|
||||
if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
|
||||
return; // no change
|
||||
}
|
||||
|
||||
// Only accept a proximity sensor reading if it remains
|
||||
// stable for the entire debounce delay.
|
||||
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
if (positive) {
|
||||
mPendingProximity = PROXIMITY_POSITIVE;
|
||||
mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
|
||||
} else {
|
||||
mPendingProximity = PROXIMITY_NEGATIVE;
|
||||
mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
|
||||
// Only accept a proximity sensor reading if it remains
|
||||
// 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;
|
||||
setPendingProximityDebounceTime(
|
||||
time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
|
||||
} else {
|
||||
mPendingProximity = PROXIMITY_NEGATIVE;
|
||||
setPendingProximityDebounceTime(
|
||||
time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
|
||||
}
|
||||
|
||||
// Debounce the new sensor reading.
|
||||
debounceProximitySensor();
|
||||
}
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user