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();
}