Merge "Adjust actual scale when zoom density changes."
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 43f8790..af20ddb 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3666,9 +3666,11 @@
      * @param interfaceName The name of the interface to remove.
      */
     public void removeJavascriptInterface(String interfaceName) {
-        WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
-        arg.mInterfaceName = interfaceName;
-        mWebViewCore.sendMessage(EventHub.REMOVE_JS_INTERFACE, arg);
+        if (mWebViewCore != null) {
+            WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
+            arg.mInterfaceName = interfaceName;
+            mWebViewCore.sendMessage(EventHub.REMOVE_JS_INTERFACE, arg);
+        }
     }
 
     /**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 2925632..eca39fc 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -624,6 +624,9 @@
      */
     private boolean mForceTranscriptScroll;
 
+    private int mGlowPaddingLeft;
+    private int mGlowPaddingRight;
+
     /**
      * Interface definition for a callback to be invoked when the list or grid
      * has been scrolled.
@@ -3314,9 +3317,11 @@
             final int scrollY = mScrollY;
             if (!mEdgeGlowTop.isFinished()) {
                 final int restoreCount = canvas.save();
-                final int width = getWidth() - mListPadding.left - mListPadding.right;
+                final int leftPadding = mListPadding.left + mGlowPaddingLeft;
+                final int rightPadding = mListPadding.right + mGlowPaddingRight;
+                final int width = getWidth() - leftPadding - rightPadding;
 
-                canvas.translate(mListPadding.left,
+                canvas.translate(leftPadding,
                         Math.min(0, scrollY + mFirstPositionDistanceGuess));
                 mEdgeGlowTop.setSize(width, getHeight());
                 if (mEdgeGlowTop.draw(canvas)) {
@@ -3326,10 +3331,12 @@
             }
             if (!mEdgeGlowBottom.isFinished()) {
                 final int restoreCount = canvas.save();
-                final int width = getWidth() - mListPadding.left - mListPadding.right;
+                final int leftPadding = mListPadding.left + mGlowPaddingLeft;
+                final int rightPadding = mListPadding.right + mGlowPaddingRight;
+                final int width = getWidth() - leftPadding - rightPadding;
                 final int height = getHeight();
 
-                canvas.translate(-width + mListPadding.left,
+                canvas.translate(-width + leftPadding,
                         Math.max(height, scrollY + mLastPositionDistanceGuess));
                 canvas.rotate(180, width, 0);
                 mEdgeGlowBottom.setSize(width, height);
@@ -3353,6 +3360,14 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public void setOverScrollEffectPadding(int leftPadding, int rightPadding) {
+        mGlowPaddingLeft = leftPadding;
+        mGlowPaddingRight = rightPadding;
+    }
+
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         int action = ev.getAction();
diff --git a/data/etc/android.hardware.usb.accessory.xml b/data/etc/android.hardware.usb.accessory.xml
index 29df966..80a0904 100644
--- a/data/etc/android.hardware.usb.accessory.xml
+++ b/data/etc/android.hardware.usb.accessory.xml
@@ -17,4 +17,6 @@
 <!-- This is the standard feature indicating that the device supports USB accessories. -->
 <permissions>
     <feature name="android.hardware.usb.accessory" />
+    <library name="com.android.future.usb.accessory"
+            file="/system/framework/com.android.future.usb.accessory.jar" />
 </permissions>
diff --git a/data/etc/com.google.android.usb.xml b/data/etc/com.google.android.usb.xml
deleted file mode 100644
index fae3d23..0000000
--- a/data/etc/com.google.android.usb.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<permissions>
-    <library name="com.google.android.usb"
-            file="/system/framework/com.google.android.usb.jar" />
-</permissions>
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 3f9f961..b8e9384 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -17,83 +17,93 @@
 package android.graphics;
 
 public class ImageFormat {
-	/*
-	 * these constants are chosen to be binary compatible with their previous
-	 * location in PixelFormat.java
-	 */
+    /*
+     * these constants are chosen to be binary compatible with their previous
+     * location in PixelFormat.java
+     */
 
-	public static final int UNKNOWN = 0;
+    public static final int UNKNOWN = 0;
 
