Merge "Misc fixes for throttling." into froyo
diff --git a/Android.mk b/Android.mk
index 10b6d67..8783934 100644
--- a/Android.mk
+++ b/Android.mk
@@ -369,6 +369,7 @@
     -since ./frameworks/base/api/5.xml 5 \
     -since ./frameworks/base/api/6.xml 6 \
     -since ./frameworks/base/api/7.xml 7 \
+    -since ./frameworks/base/api/8.xml 8 \
 		-error 1 -error 2 -warning 3 -error 4 -error 6 -error 8 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
diff --git a/core/java/android/webkit/PluginFullScreenHolder.java b/core/java/android/webkit/PluginFullScreenHolder.java
index 6d9e108..1deca67 100644
--- a/core/java/android/webkit/PluginFullScreenHolder.java
+++ b/core/java/android/webkit/PluginFullScreenHolder.java
@@ -27,6 +27,7 @@
 import android.app.Dialog;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -51,6 +52,15 @@
         contentView.setLayoutParams(new ViewGroup.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.MATCH_PARENT));
+        // fixed size is only used either during pinch zoom or surface is too
+        // big. Make sure it is not fixed size before setting it to the full
+        // screen content view
+        if (contentView instanceof SurfaceView) {
+            final SurfaceView sView = (SurfaceView) contentView;
+            if (sView.isFixedSize()) {
+                sView.getHolder().setSizeFromLayout();
+            }
+        }
         super.setContentView(contentView);
         mContentView = contentView;
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6db974c..87d8f70 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4939,6 +4939,11 @@
                                 WebViewCore.pauseUpdatePicture(mWebViewCore);
                                 // fall through to TOUCH_DRAG_MODE
                             } else {
+                                // WebKit may consume the touch event and modify
+                                // DOM. drawContentPicture() will be called with
+                                // animateSroll as true for better performance.
+                                // Force redraw in high-quality.
+                                invalidate();
                                 break;
                             }
                         } else {
diff --git a/services/java/com/android/server/NotificationPlayer.java b/services/java/com/android/server/NotificationPlayer.java
index 4c4da5a..acc4c85 100644
--- a/services/java/com/android/server/NotificationPlayer.java
+++ b/services/java/com/android/server/NotificationPlayer.java
@@ -95,6 +95,7 @@
                         audioManager.requestAudioFocus(null, mCmd.stream,
                                 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
                     }
+                    player.setOnCompletionListener(NotificationPlayer.this);
                     player.start();
                     if (mPlayer != null) {
                         mPlayer.release();
@@ -125,7 +126,6 @@
                 t.start();
                 t.wait();
             }
-            mPlayer.setOnCompletionListener(this);
             //-----------------------------------
 
             long delay = SystemClock.uptimeMillis() - cmd.requestTime;
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index c9dd553..b9021b0 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1730,7 +1730,7 @@
         }
 
         if (offMask != 0) {
-            //Slog.i(TAG, "Setting brightess off: " + offMask);
+            if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
             setLightBrightness(offMask, Power.BRIGHTNESS_OFF);
         }
         if (dimMask != 0) {
@@ -1739,7 +1739,7 @@
                     brightness > Power.BRIGHTNESS_LOW_BATTERY) {
                 brightness = Power.BRIGHTNESS_LOW_BATTERY;
             }
-            //Slog.i(TAG, "Setting brightess dim " + brightness + ": " + offMask);
+            if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
             setLightBrightness(dimMask, brightness);
         }
         if (onMask != 0) {
@@ -1748,7 +1748,7 @@
                     brightness > Power.BRIGHTNESS_LOW_BATTERY) {
                 brightness = Power.BRIGHTNESS_LOW_BATTERY;
             }
-            //Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
+            if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
             setLightBrightness(onMask, brightness);
         }
     }
@@ -1883,6 +1883,10 @@
 
     private int applyButtonState(int state) {
         int brightness = -1;
+        if ((state & BATTERY_LOW_BIT) != 0) {
+            // do not override brightness if the battery is low
+            return state;
+        }
         if (mButtonBrightnessOverride >= 0) {
             brightness = mButtonBrightnessOverride;
         } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
@@ -1899,6 +1903,10 @@
 
     private int applyKeyboardState(int state) {
         int brightness = -1;
+        if ((state & BATTERY_LOW_BIT) != 0) {
+            // do not override brightness if the battery is low
+            return state;
+        }
         if (!mKeyboardVisible) {
             brightness = 0;
         } else if (mButtonBrightnessOverride >= 0) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 13690bc..7e095b5 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -123,6 +123,8 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
 
 public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
     static final String TAG = "ActivityManager";
@@ -927,7 +929,9 @@
      */
     final ProcessStats mProcessStats = new ProcessStats(
             MONITOR_THREAD_CPU_USAGE);
-    long mLastCpuTime = 0;
+    final AtomicLong mLastCpuTime = new AtomicLong(0);
+    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
+
     long mLastWriteTime = 0;
 
     long mInitialStartTime = 0;
@@ -1430,7 +1434,7 @@
                         try {
                             synchronized(this) {
                                 final long now = SystemClock.uptimeMillis();
-                                long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
+                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
                                 //        + ", write delay=" + nextWriteDelay);
@@ -1438,12 +1442,12 @@
                                     nextCpuDelay = nextWriteDelay;
                                 }
                                 if (nextCpuDelay > 0) {
+                                    mProcessStatsMutexFree.set(true);
                                     this.wait(nextCpuDelay);
                                 }
                             }
                         } catch (InterruptedException e) {
                         }
-                        
                         updateCpuStatsNow();
                     } catch (Exception e) {
                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
@@ -1470,22 +1474,26 @@
     }
 
     void updateCpuStats() {
-        synchronized (mProcessStatsThread) {
-            final long now = SystemClock.uptimeMillis();
-            if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
+        final long now = SystemClock.uptimeMillis();
+        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
+            return;
+        }
+        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
+            synchronized (mProcessStatsThread) {
                 mProcessStatsThread.notify();
             }
         }
     }
-    
+
     void updateCpuStatsNow() {
         synchronized (mProcessStatsThread) {
+            mProcessStatsMutexFree.set(false);
             final long now = SystemClock.uptimeMillis();
             boolean haveNewCpuStats = false;
 
             if (MONITOR_CPU_USAGE &&
-                    mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
-                mLastCpuTime = now;
+                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
+                mLastCpuTime.set(now);
                 haveNewCpuStats = true;
                 mProcessStats.update();
                 //Slog.i(TAG, mProcessStats.printCurrentState());
@@ -6133,12 +6141,10 @@
         if (!(pendingResult instanceof PendingIntentRecord)) {
             return null;
         }
-        synchronized(this) {
-            try {
-                PendingIntentRecord res = (PendingIntentRecord)pendingResult;
-                return res.key.packageName;
-            } catch (ClassCastException e) {
-            }
+        try {
+            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
+            return res.key.packageName;
+        } catch (ClassCastException e) {
         }
         return null;
     }
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 4f84aab..978d821 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -735,6 +735,8 @@
                 mRunState = RUN_STATE_RUNNING;
                 noteRunState();
                 checkUseStaticIp();
+                /* Reset notification state on new connection */
+                resetNotificationTimer();
                 /*
                  * DHCP requests are blocking, so run them in a separate thread.
                  */