am 04c585e3: Merge changes Ia4825f54,If6f80560 into eclair

Merge commit '04c585e3bcb75c85ceeacf2fd94ea4194f332404' into eclair-mr2

* commit '04c585e3bcb75c85ceeacf2fd94ea4194f332404':
  Fix a race condition that resulted in the screen coming on without the brightness set to the correct value.
  PowerManagerService: Hold a wakelock while mProximityTask is queued
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index e1425d4..bde03f3 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -185,6 +185,7 @@
     private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock;
     private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock;
     private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
+    private UnsynchronizedWakeLock mProximityPartialLock;
     private HandlerThread mHandlerThread;
     private Handler mHandler;
     private TimeoutTask mTimeoutTask = new TimeoutTask();
@@ -283,6 +284,7 @@
         IBinder mToken;
         int mCount = 0;
         boolean mRefCounted;
+        boolean mHeld;
 
         UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) {
             mFlags = flags;
@@ -297,6 +299,7 @@
                 try {
                     PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
                             MY_UID, mTag);
+                    mHeld = true;
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
@@ -306,15 +309,21 @@
         public void release() {
             if (!mRefCounted || --mCount == 0) {
                 PowerManagerService.this.releaseWakeLockLocked(mToken, false);
+                mHeld = false;
             }
             if (mCount < 0) {
                 throw new RuntimeException("WakeLock under-locked " + mTag);
             }
         }
 
+        public boolean isHeld()
+        {
+            return mHeld;
+        }
+
         public String toString() {
             return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags)
-                    + " mCount=" + mCount + ")";
+                    + " mCount=" + mCount + " mHeld=" + mHeld + ")";
         }
     }
 
@@ -443,6 +452,8 @@
                                 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
         mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
                                 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
+        mProximityPartialLock = new UnsynchronizedWakeLock(
+                                PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
 
         mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
         mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -907,6 +918,7 @@
         pw.println("  mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
         pw.println("  mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
         pw.println("  mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
+        pw.println("  mProximityPartialLock=" + mProximityPartialLock);
         pw.println("  mProximityWakeLockCount=" + mProximityWakeLockCount);
         pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
         pw.println("  mProximitySensorActive=" + mProximitySensorActive);
@@ -1254,7 +1266,7 @@
                 // Forcibly turn on the screen if it's supposed to be on.  (This
                 // handles the case where the screen is currently off because of
                 // a prior preventScreenOn(true) call.)
-                if ((mPowerState & SCREEN_ON_BIT) != 0) {
+                if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
                     if (mSpew) {
                         Log.d(TAG,
                               "preventScreenOn: turning on after a prior preventScreenOn(true)!");
@@ -1835,8 +1847,10 @@
     }
 
     private void forceUserActivityLocked() {
-        // cancel animation so userActivity will succeed
-        mScreenBrightness.animating = false;
+        if (isScreenTurningOffLocked()) {
+            // cancel animation so userActivity will succeed
+            mScreenBrightness.animating = false;
+        }
         boolean savedActivityAllowed = mUserActivityAllowed;
         mUserActivityAllowed = true;
         userActivity(SystemClock.uptimeMillis(), false);
@@ -1951,6 +1965,9 @@
                     proximityChangedLocked(mProximityPendingValue == 1);
                     mProximityPendingValue = -1;
                 }
+                if (mProximityPartialLock.isHeld()) {
+                    mProximityPartialLock.release();
+                }
             }
         }
     };
@@ -2412,6 +2429,9 @@
             try {
                 mSensorManager.unregisterListener(mProximityListener);
                 mHandler.removeCallbacks(mProximityTask);
+                if (mProximityPartialLock.isHeld()) {
+                    mProximityPartialLock.release();
+                }
                 mProximitySensorEnabled = false;
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -2478,6 +2498,7 @@
                 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
                 mLastProximityEventTime = milliseconds;
                 mHandler.removeCallbacks(mProximityTask);
+                boolean proximityTaskQueued = false;
 
                 // compare against getMaximumRange to support sensors that only return 0 or 1
                 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
@@ -2490,11 +2511,21 @@
                     // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
                     mProximityPendingValue = (active ? 1 : 0);
                     mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
+                    proximityTaskQueued = true;
                 } else {
                     // process the value immediately
                     mProximityPendingValue = -1;
                     proximityChangedLocked(active);
                 }
+
+                // update mProximityPartialLock state
+                boolean held = mProximityPartialLock.isHeld();
+                if (!held && proximityTaskQueued) {
+                    // hold wakelock until mProximityTask runs
+                    mProximityPartialLock.acquire();
+                } else if (held && !proximityTaskQueued) {
+                    mProximityPartialLock.release();
+                }
             }
         }