-	/**
-	 * RGB format used for pictures encoded as RGB_565 see
-	 * {@link android.hardware.Camera.Parameters#setPictureFormat(int)}.
-	 */
-	public static final int RGB_565 = 4;
+    /**
+     * RGB format used for pictures encoded as RGB_565 see
+     * {@link android.hardware.Camera.Parameters#setPictureFormat(int)}.
+     */
+    public static final int RGB_565 = 4;
 
-	/**
-	 * Planar 4:2:0 YCrCb format. This format assumes an horizontal stride of 16
-	 * pixels for all planes and an implicit vertical stride of the image
-	 * height's next multiple of two.
-	 *   y_size = stride * ALIGN(height, 2)
-	 *   c_size = ALIGN(stride/2, 16) * height
-	 *   size = y_size + c_size * 2
-	 *   cr_offset = y_size
-	 *   cb_offset = y_size + c_size
-	 * 
-	 * Whether this format is supported by the camera hardware can be determined
-	 * by
-	 * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
-	 */
-	public static final int YV12 = 0x32315659;
+    /**
+     * Android YUV format:
+     *
+     * This format is exposed to software decoders and applications.
+     *
+     * YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed
+     * by (W/2) x (H/2) Cr and Cb planes.
+     *
+     * This format assumes
+     * - an even width
+     * - an even height
+     * - a horizontal stride multiple of 16 pixels
+     * - a vertical stride equal to the height
+     *
+     *   y_size = stride * height
+     *   c_size = ALIGN(stride/2, 16) * height/2
+     *   size = y_size + c_size * 2
+     *   cr_offset = y_size
+     *   cb_offset = y_size + c_size
+     *
+     * Whether this format is supported by the camera hardware can be determined
+     * by
+     * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int YV12 = 0x32315659;
 
-	/**
-	 * YCbCr format, used for video. Whether this format is supported by the
-	 * camera hardware can be determined by
-	 * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
-	 */
-	public static final int NV16 = 0x10;
+    /**
+     * YCbCr format, used for video. Whether this format is supported by the
+     * camera hardware can be determined by
+     * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int NV16 = 0x10;
 
-	/**
-	 * YCrCb format used for images, which uses the NV21 encoding format. This
-	 * is the default format for camera preview images, when not otherwise set
-	 * with {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}.
-	 */
-	public static final int NV21 = 0x11;
+    /**
+     * YCrCb format used for images, which uses the NV21 encoding format. This
+     * is the default format for camera preview images, when not otherwise set
+     * with {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}.
+     */
+    public static final int NV21 = 0x11;
 
-	/**
-	 * YCbCr format used for images, which uses YUYV (YUY2) encoding format.
-	 * This is an alternative format for camera preview images. Whether this
-	 * format is supported by the camera hardware can be determined by
-	 * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
-	 */
-	public static final int YUY2 = 0x14;
+    /**
+     * YCbCr format used for images, which uses YUYV (YUY2) encoding format.
+     * This is an alternative format for camera preview images. Whether this
+     * format is supported by the camera hardware can be determined by
+     * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int YUY2 = 0x14;
 
-	/**
-	 * Encoded formats. These are not necessarily supported by the hardware.
-	 */
-	public static final int JPEG = 0x100;
+    /**
+     * Encoded formats. These are not necessarily supported by the hardware.
+     */
+    public static final int JPEG = 0x100;
 
-	/**
-	 * Use this function to retrieve the number of bits per pixel of an
-	 * ImageFormat.
-	 * 
-	 * @param format
-	 * @return the number of bits per pixel of the given format or -1 if the
-	 *         format doesn't exist or is not supported.
-	 */
-	public static int getBitsPerPixel(int format) {
-		switch (format) {
-		case RGB_565:
-			return 16;
-		case NV16:
-			return 16;
-		case YUY2:
-			return 16;
-		case YV12:
-			return 12;
-		case NV21:
-			return 12;
-		}
-		return -1;
-	}
+    /**
+     * Use this function to retrieve the number of bits per pixel of an
+     * ImageFormat.
+     * 
+     * @param format
+     * @return the number of bits per pixel of the given format or -1 if the
+     *         format doesn't exist or is not supported.
+     */
+    public static int getBitsPerPixel(int format) {
+        switch (format) {
+            case RGB_565:
+                return 16;
+            case NV16:
+                return 16;
+            case YUY2:
+                return 16;
+            case YV12:
+                return 12;
+            case NV21:
+                return 12;
+        }
+        return -1;
+    }
 }
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index 9979e2a..b39d2e4 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -142,7 +142,8 @@
         }
 
         int count = x * y * z * faces;
