Merge "Disable SamplingProfilerIntegration until it's fixed."
diff --git a/api/current.xml b/api/current.xml
index 9923020..fcb0c0e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -9425,6 +9425,17 @@
  visibility="public"
 >
 </field>
+<field name="textIsSelectable"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843558"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="textLineHeight"
  type="int"
  transient="false"
@@ -243415,6 +243426,17 @@
 <parameter name="attrs" type="android.content.res.TypedArray">
 </parameter>
 </method>
+<method name="getTextIsSelectable"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getTextScaleX"
  return="float"
  abstract="false"
@@ -244583,6 +244605,19 @@
 <parameter name="colors" type="android.content.res.ColorStateList">
 </parameter>
 </method>
+<method name="setTextIsSelectable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="selectable" type="boolean">
+</parameter>
+</method>
 <method name="setTextKeepState"
  return="void"
  abstract="false"
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 8e25395..3cb5e24 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -45,5 +45,9 @@
     public static final boolean WEB_TEXT_VIEW = false;
     public static final boolean WEB_VIEW = false;
     public static final boolean WEB_VIEW_CORE = false;
-
+    /*
+     * Set to true to allow the WebTextView to draw on top of the web page in a
+     * different color so that you can see how the two line up.
+     */
+    public static final boolean DRAW_WEBTEXTVIEW = false;
 }
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index a58d648..f477f8f 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -157,7 +157,7 @@
         // Set the text color to black, regardless of the theme.  This ensures
         // that other applications that use embedded WebViews will properly
         // display the text in password textfields.
-        setTextColor(Color.BLACK);
+        setTextColor(DebugFlags.DRAW_WEBTEXTVIEW ? Color.RED : Color.BLACK);
         // This helps to align the text better with the text in the web page.
         setIncludeFontPadding(false);
     }
@@ -404,8 +404,9 @@
         // onDraw should only be called for password fields.  If WebTextView is
         // still drawing, but is no longer corresponding to a password field,
         // remove it.
-        if (mWebView == null || !mWebView.nativeFocusCandidateIsPassword()
-                || !isSameTextField(mWebView.nativeFocusCandidatePointer())) {
+        if (!DebugFlags.DRAW_WEBTEXTVIEW && (mWebView == null
+                || !mWebView.nativeFocusCandidateIsPassword()
+                || !isSameTextField(mWebView.nativeFocusCandidatePointer()))) {
             // Although calling remove() would seem to make more sense here,
             // changing it to not be a password field will make it not draw.
             // Other code will make sure that it is removed completely, but this
@@ -819,7 +820,9 @@
         }
         // For password fields, draw the WebTextView.  For others, just show
         // webkit's drawing.
-        setWillNotDraw(!inPassword);
+        if (!DebugFlags.DRAW_WEBTEXTVIEW) {
+            setWillNotDraw(!inPassword);
+        }
         setBackgroundDrawable(inPassword ? mBackground : null);
     }
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4e0c386..14dbfe2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -7481,7 +7481,7 @@
     private native Rect     nativeFocusCandidatePaddingRect();
     /* package */ native int      nativeFocusCandidatePointer();
     private native String   nativeFocusCandidateText();
