summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ActivityManagerNative.java29
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--core/java/android/app/PendingIntent.java14
-rw-r--r--core/java/android/appwidget/AppWidgetHost.java16
-rw-r--r--core/java/android/os/BatteryStats.java96
-rw-r--r--core/java/android/os/PowerManager.java2
-rw-r--r--core/java/android/util/IntProperty.java2
-rw-r--r--core/java/android/view/View.java15
-rw-r--r--core/java/android/widget/Editor.java56
-rw-r--r--core/java/android/widget/NumberPicker.java26
-rw-r--r--core/java/android/widget/TextView.java195
11 files changed, 357 insertions, 97 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 67d3930..61b2067 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1701,6 +1701,21 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case GET_INTENT_FOR_INTENT_SENDER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IIntentSender r = IIntentSender.Stub.asInterface(
+ data.readStrongBinder());
+ Intent intent = getIntentForIntentSender(r);
+ reply.writeNoException();
+ if (intent != null) {
+ reply.writeInt(1);
+ intent.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+ } else {
+ reply.writeInt(0);
+ }
+ return true;
+ }
+
case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -3977,6 +3992,20 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(sender.asBinder());
+ mRemote.transact(GET_INTENT_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
+ reply.readException();
+ Intent res = reply.readInt() != 0
+ ? Intent.CREATOR.createFromParcel(reply) : null;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
public void updatePersistentConfiguration(Configuration values) throws RemoteException
{
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8fc1c86..8af17a4 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -341,6 +341,8 @@ public interface IActivityManager extends IInterface {
public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException;
+ public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
+
public void updatePersistentConfiguration(Configuration values) throws RemoteException;
public long[] getProcessPss(int[] pids) throws RemoteException;
@@ -621,4 +623,5 @@ public interface IActivityManager extends IInterface {
int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157;
int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
+ int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
}
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index d36d99d..5c75aff 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -790,6 +790,20 @@ public final class PendingIntent implements Parcelable {
}
/**
+ * @hide
+ * Return the Intent of this PendingIntent.
+ */
+ public Intent getIntent() {
+ try {
+ return ActivityManagerNative.getDefault()
+ .getIntentForIntentSender(mTarget);
+ } catch (RemoteException e) {
+ // Should never happen.
+ return null;
+ }
+ }
+
+ /**
* Comparison operator on two PendingIntent objects, such that true
* is returned then they both represent the same operation from the
* same package. This allows you to use {@link #getActivity},
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index cb61a71..24fd2e4 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -224,6 +224,22 @@ public class AppWidgetHost {
}
}
+ /**
+ * Gets a list of all the appWidgetIds that are bound to the current host
+ *
+ * @hide
+ */
+ public int[] getAppWidgetIds() {
+ try {
+ if (sService == null) {
+ bindService();
+ }
+ return sService.getAppWidgetIdsForHost(mHostId);
+ } catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
+ }
+
private static void checkCallerIsSystem() {
int uid = Process.myUid();
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 54f2fe3..9821824 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -18,6 +18,8 @@ package android.os;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Formatter;
import java.util.List;
import java.util.Map;
@@ -1127,8 +1129,10 @@ public abstract class BatteryStats implements Parcelable {
if (totalTimeMillis != 0) {
sb.append(linePrefix);
formatTimeMs(sb, totalTimeMillis);
- if (name != null) sb.append(name);
- sb.append(' ');
+ if (name != null) {
+ sb.append(name);
+ sb.append(' ');
+ }
sb.append('(');
sb.append(count);
sb.append(" times)");
@@ -1440,8 +1444,21 @@ public abstract class BatteryStats implements Parcelable {
}
}
+ static final class TimerEntry {
+ final String mName;
+ final int mId;
+ final BatteryStats.Timer mTimer;
+ final long mTime;
+ TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
+ mName = name;
+ mId = id;
+ mTimer = timer;
+ mTime = time;
+ }
+ }
+
@SuppressWarnings("unused")
- public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) {
+ public final void dumpLocked(PrintWriter pw, String prefix, final int which, int reqUid) {
final long rawUptime = SystemClock.uptimeMillis() * 1000;
final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
final long batteryUptime = getBatteryUptime(rawUptime);
@@ -1516,19 +1533,43 @@ public abstract class BatteryStats implements Parcelable {
long txTotal = 0;
long fullWakeLockTimeTotalMicros = 0;
long partialWakeLockTimeTotalMicros = 0;
-
+
+ final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
+ @Override
+ public int compare(TimerEntry lhs, TimerEntry rhs) {
+ long lhsTime = lhs.mTime;
+ long rhsTime = rhs.mTime;
+ if (lhsTime < rhsTime) {
+ return 1;
+ }
+ if (lhsTime > rhsTime) {
+ return -1;
+ }
+ return 0;
+ }
+ };
+
if (reqUid < 0) {
Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
if (kernelWakelocks.size() > 0) {
+ final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
-
+ BatteryStats.Timer timer = ent.getValue();
+ long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
+ if (totalTimeMillis > 0) {
+ timers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
+ }
+ }
+ Collections.sort(timers, timerComparator);
+ for (int i=0; i<timers.size(); i++) {
+ TimerEntry timer = timers.get(i);
String linePrefix = ": ";
sb.setLength(0);
sb.append(prefix);
sb.append(" Kernel Wake lock ");
- sb.append(ent.getKey());
- linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
- linePrefix);
+ sb.append(timer.mName);
+ linePrefix = printWakeLock(sb, timer.mTimer, batteryRealtime, null,
+ which, linePrefix);
if (!linePrefix.equals(": ")) {
sb.append(" realtime");
// Only print out wake locks that were held
@@ -1537,7 +1578,9 @@ public abstract class BatteryStats implements Parcelable {
}
}
}
-
+
+ final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
+
for (int iu = 0; iu < NU; iu++) {
Uid u = uidStats.valueAt(iu);
rxTotal += u.getTcpBytesReceived(which);
@@ -1557,8 +1600,18 @@ public abstract class BatteryStats implements Parcelable {
Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
if (partialWakeTimer != null) {
- partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
+ long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
batteryRealtime, which);
+ if (totalTimeMicros > 0) {
+ if (reqUid < 0) {
+ // Only show the ordered list of all wake
+ // locks if the caller is not asking for data
+ // about a specific uid.
+ timers.add(new TimerEntry(ent.getKey(), u.getUid(),
+ partialWakeTimer, totalTimeMicros));
+ }
+ partialWakeLockTimeTotalMicros += totalTimeMicros;
+ }
}
}
}
@@ -1571,7 +1624,7 @@ public abstract class BatteryStats implements Parcelable {
sb.append(prefix);
sb.append(" Total full wakelock time: "); formatTimeMs(sb,
(fullWakeLockTimeTotalMicros + 500) / 1000);
- sb.append(", Total partial waklock time: "); formatTimeMs(sb,
+ sb.append(", Total partial wakelock time: "); formatTimeMs(sb,
(partialWakeLockTimeTotalMicros + 500) / 1000);
pw.println(sb.toString());
@@ -1676,9 +1729,26 @@ public abstract class BatteryStats implements Parcelable {
pw.println(getDischargeAmountScreenOnSinceCharge());
pw.print(prefix); pw.print(" Amount discharged while screen off: ");
pw.println(getDischargeAmountScreenOffSinceCharge());
- pw.println(" ");
+ pw.println();
+ }
+
+ if (timers.size() > 0) {
+ Collections.sort(timers, timerComparator);
+ pw.print(prefix); pw.println(" All partial wake locks:");
+ for (int i=0; i<timers.size(); i++) {
+ TimerEntry timer = timers.get(i);
+ sb.setLength(0);
+ sb.append(" Wake lock #");
+ sb.append(timer.mId);
+ sb.append(" ");
+ sb.append(timer.mName);
+ printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": ");
+ sb.append(" realtime");
+ pw.println(sb.toString());
+ }
+ timers.clear();
+ pw.println();
}
-
for (int iu=0; iu<NU; iu++) {
final int uid = uidStats.keyAt(iu);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 4a01113..736762f 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -182,6 +182,8 @@ public final class PowerManager {
* </p><p>
* Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported}
* to determine whether this wake lock level is supported.
+ * </p><p>
+ * Cannot be used with {@link #ACQUIRE_CAUSES_WAKEUP}.
* </p>
*
* {@hide}
diff --git a/core/java/android/util/IntProperty.java b/core/java/android/util/IntProperty.java
index 459d6b2..17977ca 100644
--- a/core/java/android/util/IntProperty.java
+++ b/core/java/android/util/IntProperty.java
@@ -42,7 +42,7 @@ public abstract class IntProperty<T> extends Property<T, Integer> {
@Override
final public void set(T object, Integer value) {
- set(object, value.intValue());
+ setValue(object, value.intValue());
}
} \ No newline at end of file
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ff44475..1747627 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -623,6 +623,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* @attr ref android.R.styleable#View_hapticFeedbackEnabled
* @attr ref android.R.styleable#View_keepScreenOn
* @attr ref android.R.styleable#View_layerType
+ * @attr ref android.R.styleable#View_layoutDirection
* @attr ref android.R.styleable#View_longClickable
* @attr ref android.R.styleable#View_minHeight
* @attr ref android.R.styleable#View_minWidth
@@ -660,6 +661,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* @attr ref android.R.styleable#View_soundEffectsEnabled
* @attr ref android.R.styleable#View_tag
* @attr ref android.R.styleable#View_textAlignment
+ * @attr ref android.R.styleable#View_textDirection
* @attr ref android.R.styleable#View_transformPivotX
* @attr ref android.R.styleable#View_transformPivotY
* @attr ref android.R.styleable#View_translationX
@@ -5854,6 +5856,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link #LAYOUT_DIRECTION_RTL},
* {@link #LAYOUT_DIRECTION_INHERIT} or
* {@link #LAYOUT_DIRECTION_LOCALE}.
+ *
* @attr ref android.R.styleable#View_layoutDirection
*
* @hide
@@ -5909,6 +5912,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
* is lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}.
+ *
+ * @attr ref android.R.styleable#View_layoutDirection
*/
@ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
@@ -16627,6 +16632,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE}
*
+ * @attr ref android.R.styleable#View_textDirection
+ *
* @hide
*/
@ViewDebug.ExportedProperty(category = "text", mapping = {
@@ -16656,6 +16663,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Resolution will be done if the value is set to TEXT_DIRECTION_INHERIT. The resolution
* proceeds up the parent chain of the view to get the value. If there is no parent, then it will
* return the default {@link #TEXT_DIRECTION_FIRST_STRONG}.
+ *
+ * @attr ref android.R.styleable#View_textDirection
*/
public void setTextDirection(int textDirection) {
if (getRawTextDirection() != textDirection) {
@@ -16684,6 +16693,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE}
+ *
+ * @attr ref android.R.styleable#View_textDirection
*/
public int getTextDirection() {
return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
@@ -16816,6 +16827,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link #TEXT_ALIGNMENT_VIEW_START},
* {@link #TEXT_ALIGNMENT_VIEW_END}
*
+ * @attr ref android.R.styleable#View_textAlignment
+ *
* @hide
*/
@ViewDebug.ExportedProperty(category = "text", mapping = {
@@ -16879,6 +16892,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link #TEXT_ALIGNMENT_TEXT_END},
* {@link #TEXT_ALIGNMENT_VIEW_START},
* {@link #TEXT_ALIGNMENT_VIEW_END}
+ *
+ * @attr ref android.R.styleable#View_textAlignment
*/
@ViewDebug.ExportedProperty(category = "text", mapping = {
@ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 521e686..85972c3 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -309,13 +309,15 @@ public class Editor {
}
private void setErrorIcon(Drawable icon) {
- final Drawables dr = mTextView.mDrawables;
- if (dr != null) {
- mTextView.setCompoundDrawables(dr.mDrawableLeft, dr.mDrawableTop, icon,
- dr.mDrawableBottom);
- } else {
- mTextView.setCompoundDrawables(null, null, icon, null);
+ Drawables dr = mTextView.mDrawables;
+ if (dr == null) {
+ mTextView.mDrawables = dr = new Drawables();
}
+ dr.setErrorDrawable(icon, mTextView);
+
+ mTextView.resetResolvedDrawables();
+ mTextView.invalidate();
+ mTextView.requestLayout();
}
private void hideError() {
@@ -329,7 +331,7 @@ public class Editor {
}
/**
- * Returns the Y offset to make the pointy top of the error point
+ * Returns the X offset to make the pointy top of the error point
* at the middle of the error icon.
*/
private int getErrorX() {
@@ -340,8 +342,23 @@ public class Editor {
final float scale = mTextView.getResources().getDisplayMetrics().density;
final Drawables dr = mTextView.mDrawables;
- return mTextView.getWidth() - mErrorPopup.getWidth() - mTextView.getPaddingRight() -
- (dr != null ? dr.mDrawableSizeRight : 0) / 2 + (int) (25 * scale + 0.5f);
+
+ final int layoutDirection = mTextView.getLayoutDirection();
+ int errorX;
+ int offset;
+ switch (layoutDirection) {
+ default:
+ case View.LAYOUT_DIRECTION_LTR:
+ offset = - (dr != null ? dr.mDrawableSizeRight : 0) / 2 + (int) (25 * scale + 0.5f);
+ errorX = mTextView.getWidth() - mErrorPopup.getWidth() -
+ mTextView.getPaddingRight() + offset;
+ break;
+ case View.LAYOUT_DIRECTION_RTL:
+ offset = (dr != null ? dr.mDrawableSizeLeft : 0) / 2 - (int) (25 * scale + 0.5f);
+ errorX = mTextView.getPaddingLeft() + offset;
+ break;
+ }
+ return errorX;
}
/**
@@ -358,16 +375,27 @@ public class Editor {
mTextView.getCompoundPaddingBottom() - compoundPaddingTop;
final Drawables dr = mTextView.mDrawables;
- int icontop = compoundPaddingTop +
- (vspace - (dr != null ? dr.mDrawableHeightRight : 0)) / 2;
+
+ final int layoutDirection = mTextView.getLayoutDirection();
+ int height;
+ switch (layoutDirection) {
+ default:
+ case View.LAYOUT_DIRECTION_LTR:
+ height = (dr != null ? dr.mDrawableHeightRight : 0);
+ break;
+ case View.LAYOUT_DIRECTION_RTL:
+ height = (dr != null ? dr.mDrawableHeightLeft : 0);
+ break;
+ }
+
+ int icontop = compoundPaddingTop + (vspace - height) / 2;
/*
* The "2" is the distance between the point and the top edge
* of the background.
*/
final float scale = mTextView.getResources().getDisplayMetrics().density;
- return icontop + (dr != null ? dr.mDrawableHeightRight : 0) - mTextView.getHeight() -
- (int) (2 * scale + 0.5f);
+ return icontop + height - mTextView.getHeight() - (int) (2 * scale + 0.5f);
}
void createInputContentTypeIfNeeded() {
@@ -3726,7 +3754,7 @@ public class Editor {
super(v, width, height);
mView = v;
// Make sure the TextView has a background set as it will be used the first time it is
- // shown and positionned. Initialized with below background, which should have
+ // shown and positioned. Initialized with below background, which should have
// dimensions identical to the above version for this to work (and is more likely).
mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
com.android.internal.R.styleable.Theme_errorMessageBackground);
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 4918e48..ac21671 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1284,7 +1284,12 @@ public class NumberPicker extends LinearLayout {
/**
* Sets the min value of the picker.
*
- * @param minValue The min value.
+ * @param minValue The min value inclusive.
+ *
+ * <strong>Note:</strong> The length of the displayed values array
+ * set via {@link #setDisplayedValues(String[])} must be equal to the
+ * range of selectable numbers which is equal to
+ * {@link #getMaxValue()} - {@link #getMinValue()} + 1.
*/
public void setMinValue(int minValue) {
if (mMinValue == minValue) {
@@ -1317,7 +1322,12 @@ public class NumberPicker extends LinearLayout {
/**
* Sets the max value of the picker.
*
- * @param maxValue The max value.
+ * @param maxValue The max value inclusive.
+ *
+ * <strong>Note:</strong> The length of the displayed values array
+ * set via {@link #setDisplayedValues(String[])} must be equal to the
+ * range of selectable numbers which is equal to
+ * {@link #getMaxValue()} - {@link #getMinValue()} + 1.
*/
public void setMaxValue(int maxValue) {
if (mMaxValue == maxValue) {
@@ -1351,6 +1361,10 @@ public class NumberPicker extends LinearLayout {
* Sets the values to be displayed.
*
* @param displayedValues The displayed values.
+ *
+ * <strong>Note:</strong> The length of the displayed values array
+ * must be equal to the range of selectable numbers which is equal to
+ * {@link #getMaxValue()} - {@link #getMinValue()} + 1.
*/
public void setDisplayedValues(String[] displayedValues) {
if (mDisplayedValues == displayedValues) {
@@ -1361,14 +1375,6 @@ public class NumberPicker extends LinearLayout {
// Allow text entry rather than strictly numeric entry.
mInputText.setRawInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
- // Make sure the min, max, respect the size of the displayed
- // values. This will take care of the current value as well.
- if (getMinValue() >= displayedValues.length) {
- setMinValue(0);
- }
- if (getMaxValue() >= displayedValues.length) {
- setMaxValue(displayedValues.length - 1);
- }
} else {
mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 267b22a..0a16a66 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -284,15 +284,144 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private TextUtils.TruncateAt mEllipsize;
static class Drawables {
+ final static int DRAWABLE_NONE = -1;
+ final static int DRAWABLE_RIGHT = 0;
+ final static int DRAWABLE_LEFT = 1;
+
final Rect mCompoundRect = new Rect();
+
Drawable mDrawableTop, mDrawableBottom, mDrawableLeft, mDrawableRight,
- mDrawableStart, mDrawableEnd;
+ mDrawableStart, mDrawableEnd, mDrawableError, mDrawableTemp;
+
int mDrawableSizeTop, mDrawableSizeBottom, mDrawableSizeLeft, mDrawableSizeRight,
- mDrawableSizeStart, mDrawableSizeEnd;
+ mDrawableSizeStart, mDrawableSizeEnd, mDrawableSizeError, mDrawableSizeTemp;
+
int mDrawableWidthTop, mDrawableWidthBottom, mDrawableHeightLeft, mDrawableHeightRight,
- mDrawableHeightStart, mDrawableHeightEnd;
+ mDrawableHeightStart, mDrawableHeightEnd, mDrawableHeightError, mDrawableHeightTemp;
+
int mDrawablePadding;
+
+ int mDrawableSaved = DRAWABLE_NONE;
+
+ public void resolveWithLayoutDirection(int layoutDirection) {
+ switch(layoutDirection) {
+ case LAYOUT_DIRECTION_RTL:
+ if (mDrawableStart != null) {
+ mDrawableRight = mDrawableStart;
+
+ mDrawableSizeRight = mDrawableSizeStart;
+ mDrawableHeightRight = mDrawableHeightStart;
+ }
+ if (mDrawableEnd != null) {
+ mDrawableLeft = mDrawableEnd;
+
+ mDrawableSizeLeft = mDrawableSizeEnd;
+ mDrawableHeightLeft = mDrawableHeightEnd;
+ }
+ break;
+
+ case LAYOUT_DIRECTION_LTR:
+ default:
+ if (mDrawableStart != null) {
+ mDrawableLeft = mDrawableStart;
+
+ mDrawableSizeLeft = mDrawableSizeStart;
+ mDrawableHeightLeft = mDrawableHeightStart;
+ }
+ if (mDrawableEnd != null) {
+ mDrawableRight = mDrawableEnd;
+
+ mDrawableSizeRight = mDrawableSizeEnd;
+ mDrawableHeightRight = mDrawableHeightEnd;
+ }
+ break;
+ }
+ applyErrorDrawableIfNeeded(layoutDirection);
+ updateDrawablesLayoutDirection(layoutDirection);
+ }
+
+ private void updateDrawablesLayoutDirection(int layoutDirection) {
+ if (mDrawableLeft != null) {
+ mDrawableLeft.setLayoutDirection(layoutDirection);
+ }
+ if (mDrawableRight != null) {
+ mDrawableRight.setLayoutDirection(layoutDirection);
+ }
+ if (mDrawableTop != null) {
+ mDrawableTop.setLayoutDirection(layoutDirection);
+ }
+ if (mDrawableBottom != null) {
+ mDrawableBottom.setLayoutDirection(layoutDirection);
+ }
+ }
+
+ public void setErrorDrawable(Drawable dr, TextView tv) {
+ if (mDrawableError != dr && mDrawableError != null) {
+ mDrawableError.setCallback(null);
+ }
+ mDrawableError = dr;
+
+ final Rect compoundRect = mCompoundRect;
+ int[] state = tv.getDrawableState();
+
+ if (mDrawableError != null) {
+ mDrawableError.setState(state);
+ mDrawableError.copyBounds(compoundRect);
+ mDrawableError.setCallback(tv);
+ mDrawableSizeError = compoundRect.width();
+ mDrawableHeightError = compoundRect.height();
+ } else {
+ mDrawableSizeError = mDrawableHeightError = 0;
+ }
+ }
+
+ private void applyErrorDrawableIfNeeded(int layoutDirection) {
+ // first restore the initial state if needed
+ switch (mDrawableSaved) {
+ case DRAWABLE_LEFT:
+ mDrawableLeft = mDrawableTemp;
+ mDrawableSizeLeft = mDrawableSizeTemp;
+ mDrawableHeightLeft = mDrawableHeightTemp;
+ break;
+ case DRAWABLE_RIGHT:
+ mDrawableRight = mDrawableTemp;
+ mDrawableSizeRight = mDrawableSizeTemp;
+ mDrawableHeightRight = mDrawableHeightTemp;
+ break;
+ case DRAWABLE_NONE:
+ default:
+ }
+ // then, if needed, assign the Error drawable to the correct location
+ if (mDrawableError != null) {
+ switch(layoutDirection) {
+ case LAYOUT_DIRECTION_RTL:
+ mDrawableSaved = DRAWABLE_LEFT;
+
+ mDrawableTemp = mDrawableLeft;
+ mDrawableSizeTemp = mDrawableSizeLeft;
+ mDrawableHeightTemp = mDrawableHeightLeft;
+
+ mDrawableLeft = mDrawableError;
+ mDrawableSizeLeft = mDrawableSizeError;
+ mDrawableHeightLeft = mDrawableHeightError;
+ break;
+ case LAYOUT_DIRECTION_LTR:
+ default:
+ mDrawableSaved = DRAWABLE_RIGHT;
+
+ mDrawableTemp = mDrawableRight;
+ mDrawableSizeTemp = mDrawableSizeRight;
+ mDrawableHeightTemp = mDrawableHeightRight;
+
+ mDrawableRight = mDrawableError;
+ mDrawableSizeRight = mDrawableSizeError;
+ mDrawableHeightRight = mDrawableHeightError;
+ break;
+ }
+ }
+ }
}
+
Drawables mDrawables;
private CharWrapper mCharWrapper;
@@ -8263,63 +8392,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return;
}
mLastLayoutDirection = layoutDirection;
- // No drawable to resolve
- if (mDrawables == null) {
- return;
- }
- // No relative drawable to resolve
- if (mDrawables.mDrawableStart == null && mDrawables.mDrawableEnd == null) {
- return;
- }
-
- Drawables dr = mDrawables;
- switch(layoutDirection) {
- case LAYOUT_DIRECTION_RTL:
- if (dr.mDrawableStart != null) {
- dr.mDrawableRight = dr.mDrawableStart;
-
- dr.mDrawableSizeRight = dr.mDrawableSizeStart;
- dr.mDrawableHeightRight = dr.mDrawableHeightStart;
- }
- if (dr.mDrawableEnd != null) {
- dr.mDrawableLeft = dr.mDrawableEnd;
- dr.mDrawableSizeLeft = dr.mDrawableSizeEnd;
- dr.mDrawableHeightLeft = dr.mDrawableHeightEnd;
- }
- break;
-
- case LAYOUT_DIRECTION_LTR:
- default:
- if (dr.mDrawableStart != null) {
- dr.mDrawableLeft = dr.mDrawableStart;
-
- dr.mDrawableSizeLeft = dr.mDrawableSizeStart;
- dr.mDrawableHeightLeft = dr.mDrawableHeightStart;
- }
- if (dr.mDrawableEnd != null) {
- dr.mDrawableRight = dr.mDrawableEnd;
-
- dr.mDrawableSizeRight = dr.mDrawableSizeEnd;
- dr.mDrawableHeightRight = dr.mDrawableHeightEnd;
- }
- break;
- }
- updateDrawablesLayoutDirection(dr, layoutDirection);
- }
-
- private void updateDrawablesLayoutDirection(Drawables dr, int layoutDirection) {
- if (dr.mDrawableLeft != null) {
- dr.mDrawableLeft.setLayoutDirection(layoutDirection);
- }
- if (dr.mDrawableRight != null) {
- dr.mDrawableRight.setLayoutDirection(layoutDirection);
- }
- if (dr.mDrawableTop != null) {
- dr.mDrawableTop.setLayoutDirection(layoutDirection);
- }
- if (dr.mDrawableBottom != null) {
- dr.mDrawableBottom.setLayoutDirection(layoutDirection);
+ // Resolve drawables
+ if (mDrawables != null) {
+ mDrawables.resolveWithLayoutDirection(layoutDirection);
}
}
@@ -8327,6 +8403,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
protected void resetResolvedDrawables() {
+ super.resetResolvedDrawables();
mLastLayoutDirection = -1;
}