-        if (hasLod && (x > 1) && (y > 1) && (z > 1)) {
+
+        while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
             if(x > 1) {
                 x >>= 1;
             }
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 8bae684..aa9b40e 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -40,9 +40,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Font::Font(FontRenderer* state, uint32_t fontId, float fontSize,
-        int flags, uint32_t italicStyle) :
+        int flags, uint32_t italicStyle, uint32_t scaleX) :
         mState(state), mFontId(fontId), mFontSize(fontSize),
-        mFlags(flags), mItalicStyle(italicStyle) {
+        mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX) {
 }
 
 
@@ -279,18 +279,19 @@
 }
 
 Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize,
-        int flags, uint32_t italicStyle) {
+        int flags, uint32_t italicStyle, uint32_t scaleX) {
     Vector<Font*> &activeFonts = state->mActiveFonts;
 
     for (uint32_t i = 0; i < activeFonts.size(); i++) {
         Font* font = activeFonts[i];
         if (font->mFontId == fontId && font->mFontSize == fontSize &&
-                font->mFlags == flags && font->mItalicStyle == italicStyle) {
+                font->mFlags == flags && font->mItalicStyle == italicStyle &&
+                font->mScaleX == scaleX) {
             return font;
         }
     }
 
-    Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle);
+    Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle, scaleX);
     activeFonts.push(newFont);
     return newFont;
 }
@@ -657,7 +658,9 @@
 
     const float skewX = paint->getTextSkewX();
     uint32_t italicStyle = *(uint32_t*) &skewX;
-    mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle);
+    const float scaleXFloat = paint->getTextScaleX();
+    uint32_t scaleX = *(uint32_t*) &scaleXFloat;
+    mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle, scaleX);
 
     const float maxPrecacheFontSize = 40.0f;
     bool isNewFont = currentNumFonts != mActiveFonts.size();
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 46f332e..3a7aa96 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -58,7 +58,7 @@
      * Creates a new font associated with the specified font state.
      */
     static Font* create(FontRenderer* state, uint32_t fontId, float fontSize,
-            int flags, uint32_t italicStyle);
+            int flags, uint32_t italicStyle, uint32_t scaleX);
 
 protected:
     friend class FontRenderer;
@@ -104,7 +104,8 @@
         SkFixed mRsbDelta;
     };
 
-    Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle);
+    Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle,
+            uint32_t scaleX);
 
     DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
 
@@ -124,6 +125,7 @@
     float mFontSize;
     int mFlags;
     uint32_t mItalicStyle;
+    uint32_t mScaleX;
 };
 
 class FontRenderer {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 24f9739..b1eb164 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -214,6 +214,11 @@
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
             layer->texture, 0);
 
+    glDisable(GL_SCISSOR_TEST);
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glEnable(GL_SCISSOR_TEST);
+
     glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
 
     return layer;
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk
index d0ef6f0..b4e1fbf 100644
--- a/libs/usb/Android.mk
+++ b/libs/usb/Android.mk
@@ -22,6 +22,6 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_MODULE:= com.google.android.usb
+LOCAL_MODULE:= com.android.future.usb.accessory
 
 include $(BUILD_JAVA_LIBRARY)
diff --git a/libs/usb/src/com/google/android/usb/UsbAccessory.java b/libs/usb/src/com/android/future/usb/UsbAccessory.java
similarity index 98%
rename from libs/usb/src/com/google/android/usb/UsbAccessory.java
rename to libs/usb/src/com/android/future/usb/UsbAccessory.java
index 931f42e..cdd2b73 100644
--- a/libs/usb/src/com/google/android/usb/UsbAccessory.java
+++ b/libs/usb/src/com/android/future/usb/UsbAccessory.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.usb;
+package com.android.future.usb;
 
 /**
  * A class representing a USB accessory.
diff --git a/libs/usb/src/com/google/android/usb/UsbManager.java b/libs/usb/src/com/android/future/usb/UsbManager.java
similarity index 98%
rename from libs/usb/src/com/google/android/usb/UsbManager.java
rename to libs/usb/src/com/android/future/usb/UsbManager.java
index d7afb95..f74b291 100644
--- a/libs/usb/src/com/google/android/usb/UsbManager.java
+++ b/libs/usb/src/com/android/future/usb/UsbManager.java
@@ -15,7 +15,7 @@
  */
 
 