-    /* package */ native int      nativeFocusCandidateTextSize();
+    /* package */ native float    nativeFocusCandidateTextSize();
     /**
      * Returns an integer corresponding to WebView.cpp::type.
      * See WebTextView.setType()
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 6e927a6..0fcd26c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1803,6 +1803,8 @@
                 } else {
                     width = Math.max(w, mViewportWidth);
                 }
+            } else if (mSettings.getUseFixedViewport()) {
+                width = mWebView.getViewWidth();
             } else {
                 width = textwrapWidth;
             }
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 7d78777..695ea6b 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -24,7 +24,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
-import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcel;
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 01044d9..7c38714 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -122,7 +122,7 @@
     private boolean mFirstLayoutHappened = false;
     private int mStackMode;
     private int mFramePadding;
-    private final Rect invalidateRect = new Rect();
+    private final Rect stackInvalidateRect = new Rect();
 
     public StackView(Context context) {
         super(context);
@@ -243,6 +243,7 @@
     @Override
     @android.view.RemotableViewMethod
     public void showNext() {
+        if (mSwipeGestureType != GESTURE_NONE) return;
         if (!mTransitionIsSetup) {
             View v = getViewAtRelativeIndex(1);
             if (v != null) {
@@ -257,6 +258,7 @@
     @Override
     @android.view.RemotableViewMethod
     public void showPrevious() {
+        if (mSwipeGestureType != GESTURE_NONE) return;
         if (!mTransitionIsSetup) {
             View v = getViewAtRelativeIndex(0);
             if (v != null) {
@@ -301,8 +303,11 @@
         // Here we need to make sure that the z-order of the children is correct
         for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) {
             int index = modulo(i, getWindowSize());
-            View v = mViewsMap.get(index).view;
-            if (v != null) v.bringToFront();
+            ViewAndIndex vi = mViewsMap.get(index);
+            if (vi != null) {
+                View v = mViewsMap.get(index).view;
+                if (v != null) v.bringToFront();
+            }
         }
         mTransitionIsSetup = false;
     }
@@ -331,16 +336,15 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        canvas.getClipBounds(invalidateRect);
+        canvas.getClipBounds(stackInvalidateRect);
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams();
-            invalidateRect.union(lp.getInvalidateRect());
+            stackInvalidateRect.union(lp.getInvalidateRect());
             lp.resetInvalidateRect();
         }
-
         canvas.save(Canvas.CLIP_SAVE_FLAG);
-        canvas.clipRect(invalidateRect, Region.Op.UNION);
+        canvas.clipRect(stackInvalidateRect, Region.Op.UNION);
         super.dispatchDraw(canvas);
         canvas.restore();
     }
@@ -553,6 +557,10 @@
 
         if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN
                 && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
+            // We reset the gesture variable, because otherwise we will ignore showPrevious() /
+            // showNext();
+            mSwipeGestureType = GESTURE_NONE;
+
             // Swipe threshold exceeded, swipe down
             if (mStackMode == ITEMS_SLIDE_UP) {
                 showPrevious();
@@ -562,6 +570,10 @@
             mHighlight.bringToFront();
         } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP
                 && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
+            // We reset the gesture variable, because otherwise we will ignore showPrevious() /
+            // showNext();
+            mSwipeGestureType = GESTURE_NONE;
+
             // Swipe threshold exceeded, swipe up
             if (mStackMode == ITEMS_SLIDE_UP) {
                 showNext();
@@ -897,7 +909,6 @@
         int horizontalOffset;
         int verticalOffset;
         View mView;
-        int left, top, right, bottom;
         private final Rect parentRect = new Rect();
         private final Rect invalidateRect = new Rect();
         private final RectF invalidateRectf = new RectF();
@@ -952,44 +963,32 @@
         }
 
         void resetInvalidateRect() {
-           invalidateRect.set(0, 0, 0, 0);
+            invalidateRect.set(0, 0, 0, 0);
         }
 
         // This is public so that ObjectAnimator can access it
         public void setVerticalOffset(int newVerticalOffset) {
-            int offsetDelta = newVerticalOffset - verticalOffset;
+            setOffsets(horizontalOffset, newVerticalOffset);
+        }
+
+        public void setHorizontalOffset(int newHorizontalOffset) {
+            setOffsets(newHorizontalOffset, verticalOffset);
+        }
+
+        public void setOffsets(int newHorizontalOffset, int newVerticalOffset) {
+            int horizontalOffsetDelta = newHorizontalOffset - horizontalOffset;
+            horizontalOffset = newHorizontalOffset;
+            int verticalOffsetDelta = newVerticalOffset - verticalOffset;
             verticalOffset = newVerticalOffset;
 
             if (mView != null) {
                 mView.requestLayout();
-                int top = Math.min(mView.getTop() + offsetDelta, mView.getTop());
-                int bottom = Math.max(mView.getBottom() + offsetDelta, mView.getBottom());
+                int left = Math.min(mView.getLeft() + horizontalOffsetDelta, mView.getLeft());
+                int right = Math.max(mView.getRight() + horizontalOffsetDelta, mView.getRight());
+                int top = Math.min(mView.getTop() + verticalOffsetDelta, mView.getTop());
+                int bottom = Math.max(mView.getBottom() + verticalOffsetDelta, mView.getBottom());
 
-                invalidateRectf.set(mView.getLeft(), top, mView.getRight(), bottom);
-
-                float xoffset = -invalidateRectf.left;
-                float yoffset = -invalidateRectf.top;
-                invalidateRectf.offset(xoffset, yoffset);
-                mView.getMatrix().mapRect(invalidateRectf);
-                invalidateRectf.offset(-xoffset, -yoffset);
-                invalidateRect.union((int) Math.floor(invalidateRectf.left),
-                        (int) Math.floor(invalidateRectf.top),
-                        (int) Math.ceil(invalidateRectf.right),
-                        (int) Math.ceil(invalidateRectf.bottom));
-
-                invalidateGlobalRegion(mView, invalidateRect);
-            }
-        }
-
-        public void setHorizontalOffset(int newHorizontalOffset) {
-            int offsetDelta = newHorizontalOffset - horizontalOffset;
-            horizontalOffset = newHorizontalOffset;
-
-            if (mView != null) {
-                mView.requestLayout();
-                int left = Math.min(mView.getLeft() + offsetDelta, mView.getLeft());
-                int right = Math.max(mView.getRight() + offsetDelta, mView.getRight());
-                invalidateRectf.set(left,  mView.getTop(), right, mView.getBottom());
+                invalidateRectf.set(left, top, right, bottom);
 
                 float xoffset = -invalidateRectf.left;
                 float yoffset = -invalidateRectf.top;
@@ -997,7 +996,7 @@
                 mView.getMatrix().mapRect(invalidateRectf);
                 invalidateRectf.offset(-xoffset, -yoffset);
 
-                invalidateRect.union((int) Math.floor(invalidateRectf.left),
+                invalidateRect.set((int) Math.floor(invalidateRectf.left),
                         (int) Math.floor(invalidateRectf.top),
                         (int) Math.ceil(invalidateRectf.right),
                         (int) Math.ceil(invalidateRectf.bottom));
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fdd75d5..5320b10 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -66,6 +66,7 @@
 import android.text.TextPaint;
 import android.text.TextUtils;
 import android.text.TextWatcher;
+import android.text.method.ArrowKeyMovementMethod;
 import android.text.method.DateKeyListener;
 import android.text.method.DateTimeKeyListener;
 import android.text.method.DialerKeyListener;
@@ -755,6 +756,11 @@
                 if (lineHeight != 0) {
                     setLineHeight(lineHeight);
                 }
+                break;
+
+            case com.android.internal.R.styleable.TextView_textIsSelectable:
+                mTextIsSelectable = a.getBoolean(attr, false);
+                break;
             }
         }
         a.recycle();
@@ -844,6 +850,14 @@
 
             mInput = TextKeyListener.getInstance(autotext, cap);
             mInputType = inputType;
+        } else if (mTextIsSelectable) {
+            // Prevent text changes from keyboard.
+            mInputType = EditorInfo.TYPE_NULL;
+            mInput = null;
+            bufferType = BufferType.SPANNABLE;
+            setFocusableInTouchMode(true);
+            // So that selection can be changed using arrow keys and touch is handled.
+            setMovementMethod(ArrowKeyMovementMethod.getInstance());
         } else if (editable) {
             mInput = TextKeyListener.getInstance();
             mInputType = EditorInfo.TYPE_CLASS_TEXT;
@@ -1098,6 +1112,8 @@
      * within the text can cause individual lines to be taller or shorter
      * than this height, and the layout may contain additional first-
      * or last-line padding.
+     *
+     * @attr ref android.R.styleable#TextView_textLineHeight
      */
     public int getLineHeight() {
         if (mLineHeight != 0) {
@@ -4028,6 +4044,71 @@
         return false;
     }
 
+    /**
+     * When a TextView is used to display a useful piece of information to the user (such as a
+     * contact's address), it should be made selectable, so that the user can select and copy this
+     * content.
+     *
+     * Use {@link #setTextIsSelectable(boolean)} or the
+     * {@link android.R.styleable#TextView_textIsSelectable} XML attribute to make this TextView
+     * selectable (the text is not selectable by default). Note that the content of an EditText is
+     * always selectable.
+     *
+     * @return True if the text displayed in this TextView can be selected by the user.
+     *
+     * @attr ref android.R.styleable#TextView_textIsSelectable
+     */
+    public boolean isTextSelectable() {
+        return mTextIsSelectable;
+    }
+
+    /**
+     * Sets whether or not (default) the content of this view is selectable by the user.
+     *
+     * See {@link #isTextSelectable} for details.
+     *
+     * @param selectable Whether or not the content of this TextView should be selectable.
+     */
+    public void setTextIsSelectable(boolean selectable) {
+        if (mTextIsSelectable == selectable) return;
+
+        mTextIsSelectable = selectable;
+
+        setFocusableInTouchMode(selectable);
+        setFocusable(selectable);
+        setClickable(selectable);
+        setLongClickable(selectable);
+
+        // mInputType is already EditorInfo.TYPE_NULL and mInput is null;
+
+        setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
+        setText(getText(), selectable ? BufferType.SPANNABLE : BufferType.NORMAL);
+
+        // Called by setText above, but safer in case of future code changes
+        prepareCursorControllers();
+    }
+
+    @Override
+    protected int[] onCreateDrawableState(int extraSpace) {
+        final int[] drawableState = super.onCreateDrawableState(extraSpace);
+        if (mTextIsSelectable) {
+            // Disable pressed state, which was introduced when TextView was made clickable.
+            // Prevents text color change.
+            // setClickable(false) would have a similar effect, but it also disables focus changes
+            // and long press actions, which are both needed by text selection.
+            final int length = drawableState.length;
+            for (int i = 0; i < length; i++) {
+                if (drawableState[i] == R.attr.state_pressed) {
+                    final int[] nonPressedState = new int[length - 1];
+                    System.arraycopy(drawableState, 0, nonPressedState, 0, i);
+                    System.arraycopy(drawableState, i + 1, nonPressedState, i, length - i - 1);
+                    return nonPressedState;
+                }
+            }
+        }
+        return drawableState;
+    }
+
     @Override
     protected void onDraw(Canvas canvas) {
         if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return;
@@ -4190,12 +4271,13 @@
             selStart = getSelectionStart();
             selEnd = getSelectionEnd();
 
-            if (mCursorVisible && selStart >= 0 && isEnabled()) {
+            if ((mCursorVisible || mTextIsSelectable) && selStart >= 0 && isEnabled()) {
                 if (mHighlightPath == null)
                     mHighlightPath = new Path();
 
                 if (selStart == selEnd) {
-                    if ((SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
+                    if (!mTextIsSelectable &&
+                            (SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
                         if (mHighlightPathBogus) {
                             mHighlightPath.reset();
                             mLayout.getCursorPath(selStart, mHighlightPath, mText);
@@ -7011,9 +7093,9 @@
                         mSelectionModifierCursorController.updatePosition();
                     }
                 }
-                if (action == MotionEvent.ACTION_UP && isFocused() && !mScrolled) {
+                if (action == MotionEvent.ACTION_UP && !mScrolled && isFocused()) {
                     InputMethodManager imm = (InputMethodManager)
-                          getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                    getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 
                     CommitSelectionReceiver csr = null;
                     if (getSelectionStart() != oldSelStart || getSelectionEnd() != oldSelEnd ||
@@ -7047,7 +7129,8 @@
                     || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
         }
 
-        if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null) {
+        if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null &&
+                !mTextIsSelectable) {
             if (mInsertionPointCursorController == null) {
                 mInsertionPointCursorController = new InsertionPointCursorController();
             }
@@ -7070,10 +7153,12 @@
     }
 
     /**
-     * @return True iff this TextView contains a text that can be edited.
+     * @return True iff this TextView contains a text that can be edited, or if this is
+     * a selectable TextView.
      */
     private boolean isTextEditable() {
-        return mText instanceof Editable && onCheckIsTextEditor() && isEnabled();
+        return (mText instanceof Editable && onCheckIsTextEditor() && isEnabled())
+                || mTextIsSelectable;
     }
 
     /**
@@ -7320,9 +7405,7 @@
         // prepareCursorController() relies on this method.
         // If you change this condition, make sure prepareCursorController is called anywhere
         // the value of this condition might be changed.
-        return (mText instanceof Spannable &&
-                mMovement != null &&
-                mMovement.canSelectArbitrarily());
+        return (mText instanceof Spannable && mMovement != null && mMovement.canSelectArbitrarily());
     }
 
     private boolean canCut() {
@@ -8883,6 +8966,7 @@
     private float                   mSpacingMult = 1;
     private float                   mSpacingAdd = 0;
     private int                     mLineHeight = 0;
+    private boolean                 mTextIsSelectable = false;
 
     private static final int        LINES = 1;
     private static final int        EMS = LINES;
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 7cf369f..cd1cae6 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -616,7 +616,7 @@
     public int getSelectedNavigationIndex() {
         switch (mActionView.getNavigationMode()) {
             case NAVIGATION_MODE_TABS:
-                return mSelectedTab.getPosition();
+                return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
             case NAVIGATION_MODE_LIST:
                 return mActionView.getDropdownSelectedPosition();
             default:
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index c9478240..1d103ed 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -24,6 +24,7 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.MeasureSpec;
+import android.view.ViewTreeObserver;
 import android.widget.AdapterView;
 import android.widget.ListPopupWindow;
 import android.widget.PopupWindow;
@@ -33,7 +34,8 @@
 /**
  * @hide
  */
-public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener {
+public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener,
+        ViewTreeObserver.OnGlobalLayoutListener {
     private static final String TAG = "MenuPopupHelper";
 
     private Context mContext;
@@ -42,6 +44,7 @@
     private int mPopupMaxWidth;
     private WeakReference<View> mAnchorView;
     private boolean mOverflowOnly;
+    private ViewTreeObserver mTreeObserver;
 
     private PopupWindow.OnDismissListener mDismissListener = new PopupWindow.OnDismissListener() {
         public void onDismiss() {
@@ -82,12 +85,18 @@
         mPopup.setAdapter(adapter);
         mPopup.setModal(true);
 
-        if (mAnchorView != null) {
-            mPopup.setAnchorView(mAnchorView.get());
-        } else if (mMenu instanceof SubMenuBuilder) {
+        View anchor = mAnchorView != null ? mAnchorView.get() : null;
+        if (anchor == null && mMenu instanceof SubMenuBuilder) {
             SubMenuBuilder subMenu = (SubMenuBuilder) mMenu;
             final MenuItemImpl itemImpl = (MenuItemImpl) subMenu.getItem();
-            mPopup.setAnchorView(itemImpl.getItemView(MenuBuilder.TYPE_ACTION_BUTTON, null));
+            anchor = itemImpl.getItemView(MenuBuilder.TYPE_ACTION_BUTTON, null);
+            mAnchorView = new WeakReference<View>(anchor);
+        }
+
+        if (anchor != null) {
+            mTreeObserver = anchor.getViewTreeObserver();
+            mTreeObserver.addOnGlobalLayoutListener(this);
+            mPopup.setAnchorView(anchor);
         } else {
             throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
         }
@@ -101,6 +110,8 @@
         if (isShowing()) {
             mPopup.dismiss();
         }
+        mTreeObserver.removeGlobalOnLayoutListener(this);
+        mTreeObserver = null;
     }
 
     public boolean isShowing() {
@@ -115,7 +126,7 @@
             item = mMenu.getItem(position);
         }
         mMenu.performItemAction(item, 0);
-        mPopup.dismiss();
+        dismiss();
     }
 
     public boolean onKey(View v, int keyCode, KeyEvent event) {
@@ -142,4 +153,17 @@
         }
         return width;
     }
+
+    @Override
+    public void onGlobalLayout() {
+        if (!isShowing()) {
+            mTreeObserver.removeGlobalOnLayoutListener(this);
+            mTreeObserver = null;
+        } else {
+            final View anchor = mAnchorView != null ? mAnchorView.get() : null;
+            if (anchor != null && !anchor.isShown()) {
+                dismiss();
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index be6a57a..7a64da0 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -330,6 +330,7 @@
         mSubtitle = subtitle;
         if (mSubtitleView != null) {
             mSubtitleView.setText(subtitle);
+            mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE);
         }
     }
 
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 7ff75b3..d305260 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -635,6 +635,10 @@
     <!-- Height of a line of text. -->
     <attr name="textLineHeight" format="dimension" />
 
+    <!-- Indicates that the content of a non-editable TextView can be selected.
+     Default value is false. EditText content is always selectable. -->
+    <attr name="textIsSelectable" format="boolean" />
+
     <!-- Where to ellipsize text. -->
     <attr name="ellipsize">
         <enum name="none" value="0" />
@@ -2477,6 +2481,9 @@
 
         <!-- Height of a line of text. -->
         <attr name="textLineHeight" />
+        <!-- Indicates that a non-editable text can be selected. -->
+        <attr name="textIsSelectable" />
+
     </declare-styleable>
     <!-- An <code>input-extras</code> is a container for extra data to supply to
          an input method.  Contains
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index bf0ac47..cecf470 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1440,4 +1440,6 @@
   <public type="style" name="Theme.Holo.DialogWhenLarge" />
   
   <public type="string" name="selectTextMode" />
+
+  <public type="attr" name="textIsSelectable" />
 </resources>
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index 026f7de..78b5617 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -41,6 +41,13 @@
         mID = id;
     }
 
+    /**
+     * Lookup the native object ID for this object.  Primarily used by the
+     * generated reflected code.
+     *
+     *
+     * @return int
+     */
     public int getID() {
         if (mDestroyed) {
             throw new RSInvalidStateException("using a destroyed object.");
@@ -53,8 +60,15 @@
     private String mName;
     RenderScript mRS;
 
-    public void setName(String s) {
-        if(s.length() < 1) {
+    /**
+     * setName assigns a name to an object.  This object can later be looked up
+     * by this name.  This name will also be retained if the object is written
+     * to an A3D file.
+     *
+     * @param name The name to assign to the object.
+     */
+    public void setName(String name) {
+        if(name.length() < 1) {
             throw new RSIllegalArgumentException("setName does not accept a zero length string.");
         }
         if(mName != null) {
@@ -62,9 +76,9 @@
         }
 
         try {
-            byte[] bytes = s.getBytes("UTF-8");
+            byte[] bytes = name.getBytes("UTF-8");
             mRS.nAssignName(mID, bytes);
-            mName = s;
+            mName = name;
         } catch (java.io.UnsupportedEncodingException e) {
             throw new RuntimeException(e);
         }
@@ -84,6 +98,12 @@
         super.finalize();
     }
 
+    /**
+     * destroy disconnects the object from the native object effectivly
+     * rendering this java object dead.  The primary use is to force immediate
+     * cleanup of resources when its believed the GC will not respond quickly
+     * enough.
+     */
     synchronized public void destroy() {
         if(mDestroyed) {
             throw new RSInvalidStateException("Object already destroyed.");
@@ -92,8 +112,10 @@
         mRS.nObjDestroy(mID);
     }
 
-    // If an object came from an a3d file, java fields need to be
-    // created with objects from the native layer
+    /**
+     * If an object came from an a3d file, java fields need to be
+     * created with objects from the native layer
+     */
     void updateFromNative() {
         mRS.validate();
         mName = mRS.nGetName(getID());
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 64afb6f..df03e13 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -28,6 +28,13 @@
 /**
  * @hide
  *
+ * RenderScript base master class.  An instance of this class creates native
+ * worker threads for processing commands from this object.  This base class
+ * does not provide any extended capabilities beyond simple data processing.
+ * For extended capabilities use derived classes such as RenderScriptGL.
+ *
+ *
+ *
  **/
 public class RenderScript {
     static final String LOG_TAG = "RenderScript_jni";
@@ -581,6 +588,14 @@
     ///////////////////////////////////////////////////////////////////////////////////
     //
 
+    /**
+     * Base class application should derive from for handling RS messages
+     * comming from their scripts.  When a script calls sendToClient the data
+     * fields will be filled in and then the run method called by a message
+     * handling thread.  This will occur some time after sendToClient completes
+     * in the script.
+     *
+     */
     public static class RSMessage implements Runnable {
         protected int[] mData;
         protected int mID;
@@ -588,16 +603,42 @@
         public void run() {
         }
     }
+    /**
+     * If an application is expecting messages it should set this field to an
+     * instance of RSMessage.  This instance will receive all the user messages
+     * sent from sendToClient by scripts from this context.
+     *
+     */
     public RSMessage mMessageCallback = null;
 
+    /**
+     * Runtime error base class.  An application should derive from this class
+     * if it wishes to install an error handler.  When errors occur at runtime
+     * the fields in this class will be filled and the run method called.
+     *
+     */
     public static class RSAsyncError implements Runnable {
         protected String mErrorMessage;
         protected int mErrorNum;
         public void run() {
         }
     }
+
+    /**
+     * Application Error handler.  All runtime errors will be dispatched to the
+     * instance of RSAsyncError set here.  If this field is null a
+     * RSRuntimeException will instead be thrown with details about the error.
+     * This will cause program termaination.
+     *
+     */
     public RSAsyncError mErrorCallback = null;
 
+    /**
+     * RenderScript worker threads priority enumeration.  The default value is
+     * NORMAL.  Applications wishing to do background processing such as
+     * wallpapers should set their priority to LOW to avoid starving forground
+     * processes.
+     */
     public enum Priority {
         LOW (5),     //ANDROID_PRIORITY_BACKGROUND + 5
         NORMAL (-4);  //ANDROID_PRIORITY_DISPLAY
@@ -614,6 +655,12 @@
         }
     }
 
+
+    /**
+     * Change the priority of the worker threads for this context.
+     *
+     * @param p New priority to be set.
+     */
     public void contextSetPriority(Priority p) {
         validate();
         nContextSetPriority(p.mID);
@@ -690,9 +737,15 @@
         }
     }
 
-    protected RenderScript() {
+    RenderScript() {
     }
 
+    /**
+     * Create a basic RenderScript context.
+     *
+     *
+     * @return RenderScript
+     */
     public static RenderScript create() {
         RenderScript rs = new RenderScript();
 
@@ -704,15 +757,32 @@
         return rs;
     }
 
+    /**
+     * Print the currently available debugging information about the state of
+     * the RS context to the log.
+     *
+     *
+     * @param bits Currently ignored.
+     */
     public void contextDump(int bits) {
         validate();
         nContextDump(bits);
     }
 
+    /**
+     * Wait for any commands in the fifo between the java bindings and native to
+     * be processed.
+     *
+     */
     public void finish() {
         nContextFinish();
     }
 
+    /**
+     * Destroy this renderscript context.  Once this function is called its no
+     * longer legal to use this or any objects created by this context.
+     *
+     */
     public void destroy() {
         validate();
         nContextDeinitToClient(mContext);
@@ -733,9 +803,6 @@
         return mContext != 0;
     }
 
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Root state
-
     protected int safeID(BaseObj o) {
         if(o != null) {
             return o.getID();
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index cace063..181d4bd 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -30,12 +30,22 @@
 /**
  * @hide
  *
+ * The Graphics derivitive of RenderScript.  Extends the basic context to add a
+ * root script which is the display window for graphical output.  When the
+ * system needs to update the display the currently bound root script will be
+ * called.  This script is expected to issue the rendering commands to repaint
+ * the screen.
  **/
 public class RenderScriptGL extends RenderScript {
     private Surface mSurface;
     int mWidth;
     int mHeight;
 
+    /**
+     * Class which is used to describe a pixel format for a graphical buffer.
+     * This is used to describe the intended format of the display surface.
+     *
+     */
     public static class SurfaceConfig {
         int mDepthMin       = 0;
         int mDepthPref      = 0;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index 2012229..d8a59ce 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -295,7 +295,7 @@
 
             if (mParams.isCustomBackgroundEnabled()) {
                 Graphics2D gc = mImage.createGraphics();
-                gc.setColor(new Color(mParams.getCustomBackgroundColor()));
+                gc.setColor(new Color(mParams.getCustomBackgroundColor(), true));
                 gc.fillRect(0, 0, renderScreenWidth, renderScreenHeight - mScreenOffset);
                 gc.dispose();
             }