Merge "Remove Ringtone.setWakeMode, it's not needed."
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 173da8d..91def67 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1811,6 +1811,14 @@
     }
 
     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            fout.println("Permission Denial: can't dump AccountsManager from from pid="
+                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                    + " without permission " + android.Manifest.permission.DUMP);
+            return;
+        }
+
         synchronized (mCacheLock) {
             final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
 
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 66373fe..be87946 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -79,6 +79,16 @@
     void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable);
 
     /**
+     * Disable IPv6 on an interface
+     */
+    void disableIpv6(String iface);
+
+    /**
+     * Enable IPv6 on an interface
+     */
+    void enableIpv6(String iface);
+
+    /**
      * Retrieves the network routes currently configured on the specified
      * interface
      */
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index dd9dd25..8b99459 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -26,6 +26,7 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.Window;
+import android.widget.AbsListView;
 import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.ListAdapter;
@@ -190,9 +191,13 @@
     }
 
     public void onItemClick(AdapterView parent, View view, int position, long id) {
+        // If the list has headers, subtract them from the index.
+        if (parent instanceof ListView) {
+            position -= ((ListView) parent).getHeaderViewsCount();
+        }
         Object item = getRootAdapter().getItem(position);
         if (!(item instanceof Preference)) return;
-        
+
         final Preference preference = (Preference) item; 
         preference.performClick(this);
     }
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index e849b71..237a892 100755
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1574,22 +1574,6 @@
             public static final String SENT_TIME = "sent_time";
         }
 
