OSDN Git Service

Allow phone to go to sleep while in call.
authorJeff Brown <jeffbrown@google.com>
Thu, 4 Oct 2012 20:18:36 +0000 (13:18 -0700)
committerJeff Brown <jeffbrown@google.com>
Thu, 4 Oct 2012 23:22:04 +0000 (16:22 -0700)
Bug: 7279383
Change-Id: Ia05490218f40a1843507b95ff48fa07910e582d4

core/java/android/os/PowerManager.java
services/java/com/android/server/power/DisplayPowerController.java
services/java/com/android/server/power/PowerManagerService.java

index fb02c0a..7e11c22 100644 (file)
@@ -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>
index 4f8cdde..d0e758f 100644 (file)
@@ -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();
     }
 
index 9a01022..eecac07 100644 (file)
@@ -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));