Merge "IOOB is Suggestions" into ics-mr1
diff --git a/core/java/android/content/ContentUris.java b/core/java/android/content/ContentUris.java
index aa7603470b..dbe8a7c 100644
--- a/core/java/android/content/ContentUris.java
+++ b/core/java/android/content/ContentUris.java
@@ -19,9 +19,54 @@
 import android.net.Uri;
 
 /**
- * Utility methods useful for working with content {@link android.net.Uri}s,
- * those with a "content" scheme.
- */
+* Utility methods useful for working with {@link android.net.Uri} objects
+* that use the "content" (content://) scheme.
+*
+*<p>
+*   Content URIs have the syntax
+*</p>
+*<p>
+*   <code>content://<em>authority</em>/<em>path</em>/<em>id</em></code>
+*</p>
+*<dl>
+*   <dt>
+*       <code>content:</code>
+*   </dt>
+*   <dd>
+*       The scheme portion of the URI. This is always set to {@link
+*       android.content.ContentResolver#SCHEME_CONTENT ContentResolver.SCHEME_CONTENT} (value
+*       <code>content://</code>).
+*   </dd>
+*   <dt>
+*       <em>authority</em>
+*   </dt>
+*   <dd>
+*       A string that identifies the entire content provider. All the content URIs for the provider
+*       start with this string. To guarantee a unique authority, providers should consider
+*       using an authority that is the same as the provider class' package identifier.
+*   </dd>
+*   <dt>
+*       <em>path</em>
+*   </dt>
+*   <dd>
+*       Zero or more segments, separated by a forward slash (<code>/</code>), that identify
+*       some subset of the provider's data. Most providers use the path part to identify
+*       individual tables. Individual segments in the path are often called
+*       &quot;directories&quot; although they do not refer to file directories. The right-most
+*       segment in a path is often called a &quot;twig&quot;
+*   </dd>
+*   <dt>
+*       <em>id</em>
+*   </dt>
+*   <dd>
+*       A unique numeric identifier for a single row in the subset of data identified by the
+*       preceding path part. Most providers recognize content URIs that contain an id part
+*       and give them special handling. A table that contains a column named <code>_ID</code>
+*       often expects the id part to be a particular value for that column.
+*   </dd>
+*</dl>
+*
+*/
 public class ContentUris {
 
     /**
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index e289fc1..d39e741e 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -250,4 +250,32 @@
         }
         return result;
     }
+
+    /**
+     * Trim leading zeros from IPv4 address strings
+     * Our base libraries will interpret that as octel..
+     * Must leave non v4 addresses and host names alone.
+     * For example, 192.168.000.010 -> 192.168.0.10
+     * TODO - fix base libraries and remove this function
+     * @param addr a string representing an ip addr
+     * @return a string propertly trimmed
+     */
+    public static String trimV4AddrZeros(String addr) {
+        if (addr == null) return null;
+        String[] octets = addr.split("\\.");
+        if (octets.length != 4) return addr;
+        StringBuilder builder = new StringBuilder(16);
+        String result = null;
+        for (int i = 0; i < 4; i++) {
+            try {
+                if (octets[i].length() > 3) return addr;
+                builder.append(Integer.parseInt(octets[i]));
+            } catch (NumberFormatException e) {
+                return addr;
+            }
+            if (i < 3) builder.append('.');
+        }
+        result = builder.toString();
+        return result;
+    }
 }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 7d034940..88fea91 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -311,7 +311,7 @@
         public static final int ICE_CREAM_SANDWICH = 14;
 
         /**
-         * Android 4.1.
+         * Android 4.0.3.
          */
         public static final int ICE_CREAM_SANDWICH_MR1 = 15;
     }
diff --git a/core/java/android/os/storage/package.html b/core/java/android/os/storage/package.html
new file mode 100644
index 0000000..a5f1e1c
--- /dev/null
+++ b/core/java/android/os/storage/package.html
@@ -0,0 +1,8 @@
+<HTML>
+<BODY>
+<p>
+Contains classes for the system storage service, which manages binary asset filesystems
+known as Opaque Binary Blobs (OBBs).
+</p>
+</BODY>
+</HTML>
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 74bcc9b..65b4e7e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3112,6 +3112,14 @@
                 "wifi_watchdog_blacklist_followup_interval_ms";
 
         /**
+         * Setting to turn off poor network avoidance on Wi-Fi. Feature is disabled by default and
+         * the setting needs to be set to 1 to enable it.
+         * @hide
+         */
+        public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
+                "wifi_watchdog_poor_network_test_enabled";
+
+        /**
          * Setting to turn off walled garden test on Wi-Fi. Feature is enabled by default and
          * the setting needs to be set to 0 to disable it.
          * @hide
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index ed2af10..0f26a34 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -92,11 +92,6 @@
     private float mAutoCorrectionUnderlineThickness;
     private int mAutoCorrectionUnderlineColor;
 
-    /*
-     * TODO: If switching IME is required, needs to add parameters for ids of InputMethodInfo
-     * and InputMethodSubtype.
-     */
-
     /**
      * @param context Context for the application
      * @param suggestions Suggestions for the string under the span
@@ -146,6 +141,16 @@
     }
 
     private void initStyle(Context context) {
+        if (context == null) {
+            mMisspelledUnderlineThickness = 0;
+            mEasyCorrectUnderlineThickness = 0;
+            mAutoCorrectionUnderlineThickness = 0;
+            mMisspelledUnderlineColor = Color.BLACK;
+            mEasyCorrectUnderlineColor = Color.BLACK;
+            mAutoCorrectionUnderlineColor = Color.BLACK;
+            return;
+        }
+
         int defStyle = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
         TypedArray typedArray = context.obtainStyledAttributes(
                 null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
@@ -169,7 +174,6 @@
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
         mAutoCorrectionUnderlineColor = typedArray.getColor(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
-
     }
 
     public SuggestionSpan(Parcel src) {
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index ce8aecc..9bd42ef 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -149,7 +149,7 @@
      * It may be appropriate to tweak this on a device-specific basis in an overlay based on
      * the characteristics of the touch panel and firmware.
      */
-    private static final int TOUCH_SLOP = 4;
+    private static final int TOUCH_SLOP = 8;
     
     /**
      * Distance a touch can wander before we think the user is attempting a paged scroll
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 63d7e29a..600bfe6 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2719,13 +2719,6 @@
             return more;
         }
 
-        float alpha = child.getAlpha();
-        // Bail out early if the view does not need to be drawn
-        if (alpha <= ViewConfiguration.ALPHA_THRESHOLD && (child.mPrivateFlags & ALPHA_SET) == 0 &&
-                !(child instanceof SurfaceView)) {
-            return more;
-        }
-
         if (hardwareAccelerated) {
             // Clear INVALIDATED flag to allow invalidation to occur during rendering, but
             // retain the flag's value temporarily in the mRecreateDisplayList flag
@@ -2779,6 +2772,7 @@
             }
         }
 
+        float alpha = child.getAlpha();
         if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) {
             if (transformToApply != null || !childHasIdentityMatrix) {
                 int transX = 0;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7f5b5be..6c982eb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3330,8 +3330,9 @@
         }
 
         // If the Control modifier is held, try to interpret the key as a shortcut.
-        if (event.getAction() == KeyEvent.ACTION_UP
+        if (event.getAction() == KeyEvent.ACTION_DOWN
                 && event.isCtrlPressed()
+                && event.getRepeatCount() == 0
                 && !KeyEvent.isModifierKey(event.getKeyCode())) {
             if (mView.dispatchKeyShortcutEvent(event)) {
                 finishKeyEvent(event, sendDone, true);
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 3574a0d..2b59b80 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -19,10 +19,13 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -51,7 +54,6 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
-import android.widget.AbsoluteLayout;
 import android.widget.AbsoluteLayout.LayoutParams;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
@@ -74,7 +76,6 @@
 
     static final String LOGTAG = "webtextview";
 
-    private Paint mRingPaint;
     private int mRingInset;
 
     private WebView         mWebView;
@@ -207,13 +208,51 @@
                 }
             }
         };
-        float ringWidth = 4f * context.getResources().getDisplayMetrics().density;
         mReceiver = new MyResultReceiver(mHandler);
-        mRingPaint = new Paint();
-        mRingPaint.setColor(0x6633b5e5);
-        mRingPaint.setStrokeWidth(ringWidth);
-        mRingPaint.setStyle(Style.FILL);
+        float ringWidth = 2f * context.getResources().getDisplayMetrics().density;
         mRingInset = (int) ringWidth;
+        setBackgroundDrawable(new BackgroundDrawable(mRingInset));
+        setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
+                getPaddingBottom());
+    }
+
+    private static class BackgroundDrawable extends Drawable {
+
+        private Paint mPaint = new Paint();
+        private int mBorderWidth;
+        private Rect mInsetRect = new Rect();
+
+        public BackgroundDrawable(int width) {
+            mPaint = new Paint();
+            mPaint.setStrokeWidth(width);
+            mBorderWidth = width;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            mPaint.setColor(0x6633b5e5);
+            canvas.drawRect(getBounds(), mPaint);
+            mInsetRect.left = getBounds().left + mBorderWidth;
+            mInsetRect.top = getBounds().top + mBorderWidth;
+            mInsetRect.right = getBounds().right - mBorderWidth;
+            mInsetRect.bottom = getBounds().bottom - mBorderWidth;
+            mPaint.setColor(Color.WHITE);
+            canvas.drawRect(mInsetRect, mPaint);
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+
     }
 
     public void setAutoFillable(int queryId) {
@@ -223,35 +262,9 @@
     }
 
     @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        if (isFocused()) {
-            final int ib = getHeight() - mRingInset;
-            canvas.drawRect(0, 0, getWidth(), mRingInset, mRingPaint);
-            canvas.drawRect(0, ib, getWidth(), getHeight(), mRingPaint);
-            canvas.drawRect(0, mRingInset, mRingInset, ib, mRingPaint);
-            canvas.drawRect(getWidth() - mRingInset, mRingInset, getWidth(), ib, mRingPaint);
-        }
-    }
-
-    private void growOrShrink(boolean grow) {
-        AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) getLayoutParams();
-        if (grow) {
-            lp.x -= mRingInset;
-            lp.y -= mRingInset;
-            lp.width += 2 * mRingInset;
-            lp.height += 2 * mRingInset;
-            setPadding(getPaddingLeft() + mRingInset, getPaddingTop() + mRingInset,
-                    getPaddingRight() + mRingInset, getPaddingBottom() + mRingInset);
-        } else {
-            lp.x += mRingInset;
-            lp.y += mRingInset;
-            lp.width -= 2 * mRingInset;
-            lp.height -= 2 * mRingInset;
-            setPadding(getPaddingLeft() - mRingInset, getPaddingTop() - mRingInset,
-                    getPaddingRight() - mRingInset, getPaddingBottom() - mRingInset);
-        }
-        setLayoutParams(lp);
+    public void setPadding(int left, int top, int right, int bottom) {
+        super.setPadding(left + mRingInset, top + mRingInset,
+                right + mRingInset, bottom + mRingInset);
     }
 
     @Override
@@ -555,7 +568,6 @@
         } else if (!mInsideRemove) {
             mWebView.setActive(false);
         }
-        growOrShrink(focused);
         mFromFocusChange = false;
     }
 
@@ -966,6 +978,10 @@
      */
     /* package */ void setRect(int x, int y, int width, int height) {
         LayoutParams lp = (LayoutParams) getLayoutParams();
+        x -= mRingInset;
+        y -= mRingInset;
+        width += 2 * mRingInset;
+        height += 2 * mRingInset;
         boolean needsUpdate = false;
         if (null == lp) {
             lp = new LayoutParams(width, height, x, y);
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index 7ba4777..07bd918 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -145,6 +145,9 @@
                 Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
             }
         }
+        public synchronized void onDataSetChangedAsync() {
+            onDataSetChanged();
+        }
         public synchronized int getCount() {
             int count = 0;
             try {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 08ad5e1..4a3a748 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9925,6 +9925,7 @@
             if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
                 Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
                 intent.putExtra("word", originalText);
+                intent.putExtra("locale", getTextServicesLocale().toString());
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 getContext().startActivity(intent);
                 // There is no way to know if the word was indeed added. Re-check.
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 72489a2..61c0c8e 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1367,10 +1367,12 @@
     /**
      * Get a message and set Message.target = this.
      *
-     * @return message
+     * @return message or null if SM has quit
      */
     public final Message obtainMessage()
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler);
     }
 
@@ -1378,9 +1380,11 @@
      * Get a message and set Message.target = this and what
      *
      * @param what is the assigned to Message.what.
-     * @return message
+     * @return message or null if SM has quit
      */
     public final Message obtainMessage(int what) {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what);
     }
 