-        public static final class ScrapSpace {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri CONTENT_URI = Uri.parse("content://mms/scrapSpace");
-
-            /**
-             * This is the scrap file we use to store the media attachment when the user
-             * chooses to capture a photo to be attached . We pass {#link@Uri} to the Camera app,
-             * which streams the captured image to the uri. Internally we write the media content
-             * to this file. It's named '.temp.jpg' so Gallery won't pick it up.
-             */
-            public static final String SCRAP_FILE_PATH =
-                Environment.getExternalStorageDirectory().getPath() + "/mms/scrapSpace/.temp.jpg";
-        }
-
         public static final class Intents {
             private Intents() {
                 // Non-instantiatable.
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index f82c9c4..c3a2308 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -76,7 +76,7 @@
                          boolean includepad,
                          TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
         this(base, display, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR,
-                spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth);
+                spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth, Integer.MAX_VALUE);
     }
 
     /**
@@ -93,7 +93,7 @@
                          int width, Alignment align, TextDirectionHeuristic textDir,
                          float spacingmult, float spacingadd,
                          boolean includepad,
-                         TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
+                         TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) {
         super((ellipsize == null)
                 ? display
                 : (display instanceof Spanned)
@@ -135,6 +135,8 @@
             mEllipsize = true;
         }
 
+        mMaxLines = maxLines;
+
         // Initial state is a single line with 0 characters (0 to 0),
         // with top at 0 and bottom at whatever is natural, and
         // undefined ellipsis.
@@ -283,7 +285,7 @@
         reflowed.generate(text, where, where + after,
                 getPaint(), getWidth(), getAlignment(), getTextDirectionHeuristic(),
                 getSpacingMultiplier(), getSpacingAdd(),
-                false, true, mEllipsizedWidth, mEllipsizeAt);
+                false, true, mEllipsizedWidth, mEllipsizeAt, mMaxLines);
         int n = reflowed.getLineCount();
 
         // If the new layout has a blank line at the end, but it is not
@@ -488,6 +490,8 @@
 
     private int mTopPadding, mBottomPadding;
 
+    private int mMaxLines;
+
     private static StaticLayout sStaticLayout = new StaticLayout(null);
 
     private static final Object[] sLock = new Object[0];
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 583cbe6..7c27396 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -139,7 +139,7 @@
 
         generate(source, bufstart, bufend, paint, outerwidth, align, textDir,
                  spacingmult, spacingadd, includepad, includepad,
-                 ellipsizedWidth, ellipsize);
+                 ellipsizedWidth, ellipsize, mMaximumVisibleLineCount);
 
         mMeasured = MeasuredText.recycle(mMeasured);
         mFontMetricsInt = null;
@@ -160,7 +160,7 @@
                         Alignment align, TextDirectionHeuristic textDir,
                         float spacingmult, float spacingadd,
                         boolean includepad, boolean trackpad,
-                        float ellipsizedWidth, TextUtils.TruncateAt ellipsize) {
+                        float ellipsizedWidth, TextUtils.TruncateAt ellipsize, int maxLines) {
         mLineCount = 0;
 
         int v = 0;
@@ -477,13 +477,13 @@
                             width = restWidth;
                         }
                     }
-                    if (mLineCount >= mMaximumVisibleLineCount) {
+                    if (mLineCount >= maxLines) {
                         break;
                     }
                 }
             }
 
-            if (paraEnd != here && mLineCount < mMaximumVisibleLineCount) {
+            if (paraEnd != here && mLineCount < maxLines) {
                 if ((fitTop | fitBottom | fitDescent | fitAscent) == 0) {
                     paint.getFontMetricsInt(fm);
 
@@ -514,7 +514,7 @@
         }
 
         if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) &&
-                mLineCount < mMaximumVisibleLineCount) {
+                mLineCount < maxLines) {
             // Log.e("text", "output last " + bufEnd);
 
             paint.getFontMetricsInt(fm);
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index 0433ec4..af524ee 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -73,10 +73,6 @@
         }
     };
 
-    public void forceUpdate() {
-        mCurrentDirty = true;
-    }
-
     public void setCharSequence(CharSequence incoming) {
         // When incoming is different object, move listeners to new sequence
         // and mark as dirty so we reload contents.
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index c974ba1..d57132a 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -250,6 +250,11 @@
         return LAYER_TYPE_HARDWARE;
     }
 
+    @Override
+    boolean hasStaticLayer() {
+        return true;
+    }
+
     /**
      * Calling this method has no effect.
      */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2ebe756be..d193d6e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10001,6 +10001,15 @@
     }
 
     /**
+     * Indicates whether this view has a static layer. A view with layer type
+     * {@link #LAYER_TYPE_NONE} is a static layer. Other types of layers are
+     * dynamic.
+     */
+    boolean hasStaticLayer() {
+        return mLayerType == LAYER_TYPE_NONE;
+    }
+
+    /**
      * Indicates what type of layer is currently associated with this view. By default
      * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
      * Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index ddb982a..fb0d80a 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2560,8 +2560,8 @@
         final View[] children = mChildren;
         for (int i = 0; i < count; i++) {
             final View child = children[i];
-            if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE ||
-                    child.getAnimation() != null) && child.getLayerType() == LAYER_TYPE_NONE) {
+            if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) &&
+                    child.hasStaticLayer()) {
                 child.mRecreateDisplayList = (child.mPrivateFlags & INVALIDATED) == INVALIDATED;
                 child.mPrivateFlags &= ~INVALIDATED;
                 child.getDisplayList();
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 75c7592..d0841dd 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -26,6 +26,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.SystemProperties;
 import android.util.Slog;
 import android.view.accessibility.AccessibilityEvent;
 
@@ -472,11 +473,14 @@
     }
 
     private class LocalWindowManager extends WindowManagerImpl.CompatModeWrapper {
+        private static final String PROPERTY_HARDWARE_UI = "persist.sys.ui.hw";
+
         private final boolean mHardwareAccelerated;
 
         LocalWindowManager(WindowManager wm, boolean hardwareAccelerated) {
             super(wm, getCompatInfo(mContext));
-            mHardwareAccelerated = hardwareAccelerated;
+            mHardwareAccelerated = hardwareAccelerated ||
+                    SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
         }
 
         public boolean isHardwareAccelerated() {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 530b230..370cce4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4308,7 +4308,7 @@
             selectionDone();
         }
         mOrientation = newConfig.orientation;
-        contentInvalidateAll();
+        mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
     }
 
     /**
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index c6e63c3..c37cc52 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -302,8 +302,6 @@
 
         getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
 
-        mAdapter.setMaxActivityCount(maxActivityCount);
-
         final boolean defaultActivityButtonShown =
             mDefaultActivityButton.getVisibility() == VISIBLE;
 
@@ -312,8 +310,10 @@
         if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED
                 && activityCount > maxActivityCount + maxActivityCountOffset) {
             mAdapter.setShowFooterView(true);
+            mAdapter.setMaxActivityCount(maxActivityCount - 1);
         } else {
             mAdapter.setShowFooterView(false);
+            mAdapter.setMaxActivityCount(maxActivityCount);
         }
 
         ListPopupWindow popupWindow = getListPopupWindow();
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index ba69288..fb9047b 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -850,32 +850,65 @@
         return c.getVisibility() == View.GONE;
     }
 
-    private void measureChildWithMargins(View child, int widthMeasureSpec, int heightMeasureSpec) {
-        LayoutParams lp = getLayoutParams(child);
-        int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
-                mPaddingLeft + mPaddingRight + getTotalMargin(child, true), lp.width);
-        int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
-                mPaddingTop + mPaddingBottom + getTotalMargin(child, false), lp.height);
-        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+    private void measureChildWithMargins2(View child, int parentWidthSpec, int parentHeightSpec,
+                                          int childWidth, int childHeight) {
+        int childWidthSpec = getChildMeasureSpec(parentWidthSpec,
+                mPaddingLeft + mPaddingRight + getTotalMargin(child, true), childWidth);
+        int childHeightSpec = getChildMeasureSpec(parentHeightSpec,
+                mPaddingTop + mPaddingBottom + getTotalMargin(child, false), childHeight);
+        child.measure(childWidthSpec, childHeightSpec);
     }
 
-    private void measureChildrenWithMargins(int widthMeasureSpec, int heightMeasureSpec) {
+    private void measureChildrenWithMargins(int widthSpec, int heightSpec, boolean firstPass) {
         for (int i = 0, N = getChildCount(); i < N; i++) {
             View c = getChildAt(i);
             if (isGone(c)) continue;
-            measureChildWithMargins(c, widthMeasureSpec, heightMeasureSpec);
+            LayoutParams lp = getLayoutParams(c);
+            if (firstPass) {
+                measureChildWithMargins2(c, widthSpec, heightSpec, lp.width, lp.height);
+            } else {
+                Spec spec = (orientation == HORIZONTAL) ? lp.columnSpec : lp.rowSpec;
+                if (spec.alignment == FILL) {
+                    Interval span = spec.span;
+                    Axis axis = (orientation == HORIZONTAL) ? horizontalAxis : verticalAxis;
+                    int[] locations = axis.getLocations();
+                    int size = locations[span.max] - locations[span.min];
+                    if (orientation == HORIZONTAL) {
+                        measureChildWithMargins2(c, widthSpec, heightSpec, size, lp.height);
+                    } else {
+                        measureChildWithMargins2(c, widthSpec, heightSpec, lp.width, size);
+                    }
+                }
+            }
         }
     }
 
     @Override
     protected void onMeasure(int widthSpec, int heightSpec) {
-        measureChildrenWithMargins(widthSpec, heightSpec);
+        /** If we have been called by {@link View#measure(int, int)}, one of width or height
+         *  is  likely to have changed. We must invalidate if so. */
+        invalidateValues();
 
-        int width = getPaddingLeft() + horizontalAxis.getMeasure(widthSpec) + getPaddingRight();
-        int height = getPaddingTop() + verticalAxis.getMeasure(heightSpec) + getPaddingBottom();
+        measureChildrenWithMargins(widthSpec, heightSpec, true);
 