-package com.google.android.usb;
+package com.android.future.usb;
 
 import android.content.Context;
 import android.content.Intent;
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index b854569..98b6090 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -7,7 +7,7 @@
 
 LOCAL_PACKAGE_NAME := AccessoryChatGB
 
-LOCAL_JAVA_LIBRARIES := com.google.android.usb
+LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory
 
 # Force an old SDK version to make sure we aren't using newer UsbManager APIs
 LOCAL_SDK_VERSION := 8
diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
index 5922421..97e2ade 100644
--- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml
+++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
@@ -1,8 +1,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.google.android.accessorychat">
+        package="com.android.accessorychat">
 
     <application>
-        <uses-library android:name="com.google.android.usb" />
+        <uses-library android:name="com.android.future.usb.accessory" />
 
         <activity android:name="AccessoryChat" android:label="Accessory Chat GB">
             <intent-filter>
@@ -19,5 +19,5 @@
                 android:resource="@xml/accessory_filter" />
         </activity>
     </application>
-    <uses-sdk android:minSdkVersion="8" />
+    <uses-sdk android:minSdkVersion="10" />
 </manifest>
diff --git a/libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
similarity index 97%
rename from libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java
rename to libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
index 0a5701c..5cf02c7 100644
--- a/libs/usb/tests/AccessoryChat/src/com/google/android/accessorychat/AccessoryChat.java
+++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.android.accessorychat;
+package com.android.accessorychat;
 
 import android.app.Activity;
 import android.content.BroadcastReceiver;
@@ -31,8 +31,8 @@
 import android.widget.EditText;
 import android.widget.TextView;
 
-import com.google.android.usb.UsbAccessory;
-import com.google.android.usb.UsbManager;
+import com.android.future.usb.UsbAccessory;
+import com.android.future.usb.UsbManager;
 
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
index 8b0250a..d443b7c 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
@@ -121,9 +121,11 @@
     uint32  temp;
 
     /*
-     *  Verify that at least the header is complete
+     * Verify that at least the header is complete
+     * Note that SYNC_WORD_LNGTH is in unit of bits, but inputBufferCurrentLength
+     * is in unit of bytes.
      */
-    if (inputStream->inputBufferCurrentLength < (SYNC_WORD_LNGTH + 21))
+    if (inputStream->inputBufferCurrentLength < ((SYNC_WORD_LNGTH + 21) >> 3))
     {
         return NO_ENOUGH_MAIN_DATA_ERROR;
     }
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 886b85f..2fda3aa 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -163,6 +163,12 @@
      */
     private Configuration mConfiguration;
 