@@ -1390,10 +1394,12 @@
      *
      * @param what is the assigned to Message.what.
      * @param obj is assigned to Message.obj.
-     * @return message
+     * @return message or null if SM has quit
      */
     public final Message obtainMessage(int what, Object obj)
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what, obj);
     }
 
@@ -1404,10 +1410,13 @@
      * @param what  is assigned to Message.what
      * @param arg1  is assigned to Message.arg1
      * @param arg2  is assigned to Message.arg2
-     * @return  A Message object from the global pool.
+     * @return  A Message object from the global pool or null if
+     *          SM has quit
      */
     public final Message obtainMessage(int what, int arg1, int arg2)
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what, arg1, arg2);
     }
 
@@ -1419,10 +1428,13 @@
      * @param arg1  is assigned to Message.arg1
      * @param arg2  is assigned to Message.arg2
      * @param obj is assigned to Message.obj
-     * @return  A Message object from the global pool.
+     * @return  A Message object from the global pool or null if
+     *          SM has quit
      */
     public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what, arg1, arg2, obj);
     }
 
@@ -1430,6 +1442,9 @@
      * Enqueue a message to this state machine.
      */
     public final void sendMessage(int what) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessage(obtainMessage(what));
     }
 
@@ -1437,6 +1452,9 @@
      * Enqueue a message to this state machine.
      */
     public final void sendMessage(int what, Object obj) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessage(obtainMessage(what,obj));
     }
 
@@ -1444,6 +1462,9 @@
      * Enqueue a message to this state machine.
      */
     public final void sendMessage(Message msg) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessage(msg);
     }
 
@@ -1451,6 +1472,9 @@
      * Enqueue a message to this state machine after a delay.
      */
     public final void sendMessageDelayed(int what, long delayMillis) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessageDelayed(obtainMessage(what), delayMillis);
     }
 
@@ -1458,6 +1482,9 @@
      * Enqueue a message to this state machine after a delay.
      */
     public final void sendMessageDelayed(int what, Object obj, long delayMillis) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessageDelayed(obtainMessage(what, obj), delayMillis);
     }
 
@@ -1465,6 +1492,9 @@
      * Enqueue a message to this state machine after a delay.
      */
     public final void sendMessageDelayed(Message msg, long delayMillis) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessageDelayed(msg, delayMillis);
     }
 
@@ -1509,6 +1539,9 @@
      * will be processed.
      */
     public final void quit() {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.quit();
     }
 