-        int measuredWidth = Math.max(width, getSuggestedMinimumWidth());
-        int measuredHeight = Math.max(height, getSuggestedMinimumHeight());
+        int width, height;
+
+        // Use the orientation property to decide which axis should be laid out first.
+        if (orientation == HORIZONTAL) {
+            width = horizontalAxis.getMeasure(widthSpec);
+            measureChildrenWithMargins(widthSpec, heightSpec, false);
+            height = verticalAxis.getMeasure(heightSpec);
+        } else {
+            height = verticalAxis.getMeasure(heightSpec);
+            measureChildrenWithMargins(widthSpec, heightSpec, false);
+            width = horizontalAxis.getMeasure(widthSpec);
+        }
+
+        int hPadding = getPaddingLeft() + getPaddingRight();
+        int vPadding = getPaddingTop() + getPaddingBottom();
+
+        int measuredWidth = Math.max(hPadding + width, getSuggestedMinimumWidth());
+        int measuredHeight = Math.max(vPadding + height, getSuggestedMinimumHeight());
 
         setMeasuredDimension(
                 resolveSizeAndState(measuredWidth, widthSpec, 0),
@@ -1015,8 +1048,6 @@
      for the vertical one.
      */
     final class Axis {
-        private static final int MIN_VALUE = -1000000;
-
         private static final int NEW = 0;
         private static final int PENDING = 1;
         private static final int COMPLETE = 2;
@@ -1024,7 +1055,7 @@
         public final boolean horizontal;
 
         public int definedCount = UNDEFINED;
-        private int inferredCount = UNDEFINED;
+        private int maxIndex = UNDEFINED;
 
         PackedMap<Spec, Bounds> groupBounds;
         public boolean groupBoundsValid = false;
@@ -1056,28 +1087,29 @@
             this.horizontal = horizontal;
         }
 
-        private int maxIndex() {
-            // note the number Integer.MIN_VALUE + 1 comes up in undefined cells
-            int count = -1;
+        private int calculateMaxIndex() {
+            // the number Integer.MIN_VALUE + 1 comes up in undefined cells
+            int result = -1;
             for (int i = 0, N = getChildCount(); i < N; i++) {
                 View c = getChildAt(i);
                 LayoutParams params = getLayoutParams(c);
                 Spec spec = horizontal ? params.columnSpec : params.rowSpec;
-                count = max(count, spec.span.min);
-                count = max(count, spec.span.max);
+                Interval span = spec.span;
+                result = max(result, span.min);
+                result = max(result, span.max);
             }
-            return count == -1 ? UNDEFINED : count;
+            return result == -1 ? UNDEFINED : result;
         }
 
-        private int getInferredCount() {
-            if (inferredCount == UNDEFINED) {
-                inferredCount = max(0, maxIndex()); // if there are no cells, actual count is zero
+        private int getMaxIndex() {
+            if (maxIndex == UNDEFINED) {
+                maxIndex = max(0, calculateMaxIndex()); // use zero when there are no children
             }
-            return inferredCount;
+            return maxIndex;
         }
 
         public int getCount() {
-            return max(definedCount, getInferredCount());
+            return max(definedCount, getMaxIndex());
         }
 
         public void setCount(int count) {
@@ -1179,7 +1211,7 @@
         }
 
         private void include(List<Arc> arcs, Interval key, MutableInt size,
-                boolean ignoreIfAlreadyPresent) {
+                             boolean ignoreIfAlreadyPresent) {
             /*
             Remove self referential links.
             These appear:
@@ -1341,19 +1373,18 @@
         }
 
         private void init(int[] locations) {
-            Arrays.fill(locations, MIN_VALUE);
-            locations[0] = 0;
+            Arrays.fill(locations, 0);
         }
 
         private String arcsToString(List<Arc> arcs) {
-            String var = horizontal ? "c" : "r";
+            String var = horizontal ? "x" : "y";
             StringBuilder result = new StringBuilder();
-            boolean first = false;
-            for(Arc arc : arcs) {
-                if (!first) {
-                    first = true;
+            boolean first = true;
+            for (Arc arc : arcs) {
+                if (first) {
+                    first = false;
                 } else {
-                    result =result.append(", ");
+                    result = result.append(", ");
                 }
                 int src = arc.span.min;
                 int dst = arc.span.max;
@@ -1434,10 +1465,6 @@
                         if (originalCulprits != null) {
                             logError(axisName, arcs, originalCulprits);
                         }
-                        if (DEBUG) {
-                            Log.v(TAG, axisName + " iteration completed in " +
-                                    (1 + i) + " steps of " + N);
-                        }
                         return;
                     }
                 }
@@ -1506,6 +1533,18 @@
 
         private void computeLocations(int[] a) {
             solve(getArcs(), a);
+            if (!orderPreserved) {
+                // Solve returns the smallest solution to the constraint system for which all
+                // values are positive. One value is therefore zero - though if the row/col
+                // order is not preserved this may not be the first vertex. For consistency,
+                // translate all the values so that they measure the distance from a[0]; the
+                // leading edge of the parent. After this transformation some values may be
+                // negative.
+                int a0 = a[0];
+                for (int i = 0, N = a.length; i < N; i++) {
+                    a[i] = a[i] - a0;
+                }
+            }
         }
 
         public int[] getLocations() {
@@ -1521,7 +1560,10 @@
         }
 
         private int size(int[] locations) {
-            return max2(locations, 0) - locations[0];
+            // The parental edges are attached to vertices 0 and N - even when order is not
+            // being preserved and other vertices fall outside this range. Measure the distance
+            // between vertices 0 and N, assuming that locations[0] = 0.
+            return locations[getCount()];
         }
 
         private void setParentConstraints(int min, int max) {
@@ -1561,7 +1603,7 @@
         }
 
         public void invalidateStructure() {
-            inferredCount = UNDEFINED;
+            maxIndex = UNDEFINED;
 
             groupBounds = null;
             forwardLinks = null;
@@ -2139,8 +2181,8 @@
 
     /**
      * A Spec defines the horizontal or vertical characteristics of a group of
-     * cells. Each spec. defines the <em>grid indices</em>, <em>alignment</em> and
-     * <em>flexibility</em> along the appropriate axis.
+     * cells. Each spec. defines the <em>grid indices</em> and <em>alignment</em>
+     * along the appropriate axis.
      * <p>
      * The <em>grid indices</em> are the leading and trailing edges of this cell group.
      * See {@link GridLayout} for a description of the conventions used by GridLayout
@@ -2149,6 +2191,15 @@
      * The <em>alignment</em> property specifies how cells should be aligned in this group.
      * For row groups, this specifies the vertical alignment.
      * For column groups, this specifies the horizontal alignment.
+     * <p>
+     * Use the following static methods to create specs:
+     * <ul>
+     *   <li>{@link #spec(int)}</li>
+     *   <li>{@link #spec(int, int)}</li>
+     *   <li>{@link #spec(int, Alignment)}</li>
+     *   <li>{@link #spec(int, int, Alignment)}</li>
+     * </ul>
+     *
      */
     public static class Spec {
         static final Spec UNDEFINED = spec(GridLayout.UNDEFINED);
diff --git a/core/java/android/widget/Space.java b/core/java/android/widget/Space.java
index d7b2ec2..bb53a77 100644
--- a/core/java/android/widget/Space.java
+++ b/core/java/android/widget/Space.java
@@ -32,20 +32,24 @@
      */
     public Space(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        if (getVisibility() == VISIBLE) {
+            setVisibility(INVISIBLE);
+        }
     }
 
     /**
      * {@inheritDoc}
      */
     public Space(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
     /**
      * {@inheritDoc}
      */
     public Space(Context context) {
-        super(context);
+        //noinspection NullableProblems
+        this(context, null);
     }
 
     /**
@@ -58,22 +62,6 @@
     }
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ViewGroup.LayoutParams getLayoutParams() {
-        return super.getLayoutParams();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setLayoutParams(ViewGroup.LayoutParams params) {
-        super.setLayoutParams(params);
-    }
-
-    /**
      * Compare to: {@link View#getDefaultSize(int, int)}
      * If mode is AT_MOST, return the child size instead of the parent size
      * (unless it is too big).
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 5d8db2f..ac9535a 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -61,7 +61,9 @@
         final TextServicesManager textServicesManager = (TextServicesManager) textView.getContext().
                 getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
         mSpellCheckerSession = textServicesManager.newSpellCheckerSession(
-                null /* not currently used by the textServicesManager */, Locale.getDefault(),
+                null /* not currently used by the textServicesManager */,
+                null /* null locale means use the languages defined in Settings
+                        if referToSpellCheckerLanguageSettings is true */,
                 this, true /* means use the languages defined in Settings */);
         mCookie = hashCode();
 
@@ -183,18 +185,16 @@
 
                     if (!isInDictionary && looksLikeTypo) {
                         String[] suggestions = getSuggestions(suggestionsInfo);
-                        if (suggestions.length > 0) {
-                            SuggestionSpan suggestionSpan = new SuggestionSpan(
-                                    mTextView.getContext(), suggestions,
-                                    SuggestionSpan.FLAG_EASY_CORRECT |
-                                    SuggestionSpan.FLAG_MISSPELLED);
-                            final int start = editable.getSpanStart(spellCheckSpan);
-                            final int end = editable.getSpanEnd(spellCheckSpan);
-                            editable.setSpan(suggestionSpan, start, end,
-                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-                            // TODO limit to the word rectangle region
-                            mTextView.invalidate();
-                        }
+                        SuggestionSpan suggestionSpan = new SuggestionSpan(
+                                mTextView.getContext(), suggestions,
+                                SuggestionSpan.FLAG_EASY_CORRECT |
+                                SuggestionSpan.FLAG_MISSPELLED);
+                        final int start = editable.getSpanStart(spellCheckSpan);
+                        final int end = editable.getSpanEnd(spellCheckSpan);
+                        editable.setSpan(suggestionSpan, start, end,
+                                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                        // TODO limit to the word rectangle region
+                        mTextView.invalidate();
                     }
                     editable.removeSpan(spellCheckSpan);
                 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index cde36c8..5cd7902 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6253,7 +6253,7 @@
             result = new DynamicLayout(mText, mTransformed, mTextPaint, w,
                     alignment, mTextDir, mSpacingMult,
                     mSpacingAdd, mIncludePad, mInput == null ? effectiveEllipsize : null,
-                            ellipsisWidth);
+                            ellipsisWidth, mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
         } else {
             if (boring == UNKNOWN_BORING) {
                 boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
@@ -7609,9 +7609,6 @@
         sendOnTextChanged(buffer, start, before, after);
         onTextChanged(buffer, start, before, after);
 
-        // The WordIterator text change listener may be called after this one.
-        // Make sure this changed text is rescanned before the iterator is used on it.
-        getWordIterator().forceUpdate();
         updateSpellCheckSpans(start, start + after);
 
         // Hide the controllers if the amount of content changed
@@ -7745,21 +7742,22 @@
     private void updateSpellCheckSpans(int start, int end) {
         if (!isTextEditable() || !isSuggestionsEnabled() || !getSpellChecker().isSessionActive())
             return;
-
         Editable text = (Editable) mText;
-        WordIterator wordIterator = getWordIterator();
-        wordIterator.setCharSequence(text);
+
+        final int shift = prepareWordIterator(start, end);
+        final int shiftedStart = start - shift;
+        final int shiftedEnd = end - shift;
 
         // Move back to the beginning of the current word, if any
-        int wordStart = wordIterator.preceding(start);
+        int wordStart = mWordIterator.preceding(shiftedStart);
         int wordEnd;
         if (wordStart == BreakIterator.DONE) {
-            wordEnd = wordIterator.following(start);
+            wordEnd = mWordIterator.following(shiftedStart);
             if (wordEnd != BreakIterator.DONE) {
-                wordStart = wordIterator.getBeginning(wordEnd);
+                wordStart = mWordIterator.getBeginning(wordEnd);
             }
         } else {
-            wordEnd = wordIterator.getEnd(wordStart);
+            wordEnd = mWordIterator.getEnd(wordStart);
         }
         if (wordEnd == BreakIterator.DONE) {
             return;
@@ -7772,22 +7770,22 @@
         final int numberOfSpellCheckSpans = spellCheckSpans.length;
 
         // Iterate over the newly added text and schedule new SpellCheckSpans
-        while (wordStart <= end) {
-            if (wordEnd >= start) {
+        while (wordStart <= shiftedEnd) {
+            if (wordEnd >= shiftedStart) {
                 // A new word has been created across the interval boundaries. Remove previous spans
-                if (wordStart < start && wordEnd > start) {
+                if (wordStart < shiftedStart && wordEnd > shiftedStart) {
                     removeSpansAt(start, spellCheckSpans, text);
                     removeSpansAt(start, suggestionSpans, text);
                 }
 
-                if (wordStart < end && wordEnd > end) {
+                if (wordStart < shiftedEnd && wordEnd > shiftedEnd) {
                     removeSpansAt(end, spellCheckSpans, text);
                     removeSpansAt(end, suggestionSpans, text);
                 }
 
                 // Do not create new boundary spans if they already exist
                 boolean createSpellCheckSpan = true;
-                if (wordEnd == start) {
+                if (wordEnd == shiftedStart) {
                     for (int i = 0; i < numberOfSpellCheckSpans; i++) {
                         final int spanEnd = text.getSpanEnd(spellCheckSpans[i]);
                         if (spanEnd == start) {
@@ -7797,9 +7795,9 @@
                     }
                 }
 
-                if (wordStart == end) {
+                if (wordStart == shiftedEnd) {
                     for (int i = 0; i < numberOfSpellCheckSpans; i++) {
-                        final int spanStart = text.getSpanEnd(spellCheckSpans[i]);
+                        final int spanStart = text.getSpanStart(spellCheckSpans[i]);
                         if (spanStart == end) {
                             createSpellCheckSpan = false;
                             break;
@@ -7808,16 +7806,16 @@
                 }
 
                 if (createSpellCheckSpan) {
-                    mSpellChecker.addSpellCheckSpan(wordStart, wordEnd);
+                    mSpellChecker.addSpellCheckSpan(wordStart + shift, wordEnd + shift);
                 }
             }
 
             // iterate word by word
-            wordEnd = wordIterator.following(wordEnd);
+            wordEnd = mWordIterator.following(wordEnd);
             if (wordEnd == BreakIterator.DONE) break;
-            wordStart = wordIterator.getBeginning(wordEnd);
+            wordStart = mWordIterator.getBeginning(wordEnd);
             if (wordStart == BreakIterator.DONE) {
-                Log.e(LOG_TAG, "Unable to find word beginning from " + wordEnd + "in " + mText);
+                Log.e(LOG_TAG, "No word beginning from " + (wordEnd + shift) + "in " + mText);
                 break;
             }
         }
@@ -8941,26 +8939,32 @@
             selectionStart = ((Spanned) mText).getSpanStart(url);
             selectionEnd = ((Spanned) mText).getSpanEnd(url);
         } else {
-            WordIterator wordIterator = getWordIterator();
-            // WordIterator handles text changes, this is a no-op if text in unchanged.
-            wordIterator.setCharSequence(mText);
+            final int shift = prepareWordIterator(minOffset, maxOffset);
 
-            selectionStart = wordIterator.getBeginning(minOffset);
+            selectionStart = mWordIterator.getBeginning(minOffset - shift);
             if (selectionStart == BreakIterator.DONE) return false;
+            selectionStart += shift;
 
-            selectionEnd = wordIterator.getEnd(maxOffset);
+            selectionEnd = mWordIterator.getEnd(maxOffset - shift);
             if (selectionEnd == BreakIterator.DONE) return false;
+            selectionEnd += shift;
         }
 
         Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
         return true;
     }
 
-    WordIterator getWordIterator() {
+    int prepareWordIterator(int start, int end) {
         if (mWordIterator == null) {
             mWordIterator = new WordIterator();
         }
-        return mWordIterator;
+
+        final int TEXT_WINDOW_WIDTH = 50; // Should be larger than the longest word's length
+        final int windowStart = Math.max(0, start - TEXT_WINDOW_WIDTH);
+        final int windowEnd = Math.min(mText.length(), end + TEXT_WINDOW_WIDTH);
+        mWordIterator.setCharSequence(mText.subSequence(windowStart, windowEnd));
+
+        return windowStart;
     }
 
     private SpellChecker getSpellChecker() {
@@ -9188,19 +9192,23 @@
                 return true;
 
             case ID_CUT:
-                setPrimaryClip(ClipData.newPlainText(null, mTransformed.subSequence(min, max)));
+                setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
                 ((Editable) mText).delete(min, max);
                 stopSelectionActionMode();
                 return true;
 
             case ID_COPY:
-                setPrimaryClip(ClipData.newPlainText(null, mTransformed.subSequence(min, max)));
+                setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
                 stopSelectionActionMode();
                 return true;
         }
         return false;
     }
 
+    private CharSequence getTransformedText(int start, int end) {
+        return removeSuggestionSpans(mTransformed.subSequence(start, end));
+    }
+
     /**
      * Prepare text so that there are not zero or two spaces at beginning and end of region defined
      * by [min, max] when replacing this region by paste.
@@ -9317,7 +9325,7 @@
                 // Start a drag
                 final int start = getSelectionStart();
                 final int end = getSelectionEnd();
-                CharSequence selectedText = mTransformed.subSequence(start, end);
+                CharSequence selectedText = getTransformedText(start, end);
                 ClipData data = ClipData.newPlainText(null, selectedText);
                 DragLocalState localState = new DragLocalState(this, start, end);
                 startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0);
@@ -9480,8 +9488,8 @@
                 return false;
             }
 
-            int posX = mPositionX + positionX;
-            int posY = mPositionY + positionY;
+            int posX = mPositionX + positionX - getScrollX();
+            int posY = mPositionY + positionY - getScrollY();
 
             // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal.
             return posX >= clip.left - 1 && posX <= clip.right + 1 &&
@@ -9900,6 +9908,8 @@
                     suggestionInfo.suggestionIndex = ADD_TO_DICTIONARY;
                     suggestionInfo.text.replace(0, suggestionInfo.text.length(),
                             getContext().getString(com.android.internal.R.string.addToDictionary));
+                    suggestionInfo.text.setSpan(suggestionInfo.highlightSpan, 0, 0,
+                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
                     mNumberOfSuggestions++;
                 }
@@ -9911,6 +9921,8 @@
             suggestionInfo.suggestionIndex = DELETE_TEXT;
             suggestionInfo.text.replace(0, suggestionInfo.text.length(),
                     getContext().getString(com.android.internal.R.string.deleteText));
+            suggestionInfo.text.setSpan(suggestionInfo.highlightSpan, 0, 0,
+                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             mNumberOfSuggestions++;
 
             if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
@@ -9939,8 +9951,7 @@
             suggestionInfo.suggestionStart = spanStart - unionStart;
             suggestionInfo.suggestionEnd = suggestionInfo.suggestionStart 
                     + suggestionInfo.text.length();
-            
-            suggestionInfo.text.clearSpans();
+
             suggestionInfo.text.setSpan(suggestionInfo.highlightSpan, 0,
                     suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 81e7c34..3795a7c 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -23,6 +23,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.os.FileObserver;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -125,6 +126,8 @@
 
     private static FileObserver sPasswordObserver;
 
+    private static boolean mLastAttemptWasBiometric = false;
+
     private static class PasswordFileObserver extends FileObserver {
         public PasswordFileObserver(String path, int mask) {
             super(path, mask);
@@ -371,7 +374,8 @@
     /**
      * Clear any lock pattern or password.
      */
-    public void clearLock() {
+    public void clearLock(boolean isFallback) {
+        if(!isFallback) deleteGallery();
         saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
         setLockPatternEnabled(false);
         saveLockPattern(null);
@@ -390,6 +394,13 @@
     }
 
     /**
+     * Sets whether the last lockscreen setup attempt was biometric
+     */
+    public static void setLastAttemptWasBiometric(boolean val) {
+        mLastAttemptWasBiometric = val;
+    }
+
+    /**
      * Determine if LockScreen can be disabled. This is used, for example, to tell if we should
      * show LockScreen or go straight to the home screen.
      *
@@ -408,6 +419,41 @@
     }
 
     /**
+     * Calls back SetupFaceLock to save the temporary gallery file if this is the backup lock.
+     * This doesn't have to verify that biometric is enabled because it's only called in that case
+    */
+    void moveTempGallery() {
+        Intent intent = new Intent().setClassName("com.android.facelock",
+                "com.android.facelock.SetupFaceLock");
+        intent.putExtra("moveTempGallery", true);
+        mContext.startActivity(intent);
+    }
+
+    /**
+     * Calls back SetupFaceLock to delete the temporary gallery file if this is the backup lock.
+     */
+    public void deleteTempGallery() {
+        //if(mLastAttemptWasBiometric) {
+            Intent intent = new Intent().setClassName("com.android.facelock",
+                    "com.android.facelock.SetupFaceLock");
+            intent.putExtra("deleteTempGallery", true);
+            mContext.startActivity(intent);
+            //}
+    }
+
+    /**
+     * Calls back SetupFaceLock to delete the gallery file when the lock type is changed
+    */
+    void deleteGallery() {
+        if(isBiometricEnabled()) {
+            Intent intent = new Intent().setClassName("com.android.facelock",
+                    "com.android.facelock.SetupFaceLock");
+            intent.putExtra("deleteGallery", true);
+            mContext.startActivity(intent);
+        }
+    }
+
+    /**
      * Save a lock pattern.
      * @param pattern The new pattern to save.
      * @param isFallback Specifies if this is a fallback to biometric weak
@@ -431,11 +477,13 @@
                 keyStore.password(patternToString(pattern));
                 setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
                 if (!isFallback) {
+                    deleteGallery();
                     setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
                 } else {
                     setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
                     setLong(PASSWORD_TYPE_ALTERNATE_KEY,
                             DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+                    moveTempGallery();
                 }
                 dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
                         .size(), 0, 0, 0, 0, 0, 0);
@@ -547,10 +595,12 @@
 
                 int computedQuality = computePasswordQuality(password);
                 if (!isFallback) {
+                    deleteGallery();
                     setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality));
                 } else {
                     setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
                     setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality));
+                    moveTempGallery();
                 }
                 if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                     int letters = 0;
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
index 4d2d535..c4be513 100644
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ b/core/java/com/google/android/mms/pdu/PduPersister.java
@@ -667,6 +667,13 @@
         String contentType = null;
         if (part.getContentType() != null) {
             contentType = toIsoString(part.getContentType());
+
+            // There is no "image/jpg" in Android (and it's an invalid mimetype).
+            // Change it to "image/jpeg"
+            if (ContentType.IMAGE_JPG.equals(contentType)) {
+                contentType = ContentType.IMAGE_JPEG;
+            }
+
             values.put(Part.CONTENT_TYPE, contentType);
             // To ensure the SMIL part is always the first part.
             if (ContentType.APP_SMIL.equals(contentType)) {
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb.png b/core/res/res/drawable-hdpi/stat_sys_adb.png
index ddb8a71..8e15aba2 100644
--- a/core/res/res/drawable-hdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-hdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_adb.png b/core/res/res/drawable-ldpi/stat_sys_adb.png
index 86b945b..aec8d90 100644
--- a/core/res/res/drawable-ldpi/stat_sys_adb.png
+++ b/core/res/res/drawable-ldpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb.png b/core/res/res/drawable-mdpi/stat_sys_adb.png
index 730d96f..ebedfa3 100644
--- a/core/res/res/drawable-mdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-mdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_adb.png b/core/res/res/drawable-xhdpi/stat_sys_adb.png
index 01eb61d..92f8dd4 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_adb.png
Binary files differ
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 5f74e50..464430b 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -791,7 +791,7 @@
             <span class="en">App Install Location</span>
           </a></li>
       <li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">
-            <span class="en">Supported Media Formats</span>
+            <span class="en">Supported Media Formats <span class="new">updated</span></span>
           </a></li>
       <li><a href="<?cs var:toroot ?>guide/appendix/g-app-intents.html">
             <span class="en">Intents List: Google Apps</span>
diff --git a/docs/html/guide/practices/ui_guidelines/widget_design.jd b/docs/html/guide/practices/ui_guidelines/widget_design.jd
index f111394..de20e00 100644
--- a/docs/html/guide/practices/ui_guidelines/widget_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/widget_design.jd
@@ -1,4 +1,4 @@
-page.title=Widget Design Guidelines
+page.title=App Widget Design Guidelines
 parent.title=UI Guidelines
 parent.link=index.html
 @jd:body
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 8baf5ec..21b8c74 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -228,7 +228,7 @@
     void setComponentRole();
 
     void setAMRFormat(bool isWAMR, int32_t bitRate);
-    void setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate);
+    status_t setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate);
     void setG711Format(int32_t numChannels);
 
     status_t setVideoPortFormatType(
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 28dba13..e2bdde1 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -81,7 +81,7 @@
                         LTE_INT(flags) {
                             LTE_INT(italicStyle) {
                                 LTE_INT(scaleX) {
-                                    return strncmp16(text, rhs.text, len >> 1) < 0;
+                                    return memcmp(text, rhs.text, len) < 0;
                                 }
                             }
                         }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index e94a8d7..ccc8a18 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -625,7 +625,11 @@
         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
         CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
 
-        setAACFormat(numChannels, sampleRate, bitRate);
+        status_t err = setAACFormat(numChannels, sampleRate, bitRate);
+        if (err != OK) {
+            CODEC_LOGE("setAACFormat() failed (err = %d)", err);
+            return err;
+        }
     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
             || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
         // These are PCM-like formats with a fixed sample rate but
@@ -3358,8 +3362,10 @@
     }
 }
 
-void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
-    CHECK(numChannels == 1 || numChannels == 2);
+status_t OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
+    if (numChannels > 2)
+        LOGW("Number of channels: (%d) \n", numChannels);
+
     if (mIsEncoder) {
         //////////////// input port ////////////////////
         setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
@@ -3410,9 +3416,13 @@
         profile.nAACERtools = OMX_AUDIO_AACERNone;
         profile.eAACProfile = OMX_AUDIO_AACObjectLC;
         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
-        CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
-                &profile, sizeof(profile)), (status_t)OK);
+        err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
+                &profile, sizeof(profile));
 
+        if (err != OK) {
+            CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err);
+            return err;
+        }
     } else {
         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
         InitOMXParams(&profile);
@@ -3428,8 +3438,14 @@
 
         err = mOMX->setParameter(
                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
-        CHECK_EQ(err, (status_t)OK);
+
+        if (err != OK) {
+            CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err);
+            return err;
+        }
     }
+
+    return OK;
 }
 
 void OMXCodec::setG711Format(int32_t numChannels) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
index 8737595..91100ae 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
@@ -20,6 +20,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
 
 /**
  * Unit test class to test the set of valid and invalid states that
@@ -27,6 +28,8 @@
  */          
 public class MediaRecorderStopStateUnitTest extends AndroidTestCase implements MediaRecorderMethodUnderTest {
     private MediaRecorderStateUnitTestTemplate mTestTemplate = new MediaRecorderStateUnitTestTemplate();
+    private static final String TAG = "MediaRecorderStopStateUnitTest";
+    private static final int SLEEP_TIME_BEFORE_STOP = 1000;
 
     /**
      * 1. It is valid to call stop() in the following states:
@@ -51,6 +54,15 @@
     }
 
     public void invokeMethodUnderTest(MediaRecorder recorder) {
+        // Wait for some time before stopping the media recorder.
+        // This will fix the assertion caused by stopping it immediatedly
+        // after it is started
+        try {
+            Thread.sleep(SLEEP_TIME_BEFORE_STOP);
+        } catch(Exception e) {
+            Log.v(TAG, "sleep was interrupted and terminated prematurely");
+        }
+
         recorder.stop();
     }
 
diff --git a/packages/SystemUI/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml
index 25c0237..c1b0066 100644
--- a/packages/SystemUI/res/layout/status_bar_tracking.xml
+++ b/packages/SystemUI/res/layout/status_bar_tracking.xml
@@ -26,12 +26,21 @@
     android:paddingRight="0px"
     >
 
-    <View
-         android:layout_width="match_parent"
-         android:layout_height="wrap_content"
-         android:layout_weight="1"
-         android:background="@drawable/notification_tracking_bg"
-         />
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:background="@drawable/notification_tracking_bg"
+        >
+        <com.android.systemui.statusbar.phone.CarrierLabel
+            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:layout_gravity="bottom"
+            android:gravity="center"
+            android:paddingBottom="20dp"
+            />
+    </FrameLayout>
 
     <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index c83c470..a98d519 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -786,6 +786,7 @@
                         mWifiActivityIconId = R.drawable.stat_sys_wifi_inout;
                         break;
                     case WifiManager.DATA_ACTIVITY_NONE:
+                        mWifiActivityIconId = 0;
                         break;
                 }
             }
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 80ee28e..790b395 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -639,6 +639,8 @@
                         sizeof(struct input_event) * capacity);
                 if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
                     // Device was removed before INotify noticed.
+                    LOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d capacity: %d errno: %d)\n",
+                         device->fd, readSize, bufferSize, capacity, errno);
                     deviceChanged = true;
                     closeDeviceLocked(device);
                 } else if (readSize < 0) {
@@ -1254,6 +1256,7 @@
             if(event->mask & IN_CREATE) {
                 openDeviceLocked(devname);
             } else {
+                LOGI("Removing device '%s' due to inotify event\n", devname);
                 closeDeviceByPathLocked(devname);
             }
         }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index e30ce72..fe49cd2 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -5596,6 +5596,16 @@
     }
 
     private void dumpInternal(PrintWriter pw) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump Backup Manager service from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid()
+                    + " without permission "
+                    + android.Manifest.permission.DUMP);
+            return;
+        }
+
         synchronized (mQueueLock) {
             pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
                     + " / " + (!mProvisioned ? "not " : "") + "provisioned / "
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 146bc94..bc145b1 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1362,13 +1362,14 @@
             mInputShown = true;
             res = true;
         } else if (mHaveConnection && SystemClock.uptimeMillis()
-                < (mLastBindTime+TIME_TO_RECONNECT)) {
+                >= (mLastBindTime+TIME_TO_RECONNECT)) {
             // The client has asked to have the input method shown, but
             // we have been sitting here too long with a connection to the
             // service and no interface received, so let's disconnect/connect
             // to try to prod things along.
             EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, mCurMethodId,
                     SystemClock.uptimeMillis()-mLastBindTime,1);
+            Slog.w(TAG, "Force disconnect/connect to the IME in showCurrentInputLocked()");
             mContext.unbindService(this);
             mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE);
         }
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 6fcf399..aacaa6a 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -508,6 +508,28 @@
         }
     }
 
+    public void enableIpv6(String iface) throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        try {
+            mConnector.doCommand(String.format("interface ipv6 %s enable", iface));
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for enabling ipv6");
+        }
+    }
+
+    public void disableIpv6(String iface) throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        try {
+            mConnector.doCommand(String.format("interface ipv6 %s disable", iface));
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for disabling ipv6");
+        }
+    }
+
     public void addRoute(String interfaceName, RouteInfo route) {
         modifyRoute(interfaceName, ADD, route);
     }
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index c792b33..ef48b9e 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -238,7 +238,8 @@
                     }
                 } else if (scs.hashCode() == hashCode) {
                     if (DBG) {
-                        Slog.w(TAG, "Return subtype " + scs.hashCode());
+                        Slog.w(TAG, "Return subtype " + scs.hashCode() + ", input= " + locale
+                                + ", " + scs.getLocale());
                     }
                     return scs;
                 }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2942c28..d038d76 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1318,6 +1318,14 @@
 
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
+                    != PackageManager.PERMISSION_GRANTED) {
+                pw.println("Permission Denial: can't dump meminfo from from pid="
+                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                        + " without permission " + android.Manifest.permission.DUMP);
+                return;
+            }
+
             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args);
         }
     }
@@ -1330,6 +1338,14 @@
 
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
+                    != PackageManager.PERMISSION_GRANTED) {
+                pw.println("Permission Denial: can't dump gfxinfo from from pid="
+                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                        + " without permission " + android.Manifest.permission.DUMP);
+                return;
+            }
+
             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
         }
     }
@@ -1342,6 +1358,14 @@
 
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
+                    != PackageManager.PERMISSION_GRANTED) {
+                pw.println("Permission Denial: can't dump cpuinfo from from pid="
+                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                        + " without permission " + android.Manifest.permission.DUMP);
+                return;
+            }
+
             synchronized (mActivityManagerService.mProcessStatsThread) {
                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 226723f..b44dc8a2 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -21,6 +21,7 @@
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -457,6 +458,14 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump BatteryStats from from pid="
+                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                    + " without permission " + android.Manifest.permission.DUMP);
+            return;
+        }
+
         boolean isCheckin = false;
         boolean noOutput = false;
         if (args != null) {
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index 0d36d69..e810e3c 100644
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.FileUtils;
@@ -1034,6 +1035,14 @@
      * The data persisted to file is parsed and the stats are computed. 
      */
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump UsageStats from from pid="
+                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                    + " without permission " + android.Manifest.permission.DUMP);
+            return;
+        }
+
         final boolean isCheckinRequest = scanArgs(args, "--checkin");
         final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c");
         final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d");
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index d2bba0b..879e858 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -176,9 +176,9 @@
                 mList->numHwLayers, mList->flags);
         result.append(buffer);
         result.append(
-                "    type   |   hints  |   flags  | tr | blend |  format  |       source crop         |           frame           name \n"
-                "-----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
-        //      "  ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
+                "   type   |  handle  |   hints  |   flags  | tr | blend |  format  |       source crop         |           frame           name \n"
+                "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
+        //      " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
         for (size_t i=0 ; i<mList->numHwLayers ; i++) {
             const hwc_layer_t& l(mList->hwLayers[i]);
             const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
@@ -190,9 +190,9 @@
                 }
             }
             snprintf(buffer, SIZE,
-                    "  %8s | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
+                    " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
                     l.compositionType ? "OVERLAY" : "FB",
-                    l.hints, l.flags, l.transform, l.blending, format,
+                    intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
                     l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
                     l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
                     layer->getName().string());
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 178e7fd..413a2dc 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -368,6 +368,7 @@
     REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364,
     COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365,
     LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366,
+    PUBLIC_KEY_ATTR = 0x010103a6,
 };
 
 const char *getComponentName(String8 &pkgName, String8 &componentName) {
@@ -1021,6 +1022,15 @@
                     } else if (tag == "compatible-screens") {
                         printCompatibleScreens(tree);
                         depth--;
+                    } else if (tag == "package-verifier") {
+                        String8 name = getAttribute(tree, NAME_ATTR, &error);
+                        if (name != "" && error == "") {
+                            String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error);
+                            if (publicKey != "" && error == "") {
+                                printf("package-verifier: name='%s' publicKey='%s'\n",
+                                        name.string(), publicKey.string());
+                            }
+                        }
                     }
                 } else if (depth == 3 && withinApplication) {
                     withinActivity = false;
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
index 9732530..8868c65 100644
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
@@ -47,14 +47,14 @@
 
     @LayoutlibDelegate
     /** @hide special for when we are faking the screen size. */
-    /*package*/ static int getRawWidth(Display theDisplay) {
+    /*package*/ static int getRawWidthNative(Display theDisplay) {
         // same as real since we're not faking compatibility mode.
         return RenderAction.getCurrentContext().getIWindowManager().getMetrics().widthPixels;
     }
 
     @LayoutlibDelegate
     /** @hide special for when we are faking the screen size. */
-    /*package*/ static int getRawHeight(Display theDisplay) {
+    /*package*/ static int getRawHeightNative(Display theDisplay) {
         // same as real since we're not faking compatibility mode.
         return RenderAction.getCurrentContext().getIWindowManager().getMetrics().heightPixels;
     }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 41fc55d..d1522fb 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1560,8 +1560,9 @@
 
         try {
             mNwService.clearInterfaceAddresses(mInterfaceName);
+            mNwService.disableIpv6(mInterfaceName);
         } catch (Exception e) {
-            Log.e(TAG, "Failed to clear IP addresses on disconnect" + e);
+            Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
         }
 
         /* Reset data structures */
@@ -1841,6 +1842,21 @@
             mWifiP2pManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
             mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
 
+            /* IPv6 is disabled at boot time and is controlled by framework
+             * to be enabled only as long as we are connected to an access point
+             *
+             * This fixes issues, a few being:
+             * - IPv6 addresses and routes stick around after disconnection
+             * - When connected, the kernel is unaware and can fail to start IPv6 negotiation
+             * - The kernel sometimes starts autoconfiguration when 802.1x is not complete
+             */
+            try {
+                mNwService.disableIpv6(mInterfaceName);
+            } catch (RemoteException re) {
+                Log.e(TAG, "Failed to disable IPv6: " + re);
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "Failed to disable IPv6: " + e);
+            }
         }
     }
 
@@ -2734,7 +2750,15 @@
             if (DBG) Log.d(TAG, getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
-             if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+            try {
+                mNwService.enableIpv6(mInterfaceName);
+            } catch (RemoteException re) {
+                Log.e(TAG, "Failed to enable IPv6: " + re);
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "Failed to enable IPv6: " + e);
+            }
+
+            if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
                 //start DHCP
                 mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
                         mContext, WifiStateMachine.this, mInterfaceName);
@@ -2758,7 +2782,7 @@
                     sendMessage(CMD_STATIC_IP_FAILURE);
                 }
             }
-         }
+        }
       @Override
       public boolean processMessage(Message message) {
           if (DBG) Log.d(TAG, getName() + message.toString() + "\n");