+    private Runnable mRecreateRunnable = new Runnable() {
+        public void run() {
+            recreateScreens();
+        }
+    };
+
     /**
      * @return Whether we are stuck on the lock screen because the sim is
      *   missing.
@@ -244,7 +250,8 @@
 
             public void recreateMe(Configuration config) {
                 mConfiguration = config;
-                recreateScreens();
+                removeCallbacks(mRecreateRunnable);
+                post(mRecreateRunnable);
             }
 
             public void takeEmergencyCallAction() {
@@ -463,6 +470,12 @@
     }
 
     @Override
+    protected void onDetachedFromWindow() {
+        removeCallbacks(mRecreateRunnable);
+        super.onDetachedFromWindow();
+    }
+
+    @Override
     public void wakeWhenReadyTq(int keyCode) {
         if (DEBUG) Log.d(TAG, "onWakeKey");
         if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen)
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index bfc80db..74be4e0 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -122,12 +122,12 @@
         // request routing change if necessary
         uint32_t newDevice = getNewDevice(mHardwareOutput, false);
 #ifdef WITH_A2DP
+        checkA2dpSuspend();
         checkOutputForAllStrategies();
         // A2DP outputs must be closed after checkOutputForAllStrategies() is executed
         if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) {
             closeA2dpOutputs();
         }
-        checkA2dpSuspend();
 #endif
         updateDeviceForStrategy();
         setOutputDevice(mHardwareOutput, newDevice);
@@ -269,8 +269,8 @@
     // check for device and output changes triggered by new phone state
     newDevice = getNewDevice(mHardwareOutput, false);
 #ifdef WITH_A2DP
-    checkOutputForAllStrategies();
     checkA2dpSuspend();
+    checkOutputForAllStrategies();
 #endif
     updateDeviceForStrategy();
 
@@ -378,8 +378,8 @@
     // check for device and output changes triggered by new phone state
     uint32_t newDevice = getNewDevice(mHardwareOutput, false);
 #ifdef WITH_A2DP
-    checkOutputForAllStrategies();
     checkA2dpSuspend();
+    checkOutputForAllStrategies();
 #endif
     updateDeviceForStrategy();
     setOutputDevice(mHardwareOutput, newDevice);
@@ -1624,7 +1624,7 @@
             if (device) break;
 #ifdef WITH_A2DP
             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
-            if (!isInCall()) {
+            if (!isInCall() && !mA2dpSuspended) {
                 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
                 if (device) break;
                 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
@@ -1647,7 +1647,7 @@
 #ifdef WITH_A2DP
             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
             // A2DP speaker when forcing to speaker output
-            if (!isInCall()) {
+            if (!isInCall() && !mA2dpSuspended) {
                 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
                 if (device) break;
             }
@@ -1687,7 +1687,7 @@
             device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
         }
 #ifdef WITH_A2DP
-        if ((mA2dpOutput != 0) &&
+        if ((mA2dpOutput != 0) && !mA2dpSuspended &&
                 (strategy != STRATEGY_SONIFICATION || a2dpUsedForSonification())) {
             if (device2 == 0) {
                 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java
index 52f84eb..15f22c0 100644
--- a/services/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/java/com/android/server/NetworkTimeUpdateService.java
@@ -26,6 +26,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
 import android.net.SntpClient;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -58,6 +60,7 @@
 
     private static final int EVENT_AUTO_TIME_CHANGED = 1;
     private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_WIFI_CONNECTED = 3;
 
     /** Normal polling frequency */
     private static final long POLLING_INTERVAL_MS = 24L * 60 * 60 * 1000; // 24 hrs
@@ -113,6 +116,7 @@
 
         registerForTelephonyIntents();
         registerForAlarms();
+        registerForConnectivityIntents();
 
         mThread = new HandlerThread(TAG);
         mThread.start();
@@ -162,6 +166,12 @@
             }, new IntentFilter(ACTION_POLL));
     }
 
+    private void registerForConnectivityIntents() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        mContext.registerReceiver(mConnectivityReceiver, intentFilter);
+    }
+
     private void onPollNetworkTime(int event) {
         // If Automatic time is not set, don't bother.
         if (!isAutomaticTimeRequested()) return;
@@ -253,6 +263,27 @@
         }
     };
 
+    /** Receiver for ConnectivityManager events */
+    private BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
+                // There is connectivity
+                NetworkInfo netInfo = (NetworkInfo)intent.getParcelableExtra(
+                        ConnectivityManager.EXTRA_NETWORK_INFO);
+                if (netInfo != null) {
+                    // Verify that it's a WIFI connection
+                    if (netInfo.getState() == NetworkInfo.State.CONNECTED &&
+                            netInfo.getType() == ConnectivityManager.TYPE_WIFI ) {
+                        mHandler.obtainMessage(EVENT_WIFI_CONNECTED).sendToTarget();
+                    }
+                }
+            }
+        }
+    };
+
     /** Handler to do the network accesses on */
     private class MyHandler extends Handler {
 
@@ -265,6 +296,7 @@
             switch (msg.what) {
                 case EVENT_AUTO_TIME_CHANGED:
                 case EVENT_POLL_NETWORK_TIME:
+                case EVENT_WIFI_CONNECTED:
                     onPollNetworkTime(msg.what);
                     break;
             }
diff --git a/wifi/java/android/net/wifi/SupplicantState.java b/wifi/java/android/net/wifi/SupplicantState.java
index 169b2d6..6b79210 100644
--- a/wifi/java/android/net/wifi/SupplicantState.java
+++ b/wifi/java/android/net/wifi/SupplicantState.java
@@ -152,6 +152,26 @@
         return state != UNINITIALIZED && state != INVALID;
     }
 