@@ -1523,6 +1556,9 @@
      * @return if debugging is enabled
      */
     public boolean isDbg() {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return false;
+
         return mSmHandler.isDbg();
     }
 
@@ -1532,6 +1568,9 @@
      * @param dbg is true to enable debugging.
      */
     public void setDbg(boolean dbg) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.setDbg(dbg);
     }
 
@@ -1539,6 +1578,9 @@
      * Start the state machine.
      */
     public void start() {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         /** Send the complete construction message */
         mSmHandler.completeConstruction();
     }
diff --git a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
index 18076c4..7317ecf 100644
--- a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
+++ b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
@@ -22,6 +22,7 @@
 /** {@hide} */
 interface IRemoteViewsFactory {
     void onDataSetChanged();
+    oneway void onDataSetChangedAsync();
     oneway void onDestroy(in Intent intent);
     int getCount();
     RemoteViews getViewAt(int position);
diff --git a/core/jni/android/graphics/HarfbuzzSkia.cpp b/core/jni/android/graphics/HarfbuzzSkia.cpp
index 92c743f..f6f7b45 100644
--- a/core/jni/android/graphics/HarfbuzzSkia.cpp
+++ b/core/jni/android/graphics/HarfbuzzSkia.cpp
@@ -211,22 +211,7 @@
 
 HB_Error harfbuzzSkiaGetTable(void* voidface, const HB_Tag tag, HB_Byte* buffer, HB_UInt* len)
 {
-    FontData* data = reinterpret_cast<FontData*>(voidface);
-    SkTypeface* typeface = data->typeFace;
-
-    const size_t tableSize = SkFontHost::GetTableSize(typeface->uniqueID(), tag);
-    if (!tableSize)
-        return HB_Err_Invalid_Argument;
-    // If Harfbuzz specified a NULL buffer then it's asking for the size of the table.
-    if (!buffer) {
-        *len = tableSize;
-        return HB_Err_Ok;
-    }
-
-    if (*len < tableSize)
-        return HB_Err_Invalid_Argument;
-    SkFontHost::GetTableData(typeface->uniqueID(), tag, 0, tableSize, buffer);
-    return HB_Err_Ok;
+    return HB_Err_Invalid_Argument;
 }
 
 }  // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 510e541..662d918 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -346,9 +346,6 @@
     font->x_scale = 1;
     font->y_scale = 1;
 
-    shaperItem.font = font;
-    shaperItem.face = HB_NewFace(shaperItem.font, harfbuzzSkiaGetTable);
-
     // Reset kerning
     shaperItem.kerning_applied = false;
 
@@ -360,8 +357,11 @@
     fontData->flags = paint->getFlags();
     fontData->hinting = paint->getHinting();
 
+    shaperItem.font = font;
     shaperItem.font->userData = fontData;
 
+    shaperItem.face = HB_NewFace(NULL, harfbuzzSkiaGetTable);
+
     // We cannot know, ahead of time, how many glyphs a given script run
     // will produce. We take a guess that script runs will not produce more
     // than twice as many glyphs as there are code points plus a bit of
diff --git a/core/res/res/layout/global_actions_silent_mode.xml b/core/res/res/layout/global_actions_silent_mode.xml
index 09b4341..18b4715 100644
--- a/core/res/res/layout/global_actions_silent_mode.xml
+++ b/core/res/res/layout/global_actions_silent_mode.xml
@@ -26,6 +26,8 @@
         android:layout_width="64dp"
         android:layout_height="match_parent"
         android:background="?android:attr/actionBarItemBackground"
+        android:contentDescription="@string/silent_mode_silent"
+        android:focusable="true"
         >
         <ImageView
             android:layout_width="48dp"
@@ -52,6 +54,8 @@
         android:layout_width="64dp"
         android:layout_height="match_parent"
         android:background="?android:attr/actionBarItemBackground"
+        android:contentDescription="@string/silent_mode_vibrate"
+        android:focusable="true"
         >
         <ImageView
             android:layout_width="48dp"
@@ -79,6 +83,8 @@
         android:layout_width="64dp"
         android:layout_height="match_parent"
         android:background="?android:attr/actionBarItemBackground"
+        android:contentDescription="@string/silent_mode_ring"
+        android:focusable="true"
         >
         <ImageView
             android:layout_width="48dp"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1853444..30002c5 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -744,5 +744,5 @@
 
     <!-- Base "touch slop" value used by ViewConfiguration as a
          movement threshold where scrolling should begin. -->
-    <dimen name="config_viewConfigurationTouchSlop">4dp</dimen>
+    <dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 50ea365..7b785ec 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 /* //device/apps/common/assets/res/any/strings.xml
 **
@@ -286,6 +286,12 @@
     <string name="screen_lock">Screen lock</string>
     <!-- Button to turn off the phone, within the Phone Options dialog -->
     <string name="power_off">Power off</string>
+    <!-- Spoken description for ringer silent option. [CHAR LIMIT=NONE] -->
+    <string name="silent_mode_silent">Ringer off</string>
+    <!-- Spoken description for ringer vibrate option. [CHAR LIMIT=NONE] -->
+    <string name="silent_mode_vibrate">Ringer vibrate</string>
+    <!-- Spoken description for ringer normal option. [CHAR LIMIT=NONE] -->
+    <string name="silent_mode_ring">Ringer on</string>
 
     <!-- Shutdown Progress Dialog. This is shown if the user chooses to power off the phone. -->
     <string name="shutdown_progress">Shutting down\u2026</string>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b18d88f..fe5388b 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -810,7 +810,7 @@
     
     <!-- Special theme for the recent apps dialog, to allow customization
          with overlays. -->
-    <style name="Theme.Dialog.RecentApplications">
+    <style name="Theme.Dialog.RecentApplications" parent="Theme.DeviceDefault.Dialog">
         <item name="windowFrame">@null</item>
         <item name="windowBackground">@android:color/transparent</item>
         <item name="android:windowAnimationStyle">@android:style/Animation.RecentApplications</item>
diff --git a/data/fonts/DroidSansArmenian.ttf b/data/fonts/DroidSansArmenian.ttf
index 62f67e0..6fafa54 100644
--- a/data/fonts/DroidSansArmenian.ttf
+++ b/data/fonts/DroidSansArmenian.ttf
Binary files differ
diff --git a/data/fonts/DroidSansGeorgian.ttf b/data/fonts/DroidSansGeorgian.ttf
index 743ae66..3a2e9fb 100644
--- a/data/fonts/DroidSansGeorgian.ttf
+++ b/data/fonts/DroidSansGeorgian.ttf
Binary files differ
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 5abffb3..5cf1a59 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -130,9 +130,8 @@
 <p class="note"><strong>Note: </strong> In order to request an invalidate from a thread other than your main
 Activity's thread, you must call <code>{@link android.view.View#postInvalidate()}</code>.</p>
 
-<p>Also read <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>
-for a guide to extending a View class, and <a href="2d-graphics.html">2D Graphics: Drawables</a> for
-information on using Drawable objects like images from your resources and other primitive shapes.</p>
+<p>For information about extending the {@link android.view.View} class, read
+<a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>.</p>
 
 <p>For a sample application, see the Snake game, in the SDK samples folder:
 <code>&lt;your-sdk-directory>/samples/Snake/</code>.</p>
@@ -188,7 +187,7 @@
 
 <p>This document discusses the basics of using Drawable objects to draw graphics and how to use a
 couple subclasses of the Drawable class. For information on using Drawables to do frame-by-frame
-animation, see <a href="{@docRoot}guide/topics/animation/drawable-animation.html">Drawable
+animation, see <a href="{@docRoot}guide/topics/graphics/drawable-animation.html">Drawable
 Animation</a>.</p>
 
 <p>A {@link android.graphics.drawable.Drawable} is a general abstraction for "something that can be
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 18dd8ef..ba9c4c4 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2021,9 +2021,9 @@
 
                 mLock.unlock();
 
-                // Initially make sure we have at least 128 bytes for the sniff
+                // Initially make sure we have at least 192 KB for the sniff
                 // to complete without blocking.
-                static const size_t kMinBytesForSniffing = 128;
+                static const size_t kMinBytesForSniffing = 192 * 1024;
 
                 off64_t metaDataSize = -1ll;
                 for (;;) {
@@ -2091,7 +2091,7 @@
         String8 mimeType;
         float confidence;
         sp<AMessage> dummy;
-        bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy);
+        bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
 
         if (!success
                 || strcasecmp(
@@ -2099,6 +2099,8 @@
             return ERROR_UNSUPPORTED;
         }
 
+        dataSource->DrmInitialization();
+
         mWVMExtractor = new WVMExtractor(dataSource);
         mWVMExtractor->setAdaptiveStreamingMode(true);
         extractor = mWVMExtractor;
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index 1f3d581..afc4a80 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -282,13 +282,13 @@
     if (decryptHandle != NULL) {
         if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) {
             *mimeType = String8("drm+container_based+") + decryptHandle->mimeType;
+            *confidence = 10.0f;
         } else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) {
             *mimeType = String8("drm+es_based+") + decryptHandle->mimeType;
-        } else if (decryptHandle->decryptApiType == DecryptApiType::WV_BASED) {
-            *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM;
-            LOGW("SniffWVM: found match\n");
+            *confidence = 10.0f;
+        } else {
+            return false;
         }
-        *confidence = 10.0f;
 
         return true;
     }
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 43539bb..6134344 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -26,6 +26,7 @@
 #include "include/DRMExtractor.h"
 #include "include/FLACExtractor.h"
 #include "include/AACExtractor.h"
+#include "include/WVMExtractor.h"
 
 #include "matroska/MatroskaExtractor.h"
 
@@ -113,6 +114,7 @@
     RegisterSniffer(SniffMP3);
     RegisterSniffer(SniffAAC);
     RegisterSniffer(SniffMPEG2PS);
+    RegisterSniffer(SniffWVM);
 
     char value[PROPERTY_VALUE_MAX];
     if (property_get("drm.service.enabled", value, NULL)
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index 26eda0c..79dedca 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -45,17 +45,12 @@
 static Mutex gWVMutex;
 
 WVMExtractor::WVMExtractor(const sp<DataSource> &source)
-    : mDataSource(source) {
-    {
-        Mutex::Autolock autoLock(gWVMutex);
-        if (gVendorLibHandle == NULL) {
-            gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
-        }
+    : mDataSource(source)
+{
+    Mutex::Autolock autoLock(gWVMutex);
 
-        if (gVendorLibHandle == NULL) {
-            LOGE("Failed to open libwvm.so");
-            return;
-        }
+    if (!getVendorLibHandle()) {
+        return;
     }
 
     typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>);
@@ -71,6 +66,19 @@
     }
 }
 
+bool WVMExtractor::getVendorLibHandle()
+{
+    if (gVendorLibHandle == NULL) {
+        gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
+    }
+
+    if (gVendorLibHandle == NULL) {
+        LOGE("Failed to open libwvm.so");
+    }
+
+    return gVendorLibHandle != NULL;
+}
+
 WVMExtractor::~WVMExtractor() {
 }
 
@@ -113,5 +121,33 @@
     }
 }
 
+bool SniffWVM(
+    const sp<DataSource> &source, String8 *mimeType, float *confidence,
+        sp<AMessage> *) {
+
+    Mutex::Autolock autoLock(gWVMutex);
+
+    if (!WVMExtractor::getVendorLibHandle()) {
+        return false;
+    }
+
+    typedef WVMLoadableExtractor *(*SnifferFunc)(sp<DataSource>);
+    SnifferFunc snifferFunc =
+        (SnifferFunc) dlsym(gVendorLibHandle,
+                            "_ZN7android15IsWidevineMediaENS_2spINS_10DataSourceEEE");
+
+    if (snifferFunc) {
+        if ((*snifferFunc)(source)) {
+            *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM;
+            *confidence = 10.0f;
+            return true;
+        }
+    } else {
+        LOGE("IsWidevineMedia not found in libwvm.so");
+    }
+
+    return false;
+}
+
 } //namespace android
 
diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h
index deecd25..9f763f9 100644
--- a/media/libstagefright/include/WVMExtractor.h
+++ b/media/libstagefright/include/WVMExtractor.h
@@ -23,6 +23,8 @@
 
 namespace android {
 
+struct AMessage;
+class String8;
 class DataSource;
 
 class WVMLoadableExtractor : public MediaExtractor {
@@ -58,6 +60,8 @@
     // is used.
     void setAdaptiveStreamingMode(bool adaptive);
 
+    static bool getVendorLibHandle();
+
 protected:
     virtual ~WVMExtractor();
 
@@ -69,6 +73,10 @@
     WVMExtractor &operator=(const WVMExtractor &);
 };
 
+bool SniffWVM(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence,
+        sp<AMessage> *);
+
 }  // namespace android
 
 #endif  // DRM_EXTRACTOR_H_
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
index 6cd8899..d51f9c8 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
@@ -15,20 +15,29 @@
  * limitations under the License.
 -->
 
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:gravity="bottom"
     >
 
+    <View
+        android:layout_height="@*android:dimen/status_bar_height"
+        android:layout_width="match_parent"
+        android:background="@drawable/status_bar_ticker_background"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:clickable="false"
+        />
+
     <ImageView
         android:id="@+id/large_icon"
         android:layout_width="@android:dimen/notification_large_icon_height"
         android:layout_height="@android:dimen/notification_large_icon_width"
         android:scaleType="center"
         android:visibility="gone"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
         />
 
     <FrameLayout
@@ -36,6 +45,8 @@
         android:layout_weight="1"
         android:layout_height="@*android:dimen/status_bar_height"
         android:layout_width="match_parent"
-        android:background="@drawable/status_bar_ticker_background"
+        android:layout_toRightOf="@id/large_icon"
+        android:layout_alignParentBottom="true"
+        android:layout_alignWithParentIfMissing="true"
         />
-</LinearLayout>
+</RelativeLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index b919aec..05ad793 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -514,6 +514,16 @@
         // don't wait for these transitions; we just want icons to fade in/out, not move around
         lt.setDuration(LayoutTransition.CHANGE_APPEARING, 0);
         lt.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 0);
+        lt.addTransitionListener(new LayoutTransition.TransitionListener() {
+            public void endTransition(LayoutTransition transition, ViewGroup container,
+                    View view, int transitionType) {
+                // ensure the menu button doesn't stick around on the status bar after it's been
+                // removed
+                mBarContents.invalidate();
+            }
+            public void startTransition(LayoutTransition transition, ViewGroup container,
+                    View view, int transitionType) {}
+        });
         mNavigationArea.setLayoutTransition(lt);
         // no multi-touch on the nav buttons
         mNavigationArea.setMotionEventSplittingEnabled(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 6045e31..e93a32b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -73,6 +73,8 @@
     private StatusBarNotification[] mQueue = new StatusBarNotification[QUEUE_LENGTH];
     private int mQueuePos;
 
+    private final int mLargeIconHeight;
+
     private TabletStatusBar mBar;
 
     private LayoutTransition mLayoutTransition;
@@ -81,6 +83,9 @@
     public TabletTicker(TabletStatusBar bar) {
         mBar = bar;
         mContext = bar.getContext();
+        final Resources res = mContext.getResources();
+        mLargeIconHeight = res.getDimensionPixelSize(
+                android.R.dimen.notification_large_icon_height);
     }
 
     public void add(IBinder key, StatusBarNotification notification) {
@@ -209,8 +214,6 @@
         final Resources res = mContext.getResources();
         final FrameLayout view = new FrameLayout(mContext);
         final int width = res.getDimensionPixelSize(R.dimen.notification_ticker_width);
-        final int height = res.getDimensionPixelSize(
-                android.R.dimen.notification_large_icon_height);
         int windowFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
@@ -219,7 +222,7 @@
         } else {
             windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
         }
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, mLargeIconHeight,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, windowFlags,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
@@ -297,6 +300,16 @@
         if (n.largeIcon != null) {
             largeIcon.setImageBitmap(n.largeIcon);
             largeIcon.setVisibility(View.VISIBLE);
+            final ViewGroup.LayoutParams lp = largeIcon.getLayoutParams();
+            final int statusBarHeight = mBar.getStatusBarHeight();
+            if (n.largeIcon.getHeight() <= statusBarHeight) {
+                // for smallish largeIcons, it looks a little odd to have them floating halfway up
+                // the ticker, so we vertically center them in the status bar area instead
+                lp.height = statusBarHeight;
+            } else {
+                lp.height = mLargeIconHeight;
+            }
+            largeIcon.setLayoutParams(lp);
         }
 
         if (CLICKABLE_TICKER) {
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 0e2d2a8..38c85bb 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -195,6 +195,7 @@
                 .setInverseBackgroundForced(true);
 
         final AlertDialog dialog = ab.create();
+        dialog.getListView().setItemsCanFocus(true);
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
 
         dialog.setOnDismissListener(this);
@@ -518,8 +519,6 @@
         public View create(Context context, View convertView, ViewGroup parent,
                 LayoutInflater inflater) {
             View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
-            // Handle clicks outside the icons and ignore
-            v.setOnClickListener(this);
 
             int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
             for (int i = 0; i < 3; i++) {
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index 4564f90..e997355 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -38,6 +38,8 @@
 import android.text.TextPaint;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
 import android.content.res.Resources;
 import android.content.Context;
 
@@ -74,9 +76,13 @@
         mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2);
 
         mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL));
-        mGlowColorPressedPaint.setColor(0xffffc300);
+
+        TypedValue value = new TypedValue();
+        mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute(
+                android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300);
         mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
-        mGlowColorFocusedPaint.setColor(0xffff8e00);
+        mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute(
+                android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00);
         mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
 
         ColorMatrix cm = new ColorMatrix();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index af86ae9..535f039 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1816,22 +1816,42 @@
 
         @Override
         public boolean dispatchKeyShortcutEvent(KeyEvent ev) {
-            // Perform the shortcut (mPreparedPanel can be null since
-            // global shortcuts (such as search) don't rely on a
-            // prepared panel or menu).
-            boolean handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
-                    Menu.FLAG_PERFORM_NO_CLOSE);
-            if (handled) {
-                if (mPreparedPanel != null) {
-                    mPreparedPanel.isHandled = true;
+            // If the panel is already prepared, then perform the shortcut using it.
+            boolean handled;
+            if (mPreparedPanel != null) {
+                handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
+                        Menu.FLAG_PERFORM_NO_CLOSE);
+                if (handled) {
+                    if (mPreparedPanel != null) {
+                        mPreparedPanel.isHandled = true;
+                    }
+                    return true;
                 }
-                return true;
             }
 
             // Shortcut not handled by the panel.  Dispatch to the view hierarchy.
             final Callback cb = getCallback();
-            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchKeyShortcutEvent(ev)
-                    : super.dispatchKeyShortcutEvent(ev);
+            handled = cb != null && !isDestroyed() && mFeatureId < 0
+                    ? cb.dispatchKeyShortcutEvent(ev) : super.dispatchKeyShortcutEvent(ev);
+            if (handled) {
+                return true;
+            }
+
+            // If the panel is not prepared, then we may be trying to handle a shortcut key
+            // combination such as Control+C.  Temporarily prepare the panel then mark it
+            // unprepared again when finished to ensure that the panel will again be prepared
+            // the next time it is shown for real.
+            if (mPreparedPanel == null) {
+                PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
+                preparePanel(st, ev);
+                handled = performPanelShortcut(st, ev.getKeyCode(), ev,
+                        Menu.FLAG_PERFORM_NO_CLOSE);
+                st.isPrepared = false;
+                if (handled) {
+                    return true;
+                }
+            }
+            return false;
         }
 
         @Override
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 46463ab..7510e04 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -298,9 +298,15 @@
     GlobalActions mGlobalActions;
     volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
     boolean mPendingPowerKeyUpCanceled;
-    RecentApplicationsDialog mRecentAppsDialog;
     Handler mHandler;
 
+    static final int RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS = 0;
+    static final int RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW = 1;
+    static final int RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH = 2;
+
+    RecentApplicationsDialog mRecentAppsDialog;
+    int mRecentAppsDialogHeldModifiers;
+
     private static final int LID_ABSENT = -1;
     private static final int LID_CLOSED = 0;
     private static final int LID_OPEN = 1;
@@ -693,7 +699,7 @@
         }
 
         if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
-            showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
+            showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
         } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
             try {
                 mStatusBarService.toggleRecentApps();
@@ -704,10 +710,10 @@
     }
 
     /**
-     * Create (if necessary) and launch the recent apps dialog, or hide it if it is
-     * already shown.
+     * Create (if necessary) and show or dismiss the recent apps dialog according
+     * according to the requested behavior.
      */
