Merge change I813fdb7a into eclair

* changes:
  Fixes for proximity sensor behavior:
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index e021012..d3ec3d9 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -66,7 +66,7 @@
                         IBinder lock = new Binder();
                         pm.acquireWakeLock(PowerManager.FULL_WAKE_LOCK, lock, "svc power");
                         pm.setStayOnSetting(val);
-                        pm.releaseWakeLock(lock);
+                        pm.releaseWakeLock(lock, 0);
                     }
                     catch (RemoteException e) {
                         System.err.println("Faild to set setting: " + e);
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index bcf769d..b9dc860 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -22,7 +22,7 @@
 {
     void acquireWakeLock(int flags, IBinder lock, String tag);
     void goToSleep(long time);
-    void releaseWakeLock(IBinder lock);
+    void releaseWakeLock(IBinder lock, int flags);
     void userActivity(long when, boolean noChangeLights);
     void userActivityWithForce(long when, boolean noChangeLights, boolean force);
     void setPokeLock(int pokey, IBinder lock, String tag);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 2efc230..4b3b6f6 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -159,6 +159,15 @@
     public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = WAKE_BIT_PROXIMITY_SCREEN_OFF;
 
     /**
+     * Flag for {@link WakeLock#release release(int)} to defer releasing a
+     * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wakelock until the proximity sensor returns
+     * a negative value.
+     *
+     * {@hide}
+     */
+    public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1;
+
+    /**
      * Normally wake locks don't actually wake the device, they just cause
      * it to remain on once it's already on.  Think of the video player
      * app as the normal behavior.  Notifications that pop up and want
@@ -267,10 +276,26 @@
          */
         public void release()
         {
+            release(0);
+        }
+
+        /**
+         * Release your claim to the CPU or screen being on.
+         * @param flags Combination of flag values to modify the release behavior.
+         *              Currently only {@link #WAIT_FOR_PROXIMITY_NEGATIVE} is supported.
+         *
+         * <p>
+         * It may turn off shortly after you release it, or it may not if there
+         * are other wake locks held.
+         *
+         * {@hide}
+         */
+        public void release(int flags)
+        {
             synchronized (mToken) {
                 if (!mRefCounted || --mCount == 0) {
                     try {
-                        mService.releaseWakeLock(mToken);
+                        mService.releaseWakeLock(mToken, flags);
                     } catch (RemoteException e) {
                     }
                     mHeld = false;
@@ -302,7 +327,7 @@
             synchronized (mToken) {
                 if (mHeld) {
                     try {
-                        mService.releaseWakeLock(mToken);
+                        mService.releaseWakeLock(mToken, 0);
                     } catch (RemoteException e) {
                     }
                     RuntimeInit.crash(TAG, new Exception(
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 94cf6d4..444c8de 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -309,7 +309,7 @@
 
         public void release() {
             if (!mRefCounted || --mCount == 0) {
-                PowerManagerService.this.releaseWakeLockLocked(mToken, false);
+                PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false);
                 mHeld = false;
             }
             if (mCount < 0) {
@@ -556,7 +556,7 @@
         }
         public void binderDied() {
             synchronized (mLocks) {
-                releaseWakeLockLocked(this.binder, true);
+                releaseWakeLockLocked(this.binder, 0, true);
             }
         }
         final int flags;
@@ -701,18 +701,18 @@
         }
     }
 
-    public void releaseWakeLock(IBinder lock) {
+    public void releaseWakeLock(IBinder lock, int flags) {
         int uid = Binder.getCallingUid();
         if (uid != Process.myUid()) {
             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
         }
 
         synchronized (mLocks) {
-            releaseWakeLockLocked(lock, false);
+            releaseWakeLockLocked(lock, flags, false);
         }
     }
 
-    private void releaseWakeLockLocked(IBinder lock, boolean death) {
+    private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
         int releaseUid;
         String releaseName;
         int releaseType;
@@ -744,7 +744,8 @@
         } else if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
             mProximityWakeLockCount--;
             if (mProximityWakeLockCount == 0) {
-                if (mProximitySensorActive) {
+                if (mProximitySensorActive &&
+                        ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
                     // wait for proximity sensor to go negative before disabling sensor
                     if (mDebugProximitySensor) {
                         Log.d(TAG, "waiting for proximity sensor to go negative");
@@ -1923,6 +1924,11 @@
                 Log.d(TAG, "ignoring user activity while turning off screen");
                 return;
             }
+            // Disable proximity sensor if if user presses power key while we are in the
+            // "waiting for proximity sensor to go negative" state.
+            if (mProximitySensorActive && mProximityWakeLockCount == 0) {
+                mProximitySensorActive = false;
+            }
             if (mLastEventTime <= time || force) {
                 mLastEventTime = time;
                 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {