am 453c275d: am 19744204: Merge "fix build break" into jb-mr1-dev

* commit '453c275dfaa97e00d3e19eb583467859da3e7b98':
  fix build break
diff --git a/Android.mk b/Android.mk
index be98487..c3126848 100644
--- a/Android.mk
+++ b/Android.mk
@@ -608,6 +608,36 @@
 
 droidcore: doc-comment-check-docs
 
+# ====  static html in the pdk ==================================
+include $(CLEAR_VARS)
+
+LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
+LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
+LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
+LOCAL_DROIDDOC_HTML_DIR:=../../vendor/pdk/data/google/docs
+LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
+LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
+
+LOCAL_MODULE := offline-pdk
+
+LOCAL_DROIDDOC_OPTIONS:=\
+		-hdf android.whichdoc offline \
+		-hdf android.whichmodule $(LOCAL_MODULE)
+
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-pdk
+
+include $(BUILD_DROIDDOC)
+
+static_doc_index_redirect := $(out_dir)/index.html
+$(static_doc_index_redirect): \
+	$(LOCAL_PATH)/docs/docs-documentation-redirect.html | $(ACP)
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(ACP) $< $@
+
+$(full_target): $(static_doc_index_redirect)
+$(full_target): $(framework_built)
+
 # ====  static html in the sdk ==================================
 include $(CLEAR_VARS)
 
diff --git a/api/current.txt b/api/current.txt
index 173dbe5..ec04cda 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23441,6 +23441,17 @@
     method public void set(T, V);
   }
 
+  public class PropertyValueModel extends android.util.ValueModel {
+    method public T get();
+    method public H getHost();
+    method public android.util.Property<H, T> getProperty();
+    method public java.lang.Class<T> getType();
+    method public static android.util.PropertyValueModel<H, T> of(H, android.util.Property<H, T>);
+    method public static android.util.PropertyValueModel<H, T> of(H, java.lang.Class<T>, java.lang.String);
+    method public static android.util.PropertyValueModel of(java.lang.Object, java.lang.String);
+    method public void set(T);
+  }
+
   public class SparseArray implements java.lang.Cloneable {
     ctor public SparseArray();
     ctor public SparseArray(int);
@@ -23589,6 +23600,14 @@
     field public int type;
   }
 
+  public abstract class ValueModel {
+    ctor protected ValueModel();
+    method public abstract T get();
+    method public abstract java.lang.Class<T> getType();
+    method public abstract void set(T);
+    field public static final android.util.ValueModel EMPTY;
+  }
+
   public class Xml {
     method public static android.util.AttributeSet asAttributeSet(org.xmlpull.v1.XmlPullParser);
     method public static android.util.Xml.Encoding findEncodingByName(java.lang.String) throws java.io.UnsupportedEncodingException;
@@ -25036,6 +25055,7 @@
     method public boolean isHorizontalScrollBarEnabled();
     method public boolean isHovered();
     method public boolean isInEditMode();
+    method public boolean isInLayout();
     method public boolean isInTouchMode();
     method public boolean isLayoutRequested();
     method public boolean isLayoutRtl();
@@ -25586,6 +25606,7 @@
     method public android.view.View getFocusedChild();
     method public android.view.animation.LayoutAnimationController getLayoutAnimation();
     method public android.view.animation.Animation.AnimationListener getLayoutAnimationListener();
+    method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getPersistentDrawingCache();
     method public int indexOfChild(android.view.View);
@@ -25633,6 +25654,7 @@
     method public void setDescendantFocusability(int);
     method public void setLayoutAnimation(android.view.animation.LayoutAnimationController);
     method public void setLayoutAnimationListener(android.view.animation.Animation.AnimationListener);
+    method public void setLayoutMode(int);
     method public void setLayoutTransition(android.animation.LayoutTransition);
     method public void setMotionEventSplittingEnabled(boolean);
     method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener);
@@ -25648,6 +25670,8 @@
     field public static final int FOCUS_AFTER_DESCENDANTS = 262144; // 0x40000
     field public static final int FOCUS_BEFORE_DESCENDANTS = 131072; // 0x20000
     field public static final int FOCUS_BLOCK_DESCENDANTS = 393216; // 0x60000
+    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
     field public static final int PERSISTENT_ALL_CACHES = 3; // 0x3
     field public static final int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
     field public static final int PERSISTENT_NO_CACHE = 0; // 0x0
@@ -27974,10 +27998,12 @@
     method public abstract void onSelectedDayChange(android.widget.CalendarView, int, int, int);
   }
 
-  public class CheckBox extends android.widget.CompoundButton {
+  public class CheckBox extends android.widget.CompoundButton implements android.widget.ValueEditor {
     ctor public CheckBox(android.content.Context);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
+    method public android.util.ValueModel<java.lang.Boolean> getValueModel();
+    method public void setValueModel(android.util.ValueModel<java.lang.Boolean>);
   }
 
   public abstract interface Checkable {
@@ -28150,14 +28176,16 @@
     method public void setSize(int, int);
   }
 
-  public class EditText extends android.widget.TextView {
+  public class EditText extends android.widget.TextView implements android.widget.ValueEditor {
     ctor public EditText(android.content.Context);
     ctor public EditText(android.content.Context, android.util.AttributeSet);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     method public void extendSelection(int);
+    method public android.util.ValueModel<java.lang.CharSequence> getValueModel();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
+    method public void setValueModel(android.util.ValueModel<java.lang.CharSequence>);
   }
 
   public abstract interface ExpandableListAdapter {
@@ -29183,11 +29211,13 @@
     method public abstract java.lang.Object[] getSections();
   }
 
-  public class SeekBar extends android.widget.AbsSeekBar {
+  public class SeekBar extends android.widget.AbsSeekBar implements android.widget.ValueEditor {
     ctor public SeekBar(android.content.Context);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
+    method public android.util.ValueModel<java.lang.Integer> getValueModel();
     method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
+    method public void setValueModel(android.util.ValueModel<java.lang.Integer>);
   }
 
   public static abstract interface SeekBar.OnSeekBarChangeListener {
@@ -29761,6 +29791,11 @@
     method public android.widget.TextView getText2();
   }
 
+  public abstract interface ValueEditor {
+    method public abstract android.util.ValueModel<T> getValueModel();
+    method public abstract void setValueModel(android.util.ValueModel<T>);
+  }
+
   public class VideoView extends android.view.SurfaceView implements android.widget.MediaController.MediaPlayerControl {
     ctor public VideoView(android.content.Context);
     ctor public VideoView(android.content.Context, android.util.AttributeSet);
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index f3c6566..0df2949 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -1824,7 +1824,7 @@
      * Returns an intent to an {@link Activity} that prompts the user to choose from a list of
      * accounts.
      * The caller will then typically start the activity by calling
-     * <code>startActivityWithResult(intent, ...);</code>.
+     * <code>startActivityForResult(intent, ...);</code>.
      * <p>
      * On success the activity returns a Bundle with the account name and type specified using
      * keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 5dc206f..0ec7e84 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -17,6 +17,7 @@
 package android.text.style;
 
 import android.content.Context;
+import android.content.Intent;
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.os.Parcel;
@@ -26,6 +27,7 @@
 import android.text.TextPaint;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.TextView;
 
 import java.util.Arrays;
@@ -45,6 +47,8 @@
  */
 public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
 
+    private static final String TAG = "SuggestionSpan";
+
     /**
      * Sets this flag if the suggestions should be easily accessible with few interactions.
      * This flag should be set for every suggestions that the user is likely to use.
@@ -82,6 +86,7 @@
     private final String[] mSuggestions;
     private final String mLocaleString;
     private final String mNotificationTargetClassName;
+    private final String mNotificationTargetPackageName;
     private final int mHashCode;
 
     private float mEasyCorrectUnderlineThickness;
@@ -134,6 +139,12 @@
             mLocaleString = "";
         }
 
+        if (context != null) {
+            mNotificationTargetPackageName = context.getPackageName();
+        } else {
+            mNotificationTargetPackageName = null;
+        }
+
         if (notificationTargetClass != null) {
             mNotificationTargetClassName = notificationTargetClass.getCanonicalName();
         } else {
@@ -185,6 +196,7 @@
         mFlags = src.readInt();
         mLocaleString = src.readString();
         mNotificationTargetClassName = src.readString();
+        mNotificationTargetPackageName = src.readString();
         mHashCode = src.readInt();
         mEasyCorrectUnderlineColor = src.readInt();
         mEasyCorrectUnderlineThickness = src.readFloat();
@@ -240,6 +252,7 @@
         dest.writeInt(mFlags);
         dest.writeString(mLocaleString);
         dest.writeString(mNotificationTargetClassName);
+        dest.writeString(mNotificationTargetPackageName);
         dest.writeInt(mHashCode);
         dest.writeInt(mEasyCorrectUnderlineColor);
         dest.writeFloat(mEasyCorrectUnderlineThickness);
@@ -325,4 +338,40 @@
         }
         return 0;
     }
+
+    /**
+     * Notifies a suggestion selection.
+     *
+     * @hide
+     */
+    public void notifySelection(Context context, String original, int index) {
+        final Intent intent = new Intent();
+
+        if (context == null || mNotificationTargetClassName == null) {
+            return;
+        }
+        // Ensures that only a class in the original IME package will receive the
+        // notification.
+        if (mSuggestions == null || index < 0 || index >= mSuggestions.length) {
+            Log.w(TAG, "Unable to notify the suggestion as the index is out of range index=" + index
+                    + " length=" + mSuggestions.length);
+            return;
+        }
+
+        // The package name is not mandatory (legacy from JB), and if the package name
+        // is missing, we try to notify the suggestion through the input method manager.
+        if (mNotificationTargetPackageName != null) {
+            intent.setClassName(mNotificationTargetPackageName, mNotificationTargetClassName);
+            intent.setAction(SuggestionSpan.ACTION_SUGGESTION_PICKED);
+            intent.putExtra(SuggestionSpan.SUGGESTION_SPAN_PICKED_BEFORE, original);
+            intent.putExtra(SuggestionSpan.SUGGESTION_SPAN_PICKED_AFTER, mSuggestions[index]);
+            intent.putExtra(SuggestionSpan.SUGGESTION_SPAN_PICKED_HASHCODE, hashCode());
+            context.sendBroadcast(intent);
+        } else {
+            InputMethodManager imm = InputMethodManager.peekInstance();
+            if (imm != null) {
+                imm.notifySuggestionPicked(this, original, index);
+            }
+        }
+    }
 }
diff --git a/core/java/android/util/PropertyValueModel.java b/core/java/android/util/PropertyValueModel.java
new file mode 100755
index 0000000..eb9c47d
--- /dev/null
+++ b/core/java/android/util/PropertyValueModel.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ * A value model for a {@link Property property} of a host object. This class can be used for
+ * both reflective and non-reflective property implementations.
+ *
+ * @param <H> the host type, where the host is the object that holds this property
+ * @param <T> the value type
+ *
+ * @see Property
+ * @see ValueModel
+ */
+public class PropertyValueModel<H, T> extends ValueModel<T> {
+    private final H mHost;
+    private final Property<H, T> mProperty;
+
+    private PropertyValueModel(H host, Property<H, T> property) {
+        mProperty = property;
+        mHost = host;
+    }
+
+    /**
+     * Returns the host.
+     *
+     * @return the host
+     */
+    public H getHost() {
+        return mHost;
+    }
+
+    /**
+     * Returns the property.
+     *
+     * @return the property
+     */
+    public Property<H, T> getProperty() {
+        return mProperty;
+    }
+
+    @Override
+    public Class<T> getType() {
+        return mProperty.getType();
+    }
+
+    @Override
+    public T get() {
+        return mProperty.get(mHost);
+    }
+
+    @Override
+    public void set(T value) {
+        mProperty.set(mHost, value);
+    }
+
+    /**
+     * Return an appropriate PropertyValueModel for this host and property.
+     *
+     * @param host the host
+     * @param property the property
+     * @return the value model
+     */
+    public static <H, T> PropertyValueModel<H, T> of(H host, Property<H, T> property) {
+        return new PropertyValueModel<H, T>(host, property);
+    }
+
+    /**
+     * Return a PropertyValueModel for this {@code host} and a
+     * reflective property, constructed from this {@code propertyType} and {@code propertyName}.
+     *
+     * @param host
+     * @param propertyType the property type
+     * @param propertyName the property name
+     * @return a value model with this host and a reflective property with this type and name
+     *
+     * @see Property#of
+     */
+    public static <H, T> PropertyValueModel<H, T> of(H host, Class<T> propertyType,
+            String propertyName) {
+        return of(host, Property.of((Class<H>) host.getClass(), propertyType, propertyName));
+    }
+
+    private static Class getNullaryMethodReturnType(Class c, String name) {
+        try {
+            return c.getMethod(name).getReturnType();
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    private static Class getFieldType(Class c, String name) {
+        try {
+            return c.getField(name).getType();
+        } catch (NoSuchFieldException e) {
+            return null;
+        }
+    }
+
+    private static String capitalize(String name) {
+        if (name.isEmpty()) {
+            return name;
+        }
+        return Character.toUpperCase(name.charAt(0)) + name.substring(1);
+    }
+
+    /**
+     * Return a PropertyValueModel for this {@code host} and and {@code propertyName}.
+     *
+     * @param host the host
+     * @param propertyName the property name
+     * @return a value model with this host and a reflective property with this name
+     */
+    public static PropertyValueModel of(Object host, String propertyName) {
+        Class clazz = host.getClass();
+        String suffix = capitalize(propertyName);
+        Class propertyType = getNullaryMethodReturnType(clazz, "get" + suffix);
+        if (propertyType == null) {
+            propertyType = getNullaryMethodReturnType(clazz, "is" + suffix);
+        } 
+        if (propertyType == null) {
+            propertyType = getFieldType(clazz, propertyName); 
+        }         
+        if (propertyType == null) {
+            throw new NoSuchPropertyException(propertyName); 
+        }
+        return of(host, propertyType, propertyName);
+    }
+}
diff --git a/core/java/android/util/ValueModel.java b/core/java/android/util/ValueModel.java
new file mode 100755
index 0000000..4789682
--- /dev/null
+++ b/core/java/android/util/ValueModel.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ * A ValueModel is an abstraction for a 'slot' or place in memory in which a value
+ * may be stored and retrieved. A common implementation of ValueModel is a regular property of
+ * an object, whose value may be retrieved by calling the appropriate <em>getter</em>
+ * method and set by calling the corresponding <em>setter</em> method.
+ *
+ * @param <T> the value type
+ *
+ * @see PropertyValueModel
+ */
+public abstract class ValueModel<T> {
+    /**
+     * The empty model should be used in place of {@code null} to indicate that a
+     * model has not been set. The empty model has no value and does nothing when it is set.
+     */
+    public static final ValueModel EMPTY = new ValueModel() {
+        @Override
+        public Class getType() {
+            return Object.class;
+        }
+
+        @Override
+        public Object get() {
+            return null;
+        }
+
+        @Override
+        public void set(Object value) {
+
+        }
+    };
+
+    protected ValueModel() {
+    }
+
+    /**
+     * Returns the type of this property.
+     *
+     * @return the property type
+     */
+    public abstract Class<T> getType();
+
+    /**
+     * Returns the value of this property.
+     *
+     * @return the property value
+     */
+    public abstract T get();
+
+    /**
+     * Sets the value of this property.
+     *
+     * @param value the new value for this property
+     */
+    public abstract void set(T value);
+}
\ No newline at end of file
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 12eb800..d1e7ff5 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13926,6 +13926,25 @@
     }
 
     /**
+     * Return true if o is a ViewGroup that is laying out using optical bounds.
+     * @hide
+     */
+    public static boolean isLayoutModeOptical(Object o) {
+        return o instanceof ViewGroup && ((ViewGroup) o).isLayoutModeOptical();
+    }
+
+    private boolean setOpticalFrame(int left, int top, int right, int bottom) {
+        Insets parentInsets = mParent instanceof View ?
+                ((View) mParent).getOpticalInsets() : Insets.NONE;
+        Insets childInsets = getOpticalInsets();
+        return setFrame(
+                left   + parentInsets.left - childInsets.left,
+                top    + parentInsets.top  - childInsets.top,
+                right  + parentInsets.left + childInsets.right,
+                bottom + parentInsets.top  + childInsets.bottom);
+    }
+
+    /**
      * Assign a size and position to a view and all of its
      * descendants
      *
@@ -13951,7 +13970,8 @@
         int oldT = mTop;
         int oldB = mBottom;
         int oldR = mRight;
-        boolean changed = setFrame(l, t, r, b);
+        boolean changed = isLayoutModeOptical(mParent) ?
+                setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
         if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
             onLayout(changed, l, t, r, b);
             mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
@@ -14762,21 +14782,18 @@
         return (mUserPaddingStart != UNDEFINED_PADDING || mUserPaddingEnd != UNDEFINED_PADDING);
     }
 
-    /**
-     * @hide
-     */
-    public Insets getOpticalInsets() {
-        if (mLayoutInsets == null) {
-            mLayoutInsets = (mBackground == null) ? Insets.NONE : mBackground.getLayoutInsets();
-        }
-        return mLayoutInsets;
+    Insets computeOpticalInsets() {
+        return (mBackground == null) ? Insets.NONE : mBackground.getOpticalInsets();
     }
 
     /**
      * @hide
      */
-    public void setLayoutInsets(Insets layoutInsets) {
-        mLayoutInsets = layoutInsets;
+    public Insets getOpticalInsets() {
+        if (mLayoutInsets == null) {
+            mLayoutInsets = computeOpticalInsets();
+        }
+        return mLayoutInsets;
     }
 
     /**
@@ -15386,11 +15403,34 @@
     }
 
     /**
+     * Returns whether the view hierarchy is currently undergoing a layout pass. This
+     * information is useful to avoid situations such as calling {@link #requestLayout()} during
+     * a layout pass.
+     *
+     * @return whether the view hierarchy is currently undergoing a layout pass
+     */
+    public boolean isInLayout() {
+        ViewRootImpl viewRoot = getViewRootImpl();
+        return (viewRoot != null && viewRoot.isInLayout());
+    }
+
+    /**
      * Call this when something has changed which has invalidated the
      * layout of this view. This will schedule a layout pass of the view
-     * tree.
+     * tree. This should not be called while the view hierarchy is currently in a layout
+     * pass ({@link #isInLayout()}. If layout is happening, the request may be honored at the
+     * end of the current layout pass (and then layout will run again) or after the current
+     * frame is drawn and the next layout occurs.
+     *
+     * <p>Subclasses which override this method should call the superclass method to
+     * handle possible request-during-layout errors correctly.</p>
      */
     public void requestLayout() {
+        ViewRootImpl viewRoot = getViewRootImpl();
+        if (viewRoot != null && viewRoot.isInLayout()) {
+            viewRoot.requestLayoutDuringLayout(this);
+            return;
+        }
         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
         mPrivateFlags |= PFLAG_INVALIDATED;
 
@@ -15430,6 +15470,14 @@
      * @see #onMeasure(int, int)
      */
     public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
+        boolean optical = isLayoutModeOptical(this);
+        if (optical != isLayoutModeOptical(mParent)) {
+            Insets insets = getOpticalInsets();
+            int oWidth  = insets.left + insets.right;
+            int oHeight = insets.top  + insets.bottom;
+            widthMeasureSpec  = MeasureSpec.adjust(widthMeasureSpec,  optical ? -oWidth  : oWidth);
+            heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight);
+        }
         if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
                 widthMeasureSpec != mOldWidthMeasureSpec ||
                 heightMeasureSpec != mOldHeightMeasureSpec) {
@@ -15521,6 +15569,15 @@
      * {@link #MEASURED_STATE_TOO_SMALL}.
      */
     protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
+        boolean optical = isLayoutModeOptical(this);
+        if (optical != isLayoutModeOptical(mParent)) {
+            Insets insets = getOpticalInsets();
+            int opticalWidth  = insets.left + insets.right;
+            int opticalHeight = insets.top  + insets.bottom;
+
+            measuredWidth  += optical ? opticalWidth  : -opticalWidth;
+            measuredHeight += optical ? opticalHeight : -opticalHeight;
+        }
         mMeasuredWidth = measuredWidth;
         mMeasuredHeight = measuredHeight;
 
@@ -17193,6 +17250,10 @@
             return (measureSpec & ~MODE_MASK);
         }
 
+        static int adjust(int measureSpec, int delta) {
+            return makeMeasureSpec(getSize(measureSpec + delta), getMode(measureSpec));
+        }
+
         /**
          * Returns a String representation of the specified measure
          * specification.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 41890d6..d8ed881 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -23,9 +23,11 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.DashPathEffect;
 import android.graphics.Insets;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.PathEffect;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -83,6 +85,8 @@
     private static final String TAG = "ViewGroup";
 
     private static final boolean DBG = false;
+    /** @hide */
+    public static boolean DEBUG_DRAW = false;
 
     /**
      * Views which have been hidden or removed which need to be animated on
@@ -180,10 +184,10 @@
     })
     protected int mGroupFlags;
 
-    /*
-     * The layout mode: either {@link #CLIP_BOUNDS} or {@link #OPTICAL_BOUNDS}
+    /**
+     * Either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
      */
-    private int mLayoutMode = CLIP_BOUNDS;
+    private int mLayoutMode = DEFAULT_LAYOUT_MODE;
 
     /**
      * NOTE: If you change the flags below make sure to reflect the changes
@@ -356,20 +360,19 @@
      * This constant is a {@link #setLayoutMode(int) layoutMode}.
      * Clip bounds are the raw values of {@link #getLeft() left}, {@link #getTop() top},
      * {@link #getRight() right} and {@link #getBottom() bottom}.
-     *
-     * @hide
      */
-    public static final int CLIP_BOUNDS = 0;
+    public static final int LAYOUT_MODE_CLIP_BOUNDS = 0;
 
     /**
      * This constant is a {@link #setLayoutMode(int) layoutMode}.
      * Optical bounds describe where a widget appears to be. They sit inside the clip
      * bounds which need to cover a larger area to allow other effects,
      * such as shadows and glows, to be drawn.
-     *
-     * @hide
      */
-    public static final int OPTICAL_BOUNDS = 1;
+    public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1;
+
+    /** @hide */
+    public static int DEFAULT_LAYOUT_MODE = LAYOUT_MODE_CLIP_BOUNDS;
 
     /**
      * We clip to padding when FLAG_CLIP_TO_PADDING and FLAG_PADDING_NOT_NULL
@@ -434,7 +437,7 @@
     }
 
     private boolean debugDraw() {
-        return mAttachInfo != null && mAttachInfo.mDebugLayout;
+        return DEBUG_DRAW || mAttachInfo != null && mAttachInfo.mDebugLayout;
     }
 
     private void initViewGroup() {
@@ -504,6 +507,9 @@
                         setLayoutTransition(new LayoutTransition());
                     }
                     break;
+                case R.styleable.ViewGroup_layoutMode:
+                    setLayoutMode(a.getInt(attr, DEFAULT_LAYOUT_MODE));
+                    break;
             }
         }
 
@@ -2420,7 +2426,7 @@
         for (int i = 0; i < count; i++) {
             final View child = children[i];
             child.dispatchAttachedToWindow(info,
-                    visibility | (child.mViewFlags&VISIBILITY_MASK));
+                    visibility | (child.mViewFlags & VISIBILITY_MASK));
         }
     }
 
@@ -2682,20 +2688,89 @@
         return b;
     }
 
-    private static void drawRect(Canvas canvas, int x1, int y1, int x2, int y2, int color) {
-        Paint paint = getDebugPaint();
-        paint.setColor(color);
+    /** Return true if this ViewGroup is laying out using optical bounds. */
+    boolean isLayoutModeOptical() {
+        return mLayoutMode == LAYOUT_MODE_OPTICAL_BOUNDS;
+    }
 
-        canvas.drawLines(getDebugLines(x1, y1, x2, y2), paint);
+    Insets computeOpticalInsets() {
+        if (isLayoutModeOptical()) {
+            int left = 0;
+            int top = 0;
+            int right = 0;
+            int bottom = 0;
+            for (int i = 0; i < mChildrenCount; i++) {
+                View child = getChildAt(i);
+                if (child.getVisibility() == VISIBLE) {
+                    Insets insets = child.getOpticalInsets();
+                    left =   Math.max(left,   insets.left);
+                    top =    Math.max(top,    insets.top);
+                    right =  Math.max(right,  insets.right);
+                    bottom = Math.max(bottom, insets.bottom);
+                }
+            }
+            return Insets.of(left, top, right, bottom);
+        } else {
+            return Insets.NONE;
+        }
+    }
+
+    private static void fillRect(Canvas canvas, Paint paint, int x1, int y1, int x2, int y2) {
+        if (x1 != x2 && y1 != y2) {
+            if (x1 > x2) {
+                int tmp = x1; x1 = x2; x2 = tmp;
+            }
+            if (y1 > y2) {
+                int tmp = y1; y1 = y2; y2 = tmp;
+            }
+            canvas.drawRect(x1, y1, x2, y2, paint);
+        }
+    }
+
+    private static int sign(int x) {
+        return (x >= 0) ? 1 : -1;
+    }
+
+    private static void drawCorner(Canvas c, Paint paint, int x1, int y1, int dx, int dy, int lw) {
+        fillRect(c, paint, x1, y1, x1 + dx, y1 + lw * sign(dy));
+        fillRect(c, paint, x1, y1, x1 + lw * sign(dx), y1 + dy);
+    }
+
+    private int dipsToPixels(int dips) {
+        float scale = getContext().getResources().getDisplayMetrics().density;
+        return (int) (dips * scale + 0.5f);
+    }
+
+    private void drawRectCorners(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint,
+                                 int lineLength, int lineWidth) {
+        drawCorner(canvas, paint, x1, y1, lineLength, lineLength, lineWidth);
+        drawCorner(canvas, paint, x1, y2, lineLength, -lineLength, lineWidth);
+        drawCorner(canvas, paint, x2, y1, -lineLength, lineLength, lineWidth);
+        drawCorner(canvas, paint, x2, y2, -lineLength, -lineLength, lineWidth);
+    }
+
+    private static void fillDifference(Canvas canvas,
+            int x2, int y2, int x3, int y3,
+            int dx1, int dy1, int dx2, int dy2, Paint paint) {
+        int x1 = x2 - dx1;
+        int y1 = y2 - dy1;
+
+        int x4 = x3 + dx2;
+        int y4 = y3 + dy2;
+
+        fillRect(canvas, paint, x1, y1, x4, y2);
+        fillRect(canvas, paint, x1, y2, x2, y3);
+        fillRect(canvas, paint, x3, y2, x4, y3);
+        fillRect(canvas, paint, x1, y3, x4, y4);
     }
 
     /**
      * @hide
      */
-    protected void onDebugDrawMargins(Canvas canvas) {
+    protected void onDebugDrawMargins(Canvas canvas, Paint paint) {
         for (int i = 0; i < getChildCount(); i++) {
             View c = getChildAt(i);
-            c.getLayoutParams().onDebugDraw(c, canvas);
+            c.getLayoutParams().onDebugDraw(c, canvas, paint);
         }
     }
 
@@ -2703,26 +2778,49 @@
      * @hide
      */
     protected void onDebugDraw(Canvas canvas) {
+        Paint paint = getDebugPaint();
+
         // Draw optical bounds
-        if (getLayoutMode() == OPTICAL_BOUNDS) {
+        {
+            paint.setColor(Color.RED);
+            paint.setStyle(Paint.Style.STROKE);
+            PathEffect pathEffect = paint.getPathEffect();
+            int len = dipsToPixels(4);
+            paint.setPathEffect(new DashPathEffect(new float[]{len, len}, 0));
+
             for (int i = 0; i < getChildCount(); i++) {
                 View c = getChildAt(i);
                 Insets insets = c.getOpticalInsets();
-                drawRect(canvas,
-                        c.getLeft() + insets.left,
-                        c.getTop() + insets.top,
-                        c.getRight() - insets.right,
-                        c.getBottom() - insets.bottom, Color.RED);
+
+                drawRect(canvas, paint,
+                        c.getLeft()   + insets.left,
+                        c.getTop()    + insets.top,
+                        c.getRight()  - insets.right  - 1,
+                        c.getBottom() - insets.bottom - 1);
             }
+            paint.setPathEffect(pathEffect);
         }
 
         // Draw margins
-        onDebugDrawMargins(canvas);
+        {
+            paint.setColor(Color.argb(63, 255, 0, 255));
+            paint.setStyle(Paint.Style.FILL);
 
-        // Draw bounds
-        for (int i = 0; i < getChildCount(); i++) {
-            View c = getChildAt(i);
-            drawRect(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(), Color.BLUE);
+            onDebugDrawMargins(canvas, paint);
+        }
+
+        // Draw clip bounds
+        {
+            paint.setColor(Color.rgb(63, 127, 255));
+            paint.setStyle(Paint.Style.FILL);
+
+            int lineLength = dipsToPixels(8);
+            int lineWidth = dipsToPixels(1);
+            for (int i = 0; i < getChildCount(); i++) {
+                View c = getChildAt(i);
+                drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(),
+                        paint, lineLength, lineWidth);
+            }
         }
     }
 
@@ -4608,13 +4706,11 @@
 
     /**
      * Returns the basis of alignment during layout operations on this view group:
-     * either {@link #CLIP_BOUNDS} or {@link #OPTICAL_BOUNDS}.
+     * either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
      *
      * @return the layout mode to use during layout operations
      *
      * @see #setLayoutMode(int)
-     *
-     * @hide
      */
     public int getLayoutMode() {
         return mLayoutMode;
@@ -4622,15 +4718,14 @@
 
     /**
      * Sets the basis of alignment during the layout of this view group.
-     * Valid values are either {@link #CLIP_BOUNDS} or {@link #OPTICAL_BOUNDS}.
+     * Valid values are either {@link #LAYOUT_MODE_CLIP_BOUNDS} or
+     * {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
      * <p>
-     * The default is {@link #CLIP_BOUNDS}.
+     * The default is {@link #LAYOUT_MODE_CLIP_BOUNDS}.
      *
      * @param layoutMode the layout mode to use during layout operations
      *
      * @see #getLayoutMode()
-     *
-     * @hide
      */
     public void setLayoutMode(int layoutMode) {
         if (mLayoutMode != layoutMode) {
@@ -5556,7 +5651,7 @@
          *
          * @hide
          */
-        public void onDebugDraw(View view, Canvas canvas) {
+        public void onDebugDraw(View view, Canvas canvas, Paint paint) {
         }
 
         /**
@@ -5901,12 +5996,19 @@
          * @hide
          */
         @Override
-        public void onDebugDraw(View view, Canvas canvas) {
-            drawRect(canvas,
-                    view.getLeft() - leftMargin,
-                    view.getTop() - topMargin,
-                    view.getRight() + rightMargin,
-                    view.getBottom() + bottomMargin, Color.MAGENTA);
+        public void onDebugDraw(View view, Canvas canvas, Paint paint) {
+            Insets oi = isLayoutModeOptical(view.mParent) ? view.getOpticalInsets() : Insets.NONE;
+
+            fillDifference(canvas,
+                    view.getLeft()   + oi.left,
+                    view.getTop()    + oi.top,
+                    view.getRight()  - oi.right,
+                    view.getBottom() - oi.bottom,
+                    leftMargin,
+                    topMargin,
+                    rightMargin,
+                    bottomMargin,
+                    paint);
         }
     }
 
@@ -6240,14 +6342,11 @@
         return sDebugPaint;
     }
 
-    private static float[] getDebugLines(int x1, int y1, int x2, int y2) {
+    private void drawRect(Canvas canvas, Paint paint, int x1, int y1, int x2, int y2) {
         if (sDebugLines== null) {
             sDebugLines = new float[16];
         }
 
-        x2--;
-        y2--;
-
         sDebugLines[0] = x1;
         sDebugLines[1] = y1;
         sDebugLines[2] = x2;
@@ -6256,18 +6355,18 @@
         sDebugLines[4] = x2;
         sDebugLines[5] = y1;
         sDebugLines[6] = x2;
-        sDebugLines[7] = y2 + 1;
+        sDebugLines[7] = y2;
 
-        sDebugLines[8] = x2 + 1;
+        sDebugLines[8] = x2;
         sDebugLines[9] = y2;
         sDebugLines[10] = x1;
         sDebugLines[11] = y2;
 
-        sDebugLines[12]  = x1;
-        sDebugLines[13]  = y2;
+        sDebugLines[12] = x1;
+        sDebugLines[13] = y2;
         sDebugLines[14] = x1;
         sDebugLines[15] = y1;
 
-        return sDebugLines;
+        canvas.drawLines(sDebugLines, paint);
     }
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6db40ba..49dea53 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -316,6 +316,11 @@
     private final int mDensity;
     private final int mNoncompatDensity;
 
+    private boolean mInLayout = false;
+    ArrayList<View> mLayoutRequesters = new ArrayList<View>();
+    boolean mHandlingLayoutInLayoutRequest = false;
+
+
     /**
      * Consistency verifier for debugging purposes.
      */
@@ -1866,9 +1871,49 @@
         }
     }
 
+    /**
+     * Called by {@link android.view.View#isInLayout()} to determine whether the view hierarchy
+     * is currently undergoing a layout pass.
+     *
+     * @return whether the view hierarchy is currently undergoing a layout pass
+     */
+    boolean isInLayout() {
+        return mInLayout;
+    }
+
+    /**
+     * Called by {@link android.view.View#requestLayout()} if the view hiearchy is currently
+     * undergoing a layout pass. requestLayout() should not be called during layout, but if it
+     * is called anyway, we handle the situation here rather than leave the hierarchy in an
+     * indeterminate state. The solution is to queue up all requests during layout, apply those
+     * requests as soon as layout is complete, and then run layout once more immediately. If
+     * more requestLayout() calls are received during that second layout pass, we post those
+     * requests to the next frame, to avoid possible infinite loops.
+     *
+     * @param view the view that requested the layout.
+     */
+    void requestLayoutDuringLayout(final View view) {
+        if (!mHandlingLayoutInLayoutRequest) {
+            if (!mLayoutRequesters.contains(view)) {
+                Log.w("View", "requestLayout() called by " + view + " during layout pass");
+                mLayoutRequesters.add(view);
+            }
+        } else {
+            Log.w("View", "requestLayout() called by " + view + " during second layout pass: " +
+                    "posting to next frame");
+            view.post(new Runnable() {
+                @Override
+                public void run() {
+                    view.requestLayout();
+                }
+            });
+        }
+    }
+
     private void performLayout() {
         mLayoutRequested = false;
         mScrollMayChange = true;
+        mInLayout = true;
 
         final View host = mView;
         if (DEBUG_ORIENTATION || DEBUG_LAYOUT) {
@@ -1879,9 +1924,22 @@
         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "layout");
         try {
             host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
+            int numViewsRequestingLayout = mLayoutRequesters.size();
+            if (numViewsRequestingLayout > 0) {
+                // requestLayout() was called during layout: unusual, but try to handle correctly
+                mHandlingLayoutInLayoutRequest = true;
+                for (int i = 0; i < numViewsRequestingLayout; ++i) {
+                    mLayoutRequesters.get(i).requestLayout();
+                }
+                // Now run layout one more time
+                host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
+                mHandlingLayoutInLayoutRequest = false;
+                mLayoutRequesters.clear();
+            }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_VIEW);
         }
+        mInLayout = false;
     }
 
     public void requestTransparentRegion(View child) {
diff --git a/core/java/android/webkit/EventLogTags.logtags b/core/java/android/webkit/EventLogTags.logtags
index 082a437..b0b5493 100644
--- a/core/java/android/webkit/EventLogTags.logtags
+++ b/core/java/android/webkit/EventLogTags.logtags
@@ -8,4 +8,3 @@
 # 70103- used by the browser app itself
 
 70150 browser_snap_center
-70151 browser_text_size_change (oldSize|1|5), (newSize|1|5)
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index aa68904..7f6fa1a 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -89,6 +89,14 @@
         ZoomDensity(int size) {
             value = size;
         }
+
+        /**
+         * @hide Only for use by WebViewProvider implementations
+         */
+        public int getValue() {
+            return value;
+        }
+
         int value;
     }
 
@@ -936,6 +944,9 @@
      * access to content from other file scheme URLs. See
      * {@link #setAllowFileAccessFromFileURLs}. To enable the most restrictive,
      * and therefore secure policy, this setting should be disabled.
+     * Note that this setting affects only JavaScript access to file scheme
+     * resources. Other access to such resources, for example, from image HTML
+     * elements, is unaffected.
      * <p>
      * The default value is true for API level
      * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
@@ -953,6 +964,9 @@
      * enable the most restrictive, and therefore secure policy, this setting
      * should be disabled. Note that the value of this setting is ignored if
      * the value of {@link #getAllowUniversalAccessFromFileURLs} is true.
+     * Note too, that this setting affects only JavaScript access to file scheme
+     * resources. Other access to such resources, for example, from image HTML
+     * elements, is unaffected.
      * <p>
      * The default value is true for API level
      * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
@@ -1121,9 +1135,22 @@
     }
 
     /**
-     * Sets whether Geolocation is enabled. The default is true. See also
-     * {@link #setGeolocationDatabasePath} for how to correctly set up
-     * Geolocation.
+     * Sets whether Geolocation is enabled. The default is true.
+     * <p>
+     * Please note that in order for the Geolocation API to be usable
+     * by a page in the WebView, the following requirements must be met:
+     * <ul>
+     *   <li>an application must have permission to access the device location,
+     *   see {@link android.Manifest.permission#ACCESS_COARSE_LOCATION},
+     *   {@link android.Manifest.permission#ACCESS_FINE_LOCATION};
+     *   <li>an application must provide an implementation of the
+     *   {@link WebChromeClient#onGeolocationPermissionsShowPrompt} callback
+     *   to receive notifications that a page is requesting access to location
+     *   via the JavaScript Geolocation API.
+     * </ul>
+     * <p>
+     * As an option, it is possible to store previous locations and web origin
+     * permissions in a database. See {@link #setGeolocationDatabasePath}.
      *
      * @param flag whether Geolocation should be enabled
      */
@@ -1295,7 +1322,7 @@
      * and content is re-validated as needed. When navigating back, content is
      * not revalidated, instead the content is just retrieved from the cache.
      * This method allows the client to override this behavior by specifying
-     * one of {@link #LOAD_DEFAULT}, {@link #LOAD_NORMAL},
+     * one of {@link #LOAD_DEFAULT},
      * {@link #LOAD_CACHE_ELSE_NETWORK}, {@link #LOAD_NO_CACHE} or
      * {@link #LOAD_CACHE_ONLY}. The default value is {@link #LOAD_DEFAULT}.
      *
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 1bbe7bb..e3d095f 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -647,10 +647,6 @@
     @Override
     public synchronized void setTextZoom(int textZoom) {
         if (mTextSize != textZoom) {
-            if (WebViewClassic.mLogEvent) {
-                EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE,
-                        mTextSize, textZoom);
-            }
             mTextSize = textZoom;
             postSync();
         }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4202a7f..58ecd24 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2138,4 +2138,10 @@
         super.setLayerType(layerType, paint);
         mProvider.getViewDelegate().setLayerType(layerType, paint);
     }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        mProvider.getViewDelegate().preDispatchDraw(canvas);
+        super.dispatchDraw(canvas);
+    }
 }
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 1c47615..6205380 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -8544,6 +8544,11 @@
         updateHwAccelerated();
     }
 
+    @Override
+    public void preDispatchDraw(Canvas canvas) {
+        // no-op for WebViewClassic.
+    }
+
     private void updateHwAccelerated() {
         if (mNativeClass == 0) {
             return;
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index c9f9fbd..1020634 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -341,6 +341,8 @@
         public void setBackgroundColor(int color);
 
         public void setLayerType(int layerType, Paint paint);
+
+        public void preDispatchDraw(Canvas canvas);
     }
 
     interface ScrollDelegate {
diff --git a/core/java/android/widget/CheckBox.java b/core/java/android/widget/CheckBox.java
index f1804f8..41ab5f2 100644
--- a/core/java/android/widget/CheckBox.java
+++ b/core/java/android/widget/CheckBox.java
@@ -20,6 +20,7 @@
 import android.util.AttributeSet;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.util.ValueModel;
 
 
 /**
@@ -55,7 +56,9 @@
  * {@link android.R.styleable#View View Attributes}
  * </p>
  */
-public class CheckBox extends CompoundButton {
+public class CheckBox extends CompoundButton implements ValueEditor<Boolean> {
+    private ValueModel<Boolean> mValueModel = ValueModel.EMPTY;
+
     public CheckBox(Context context) {
         this(context, null);
     }
@@ -79,4 +82,22 @@
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(CheckBox.class.getName());
     }
+
+    @Override
+    public ValueModel<Boolean> getValueModel() {
+        return mValueModel;
+    }
+
+    @Override
+    public void setValueModel(ValueModel<Boolean> valueModel) {
+        mValueModel = valueModel;
+        setChecked(mValueModel.get());
+    }
+
+    @Override
+    public boolean performClick() {
+        boolean handled = super.performClick();
+        mValueModel.set(isChecked());
+        return handled;
+    }
 }
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 57e51c2..ec81214 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.text.Editable;
 import android.text.Selection;
 import android.text.Spannable;
@@ -24,6 +25,7 @@
 import android.text.method.ArrowKeyMovementMethod;
 import android.text.method.MovementMethod;
 import android.util.AttributeSet;
+import android.util.ValueModel;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -47,7 +49,9 @@
  * {@link android.R.styleable#TextView TextView Attributes},
  * {@link android.R.styleable#View View Attributes}
  */
-public class EditText extends TextView {
+public class EditText extends TextView implements ValueEditor<CharSequence> {
+    private ValueModel<CharSequence> mValueModel = ValueModel.EMPTY;
+
     public EditText(Context context) {
         this(context, null);
     }
@@ -128,4 +132,21 @@
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(EditText.class.getName());
     }
+
+    @Override
+    public ValueModel<CharSequence> getValueModel() {
+        return mValueModel;
+    }
+
+    @Override
+    public void setValueModel(ValueModel<CharSequence> valueModel) {
+        mValueModel = valueModel;
+        setText(mValueModel.get());
+    }
+
+    @Override
+    void sendAfterTextChanged(Editable text) {
+        super.sendAfterTextChanged(text);
+        mValueModel.set(text);
+    }
 }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index c67cae6..143b5aa 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2601,15 +2601,10 @@
                         suggestionStart, suggestionEnd).toString();
                 mTextView.replaceText_internal(spanStart, spanEnd, suggestion);
 
-                // Notify source IME of the suggestion pick. Do this before swaping texts.
-                if (!TextUtils.isEmpty(
-                        suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
-                    InputMethodManager imm = InputMethodManager.peekInstance();
-                    if (imm != null) {
-                        imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
-                                suggestionInfo.suggestionIndex);
-                    }
-                }
+                // Notify source IME of the suggestion pick. Do this before
+                // swaping texts.
+                suggestionInfo.suggestionSpan.notifySelection(
+                        mTextView.getContext(), originalText, suggestionInfo.suggestionIndex);
 
                 // Swap text content between actual text and Suggestion span
                 String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 772d748..85ed8db 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -605,7 +605,7 @@
     }
 
     private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) {
-        return isAtEdge ? DEFAULT_CONTAINER_MARGIN : getDefaultMargin(c, horizontal, leading);
+        return /*isAtEdge ? DEFAULT_CONTAINER_MARGIN :*/ getDefaultMargin(c, horizontal, leading);
     }
 
     private int getDefaultMargin(View c, LayoutParams p, boolean horizontal, boolean leading) {
@@ -824,13 +824,11 @@
     // Draw grid
 
     private void drawLine(Canvas graphics, int x1, int y1, int x2, int y2, Paint paint) {
-        int dx = getPaddingLeft();
-        int dy = getPaddingTop();
         if (isLayoutRtl()) {
             int width = getWidth();
-            graphics.drawLine(width - dx - x1, dy + y1, width - dx - x2, dy + y2, paint);
+            graphics.drawLine(width - x1, y1, width - x2, y2, paint);
         } else {
-            graphics.drawLine(dx + x1, dy + y1, dx + x2, dy + y2, paint);
+            graphics.drawLine(x1, y1, x2, y2, paint);
         }
     }
 
@@ -838,18 +836,17 @@
      * @hide
      */
     @Override
-    protected void onDebugDrawMargins(Canvas canvas) {
+    protected void onDebugDrawMargins(Canvas canvas, Paint paint) {
         // Apply defaults, so as to remove UNDEFINED values
         LayoutParams lp = new LayoutParams();
         for (int i = 0; i < getChildCount(); i++) {
             View c = getChildAt(i);
-            Insets insets = getLayoutMode() == OPTICAL_BOUNDS ? c.getOpticalInsets() : Insets.NONE;
             lp.setMargins(
-                    getMargin1(c, true, true) - insets.left,
-                    getMargin1(c, false, true) - insets.top,
-                    getMargin1(c, true, false) - insets.right,
-                    getMargin1(c, false, false) - insets.bottom);
-            lp.onDebugDraw(c, canvas);
+                    getMargin1(c, true, true),
+                    getMargin1(c, false, true),
+                    getMargin1(c, true, false),
+                    getMargin1(c, false, false));
+            lp.onDebugDraw(c, canvas, paint);
         }
     }
 
@@ -858,26 +855,30 @@
      */
     @Override
     protected void onDebugDraw(Canvas canvas) {
-        int height = getHeight() - getPaddingTop() - getPaddingBottom();
-        int width = getWidth() - getPaddingLeft() - getPaddingRight();
-
         Paint paint = new Paint();
         paint.setStyle(Paint.Style.STROKE);
         paint.setColor(Color.argb(50, 255, 255, 255));
 
+        Insets insets = getOpticalInsets();
+
+        int top    =               getPaddingTop()    + insets.top;
+        int left   =               getPaddingLeft()   + insets.left;
+        int right  = getWidth()  - getPaddingRight()  - insets.right;
+        int bottom = getHeight() - getPaddingBottom() - insets.bottom;
+
         int[] xs = horizontalAxis.locations;
         if (xs != null) {
             for (int i = 0, length = xs.length; i < length; i++) {
-                int x = xs[i];
-                drawLine(canvas, x, 0, x, height - 1, paint);
+                int x = left + xs[i];
+                drawLine(canvas, x, top, x, bottom, paint);
             }
         }
 
         int[] ys = verticalAxis.locations;
         if (ys != null) {
             for (int i = 0, length = ys.length; i < length; i++) {
-                int y = ys[i];
-                drawLine(canvas, 0, y, width - 1, y, paint);
+                int y = top + ys[i];
+                drawLine(canvas, left, y, right, y, paint);
             }
         }
 
@@ -1013,12 +1014,7 @@
     }
 
     private int getMeasurement(View c, boolean horizontal) {
-        int result = horizontal ? c.getMeasuredWidth() : c.getMeasuredHeight();
-        if (getLayoutMode() == OPTICAL_BOUNDS) {
-            Insets insets = c.getOpticalInsets();
-            return result - (horizontal ? insets.left + insets.right : insets.top + insets.bottom);
-        }
-        return result;
+        return horizontal ? c.getMeasuredWidth() : c.getMeasuredHeight();
     }
 
     final int getMeasurementIncludingMargin(View c, boolean horizontal) {
@@ -1124,14 +1120,6 @@
                     targetWidth - width - paddingRight - rightMargin - dx;
             int cy = paddingTop + y1 + gravityOffsetY + alignmentOffsetY + topMargin;
 
-            boolean useLayoutBounds = getLayoutMode() == OPTICAL_BOUNDS;
-            if (useLayoutBounds) {
-                Insets insets = c.getOpticalInsets();
-                cx -= insets.left;
-                cy -= insets.top;
-                width += (insets.left + insets.right);
-                height += (insets.top + insets.bottom);
-            }
             if (width != c.getMeasuredWidth() || height != c.getMeasuredHeight()) {
                 c.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY));
             }
@@ -2418,6 +2406,8 @@
      *     <li> {@code spec.span = [start, start + size]} </li>
      *     <li> {@code spec.alignment = alignment} </li>
      * </ul>
+     * <p>
+     * To leave the start index undefined, use the value {@link #UNDEFINED}.
      *
      * @param start     the start
      * @param size      the size
@@ -2433,9 +2423,13 @@
      *     <li> {@code spec.span = [start, start + 1]} </li>
      *     <li> {@code spec.alignment = alignment} </li>
      * </ul>
+     * <p>
+     * To leave the start index undefined, use the value {@link #UNDEFINED}.
      *
      * @param start     the start index
      * @param alignment the alignment
+     *
+     * @see #spec(int, int, Alignment)
      */
     public static Spec spec(int start, Alignment alignment) {
         return spec(start, 1, alignment);
@@ -2446,9 +2440,13 @@
      * <ul>
      *     <li> {@code spec.span = [start, start + size]} </li>
      * </ul>
+     * <p>
+     * To leave the start index undefined, use the value {@link #UNDEFINED}.
      *
      * @param start     the start
      * @param size      the size
+     *
+     * @see #spec(int, Alignment)
      */
     public static Spec spec(int start, int size) {
         return spec(start, size, UNDEFINED_ALIGNMENT);
@@ -2459,8 +2457,12 @@
      * <ul>
      *     <li> {@code spec.span = [start, start + 1]} </li>
      * </ul>
+     * <p>
+     * To leave the start index undefined, use the value {@link #UNDEFINED}.
      *
      * @param start     the start index
+     *
+     * @see #spec(int, int)
      */
     public static Spec spec(int start) {
         return spec(start, 1);
@@ -2654,14 +2656,7 @@
         @Override
         public int getAlignmentValue(View view, int viewSize, int mode) {
             int baseline = view.getBaseline();
-            if (baseline == -1) {
-                return UNDEFINED;
-            } else {
-                if (mode == OPTICAL_BOUNDS) {
-                    return baseline - view.getOpticalInsets().top;
-                }
-                return baseline;
-            }
+            return baseline == -1 ? UNDEFINED : baseline;
         }
 
         @Override
diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java
index 2737f94..a6486a8 100644
--- a/core/java/android/widget/SeekBar.java
+++ b/core/java/android/widget/SeekBar.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.util.ValueModel;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -33,7 +34,7 @@
  *
  * @attr ref android.R.styleable#SeekBar_thumb
  */
-public class SeekBar extends AbsSeekBar {
+public class SeekBar extends AbsSeekBar implements ValueEditor<Integer> {
 
     /**
      * A callback that notifies clients when the progress level has been
@@ -69,8 +70,9 @@
         void onStopTrackingTouch(SeekBar seekBar);
     }
 
+    private ValueModel<Integer> mValueModel = ValueModel.EMPTY;
     private OnSeekBarChangeListener mOnSeekBarChangeListener;
-    
+
     public SeekBar(Context context) {
         this(context, null);
     }
@@ -89,9 +91,23 @@
 
         if (mOnSeekBarChangeListener != null) {
             mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
+            if (fromUser) {
+                mValueModel.set(getProgress());
+            }
         }
     }
 
+    @Override
+    public ValueModel<Integer> getValueModel() {
+        return mValueModel;
+    }
+
+    @Override
+    public void setValueModel(ValueModel<Integer> valueModel) {
+        mValueModel = valueModel;
+        setProgress(mValueModel.get());
+    }
+
     /**
      * Sets a listener to receive notifications of changes to the SeekBar's progress level. Also
      * provides notifications of when the user starts and stops a touch gesture within the SeekBar.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2937166..3ca330c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -26,6 +26,7 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
+import android.graphics.Insets;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Rect;
@@ -4214,6 +4215,14 @@
 
     /////////////////////////////////////////////////////////////////////////
 
+    private int getBoxHeight(Layout l) {
+        Insets opticalInsets = isLayoutModeOptical(mParent) ? getOpticalInsets() : Insets.NONE;
+        int padding = (l == mHintLayout) ?
+                getCompoundPaddingTop() + getCompoundPaddingBottom() :
+                getExtendedPaddingTop() + getExtendedPaddingBottom();
+        return getMeasuredHeight() - padding + opticalInsets.top + opticalInsets.bottom;
+    }
+
     int getVerticalOffset(boolean forceNormal) {
         int voffset = 0;
         final int gravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
@@ -4224,15 +4233,7 @@
         }
 
         if (gravity != Gravity.TOP) {
-            int boxht;
-
-            if (l == mHintLayout) {
-                boxht = getMeasuredHeight() - getCompoundPaddingTop() -
-                        getCompoundPaddingBottom();
-            } else {
-                boxht = getMeasuredHeight() - getExtendedPaddingTop() -
-                        getExtendedPaddingBottom();
-            }
+            int boxht = getBoxHeight(l);
             int textht = l.getHeight();
 
             if (textht < boxht) {
@@ -4255,15 +4256,7 @@
         }
 
         if (gravity != Gravity.BOTTOM) {
-            int boxht;
-
-            if (l == mHintLayout) {
-                boxht = getMeasuredHeight() - getCompoundPaddingTop() -
-                        getCompoundPaddingBottom();
-            } else {
-                boxht = getMeasuredHeight() - getExtendedPaddingTop() -
-                        getExtendedPaddingBottom();
-            }
+            int boxht = getBoxHeight(l);
             int textht = l.getHeight();
 
             if (textht < boxht) {
@@ -4999,6 +4992,10 @@
             voffset = getVerticalOffset(true);
         }
 
+        if (isLayoutModeOptical(mParent)) {
+            voffset -= getOpticalInsets().top;
+        }
+
         return getExtendedPaddingTop() + voffset + mLayout.getLineBaseline(0);
     }
 
diff --git a/core/java/android/widget/ValueEditor.java b/core/java/android/widget/ValueEditor.java
new file mode 100755
index 0000000..2b91abf
--- /dev/null
+++ b/core/java/android/widget/ValueEditor.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.util.ValueModel;
+
+/**
+ * An interface for editors of simple values. Classes implementing this interface are normally
+ * UI controls (subclasses of {@link android.view.View View}) that can provide a suitable
+ * user interface to display and edit values of the specified type. This interface is
+ * intended to describe editors for simple types, like {@code boolean}, {@code int} or
+ * {@code String}, where the values themselves are immutable.
+ * <p>
+ * For example, {@link android.widget.CheckBox CheckBox} implements
+ * this interface for the Boolean type as it is capable of providing an appropriate
+ * mechanism for displaying and changing the value of a Boolean property.
+ *
+ * @param <T> the value type that this editor supports
+ */
+public interface ValueEditor<T> {
+    /**
+     * Return the last value model that was set. If no value model has been set, the editor
+     * should return the value {@link android.util.ValueModel#EMPTY}.
+     *
+     * @return the value model
+     */
+    public ValueModel<T> getValueModel();
+
+    /**
+     * Sets the value model for this editor. When the value model is set, the editor should
+     * retrieve the value from the value model, using {@link android.util.ValueModel#get()},
+     * and set its internal state accordingly. Likewise, when the editor's internal state changes
+     * it should update the value model by calling  {@link android.util.ValueModel#set(T)}
+     * with the appropriate value.
+     *
+     * @param valueModel the new value model for this editor.
+     */
+    public void setValueModel(ValueModel<T> valueModel);
+}
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 8823328..1fb8c91 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -210,19 +210,28 @@
     JavaPixelAllocator javaAllocator(env);
 
     SkBitmap* bitmap;
+    bool useExistingBitmap = false;
     if (javaBitmap == NULL) {
         bitmap = new SkBitmap;
     } else {
         if (sampleSize != 1) {
             return nullObjectReturn("SkImageDecoder: Cannot reuse bitmap with sampleSize != 1");
         }
+
         bitmap = (SkBitmap*) env->GetIntField(javaBitmap, gBitmap_nativeBitmapFieldID);
-        // config of supplied bitmap overrules config set in options
-        prefConfig = bitmap->getConfig();
+        // only reuse the provided bitmap if it is immutable
+        if (!bitmap->isImmutable()) {
+            useExistingBitmap = true;
+            // config of supplied bitmap overrules config set in options
+            prefConfig = bitmap->getConfig();
+        } else {
+            ALOGW("Unable to reuse an immutable bitmap as an image decoder target.");
+            bitmap = new SkBitmap;
+        }
     }
 
     SkAutoTDelete<SkImageDecoder> add(decoder);
-    SkAutoTDelete<SkBitmap> adb(bitmap, javaBitmap == NULL);
+    SkAutoTDelete<SkBitmap> adb(bitmap, !useExistingBitmap);
 
     decoder->setPeeker(&peeker);
     if (!isPurgeable) {
@@ -383,7 +392,7 @@
     // detach bitmap from its autodeleter, since we want to own it now
     adb.detach();
 
-    if (javaBitmap != NULL) {
+    if (useExistingBitmap) {
         // If a java bitmap was passed in for reuse, pass it back
         return javaBitmap;
     }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9759bdc..35c396d 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2244,6 +2244,14 @@
              See {@link android.view.ViewGroup#setMotionEventSplittingEnabled(boolean)}
              for more information. -->
         <attr name="splitMotionEvents" format="boolean" />
+
+        <!-- Defines the layout mode of this ViewGroup. -->
+        <attr name="layoutMode">
+            <!-- Use the children's clip bounds when laying out this container. -->
+            <enum name="clipBounds" value="0" />
+            <!-- Use the children's optical bounds when laying out this container. -->
+            <enum name="opticalBounds" value="1" />
+        </attr>
     </declare-styleable>
 
     <!-- A {@link android.view.ViewStub} lets you lazily include other XML layouts
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3936ed4..b6e20b7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1718,4 +1718,8 @@
   <!-- From PinyinIME(!!!) -->
   <java-symbol type="string" name="inputMethod" />
 
+  <!-- From Chromium-WebView -->
+  <java-symbol type="attr" name="actionModeWebSearchDrawable" />
+  <java-symbol type="string" name="websearch" />
+
 </resources>
diff --git a/docs/html/guide/google/gcm/gcm.jd b/docs/html/guide/google/gcm/gcm.jd
index c4dfecf..db3cb2e 100644
--- a/docs/html/guide/google/gcm/gcm.jd
+++ b/docs/html/guide/google/gcm/gcm.jd
@@ -906,6 +906,7 @@
 # curl --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send  -d "{\"registration_ids\":[\"ABC\"]}"</pre>
 
 
+
 If you receive a 401 HTTP status code, your API key is not valid. Otherwise you should see something like this:<br/>
 
 <pre>
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index f9392e4..54d1bf5 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -715,7 +715,7 @@
      *
      * @hide
      */
-    public Insets getLayoutInsets() {
+    public Insets getOpticalInsets() {
         return Insets.NONE;
     }
 
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 41b272d..3af2969 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -95,8 +95,8 @@
      * @hide
      */
     @Override
-    public Insets getLayoutInsets() {
-        return (mCurrDrawable == null) ? Insets.NONE : mCurrDrawable.getLayoutInsets();
+    public Insets getOpticalInsets() {
+        return (mCurrDrawable == null) ? Insets.NONE : mCurrDrawable.getOpticalInsets();
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 2ee6233..a9dc22b 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -56,7 +56,7 @@
     private NinePatchState mNinePatchState;
     private NinePatch mNinePatch;
     private Rect mPadding;
-    private Insets mLayoutInsets = Insets.NONE;
+    private Insets mOpticalInsets = Insets.NONE;
     private Paint mPaint;
     private boolean mMutated;
 
@@ -96,8 +96,8 @@
      * @hide
      */
     public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk,
-            Rect padding, Rect layoutInsets, String srcName) {
-        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding, layoutInsets), res);
+            Rect padding, Rect opticalInsets, String srcName) {
+        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding, opticalInsets), res);
         mNinePatchState.mTargetDensity = mTargetDensity;
     }
 
@@ -195,7 +195,7 @@
         if (sdensity == tdensity) {
             mBitmapWidth = mNinePatch.getWidth();
             mBitmapHeight = mNinePatch.getHeight();
-            mLayoutInsets = mNinePatchState.mLayoutInsets;
+            mOpticalInsets = mNinePatchState.mOpticalInsets;
         } else {
             mBitmapWidth = Bitmap.scaleFromDensity(mNinePatch.getWidth(),
                     sdensity, tdensity);
@@ -212,7 +212,7 @@
                 dest.right = Bitmap.scaleFromDensity(src.right, sdensity, tdensity);
                 dest.bottom = Bitmap.scaleFromDensity(src.bottom, sdensity, tdensity);
             }
-            mLayoutInsets = scaleFromDensity(mNinePatchState.mLayoutInsets, sdensity, tdensity);
+            mOpticalInsets = scaleFromDensity(mNinePatchState.mOpticalInsets, sdensity, tdensity);
         }
     }
 
@@ -236,8 +236,8 @@
      * @hide
      */
     @Override
-    public Insets getLayoutInsets() {
-        return mLayoutInsets;
+    public Insets getOpticalInsets() {
+        return mOpticalInsets;
     }
 
     @Override
@@ -299,7 +299,7 @@
         options.inScreenDensity = r.getDisplayMetrics().noncompatDensityDpi;
 
         final Rect padding = new Rect();
-        final Rect layoutInsets = new Rect();
+        final Rect opticalInsets = new Rect();
         Bitmap bitmap = null;
 
         try {
@@ -323,7 +323,7 @@
 
         setNinePatchState(new NinePatchState(
                 new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"),
-                padding, layoutInsets, dither), r);
+                padding, opticalInsets, dither), r);
         mNinePatchState.mTargetDensity = mTargetDensity;
 
         a.recycle();
@@ -397,7 +397,7 @@
     private final static class NinePatchState extends ConstantState {
         final NinePatch mNinePatch;
         final Rect mPadding;
-        final Insets mLayoutInsets;
+        final Insets mOpticalInsets;
         final boolean mDither;
         int mChangingConfigurations;
         int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -406,14 +406,14 @@
             this(ninePatch, padding, new Rect(), DEFAULT_DITHER);
         }
 
-        NinePatchState(NinePatch ninePatch, Rect padding, Rect layoutInsets) {
-            this(ninePatch, padding, layoutInsets, DEFAULT_DITHER);
+        NinePatchState(NinePatch ninePatch, Rect padding, Rect opticalInsets) {
+            this(ninePatch, padding, opticalInsets, DEFAULT_DITHER);
         }
 
-        NinePatchState(NinePatch ninePatch, Rect rect, Rect layoutInsets, boolean dither) {
+        NinePatchState(NinePatch ninePatch, Rect rect, Rect opticalInsets, boolean dither) {
             mNinePatch = ninePatch;
             mPadding = rect;
-            mLayoutInsets = Insets.of(layoutInsets);
+            mOpticalInsets = Insets.of(opticalInsets);
             mDither = dither;
         }
 
@@ -423,7 +423,7 @@
             mNinePatch = new NinePatch(state.mNinePatch);
             // Note we don't copy the padding because it is immutable.
             mPadding = state.mPadding;
-            mLayoutInsets = state.mLayoutInsets;
+            mOpticalInsets = state.mOpticalInsets;
             mDither = state.mDither;
             mChangingConfigurations = state.mChangingConfigurations;
             mTargetDensity = state.mTargetDensity;
diff --git a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
index 6da7d4a..4349444 100644
--- a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
@@ -18,7 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"پشتیبان‌گیری کامل"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"بازیابی کامل"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"درخواست پشتیبان گیری کامل از تمام داده‌ها به یک رایانه دسک‌تاپ متصل داده شده است. آیا می‌خواهید این عمل انجام شود؟"\n\n"اگر شما درخواست تهیه نسخهٔ پشتیبان را نداده‌اید، اجازه‌ ادامه عملیات را ندهید."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"درخواست پشتیبان گیری کامل از تمام داده‌ها به یک رایانه دسک‌تاپ متصل داده شده است. آیا می‌خواهید این عمل انجام شود؟"\n\n"اگر شما درخواست تهیهٔ نسخهٔ پشتیبان را نداده‌اید، اجازه‌ ادامه عملیات را ندهید."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"از داده‌های من نسخهٔ پشتیبان تهیه شود"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"نسخهٔ پشتیبان تهیه نشود"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"بازیابی کامل تمام داده‌ها از یک رایانه دسک تاپ متصل درخواست شده است. آیا می‌خواهید این اجازه را بدهید؟"\n\n"اگر خود شما درخواست بازیابی نداده‌اید، اجازه ادامه این عملیات را ندهید. با این کار همه داده‌هایی که اکنون روی دستگاه است جایگزین می‌شود!"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
index ccac982..1495f8e 100644
--- a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
@@ -24,12 +24,12 @@
     <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्‍ट कि‍ए गए डेस्‍कटॉप कंप्‍यूटर से सभी डेटा की पूर्ण पुनर्स्थापना का अनुरोध कि‍या गया है. क्‍या आप इसकी अनुमति‍ देना चाहते हैं?"\n\n"यदि‍ आपने स्‍वयं पुनर्प्राप्ति‍ का अनुरोध नहीं कि‍या है, तो प्रक्रि‍या जारी रखने की अनुमति‍ न दें. इससे वर्तमान में आपके उपकरण पर मौजूद डेटा बदल जाएगा!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"मेरा डेटा पुनर्स्थापित करें"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"पुनर्स्‍थापित न करें"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"कृपया नीचे अपना वर्तमान बैकअप पासवर्ड दर्ज करें:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया नीचे अपना उपकरण एन्‍क्रिप्शन पासवर्ड दर्ज करें."</string>
+    <string name="current_password_text" msgid="8268189555578298067">"कृपया नीचे अपना वर्तमान बैकअप पासवर्ड डालें:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया नीचे अपना उपकरण एन्‍क्रिप्शन पासवर्ड डालें."</string>
     <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया अपना उपकरण एन्क्रिप्शन पासवर्ड नीचे दर्ज करें. बैकअप संग्रहण को एन्‍क्रिप्‍ट करने के लिए भी इसका उपयोग किया जाएगा."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"कृपया संपूर्ण बैकअप डेटा को एन्‍क्रि‍प्‍ट करने में उपयोग के लि‍ए पासवर्ड दर्ज करें. यदि‍ यह खाली छोड़ दि‍या जाता है, तो आपके वर्तमान बैकअप पासवर्ड का उपयोग कि‍या जाएगा:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि‍ आप संपूर्ण बैकअप डेटा एन्‍क्रि‍प्‍ट करना चाहते हैं, तो नीचे पासवर्ड दर्ज करें:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"यदि‍ पुनर्स्थापित डेटा को एन्‍क्रि‍प्‍ट कि‍या गया है, तो कृपया नीचे पासवर्ड दर्ज करें:"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"कृपया संपूर्ण बैकअप डेटा को एन्‍क्रि‍प्‍ट करने में उपयोग के लि‍ए पासवर्ड डालें. यदि‍ यह खाली छोड़ दि‍या जाता है, तो आपके वर्तमान बैकअप पासवर्ड का उपयोग कि‍या जाएगा:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि‍ आप संपूर्ण बैकअप डेटा एन्‍क्रि‍प्‍ट करना चाहते हैं, तो नीचे पासवर्ड डालें:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"यदि‍ पुनर्स्थापित डेटा को एन्‍क्रि‍प्‍ट कि‍या गया है, तो कृपया नीचे पासवर्ड डालें:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"बैकअप प्रारंभ हो रहा है..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"बैकअप पूर्ण"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"पुनर्स्‍थापना प्रारंभ हो रही है..."</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
index 9540300..2fdba28 100644
--- a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Cópia de segurança completa"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restauro completo"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitada uma cópia de segurança completa de todos os dados para um computador de secretária. Pretende permitir esta operação?"\n\n"Caso não tenha solicitado a cópia de segurança, não permita que a operação prossiga."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitada uma cópia de segurança completa de todos os dados para um computador. Pretende permitir esta operação?"\n\n"Caso não tenha solicitado a cópia de segurança, não permita que a operação prossiga."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Fazer cópia de seg. dos dados"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Não efetuar cópia de seg."</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Foi solicitado um restauro completo de todos os dados a partir de um computador de secretária. Pretende permitir esta operação?"\n\n"Caso não tenha solicitado o restauro, não permita que a operação prossiga. Isto substituirá os dados existentes no aparelho!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Foi solicitado um restauro completo de todos os dados a partir de um computador. Pretende permitir esta operação?"\n\n"Caso não tenha solicitado o restauro, não permita que a operação prossiga. Isto substituirá os dados existentes no equipamento!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar os meus dados"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Não restaurar"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Introduza a palavra-passe de cópia de segurança atual abaixo:"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index f25ac0d..2723f82 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -82,6 +82,7 @@
     private static final String SCREENSHOTS_DIR_NAME = "Screenshots";
     private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
     private static final String SCREENSHOT_FILE_PATH_TEMPLATE = "%s/%s/%s";
+    private static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)";
 
     private int mNotificationId;
     private NotificationManager mNotificationManager;
@@ -184,9 +185,13 @@
             values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
             Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
 
+            String subjectDate = new SimpleDateFormat("hh:mma, MMM dd, yyyy")
+                .format(new Date(mImageTime));
+            String subject = String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate);
             Intent sharingIntent = new Intent(Intent.ACTION_SEND);
             sharingIntent.setType("image/png");
             sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
+            sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
 
             Intent chooserIntent = Intent.createChooser(sharingIntent, null);
             chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK 
@@ -600,14 +605,17 @@
         Resources r = context.getResources();
 
         // Clear all existing notification, compose the new notification and show it
-        Notification n = new Notification.Builder(context)
+        Notification.Builder b = new Notification.Builder(context)
             .setTicker(r.getString(R.string.screenshot_failed_title))
             .setContentTitle(r.getString(R.string.screenshot_failed_title))
             .setContentText(r.getString(R.string.screenshot_failed_text))
             .setSmallIcon(R.drawable.stat_notify_image_error)
             .setWhen(System.currentTimeMillis())
-            .setAutoCancel(true)
-            .getNotification();
+            .setAutoCancel(true);
+        Notification n =
+            new Notification.BigTextStyle(b)
+                .bigText(r.getString(R.string.screenshot_failed_text))
+                .build();
         nManager.notify(SCREENSHOT_NOTIFICATION_ID, n);
     }
 }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 370d427..a22193c 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1402,7 +1402,7 @@
         context.setTheme(android.R.style.Theme_Holo);
         m.mContext = context;
         m.mFactoryTest = factoryTest;
-        m.mMainStack = new ActivityStack(m, context, true);
+        m.mMainStack = new ActivityStack(m, context, true, thr.mLooper);
         
         m.mBatteryStatsService.publish(context);
         m.mUsageStatsService.publish(context);
@@ -1423,6 +1423,7 @@
     
     static class AThread extends Thread {
         ActivityManagerService mService;
+        Looper mLooper;
         boolean mReady = false;
 
         public AThread() {
@@ -1440,6 +1441,7 @@
 
             synchronized (this) {
                 mService = m;
+                mLooper = Looper.myLooper();
                 notifyAll();
             }
 
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2d445274..7a39ed4 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -49,6 +49,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
@@ -305,11 +306,17 @@
         }
     }
 
-    final Handler mHandler = new Handler() {
+    final Handler mHandler;
+
+    final class ActivityStackHandler extends Handler {
         //public Handler() {
         //    if (localLOGV) Slog.v(TAG, "Handler started!");
         //}
+        public ActivityStackHandler(Looper looper) {
+            super(looper);
+        }
 
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case SLEEP_TIMEOUT_MSG: {
@@ -409,7 +416,8 @@
         }
     };
     
-    ActivityStack(ActivityManagerService service, Context context, boolean mainStack) {
+    ActivityStack(ActivityManagerService service, Context context, boolean mainStack, Looper looper) {
+        mHandler = new ActivityStackHandler(looper);
         mService = service;
         mContext = context;
         mMainStack = mainStack;
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java b/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java
index 103de2f..81440a5 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java
@@ -10,9 +10,8 @@
 import android.widget.GridLayout;
 import android.widget.TextView;
 
-import static android.widget.GridLayout.ALIGN_BOUNDS;
 import static android.widget.GridLayout.LayoutParams;
-import static android.widget.GridLayout.OPTICAL_BOUNDS;
+import static android.widget.GridLayout.LAYOUT_MODE_OPTICAL_BOUNDS;
 
 public class LayoutInsetsTest extends Activity {
     static int[] GRAVITIES = {Gravity.LEFT, Gravity.LEFT, Gravity.CENTER_HORIZONTAL, Gravity.RIGHT, Gravity.RIGHT};
@@ -23,7 +22,7 @@
         GridLayout p = new GridLayout(context);
         p.setUseDefaultMargins(true);
         //p.setAlignmentMode(ALIGN_BOUNDS);
-        p.setLayoutMode(OPTICAL_BOUNDS);
+        p.setLayoutMode(LAYOUT_MODE_OPTICAL_BOUNDS);
 
         p.setColumnCount(N);