-    void showOrHideRecentAppsDialog(final int heldModifiers, final boolean dismissIfShown) {
+    void showOrHideRecentAppsDialog(final int behavior) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -715,12 +721,33 @@
                     mRecentAppsDialog = new RecentApplicationsDialog(mContext);
                 }
                 if (mRecentAppsDialog.isShowing()) {
-                    if (dismissIfShown) {
-                        mRecentAppsDialog.dismiss();
+                    switch (behavior) {
+                        case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
+                            mRecentAppsDialog.dismiss();
+                            break;
+                        case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
+                            mRecentAppsDialog.dismissAndSwitch();
+                            break;
+                        case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
+                        default:
+                            break;
                     }
                 } else {
-                    mRecentAppsDialog.setHeldModifiers(heldModifiers);
-                    mRecentAppsDialog.show();
+                    switch (behavior) {
+                        case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
+                            mRecentAppsDialog.show();
+                            break;
+                        case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
+                            try {
+                                mWindowManager.setInTouchMode(false);
+                            } catch (RemoteException e) {
+                            }
+                            mRecentAppsDialog.show();
+                            break;
+                        case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
+                        default:
+                            break;
+                    }
                 }
             }
         });
@@ -1598,7 +1625,7 @@
             return 0;
         } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
             if (down && repeatCount == 0) {
-                showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
+                showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
             }
             return -1;
         }
@@ -1634,6 +1661,26 @@
             }
         }
 
