summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/PowerManager.java10
-rw-r--r--services/java/com/android/server/power/DisplayPowerController.java27
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java35
3 files changed, 61 insertions, 11 deletions
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index fb02c0a..7e11c22 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -178,6 +178,16 @@ public final class PowerManager {
/**
* Wake lock level: Turns the screen off when the proximity sensor activates.
* <p>
+ * If the proximity sensor detects that an object is nearby, the screen turns off
+ * immediately. Shortly after the object moves away, the screen turns on again.
+ * </p><p>
+ * A proximity wake lock does not prevent the device from falling asleep
+ * unlike {@link #FULL_WAKE_LOCK}, {@link #SCREEN_BRIGHT_WAKE_LOCK} and
+ * {@link #SCREEN_DIM_WAKE_LOCK}. If there is no user activity and no other
+ * wake locks are held, then the device will fall asleep (and lock) as usual.
+ * However, the device will not fall asleep while the screen has been turned off
+ * by the proximity sensor because it effectively counts as ongoing user activity.
+ * </p><p>
* Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported}
* to determine whether this wake lock level is supported.
* </p>
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index 4f8cdde..d0e758f 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -117,8 +117,9 @@ final class DisplayPowerController {
private static final int PROXIMITY_NEGATIVE = 0;
private static final int PROXIMITY_POSITIVE = 1;
- // Proximity sensor debounce delay in milliseconds.
- private static final int PROXIMITY_SENSOR_DEBOUNCE_DELAY = 250;
+ // 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;
// Trigger proximity if distance is less than 5 cm.
private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
@@ -562,6 +563,7 @@ final class DisplayPowerController {
if (!mScreenOffBecauseOfProximity
&& mProximity == PROXIMITY_POSITIVE) {
mScreenOffBecauseOfProximity = true;
+ sendOnProximityPositive();
setScreenOn(false);
}
} else if (mWaitingForNegativeProximity
@@ -734,8 +736,13 @@ final class DisplayPowerController {
// Only accept a proximity sensor reading if it remains
// stable for the entire debounce delay.
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
- mPendingProximity = positive ? PROXIMITY_POSITIVE : PROXIMITY_NEGATIVE;
- mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_DEBOUNCE_DELAY;
+ if (positive) {
+ mPendingProximity = PROXIMITY_POSITIVE;
+ mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
+ } else {
+ mPendingProximity = PROXIMITY_NEGATIVE;
+ mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
+ }
debounceProximitySensor();
}
@@ -973,6 +980,17 @@ final class DisplayPowerController {
}
};
+ private void sendOnProximityPositive() {
+ mCallbackHandler.post(mOnProximityPositiveRunnable);
+ }
+
+ private final Runnable mOnProximityPositiveRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mCallbacks.onProximityPositive();
+ }
+ };
+
private void sendOnProximityNegative() {
mCallbackHandler.post(mOnProximityNegativeRunnable);
}
@@ -1090,6 +1108,7 @@ final class DisplayPowerController {
*/
public interface Callbacks {
void onStateChanged();
+ void onProximityPositive();
void onProximityNegative();
}
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 9a01022..eecac07 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -98,6 +98,8 @@ public final class PowerManagerService extends IPowerManager.Stub
private static final int DIRTY_STAY_ON = 1 << 7;
// Dirty bit: battery state changed
private static final int DIRTY_BATTERY_STATE = 1 << 8;
+ // Dirty bit: proximity state changed
+ private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
// The screen should be off or in the process of being turned off by the display controller.
@@ -258,6 +260,9 @@ public final class PowerManagerService extends IPowerManager.Stub
// True if the device should stay on.
private boolean mStayOn;
+ // True if the proximity sensor reads a positive result.
+ private boolean mProximityPositive;
+
// Screen brightness setting limits.
private int mScreenBrightnessSettingMinimum;
private int mScreenBrightnessSettingMaximum;
@@ -1101,12 +1106,17 @@ public final class PowerManagerService extends IPowerManager.Stub
*/
private void updateStayOnLocked(int dirty) {
if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
+ final boolean wasStayOn = mStayOn;
if (mStayOnWhilePluggedInSetting != 0
&& !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
} else {
mStayOn = false;
}
+
+ if (mStayOn != wasStayOn) {
+ mDirty |= DIRTY_STAY_ON;
+ }
}
}
@@ -1265,7 +1275,7 @@ public final class PowerManagerService extends IPowerManager.Stub
private boolean updateWakefulnessLocked(int dirty) {
boolean changed = false;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
- | DIRTY_WAKEFULNESS | DIRTY_STAY_ON)) != 0) {
+ | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE)) != 0) {
if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
@@ -1288,17 +1298,17 @@ public final class PowerManagerService extends IPowerManager.Stub
* to being fully awake or else go to sleep for good.
*/
private boolean isItBedTimeYetLocked() {
- return mBootCompleted && !isScreenBeingKeptOnLocked();
+ return mBootCompleted && !isBeingKeptAwakeLocked();
}
/**
- * Returns true if the screen is being kept on by a wake lock, user activity
+ * Returns true if the device is being kept awake by a wake lock, user activity
* or the stay on while powered setting.
*/
- private boolean isScreenBeingKeptOnLocked() {
+ private boolean isBeingKeptAwakeLocked() {
return mStayOn
- || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
- | WAKE_LOCK_PROXIMITY_SCREEN_OFF)) != 0
+ || mProximityPositive
+ || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0
|| (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
| USER_ACTIVITY_SCREEN_DIM)) != 0;
}
@@ -1314,6 +1324,7 @@ public final class PowerManagerService extends IPowerManager.Stub
| DIRTY_SETTINGS
| DIRTY_IS_POWERED
| DIRTY_STAY_ON
+ | DIRTY_PROXIMITY_POSITIVE
| DIRTY_BATTERY_STATE)) != 0) {
scheduleSandmanLocked();
}
@@ -1401,7 +1412,7 @@ public final class PowerManagerService extends IPowerManager.Stub
&& mDreamsEnabledSetting
&& mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
&& mBootCompleted
- && (mIsPowered || isScreenBeingKeptOnLocked());
+ && (mIsPowered || isBeingKeptAwakeLocked());
}
/**
@@ -1528,7 +1539,16 @@ public final class PowerManagerService extends IPowerManager.Stub
}
@Override
+ public void onProximityPositive() {
+ mProximityPositive = true;
+ mDirty |= DIRTY_PROXIMITY_POSITIVE;
+ updatePowerStateLocked();
+ }
+
+ @Override
public void onProximityNegative() {
+ mProximityPositive = false;
+ mDirty |= DIRTY_PROXIMITY_POSITIVE;
userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
updatePowerStateLocked();
@@ -1986,6 +2006,7 @@ public final class PowerManagerService extends IPowerManager.Stub
pw.println(" mIsPowered=" + mIsPowered);
pw.println(" mPlugType=" + mPlugType);
pw.println(" mStayOn=" + mStayOn);
+ pw.println(" mProximityPositive=" + mProximityPositive);
pw.println(" mBootCompleted=" + mBootCompleted);
pw.println(" mSystemReady=" + mSystemReady);
pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));