+    static boolean isConnecting(SupplicantState state) {
+        switch(state) {
+            case ASSOCIATING:
+            case ASSOCIATED:
+            case FOUR_WAY_HANDSHAKE:
+            case GROUP_HANDSHAKE:
+            case COMPLETED:
+                return true;
+            case DISCONNECTED:
+            case INACTIVE:
+            case SCANNING:
+            case DORMANT:
+            case UNINITIALIZED:
+            case INVALID:
+                return false;
+            default:
+                throw new IllegalArgumentException("Unknown supplicant state");
+        }
+    }
+
     /** Implement the Parcelable interface {@hide} */
     public int describeContents() {
         return 0;
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index e89858c9..589d88c 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -344,6 +344,9 @@
      */
     private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */
 
+    private static final int MIN_RSSI = -200;
+    private static final int MAX_RSSI = 256;
+
     /* Default parent state */
     private HierarchicalState mDefaultState = new DefaultState();
     /* Temporary initial state */
@@ -1239,7 +1242,7 @@
      */
     private void fetchRssiAndLinkSpeedNative() {
         int newRssi = WifiNative.getRssiCommand();
-        if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
+        if (newRssi != -1 && MIN_RSSI < newRssi && newRssi < MAX_RSSI) { // screen out invalid values
             /* some implementations avoid negative values by adding 256
              * so we need to adjust for that here.
              */
@@ -1264,7 +1267,7 @@
             }
             mLastSignalLevel = newSignalLevel;
         } else {
-            mWifiInfo.setRssi(-200);
+            mWifiInfo.setRssi(MIN_RSSI);
         }
         int newLinkSpeed = WifiNative.getLinkSpeedCommand();
         if (newLinkSpeed != -1) {
@@ -1386,15 +1389,17 @@
         /* Disable interface */
         NetworkUtils.disableInterface(mInterfaceName);
 
-        /* send event to CM & network change broadcast */
-        setNetworkDetailedState(DetailedState.DISCONNECTED);
-        sendNetworkStateChangeBroadcast(mLastBssid);
-
         /* Reset data structures */
         mWifiInfo.setInetAddress(null);
         mWifiInfo.setBSSID(null);
         mWifiInfo.setSSID(null);
         mWifiInfo.setNetworkId(-1);
+        mWifiInfo.setRssi(MIN_RSSI);
+        mWifiInfo.setLinkSpeed(-1);
+
+        /* send event to CM & network change broadcast */
+        setNetworkDetailedState(DetailedState.DISCONNECTED);
+        sendNetworkStateChangeBroadcast(mLastBssid);
 
         /* Clear network properties */
         mLinkProperties.clear();
@@ -2363,7 +2368,10 @@
                     // 50023 supplicant_state_changed (custom|1|5)
                     EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
                     mWifiInfo.setSupplicantState(state);
-                    mWifiInfo.setNetworkId(stateChangeResult.networkId);
+                    // Network id is only valid when we start connecting
+                    if (SupplicantState.isConnecting(state)) {
+                        mWifiInfo.setNetworkId(stateChangeResult.networkId);
+                    }
                     if (state == SupplicantState.ASSOCIATING) {
                         /* BSSID is valid only in ASSOCIATING state */
                         mWifiInfo.setBSSID(stateChangeResult.BSSID);
@@ -2741,6 +2749,15 @@
             }
             return HANDLED;
         }
+        @Override
+        public void exit() {
+            /* If a scan result is pending in connected state, the supplicant
+             * is in SCAN_ONLY_MODE. Restore CONNECT_MODE on exit
+             */
+            if (mScanResultIsPending) {
+                WifiNative.setScanResultHandlingCommand(CONNECT_MODE);
+            }
+        }
     }
 
     class DisconnectingState extends HierarchicalState {