+        // Invoke shortcuts using Meta.
+        if (down && repeatCount == 0
+                && (metaState & KeyEvent.META_META_ON) != 0) {
+            final KeyCharacterMap kcm = event.getKeyCharacterMap();
+            Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
+                    metaState & ~(KeyEvent.META_META_ON
+                            | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
+            if (shortcutIntent != null) {
+                shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                try {
+                    mContext.startActivity(shortcutIntent);
+                } catch (ActivityNotFoundException ex) {
+                    Slog.w(TAG, "Dropping shortcut key combination because "
+                            + "the activity to which it is registered was not found: "
+                            + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
+                }
+                return -1;
+            }
+        }
+
         // Handle application launch keys.
         if (down && repeatCount == 0) {
             String category = sApplicationLaunchKeyCategories.get(keyCode);
@@ -1647,9 +1694,29 @@
                             + "the activity to which it is registered was not found: "
                             + "keyCode=" + keyCode + ", category=" + category, ex);
                 }
+                return -1;
             }
         }
 
+        // Display task switcher for ALT-TAB or Meta-TAB.
+        if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
+            if (mRecentAppsDialogHeldModifiers == 0) {
+                final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
+                if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
+                        || KeyEvent.metaStateHasModifiers(
+                                shiftlessModifiers, KeyEvent.META_META_ON)) {
+                    mRecentAppsDialogHeldModifiers = shiftlessModifiers;
+                    showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW);
+                    return -1;
+                }
+            }
+        } else if (!down && mRecentAppsDialogHeldModifiers != 0
+                && (metaState & mRecentAppsDialogHeldModifiers) == 0) {
+            mRecentAppsDialogHeldModifiers = 0;
+            showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
+        }
+
+        // Let the application handle the key.
         return 0;
     }
 
@@ -1671,39 +1738,6 @@
             final KeyCharacterMap kcm = event.getKeyCharacterMap();
             final int keyCode = event.getKeyCode();
             final int metaState = event.getMetaState();
-            final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
-                    && event.getRepeatCount() == 0;
-
-            if (initialDown) {
-                // Invoke shortcuts using Meta as a fallback.
-                if ((metaState & KeyEvent.META_META_ON) != 0) {
-                    Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
-                            metaState & ~(KeyEvent.META_META_ON
-                                    | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
-                    if (shortcutIntent != null) {
-                        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        try {
-                            mContext.startActivity(shortcutIntent);
-                        } catch (ActivityNotFoundException ex) {
-                            Slog.w(TAG, "Dropping shortcut key combination because "
-                                    + "the activity to which it is registered was not found: "
-                                    + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
-                        }
-                        return null;
-                    }
-                }
-
-                // Display task switcher for ALT-TAB or Meta-TAB.
-                if (keyCode == KeyEvent.KEYCODE_TAB) {
-                    final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
-                    if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
-                            || KeyEvent.metaStateHasModifiers(
-                                    shiftlessModifiers, KeyEvent.META_META_ON)) {
-                        showOrHideRecentAppsDialog(shiftlessModifiers, false /*dismissIfShown*/);
-                        return null;
-                    }
-                }
-            }
 
             // Check for fallback actions specified by the key character map.
             if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
@@ -3134,10 +3168,7 @@
             }
 
             final int preferredRotation;
-            if (mHdmiPlugged) {
-                // Ignore sensor when plugged into HDMI.
-                preferredRotation = mHdmiRotation;
-            } else if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
+            if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
                 // Ignore sensor when lid switch is open and rotation is forced.
                 preferredRotation = mLidOpenRotation;
             } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
@@ -3156,6 +3187,10 @@
                 // enable 180 degree rotation while docked.
                 preferredRotation = mDeskDockEnablesAccelerometer
                         ? sensorRotation : mDeskDockRotation;
+            } else if (mHdmiPlugged) {
+                // Ignore sensor when plugged into HDMI.
+                // Note that the dock orientation overrides the HDMI orientation.
+                preferredRotation = mHdmiRotation;
             } else if ((mAccelerometerDefault != 0 /* implies not rotation locked */
                             && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
                                     || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED))
@@ -3398,6 +3433,9 @@
                             WindowManager.LayoutParams.FLAG_DIM_BEHIND
                             | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
                     mBootMsgDialog.getWindow().setDimAmount(1);
+                    WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes();
+                    lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+                    mBootMsgDialog.getWindow().setAttributes(lp);
                     mBootMsgDialog.setCancelable(false);
                     mBootMsgDialog.show();
                 }
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
index aa00fbdd..b9903dd 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
@@ -71,8 +71,6 @@
         }
     };
 
-    private int mHeldModifiers;
-
     public RecentApplicationsDialog(Context context) {
         super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
 
@@ -124,17 +122,6 @@
         }
     }
 
-    /**
-     * Sets the modifier keys that are being held to keep the dialog open, or 0 if none.
-     * Used to make the recent apps dialog automatically dismiss itself when the modifiers
-     * all go up.
-     * @param heldModifiers The held key modifiers, such as {@link KeyEvent#META_ALT_ON}.
-     * Should exclude shift.
-     */
-    public void setHeldModifiers(int heldModifiers) {
-        mHeldModifiers = heldModifiers;
-    }
-
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_TAB) {
@@ -174,30 +161,27 @@
         return super.onKeyDown(keyCode, event);
     }
 
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (mHeldModifiers != 0 && (event.getModifiers() & mHeldModifiers) == 0) {
-            final int numIcons = mIcons.length;
-            RecentTag tag = null;
-            for (int i = 0; i < numIcons; i++) {
-                if (mIcons[i].getVisibility() != View.VISIBLE) {
+    /**
+     * Dismiss the dialog and switch to the selected application.
+     */
+    public void dismissAndSwitch() {
+        final int numIcons = mIcons.length;
+        RecentTag tag = null;
+        for (int i = 0; i < numIcons; i++) {
+            if (mIcons[i].getVisibility() != View.VISIBLE) {
+                break;
+            }
+            if (i == 0 || mIcons[i].hasFocus()) {
+                tag = (RecentTag) mIcons[i].getTag();
+                if (mIcons[i].hasFocus()) {
                     break;
                 }
-                if (i == 0 || mIcons[i].hasFocus()) {
-                    tag = (RecentTag) mIcons[i].getTag();
-                    if (mIcons[i].hasFocus()) {
-                        break;
-                    }
-                }
             }
-            if (tag != null) {
-                switchTo(tag);
-            }
-            dismiss();
-            return true;
         }
-
-        return super.onKeyUp(keyCode, event);
+        if (tag != null) {
+            switchTo(tag);
+        }
+        dismiss();
     }
 
     /**
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 04b4855..40268b0 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -4320,12 +4320,23 @@
             mKeyMementos.removeAt(index);
             return true;
         }
+        /* FIXME: We can't just drop the key up event because that prevents creating
+         * popup windows that are automatically shown when a key is held and then
+         * dismissed when the key is released.  The problem is that the popup will
+         * not have received the original key down, so the key up will be considered
+         * to be inconsistent with its observed state.  We could perhaps handle this
+         * by synthesizing a key down but that will cause other problems.
+         *
+         * So for now, allow inconsistent key up events to be dispatched.
+         *
 #if DEBUG_OUTBOUND_EVENT_DETAILS
         LOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
                 "keyCode=%d, scanCode=%d",
                 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
 #endif
         return false;
+        */
+        return true;
     }
 
     case AKEY_EVENT_ACTION_DOWN: {
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 2af5103..4f81178 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -24,9 +24,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.Intent.FilterComparison;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.content.Intent.FilterComparison;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -39,6 +39,8 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -74,6 +76,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 
 class AppWidgetService extends IAppWidgetService.Stub
 {
@@ -805,6 +808,45 @@
                     id.host.callbacks = null;
                 }
             }
+
+            // If the host is unavailable, then we call the associated
+            // RemoteViewsFactory.onDataSetChanged() directly
+            if (id.host.callbacks == null) {
+                Set<FilterComparison> keys = mRemoteViewsServicesAppWidgets.keySet();
+                for (FilterComparison key : keys) {
+                    if (mRemoteViewsServicesAppWidgets.get(key).contains(id.appWidgetId)) {
+                        Intent intent = key.getIntent();
+
+                        final ServiceConnection conn = new ServiceConnection() {
+                            @Override
+                            public void onServiceConnected(ComponentName name, IBinder service) {
+                                IRemoteViewsFactory cb =
+                                    IRemoteViewsFactory.Stub.asInterface(service);
+                                try {
+                                    cb.onDataSetChangedAsync();
+                                } catch (RemoteException e) {
+                                    e.printStackTrace();
+                                } catch (RuntimeException e) {
+                                    e.printStackTrace();
+                                }
+                                mContext.unbindService(this);
+                            }
+                            @Override
+                            public void onServiceDisconnected(android.content.ComponentName name) {
+                                // Do nothing
+                            }
+                        };
+
+                        // Bind to the service and call onDataSetChanged()
+                        final long token = Binder.clearCallingIdentity();
+                        try {
+                            mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+                        } finally {
+                            Binder.restoreCallingIdentity(token);
+                        }
+                    }
+                }
+            }
         }
     }
 
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 3c65255..16643ff 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1078,7 +1078,6 @@
                 mWifiStateMachine.setHighPerfModeEnabled(strongestLockMode
                         == WifiManager.WIFI_MODE_FULL_HIGH_PERF);
             } else {
-                mWifiStateMachine.requestCmWakeLock();
                 mWifiStateMachine.setDriverStart(false);
             }
         } else {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index b5edc0a..6c11953 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1932,8 +1932,9 @@
                     // should be left as-is.
                     replyChainEnd = -1;
                 }
-                
-            } else if (target.resultTo != null) {
+
+            } else if (target.resultTo != null && (below == null
+                    || below.task == target.task)) {
                 // If this activity is sending a reply to a previous
                 // activity, we can't do anything with it now until
                 // we reach the start of the reply chain.
@@ -1963,6 +1964,8 @@
                         replyChainEnd = targetI;
                     }
                     ActivityRecord p = null;
+                    if (DEBUG_TASKS) Slog.v(TAG, "Finishing task at index "
+                            + targetI + " to " + replyChainEnd);
                     for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
                         p = mHistory.get(srcPos);
                         if (p.finishing) {
@@ -1981,6 +1984,8 @@
                     if (replyChainEnd < 0) {
                         replyChainEnd = targetI;
                     }
+                    if (DEBUG_TASKS) Slog.v(TAG, "Reparenting task at index "
+                            + targetI + " to " + replyChainEnd);
                     for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
                         ActivityRecord p = mHistory.get(srcPos);
                         if (p.finishing) {
@@ -2002,6 +2007,7 @@
                         p.setTask(task, null, false);
                         mHistory.add(lastReparentPos, p);
                         if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p
+                                + " from " + srcPos + " to " + lastReparentPos
                                 + " in to resetting task " + task);
                         mService.mWindowManager.moveAppToken(lastReparentPos, p.appToken);
                         mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
@@ -2031,6 +2037,11 @@
                         }
                     }
                 }
+
+            } else if (below != null && below.task != target.task) {
+                // We hit the botton of a task; the reply chain can't
+                // pass through it.
+                replyChainEnd = -1;
             }
             
             target = below;
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index f111dd6..07b6183 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -683,6 +683,13 @@
         mRilConnectedRegistrants.remove(h);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setCurrentPreferredNetworkType() {
+    }
+
     //***** Protected Methods
     /**
      * Store new RadioState and send notification based on the changes
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 33ead75..d6e6ae0 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -1311,6 +1311,12 @@
     void queryAvailableBandMode (Message response);
 
     /**
+     * Set the current preferred network type. This will be the last
+     * networkType that was passed to setPreferredNetworkType.
+     */
+    void setCurrentPreferredNetworkType();
+
+    /**
      *  Requests to set the preferred network type for searching and registering
      * (CS/PS domain, RAT, and operation mode)
      * @param networkType one of  NT_*_TYPE
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 9f93fb8..f2e7f45 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1823,6 +1823,16 @@
     /**
      * {@inheritDoc}
      */
+    @Override
+    public void setCurrentPreferredNetworkType() {
+        if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType: " + mSetPreferredNetworkType);
+        setPreferredNetworkType(mSetPreferredNetworkType, null);
+    }
+    private int mSetPreferredNetworkType;
+
+    /**
+     * {@inheritDoc}
+     */
     public void setPreferredNetworkType(int networkType , Message response) {
         RILRequest rr = RILRequest.obtain(
                 RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
@@ -1830,6 +1840,7 @@
         rr.mp.writeInt(1);
         rr.mp.writeInt(networkType);
 
+        mSetPreferredNetworkType = networkType;
         mPreferredNetworkType = networkType;
 
         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 3d6cd68..d939e98 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -257,6 +257,9 @@
             break;
 
         case EVENT_RUIM_READY:
+            // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
+            // cm.setCurrentPreferredNetworkType();
+
             // The RUIM is now ready i.e if it was locked it has been
             // unlocked. At this stage, the radio is already powered on.
             isSubscriptionFromRuim = true;
@@ -277,6 +280,9 @@
             break;
 
         case EVENT_NV_READY:
+            // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
+            // cm.setCurrentPreferredNetworkType();
+
             isSubscriptionFromRuim = false;
             // For Non-RUIM phones, the subscription information is stored in
             // Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 11f1623..963db2c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -914,10 +914,16 @@
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY)),
+                        NetworkUtils.trimV4AddrZeros(
+                                cursor.getString(
+                                cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY)),
+                        NetworkUtils.trimV4AddrZeros(
+                                cursor.getString(
+                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
+                        NetworkUtils.trimV4AddrZeros(
+                                cursor.getString(
+                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 3799894..16d3129 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -132,7 +132,7 @@
     // See TS 22.030 6.5.2 "Structure of the MMI"
 
     static Pattern sPatternSuppService = Pattern.compile(
-        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
+        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)([^#]*)");
 /*       1  2                    3          4  5       6   7         8    9     10  11             12
 
          1 = Full string up to and including #
@@ -141,7 +141,7 @@
          5 = SIA
          7 = SIB
          9 = SIC
-         10 = dialing number
+         10 = dialing number which must not include #, e.g. *SCn*SI#DN format
 */
 
     static final int MATCH_GROUP_POUND_STRING = 1;
@@ -1338,4 +1338,20 @@
      * SpecialCharSequenceMgr class.
      */
 
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("GsmMmiCode {");
+
+        sb.append("State=" + getState());
+        if (action != null) sb.append(" action=" + action);
+        if (sc != null) sb.append(" sc=" + sc);
+        if (sia != null) sb.append(" sia=" + sia);
+        if (sib != null) sb.append(" sib=" + sib);
+        if (sic != null) sb.append(" sic=" + sic);
+        if (poundString != null) sb.append(" poundString=" + poundString);
+        if (dialingNumber != null) sb.append(" dialingNumber=" + dialingNumber);
+        if (pwd != null) sb.append(" pwd=" + pwd);
+        sb.append("}");
+        return sb.toString();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index eea2780f..84127cf 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -270,6 +270,9 @@
                 break;
 
             case EVENT_SIM_READY:
+                // Set the network type, in case the radio does not restore it.
+                cm.setCurrentPreferredNetworkType();
+
                 // The SIM is now ready i.e if it was locked
                 // it has been unlocked. At this stage, the radio is already
                 // powered on.
diff --git a/tests/StatusBar/res/layout/notification_builder_test.xml b/tests/StatusBar/res/layout/notification_builder_test.xml
index e1199c7..6c384f7 100644
--- a/tests/StatusBar/res/layout/notification_builder_test.xml
+++ b/tests/StatusBar/res/layout/notification_builder_test.xml
@@ -605,6 +605,11 @@
                         style="@style/FieldContents"
                         android:text="pineapple2"
                         />
+                <RadioButton
+                        android:id="@+id/large_icon_small"
+                        style="@style/FieldContents"
+                        android:text="small"
+                        />
             </RadioGroup>
             
 
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
index 5a2ebac..fefd890 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
@@ -287,6 +287,9 @@
             case R.id.large_icon_pineapple2:
                 b.setLargeIcon(loadBitmap(R.drawable.pineapple2));
                 break;
+            case R.id.large_icon_small:
+                b.setLargeIcon(loadBitmap(R.drawable.icon2));
+                break;
         }
 
         // sound TODO
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 3ed9bd5..8f807fe 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -306,8 +306,6 @@
     static final int CMD_SET_HIGH_PERF_MODE               = BASE + 77;
     /* Set the country code */
     static final int CMD_SET_COUNTRY_CODE                 = BASE + 80;
-    /* Request connectivity manager wake lock before driver stop */
-    static final int CMD_REQUEST_CM_WAKELOCK              = BASE + 81;
     /* Enables RSSI poll */
     static final int CMD_ENABLE_RSSI_POLL                 = BASE + 82;
     /* RSSI poll */
@@ -1061,15 +1059,6 @@
         return result;
     }
 
-    /**
-     * Request a wakelock with connectivity service to
-     * keep the device awake until we hand-off from wifi
-     * to an alternate network
-     */
-    public void requestCmWakeLock() {
-        sendMessage(CMD_REQUEST_CM_WAKELOCK);
-    }
-
     public void updateBatteryWorkSource(WorkSource newSource) {
         synchronized (mRunningWifiUids) {
             try {
@@ -1867,7 +1856,6 @@
                 case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_COUNTRY_CODE:
                 case CMD_SET_FREQUENCY_BAND:
-                case CMD_REQUEST_CM_WAKELOCK:
                 case CMD_CONNECT_NETWORK:
                 case CMD_SAVE_NETWORK:
                 case CMD_FORGET_NETWORK:
@@ -3024,10 +3012,6 @@
                     WifiNative.disconnectCommand();
                     transitionTo(mDisconnectingState);
                     break;
-                case CMD_REQUEST_CM_WAKELOCK:
-                    checkAndSetConnectivityInstance();
-                    mCm.requestNetworkTransitionWakelock(TAG);
-                    break;
                 case CMD_SET_SCAN_MODE:
                     if (message.arg1 == SCAN_ONLY_MODE) {
                         sendMessage(CMD_DISCONNECT);
@@ -3100,6 +3084,11 @@
         }
         @Override
         public void exit() {
+
+            /* Request a CS wakelock during transition to mobile */
+            checkAndSetConnectivityInstance();
+            mCm.requestNetworkTransitionWakelock(TAG);
+
             /* If a scan result is pending in connected state, the supplicant
              * is in SCAN_ONLY_MODE. Restore CONNECT_MODE on exit
              */
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index c58253d..b27c60f 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -150,6 +150,7 @@
     private ConnectedState mConnectedState = new ConnectedState();
     private DnsCheckingState mDnsCheckingState = new DnsCheckingState();
     private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
+    private OnlineState mOnlineState = new OnlineState();
     private DnsCheckFailureState mDnsCheckFailureState = new DnsCheckFailureState();
     private DelayWalledGardenState mDelayWalledGardenState = new DelayWalledGardenState();
     private WalledGardenState mWalledGardenState = new WalledGardenState();
@@ -163,6 +164,7 @@
     private int mMinDnsResponses;
     private int mDnsPingTimeoutMs;
     private long mBlacklistFollowupIntervalMs;
+    private boolean mPoorNetworkDetectionEnabled;
     private boolean mWalledGardenTestEnabled;
     private String mWalledGardenUrl;
 
@@ -226,6 +228,7 @@
                     addState(mWalledGardenState, mConnectedState);
                     addState(mBlacklistedApState, mConnectedState);
                     addState(mOnlineWatchState, mConnectedState);
+                    addState(mOnlineState, mConnectedState);
 
         setInitialState(mWatchdogDisabledState);
         updateSettings();
@@ -386,9 +389,7 @@
     }
 
     private boolean isWatchdogEnabled() {
-        //return getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
-        //TODO: fix this when we do aggressive monitoring
-        return false;
+        return getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
     }
 
     private void updateSettings() {
@@ -413,6 +414,10 @@
         mBlacklistFollowupIntervalMs = Secure.getLong(mContentResolver,
                 Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS,
                 DEFAULT_BLACKLIST_FOLLOWUP_INTERVAL_MS);
+        //TODO: enable this by default after changing watchdog behavior
+        //Also, update settings description
+        mPoorNetworkDetectionEnabled = getSettingsBoolean(mContentResolver,
+                Settings.Secure.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED, false);
         mWalledGardenTestEnabled = getSettingsBoolean(mContentResolver,
                 Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, true);
         mWalledGardenUrl = getSettingsStr(mContentResolver,
@@ -625,9 +630,13 @@
 
                             initConnection(wifiInfo);
                             mConnectionInfo = wifiInfo;
-                            updateBssids();
-                            transitionTo(mDnsCheckingState);
                             mNetEventCounter++;
+                            if (mPoorNetworkDetectionEnabled) {
+                                updateBssids();
+                                transitionTo(mDnsCheckingState);
+                            } else {
+                                transitionTo(mDelayWalledGardenState);
+                            }
                             break;
                         default:
                             mNetEventCounter++;
@@ -679,12 +688,18 @@
         public boolean processMessage(Message msg) {
             switch (msg.what) {
                 case EVENT_SCAN_RESULTS_AVAILABLE:
-                    updateBssids();
+                    if (mPoorNetworkDetectionEnabled) {
+                        updateBssids();
+                    }
                     return HANDLED;
                 case EVENT_WATCHDOG_SETTINGS_CHANGE:
-                    // Stop current checks, but let state update
-                    transitionTo(mOnlineWatchState);
-                    return NOT_HANDLED;
+                    updateSettings();
+                    if (mPoorNetworkDetectionEnabled) {
+                        transitionTo(mOnlineWatchState);
+                    } else {
+                        transitionTo(mOnlineState);
+                    }
+                    return HANDLED;
             }
             return NOT_HANDLED;
         }
@@ -831,7 +846,11 @@
                         transitionTo(mWalledGardenState);
                     } else {
                         if (DBG) log("Walled garden test complete - online");
-                        transitionTo(mOnlineWatchState);
+                        if (mPoorNetworkDetectionEnabled) {
+                            transitionTo(mOnlineWatchState);
+                        } else {
+                            transitionTo(mOnlineState);
+                        }
                     }
                     return HANDLED;
                 default:
@@ -963,6 +982,13 @@
         }
     }
 
+
+    /* Child state of ConnectedState indicating that we are online
+     * and there is nothing to do
+     */
+    class OnlineState extends State {
+    }
+
     class DnsCheckFailureState extends State {
 
         @Override
@@ -1039,7 +1065,11 @@
                 return HANDLED;
             }
             setWalledGardenNotificationVisible(true);
-            transitionTo(mOnlineWatchState);
+            if (mPoorNetworkDetectionEnabled) {
+                transitionTo(mOnlineWatchState);
+            } else {
+                transitionTo(mOnlineState);
+            }
             return HANDLED;
         }
     }