Merge "Fix glop rendering within unclipped saveLayers"
diff --git a/api/current.txt b/api/current.txt
index 676a1cd..a9cd058 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -141,6 +141,7 @@
field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";
+ field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
field public static final java.lang.String WAKE_LOCK = "android.permission.WAKE_LOCK";
@@ -296,6 +297,7 @@
field public static final int allowParallelSyncs = 16843570; // 0x1010332
field public static final int allowSingleTap = 16843353; // 0x1010259
field public static final int allowTaskReparenting = 16843268; // 0x1010204
+ field public static final int allowUndo = 16844006; // 0x10104e6
field public static final int alpha = 16843551; // 0x101031f
field public static final int alphabeticShortcut = 16843235; // 0x10101e3
field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
@@ -664,6 +666,8 @@
field public static final int host = 16842792; // 0x1010028
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
+ field public static final int iconTint = 16844000; // 0x10104e0
+ field public static final int iconTintMode = 16844001; // 0x10104e1
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
field public static final int id = 16842960; // 0x10100d0
field public static final int ignoreGravity = 16843263; // 0x10101ff
@@ -873,6 +877,8 @@
field public static final int navigationContentDescription = 16843969; // 0x10104c1
field public static final int navigationIcon = 16843968; // 0x10104c0
field public static final int navigationMode = 16843471; // 0x10102cf
+ field public static final int navigationTint = 16844004; // 0x10104e4
+ field public static final int navigationTintMode = 16844005; // 0x10104e5
field public static final int negativeButtonText = 16843254; // 0x10101f6
field public static final int nestedScrollingEnabled = 16843830; // 0x1010436
field public static final int nextFocusDown = 16842980; // 0x10100e4
@@ -904,6 +910,8 @@
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
+ field public static final int overflowTint = 16844002; // 0x10104e2
+ field public static final int overflowTintMode = 16844003; // 0x10104e3
field public static final int overlapAnchor = 16843874; // 0x1010462
field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
field public static final int packageNames = 16843649; // 0x1010381
@@ -1710,10 +1718,10 @@
field public static final int message = 16908299; // 0x102000b
field public static final int navigationBarBackground = 16908336; // 0x1020030
field public static final int paste = 16908322; // 0x1020022
- field public static final int pasteAsPlainText = 16908339; // 0x1020033
+ field public static final int pasteAsPlainText = 16908337; // 0x1020031
field public static final int primary = 16908300; // 0x102000c
field public static final int progress = 16908301; // 0x102000d
- field public static final int redo = 16908338; // 0x1020032
+ field public static final int redo = 16908339; // 0x1020033
field public static final int secondaryProgress = 16908303; // 0x102000f
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
@@ -1730,7 +1738,7 @@
field public static final int text2 = 16908309; // 0x1020015
field public static final int title = 16908310; // 0x1020016
field public static final int toggle = 16908311; // 0x1020017
- field public static final int undo = 16908337; // 0x1020031
+ field public static final int undo = 16908338; // 0x1020032
field public static final int widget_frame = 16908312; // 0x1020018
}
@@ -25050,9 +25058,12 @@
ctor public ContactsContract.QuickContact();
method public static void showQuickContact(android.content.Context, android.view.View, android.net.Uri, int, java.lang.String[]);
method public static void showQuickContact(android.content.Context, android.graphics.Rect, android.net.Uri, int, java.lang.String[]);
+ method public static void showQuickContact(android.content.Context, android.view.View, android.net.Uri, java.lang.String[], java.lang.String);
+ method public static void showQuickContact(android.content.Context, android.graphics.Rect, android.net.Uri, java.lang.String[], java.lang.String);
field public static final java.lang.String ACTION_QUICK_CONTACT = "android.provider.action.QUICK_CONTACT";
field public static final java.lang.String EXTRA_EXCLUDE_MIMES = "android.provider.extra.EXCLUDE_MIMES";
field public static final java.lang.String EXTRA_MODE = "android.provider.extra.MODE";
+ field public static final java.lang.String EXTRA_PRIORITIZED_MIMETYPE = "android.provider.extra.PRIORITIZED_MIMETYPE";
field public static final int MODE_LARGE = 3; // 0x3
field public static final int MODE_MEDIUM = 2; // 0x2
field public static final int MODE_SMALL = 1; // 0x1
@@ -28513,6 +28524,15 @@
field public static final int STDERR_FILENO;
field public static final int STDIN_FILENO;
field public static final int STDOUT_FILENO;
+ field public static final int ST_MANDLOCK;
+ field public static final int ST_NOATIME;
+ field public static final int ST_NODEV;
+ field public static final int ST_NODIRATIME;
+ field public static final int ST_NOEXEC;
+ field public static final int ST_NOSUID;
+ field public static final int ST_RDONLY;
+ field public static final int ST_RELATIME;
+ field public static final int ST_SYNCHRONOUS;
field public static final int S_IFBLK;
field public static final int S_IFCHR;
field public static final int S_IFDIR;
@@ -28752,6 +28772,7 @@
method public boolean handleMmi(java.lang.String);
method public boolean isInCall();
method public void showInCallScreen(boolean);
+ field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
@@ -33486,6 +33507,8 @@
method public abstract android.view.MenuItem setEnabled(boolean);
method public abstract android.view.MenuItem setIcon(android.graphics.drawable.Drawable);
method public abstract android.view.MenuItem setIcon(int);
+ method public abstract android.view.MenuItem setIconTintList(android.content.res.ColorStateList);
+ method public abstract android.view.MenuItem setIconTintMode(android.graphics.PorterDuff.Mode);
method public abstract android.view.MenuItem setIntent(android.content.Intent);
method public abstract android.view.MenuItem setNumericShortcut(char);
method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener);
@@ -37425,6 +37448,8 @@
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onDetachedFromWindow();
method public void setOnMenuItemClickListener(android.widget.ActionMenuView.OnMenuItemClickListener);
+ method public void setOverflowTintList(android.content.res.ColorStateList);
+ method public void setOverflowTintMode(android.graphics.PorterDuff.Mode);
method public void setPopupTheme(int);
method public boolean showOverflowMenu();
}
@@ -38753,6 +38778,7 @@
method public void setImageToDefault();
method public void setMode(int);
method public void setOverlay(android.graphics.drawable.Drawable);
+ method public void setPrioritizedMimeType(java.lang.String);
field protected java.lang.String[] mExcludeMimes;
}
@@ -38850,6 +38876,7 @@
method public void addRule(int);
method public void addRule(int, int);
method public java.lang.String debug(java.lang.String);
+ method public int getRule(int);
method public int[] getRules();
method public void removeRule(int);
field public boolean alignWithParent;
@@ -39719,7 +39746,11 @@
method public void setNavigationIcon(int);
method public void setNavigationIcon(android.graphics.drawable.Drawable);
method public void setNavigationOnClickListener(android.view.View.OnClickListener);
+ method public void setNavigationTintList(android.content.res.ColorStateList);
+ method public void setNavigationTintMode(android.graphics.PorterDuff.Mode);
method public void setOnMenuItemClickListener(android.widget.Toolbar.OnMenuItemClickListener);
+ method public void setOverflowTintList(android.content.res.ColorStateList);
+ method public void setOverflowTintMode(android.graphics.PorterDuff.Mode);
method public void setPopupTheme(int);
method public void setSubtitle(int);
method public void setSubtitle(java.lang.CharSequence);
diff --git a/api/system-current.txt b/api/system-current.txt
index 95e57c4..52586ed 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -210,6 +210,7 @@
field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";
+ field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
field public static final java.lang.String WAKE_LOCK = "android.permission.WAKE_LOCK";
@@ -368,6 +369,7 @@
field public static final int allowParallelSyncs = 16843570; // 0x1010332
field public static final int allowSingleTap = 16843353; // 0x1010259
field public static final int allowTaskReparenting = 16843268; // 0x1010204
+ field public static final int allowUndo = 16844006; // 0x10104e6
field public static final int alpha = 16843551; // 0x101031f
field public static final int alphabeticShortcut = 16843235; // 0x10101e3
field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
@@ -736,6 +738,8 @@
field public static final int host = 16842792; // 0x1010028
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
+ field public static final int iconTint = 16844000; // 0x10104e0
+ field public static final int iconTintMode = 16844001; // 0x10104e1
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
field public static final int id = 16842960; // 0x10100d0
field public static final int ignoreGravity = 16843263; // 0x10101ff
@@ -945,6 +949,8 @@
field public static final int navigationContentDescription = 16843969; // 0x10104c1
field public static final int navigationIcon = 16843968; // 0x10104c0
field public static final int navigationMode = 16843471; // 0x10102cf
+ field public static final int navigationTint = 16844004; // 0x10104e4
+ field public static final int navigationTintMode = 16844005; // 0x10104e5
field public static final int negativeButtonText = 16843254; // 0x10101f6
field public static final int nestedScrollingEnabled = 16843830; // 0x1010436
field public static final int nextFocusDown = 16842980; // 0x10100e4
@@ -976,6 +982,8 @@
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
+ field public static final int overflowTint = 16844002; // 0x10104e2
+ field public static final int overflowTintMode = 16844003; // 0x10104e3
field public static final int overlapAnchor = 16843874; // 0x1010462
field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
field public static final int packageNames = 16843649; // 0x1010381
@@ -1786,10 +1794,10 @@
field public static final int message = 16908299; // 0x102000b
field public static final int navigationBarBackground = 16908336; // 0x1020030
field public static final int paste = 16908322; // 0x1020022
- field public static final int pasteAsPlainText = 16908339; // 0x1020033
+ field public static final int pasteAsPlainText = 16908337; // 0x1020031
field public static final int primary = 16908300; // 0x102000c
field public static final int progress = 16908301; // 0x102000d
- field public static final int redo = 16908338; // 0x1020032
+ field public static final int redo = 16908339; // 0x1020033
field public static final int secondaryProgress = 16908303; // 0x102000f
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
@@ -1806,7 +1814,7 @@
field public static final int text2 = 16908309; // 0x1020015
field public static final int title = 16908310; // 0x1020016
field public static final int toggle = 16908311; // 0x1020017
- field public static final int undo = 16908337; // 0x1020031
+ field public static final int undo = 16908338; // 0x1020032
field public static final int widget_frame = 16908312; // 0x1020018
}
@@ -26649,9 +26657,12 @@
ctor public ContactsContract.QuickContact();
method public static void showQuickContact(android.content.Context, android.view.View, android.net.Uri, int, java.lang.String[]);
method public static void showQuickContact(android.content.Context, android.graphics.Rect, android.net.Uri, int, java.lang.String[]);
+ method public static void showQuickContact(android.content.Context, android.view.View, android.net.Uri, java.lang.String[], java.lang.String);
+ method public static void showQuickContact(android.content.Context, android.graphics.Rect, android.net.Uri, java.lang.String[], java.lang.String);
field public static final java.lang.String ACTION_QUICK_CONTACT = "android.provider.action.QUICK_CONTACT";
field public static final java.lang.String EXTRA_EXCLUDE_MIMES = "android.provider.extra.EXCLUDE_MIMES";
field public static final java.lang.String EXTRA_MODE = "android.provider.extra.MODE";
+ field public static final java.lang.String EXTRA_PRIORITIZED_MIMETYPE = "android.provider.extra.PRIORITIZED_MIMETYPE";
field public static final int MODE_LARGE = 3; // 0x3
field public static final int MODE_MEDIUM = 2; // 0x2
field public static final int MODE_SMALL = 1; // 0x1
@@ -30202,6 +30213,15 @@
field public static final int STDERR_FILENO;
field public static final int STDIN_FILENO;
field public static final int STDOUT_FILENO;
+ field public static final int ST_MANDLOCK;
+ field public static final int ST_NOATIME;
+ field public static final int ST_NODEV;
+ field public static final int ST_NODIRATIME;
+ field public static final int ST_NOEXEC;
+ field public static final int ST_NOSUID;
+ field public static final int ST_RDONLY;
+ field public static final int ST_RELATIME;
+ field public static final int ST_SYNCHRONOUS;
field public static final int S_IFBLK;
field public static final int S_IFCHR;
field public static final int S_IFDIR;
@@ -30872,6 +30892,7 @@
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+ field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
@@ -35647,6 +35668,8 @@
method public abstract android.view.MenuItem setEnabled(boolean);
method public abstract android.view.MenuItem setIcon(android.graphics.drawable.Drawable);
method public abstract android.view.MenuItem setIcon(int);
+ method public abstract android.view.MenuItem setIconTintList(android.content.res.ColorStateList);
+ method public abstract android.view.MenuItem setIconTintMode(android.graphics.PorterDuff.Mode);
method public abstract android.view.MenuItem setIntent(android.content.Intent);
method public abstract android.view.MenuItem setNumericShortcut(char);
method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener);
@@ -39884,6 +39907,8 @@
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onDetachedFromWindow();
method public void setOnMenuItemClickListener(android.widget.ActionMenuView.OnMenuItemClickListener);
+ method public void setOverflowTintList(android.content.res.ColorStateList);
+ method public void setOverflowTintMode(android.graphics.PorterDuff.Mode);
method public void setPopupTheme(int);
method public boolean showOverflowMenu();
}
@@ -41212,6 +41237,7 @@
method public void setImageToDefault();
method public void setMode(int);
method public void setOverlay(android.graphics.drawable.Drawable);
+ method public void setPrioritizedMimeType(java.lang.String);
field protected java.lang.String[] mExcludeMimes;
}
@@ -41309,6 +41335,7 @@
method public void addRule(int);
method public void addRule(int, int);
method public java.lang.String debug(java.lang.String);
+ method public int getRule(int);
method public int[] getRules();
method public void removeRule(int);
field public boolean alignWithParent;
@@ -42178,7 +42205,11 @@
method public void setNavigationIcon(int);
method public void setNavigationIcon(android.graphics.drawable.Drawable);
method public void setNavigationOnClickListener(android.view.View.OnClickListener);
+ method public void setNavigationTintList(android.content.res.ColorStateList);
+ method public void setNavigationTintMode(android.graphics.PorterDuff.Mode);
method public void setOnMenuItemClickListener(android.widget.Toolbar.OnMenuItemClickListener);
+ method public void setOverflowTintList(android.content.res.ColorStateList);
+ method public void setOverflowTintMode(android.graphics.PorterDuff.Mode);
method public void setPopupTheme(int);
method public void setSubtitle(int);
method public void setSubtitle(java.lang.CharSequence);
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 3a2c21b..a3b3022 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -31,20 +31,21 @@
import com.android.internal.R;
/**
- * A dialog that prompts the user for the time of day using a {@link TimePicker}.
+ * A dialog that prompts the user for the time of day using a
+ * {@link TimePicker}.
*
- * <p>See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
- * guide.</p>
+ * <p>
+ * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
+ * guide.
*/
public class TimePickerDialog extends AlertDialog implements OnClickListener,
OnTimeChangedListener {
-
private static final String HOUR = "hour";
private static final String MINUTE = "minute";
private static final String IS_24_HOUR = "is24hour";
private final TimePicker mTimePicker;
- private final OnTimeSetListener mTimeSetCallback;
+ private final OnTimeSetListener mTimeSetListener;
private final int mInitialHourOfDay;
private final int mInitialMinute;
@@ -52,59 +53,70 @@
/**
* The callback interface used to indicate the user is done filling in
- * the time (they clicked on the 'Done' button).
+ * the time (e.g. they clicked on the 'OK' button).
*/
public interface OnTimeSetListener {
-
/**
- * @param view The view associated with this listener.
- * @param hourOfDay The hour that was set.
- * @param minute The minute that was set.
+ * Called when the user is done setting a new time and the dialog has
+ * closed.
+ *
+ * @param view the view associated with this listener
+ * @param hourOfDay the hour that was set
+ * @param minute the minute that was set
*/
- void onTimeSet(TimePicker view, int hourOfDay, int minute);
+ public void onTimeSet(TimePicker view, int hourOfDay, int minute);
}
/**
- * @param context Parent.
- * @param callBack How parent is notified.
- * @param hourOfDay The initial hour.
- * @param minute The initial minute.
- * @param is24HourView Whether this is a 24 hour view, or AM/PM.
+ * Creates a new time picker dialog.
+ *
+ * @param context the parent context
+ * @param listener the listener to call when the time is set
+ * @param hourOfDay the initial hour
+ * @param minute the initial minute
+ * @param is24HourView whether this is a 24 hour view or AM/PM
*/
- public TimePickerDialog(Context context,
- OnTimeSetListener callBack,
- int hourOfDay, int minute, boolean is24HourView) {
- this(context, 0, callBack, hourOfDay, minute, is24HourView);
+ public TimePickerDialog(Context context, OnTimeSetListener listener, int hourOfDay, int minute,
+ boolean is24HourView) {
+ this(context, 0, listener, hourOfDay, minute, is24HourView);
}
- static int resolveDialogTheme(Context context, int resid) {
- if (resid == 0) {
+ static int resolveDialogTheme(Context context, int resId) {
+ if (resId == 0) {
final TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
return outValue.resourceId;
} else {
- return resid;
+ return resId;
}
}
/**
- * @param context Parent.
- * @param theme the theme to apply to this dialog
- * @param callBack How parent is notified.
- * @param hourOfDay The initial hour.
- * @param minute The initial minute.
+ * Creates a new time picker dialog with the specified theme.
+ *
+ * @param context the parent context
+ * @param themeResId the resource ID of the theme to apply to this dialog
+ * @param listener the listener to call when the time is set
+ * @param hourOfDay the initial hour
+ * @param minute the initial minute
* @param is24HourView Whether this is a 24 hour view, or AM/PM.
*/
- public TimePickerDialog(Context context, int theme, OnTimeSetListener callBack, int hourOfDay,
- int minute, boolean is24HourView) {
- super(context, resolveDialogTheme(context, theme));
+ public TimePickerDialog(Context context, int themeResId, OnTimeSetListener listener,
+ int hourOfDay, int minute, boolean is24HourView) {
+ super(context, resolveDialogTheme(context, themeResId));
- mTimeSetCallback = callBack;
+ mTimeSetListener = listener;
mInitialHourOfDay = hourOfDay;
mInitialMinute = minute;
mIs24HourView = is24HourView;
final Context themeContext = getContext();
+
+
+ final TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
+ final int layoutResId = outValue.resourceId;
+
final LayoutInflater inflater = LayoutInflater.from(themeContext);
final View view = inflater.inflate(R.layout.time_picker_dialog, null);
setView(view);
@@ -129,8 +141,8 @@
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case BUTTON_POSITIVE:
- if (mTimeSetCallback != null) {
- mTimeSetCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+ if (mTimeSetListener != null) {
+ mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute());
}
break;
diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java
index e3bc238..559b01c 100644
--- a/core/java/android/content/UndoManager.java
+++ b/core/java/android/content/UndoManager.java
@@ -105,8 +105,7 @@
return owner;
}
- owner = new UndoOwner(tag);
- owner.mManager = this;
+ owner = new UndoOwner(tag, this);
owner.mData = data;
mOwners.put(tag, owner);
return owner;
@@ -116,7 +115,6 @@
// XXX need to figure out how to prune.
if (false) {
mOwners.remove(owner.mTag);
- owner.mManager = null;
}
}
@@ -202,7 +200,7 @@
UndoOwner owner = mStateOwners[idx];
if (owner == null) {
String tag = in.readString();
- owner = new UndoOwner(tag);
+ owner = new UndoOwner(tag, this);
mStateOwners[idx] = owner;
mOwners.put(tag, owner);
}
diff --git a/core/java/android/content/UndoOwner.java b/core/java/android/content/UndoOwner.java
index d0cdc95..9106588 100644
--- a/core/java/android/content/UndoOwner.java
+++ b/core/java/android/content/UndoOwner.java
@@ -23,8 +23,8 @@
*/
public class UndoOwner {
final String mTag;
+ final UndoManager mManager;
- UndoManager mManager;
Object mData;
int mOpCount;
@@ -32,8 +32,15 @@
int mStateSeq;
int mSavedIdx;
- UndoOwner(String tag) {
+ UndoOwner(String tag, UndoManager manager) {
+ if (tag == null) {
+ throw new NullPointerException("tag can't be null");
+ }
+ if (manager == null) {
+ throw new NullPointerException("manager can't be null");
+ }
mTag = tag;
+ mManager = manager;
}
/**
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index b42d8bc..ace402a 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -462,46 +462,6 @@
return mColors;
}
- /**
- * If the color state list does not already have an entry matching the
- * specified state, prepends a state set and color pair to a color state
- * list.
- * <p>
- * This is a workaround used in TimePicker and DatePicker until we can
- * add support for theme attributes in ColorStateList.
- *
- * @param colorStateList the source color state list
- * @param state the state to prepend
- * @param color the color to use for the given state
- * @return a new color state list, or the source color state list if there
- * was already a matching state set
- *
- * @hide Remove when we can support theme attributes.
- */
- public static ColorStateList addFirstIfMissing(
- ColorStateList colorStateList, int state, int color) {
- final int[][] inputStates = colorStateList.getStates();
- for (int i = 0; i < inputStates.length; i++) {
- final int[] inputState = inputStates[i];
- for (int j = 0; j < inputState.length; j++) {
- if (inputState[j] == state) {
- return colorStateList;
- }
- }
- }
-
- final int[][] outputStates = new int[inputStates.length + 1][];
- System.arraycopy(inputStates, 0, outputStates, 1, inputStates.length);
- outputStates[0] = new int[] { state };
-
- final int[] inputColors = colorStateList.getColors();
- final int[] outputColors = new int[inputColors.length + 1];
- System.arraycopy(inputColors, 0, outputColors, 1, inputColors.length);
- outputColors[0] = color;
-
- return new ColorStateList(outputStates, outputColors);
- }
-
@Override
public String toString() {
return "ColorStateList{" +
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 67ac043..9cc12b5 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8069,6 +8069,14 @@
public static final String EXTRA_MODE = "android.provider.extra.MODE";
/**
+ * Extra used to specify which mimetype should be prioritized in the QuickContacts UI.
+ * For example, passing the value {@link CommonDataKinds.Phone#CONTENT_ITEM_TYPE} can
+ * cause phone numbers to be displayed more prominently in QuickContacts.
+ */
+ public static final String EXTRA_PRIORITIZED_MIMETYPE
+ = "android.provider.extra.PRIORITIZED_MIMETYPE";
+
+ /**
* Extra used to indicate a list of specific MIME-types to exclude and not display in the
* QuickContacts dialog. Stored as a {@link String} array.
*/
@@ -8206,6 +8214,80 @@
startActivityWithErrorToast(context, intent);
}
+ /**
+ * Trigger a dialog that lists the various methods of interacting with
+ * the requested {@link Contacts} entry. This may be based on available
+ * {@link ContactsContract.Data} rows under that contact, and may also
+ * include social status and presence details.
+ *
+ * @param context The parent {@link Context} that may be used as the
+ * parent for this dialog.
+ * @param target Specific {@link View} from your layout that this dialog
+ * should be centered around. In particular, if the dialog
+ * has a "callout" arrow, it will be pointed and centered
+ * around this {@link View}.
+ * @param lookupUri A
+ * {@link ContactsContract.Contacts#CONTENT_LOOKUP_URI} style
+ * {@link Uri} that describes a specific contact to feature
+ * in this dialog.
+ * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types
+ * to exclude when showing this dialog. For example, when
+ * already viewing the contact details card, this can be used
+ * to omit the details entry from the dialog.
+ * @param prioritizedMimeType This mimetype should be prioritized in the QuickContacts UI.
+ * For example, passing the value
+ * {@link CommonDataKinds.Phone#CONTENT_ITEM_TYPE} can cause phone numbers to be
+ * displayed more prominently in QuickContacts.
+ */
+ public static void showQuickContact(Context context, View target, Uri lookupUri,
+ String[] excludeMimes, String prioritizedMimeType) {
+ // Use MODE_LARGE instead of accepting mode as a parameter. The different mode
+ // values defined in ContactsContract only affect very old implementations
+ // of QuickContacts.
+ Intent intent = composeQuickContactsIntent(context, target, lookupUri, MODE_LARGE,
+ excludeMimes);
+ intent.putExtra(EXTRA_PRIORITIZED_MIMETYPE, prioritizedMimeType);
+ startActivityWithErrorToast(context, intent);
+ }
+
+ /**
+ * Trigger a dialog that lists the various methods of interacting with
+ * the requested {@link Contacts} entry. This may be based on available
+ * {@link ContactsContract.Data} rows under that contact, and may also
+ * include social status and presence details.
+ *
+ * @param context The parent {@link Context} that may be used as the
+ * parent for this dialog.
+ * @param target Specific {@link Rect} that this dialog should be
+ * centered around, in screen coordinates. In particular, if
+ * the dialog has a "callout" arrow, it will be pointed and
+ * centered around this {@link Rect}. If you are running at a
+ * non-native density, you need to manually adjust using
+ * {@link DisplayMetrics#density} before calling.
+ * @param lookupUri A
+ * {@link ContactsContract.Contacts#CONTENT_LOOKUP_URI} style
+ * {@link Uri} that describes a specific contact to feature
+ * in this dialog.
+ * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types
+ * to exclude when showing this dialog. For example, when
+ * already viewing the contact details card, this can be used
+ * to omit the details entry from the dialog.
+ * @param prioritizedMimeType This mimetype should be prioritized in the QuickContacts UI.
+ * For example, passing the value
+ * {@link CommonDataKinds.Phone#CONTENT_ITEM_TYPE} can cause phone numbers to be
+ * displayed more prominently in QuickContacts.
+ */
+ public static void showQuickContact(Context context, Rect target, Uri lookupUri,
+ String[] excludeMimes, String prioritizedMimeType) {
+ // Use MODE_LARGE instead of accepting mode as a parameter. The different mode
+ // values defined in ContactsContract only affect very old implementations
+ // of QuickContacts.
+ Intent intent = composeQuickContactsIntent(context, target, lookupUri, MODE_LARGE,
+ excludeMimes);
+ intent.putExtra(EXTRA_PRIORITIZED_MIMETYPE, prioritizedMimeType);
+ startActivityWithErrorToast(context, intent);
+ }
+
private static void startActivityWithErrorToast(Context context, Intent intent) {
try {
context.startActivity(intent);
diff --git a/core/java/android/service/fingerprint/FingerprintManager.java b/core/java/android/service/fingerprint/FingerprintManager.java
index 178cc8b..494c238 100644
--- a/core/java/android/service/fingerprint/FingerprintManager.java
+++ b/core/java/android/service/fingerprint/FingerprintManager.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.os.BaseBundle;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -31,6 +32,9 @@
import android.util.Log;
import android.util.Slog;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A class that coordinates access to the fingerprint hardware.
* @hide
@@ -97,6 +101,15 @@
}
};
+ public static final class FingerprintItem {
+ CharSequence name;
+ int id;
+ FingerprintItem(CharSequence name, int id) {
+ this.name = name;
+ this.id = id;
+ }
+ }
+
/**
* @hide
*/
@@ -248,4 +261,38 @@
private void sendError(int msg, int arg1, int arg2) {
mHandler.obtainMessage(msg, arg1, arg2);
}
+
+ /**
+ * @return list of current fingerprint items
+ * @hide
+ */
+ public List<FingerprintItem> getEnrolledFingerprints() {
+ int[] ids = FingerprintUtils.getFingerprintIdsForUser(mContext.getContentResolver(),
+ getCurrentUserId());
+ List<FingerprintItem> result = new ArrayList<FingerprintItem>();
+ for (int i = 0; i < ids.length; i++) {
+ // TODO: persist names in Settings
+ FingerprintItem item = new FingerprintItem("Finger" + ids[i], ids[i]);
+ result.add(item);
+ }
+ return result;
+ }
+
+ /**
+ * Determine if fingerprint hardware is present and functional.
+ * @return true if hardware is present and functional, false otherwise.
+ * @hide
+ */
+ public boolean isHardwareDetected() {
+ if (mService != null) {
+ try {
+ return mService.isHardwareDetected();
+ } catch (RemoteException e) {
+ Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
+ }
+ } else {
+ Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
+ }
+ return false;
+ }
}
\ No newline at end of file
diff --git a/core/java/android/service/fingerprint/FingerprintUtils.java b/core/java/android/service/fingerprint/FingerprintUtils.java
index a4caf8e..cc17b99 100644
--- a/core/java/android/service/fingerprint/FingerprintUtils.java
+++ b/core/java/android/service/fingerprint/FingerprintUtils.java
@@ -21,7 +21,11 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
* Utility class for dealing with fingerprints and fingerprint settings.
@@ -32,34 +36,50 @@
private static final boolean DEBUG = true;
private static final String TAG = "FingerprintUtils";
+ private static int[] toIntArray(List<Integer> list) {
+ if (list == null) {
+ return null;
+ }
+ int[] arr = new int[list.size()];
+ int i = 0;
+ for (int elem : list) {
+ arr[i] = elem;
+ i++;
+ }
+ return arr;
+ }
+
public static int[] getFingerprintIdsForUser(ContentResolver res, int userId) {
String fingerIdsRaw = Settings.Secure.getStringForUser(res,
Settings.Secure.USER_FINGERPRINT_IDS, userId);
-
- int result[] = {};
+ ArrayList<Integer> tmp = new ArrayList<Integer>();
if (!TextUtils.isEmpty(fingerIdsRaw)) {
String[] fingerStringIds = fingerIdsRaw.replace("[","").replace("]","").split(", ");
- result = new int[fingerStringIds.length];
- for (int i = 0; i < result.length; i++) {
+ int length = fingerStringIds.length;
+ for (int i = 0; i < length; i++) {
try {
- result[i] = Integer.decode(fingerStringIds[i]);
+ tmp.add(Integer.decode(fingerStringIds[i]));
} catch (NumberFormatException e) {
- if (DEBUG) Log.d(TAG, "Error when parsing finger id " + fingerStringIds[i]);
+ if (DEBUG) Log.w(TAG, "Error parsing finger id: '" + fingerStringIds[i] + "'");
}
}
}
- return result;
+ return toIntArray(tmp);
}
public static void addFingerprintIdForUser(int fingerId, ContentResolver res, int userId) {
+ // FingerId 0 has special meaning.
+ if (fingerId == 0) {
+ Log.w(TAG, "Tried to add fingerId 0");
+ return;
+ }
+
int[] fingerIds = getFingerprintIdsForUser(res, userId);
- // FingerId 0 has special meaning.
- if (fingerId == 0) return;
-
// Don't allow dups
- for (int i = 0; i < fingerIds.length; i++) {
- if (fingerIds[i] == fingerId) return;
+ if (ArrayUtils.contains(fingerIds, fingerId)) {
+ Log.w(TAG, "finger already added " + fingerId);
+ return;
}
int[] newList = Arrays.copyOf(fingerIds, fingerIds.length + 1);
newList[fingerIds.length] = fingerId;
@@ -72,19 +92,13 @@
// FingerId 0 has special meaning. The HAL layer is supposed to remove each finger one
// at a time and invoke notify() for each fingerId. If we get called with 0 here, it means
// something bad has happened.
- if (fingerId == 0) throw new IllegalStateException("Bad fingerId");
+ if (fingerId == 0) throw new IllegalArgumentException("fingerId can't be 0");
- int[] fingerIds = getFingerprintIdsForUser(res, userId);
- int[] resultIds = Arrays.copyOf(fingerIds, fingerIds.length);
- int resultCount = 0;
- for (int i = 0; i < fingerIds.length; i++) {
- if (fingerId != fingerIds[i]) {
- resultIds[resultCount++] = fingerIds[i];
- }
- }
- if (resultCount > 0) {
+ final int[] fingerIds = getFingerprintIdsForUser(res, userId);
+ if (ArrayUtils.contains(fingerIds, fingerId)) {
+ final int[] result = ArrayUtils.removeInt(fingerIds, fingerId);
Settings.Secure.putStringForUser(res, Settings.Secure.USER_FINGERPRINT_IDS,
- Arrays.toString(Arrays.copyOf(resultIds, resultCount)), userId);
+ Arrays.toString(result), userId);
return true;
}
return false;
diff --git a/core/java/android/service/fingerprint/IFingerprintService.aidl b/core/java/android/service/fingerprint/IFingerprintService.aidl
index 43d5e9a..a7d4090 100644
--- a/core/java/android/service/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/service/fingerprint/IFingerprintService.aidl
@@ -22,10 +22,10 @@
* Communication channel from client to the fingerprint service.
* @hide
*/
-oneway interface IFingerprintService {
+interface IFingerprintService {
// Any errors resulting from this call will be returned to the listener
void enroll(IBinder token, long timeout, int userId);
-
+
// Any errors resulting from this call will be returned to the listener
void enrollCancel(IBinder token, int userId);
@@ -38,4 +38,7 @@
// Stops listening for fingerprints
void stopListening(IBinder token, int userId);
+
+ // Determine if HAL is loaded and ready
+ boolean isHardwareDetected();
}
diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java
index 3492aa0..b49a59e 100644
--- a/core/java/android/view/MenuInflater.java
+++ b/core/java/android/view/MenuInflater.java
@@ -25,8 +25,11 @@
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -334,6 +337,11 @@
private ActionProvider itemActionProvider;
+ private ColorStateList itemIconTintList;
+ private boolean itemIconTintListSet;
+ private PorterDuff.Mode itemIconTintMode;
+ private boolean itemIconTintModeSet;
+
private static final int defaultGroupId = NO_ID;
private static final int defaultItemId = NO_ID;
private static final int defaultItemCategory = 0;
@@ -424,6 +432,23 @@
itemActionProvider = null;
}
+ if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTint)) {
+ itemIconTintList = a.getColorStateList(
+ com.android.internal.R.styleable.MenuItem_iconTint);
+ itemIconTintListSet = true;
+ } else {
+ itemIconTintList = null;
+ itemIconTintListSet = false;
+ }
+ if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTintMode)) {
+ itemIconTintMode = Drawable.parseTintMode(
+ a.getInt(com.android.internal.R.styleable.MenuItem_iconTintMode, -1), null);
+ itemIconTintModeSet = true;
+ } else {
+ itemIconTintMode = null;
+ itemIconTintModeSet = false;
+ }
+
a.recycle();
itemAdded = false;
@@ -486,6 +511,13 @@
if (itemActionProvider != null) {
item.setActionProvider(itemActionProvider);
}
+
+ if (itemIconTintListSet) {
+ item.setIconTintList(itemIconTintList);
+ }
+ if (itemIconTintModeSet) {
+ item.setIconTintMode(itemIconTintMode);
+ }
}
public MenuItem addItem() {
diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java
index 9e8b97e..2948007 100644
--- a/core/java/android/view/MenuItem.java
+++ b/core/java/android/view/MenuItem.java
@@ -21,6 +21,8 @@
import android.annotation.StringRes;
import android.app.Activity;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
@@ -599,4 +601,26 @@
* @return This menu item instance for call chaining
*/
public MenuItem setOnActionExpandListener(OnActionExpandListener listener);
+
+ /**
+ * Applies a tint to the icon drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link android.view.MenuItem#setIcon(android.graphics.drawable.Drawable)}
+ * will automatically mutate the drawable and apply the specified tint and tint mode.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public MenuItem setIconTintList(ColorStateList tint);
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setIconTintList(ColorStateList)} to the icon drawable. The default mode is {@link
+ * PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 502d5ee..6d3c07a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16,9 +16,7 @@
package android.view;
-import android.animation.Animator;
import android.animation.AnimatorInflater;
-import android.animation.ObjectAnimator;
import android.animation.StateListAnimator;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
@@ -34,10 +32,13 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Insets;
+import android.graphics.Interpolator;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
@@ -4325,7 +4326,9 @@
* @hide This is the real method; the public one is shimmed to be safe to call from apps.
*/
protected void initializeFadingEdgeInternal(TypedArray a) {
- getScrollCache().fadingEdgeLength = a.getDimensionPixelSize(
+ initScrollCache();
+
+ mScrollCache.fadingEdgeLength = a.getDimensionPixelSize(
R.styleable.View_fadingEdgeLength,
ViewConfiguration.get(mContext).getScaledFadingEdgeLength());
}
@@ -4359,7 +4362,8 @@
* content in this view is visible.
*/
public void setFadingEdgeLength(int length) {
- getScrollCache().fadingEdgeLength = length;
+ initScrollCache();
+ mScrollCache.fadingEdgeLength = length;
}
/**
@@ -4463,7 +4467,10 @@
* @hide
*/
protected void initializeScrollbarsInternal(TypedArray a) {
- final ScrollabilityCache scrollabilityCache = getScrollCache();
+ initScrollCache();
+
+ final ScrollabilityCache scrollabilityCache = mScrollCache;
+
if (scrollabilityCache.scrollBar == null) {
scrollabilityCache.scrollBar = new ScrollBarDrawable();
scrollabilityCache.scrollBar.setCallback(this);
@@ -4471,16 +4478,23 @@
}
final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true);
- scrollabilityCache.setFadingEnabled(fadeScrollbars);
+
+ if (!fadeScrollbars) {
+ scrollabilityCache.state = ScrollabilityCache.ON;
+ }
+ scrollabilityCache.fadeScrollBars = fadeScrollbars;
+
scrollabilityCache.scrollBarFadeDuration = a.getInt(
- R.styleable.View_scrollbarFadeDuration,
- ViewConfiguration.getScrollBarFadeDuration());
+ R.styleable.View_scrollbarFadeDuration, ViewConfiguration
+ .getScrollBarFadeDuration());
scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
R.styleable.View_scrollbarDefaultDelayBeforeFade,
ViewConfiguration.getScrollDefaultDelay());
+
+
scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
- R.styleable.View_scrollbarSize,
+ com.android.internal.R.styleable.View_scrollbarSize,
ViewConfiguration.get(mContext).getScaledScrollBarSize());
Drawable track = a.getDrawable(R.styleable.View_scrollbarTrackHorizontal);
@@ -4525,12 +4539,18 @@
}
/**
- * Returns the scrollability cache, initializing a new cache if necessary.
+ * <p>
+ * Initalizes the scrollability cache if necessary.
+ * </p>
*/
- private ScrollabilityCache getScrollCache() {
+ private void initScrollCache() {
if (mScrollCache == null) {
- mScrollCache = new ScrollabilityCache(this);
+ mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
}
+ }
+
+ private ScrollabilityCache getScrollCache() {
+ initScrollCache();
return mScrollCache;
}
@@ -10047,6 +10067,10 @@
*
* @return The measured width of this view as a bit mask.
*/
+ @ViewDebug.ExportedProperty(category = "measurement", flagMapping = {
+ @ViewDebug.FlagToString(mask = MEASURED_STATE_MASK, equals = MEASURED_STATE_TOO_SMALL,
+ name = "MEASURED_STATE_TOO_SMALL"),
+ })
public final int getMeasuredWidthAndState() {
return mMeasuredWidth;
}
@@ -10071,6 +10095,10 @@
*
* @return The measured width of this view as a bit mask.
*/
+ @ViewDebug.ExportedProperty(category = "measurement", flagMapping = {
+ @ViewDebug.FlagToString(mask = MEASURED_STATE_MASK, equals = MEASURED_STATE_TOO_SMALL,
+ name = "MEASURED_STATE_TOO_SMALL"),
+ })
public final int getMeasuredHeightAndState() {
return mMeasuredHeight;
}
@@ -11551,30 +11579,31 @@
* @see #setVerticalScrollBarEnabled(boolean)
*/
protected boolean awakenScrollBars() {
- return mScrollCache != null
- && awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
+ return mScrollCache != null &&
+ awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
}
/**
* Trigger the scrollbars to draw.
- * <p>
* This method differs from awakenScrollBars() only in its default duration.
* initialAwakenScrollBars() will show the scroll bars for longer than
* usual to give the user more of a chance to notice them.
*
* @return true if the animation is played, false otherwise.
- * @see #awakenScrollBars()
*/
private boolean initialAwakenScrollBars() {
- return mScrollCache != null
- && awakenScrollBars(mScrollCache.scrollBarDelayBeforeInitialFade, true);
+ return mScrollCache != null &&
+ awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true);
}
/**
+ * <p>
* Trigger the scrollbars to draw. When invoked this method starts an
* animation to fade the scrollbars out after a fixed delay. If a subclass
* provides animated scrolling, the start delay should equal the duration of
* the scrolling animation.
+ * </p>
+ *
* <p>
* The animation starts only if at least one of the scrollbars is enabled,
* as specified by {@link #isHorizontalScrollBarEnabled()} and
@@ -11582,14 +11611,18 @@
* this method returns true, and false otherwise. If the animation is
* started, this method calls {@link #invalidate()}; in that case the caller
* should not call {@link #invalidate()}.
+ * </p>
+ *
* <p>
* This method should be invoked every time a subclass directly updates the
* scroll parameters.
+ * </p>
*
- * @param fadeOutDelay the delay in milliseconds before the fade out
- * animation should start, or 0 to start the animation
- * immediately
+ * @param startDelay the delay, in milliseconds, after which the animation
+ * should start; when the delay is 0, the animation starts
+ * immediately
* @return true if the animation is played, false otherwise
+ *
* @see #scrollBy(int, int)
* @see #scrollTo(int, int)
* @see #isHorizontalScrollBarEnabled()
@@ -11597,15 +11630,18 @@
* @see #setHorizontalScrollBarEnabled(boolean)
* @see #setVerticalScrollBarEnabled(boolean)
*/
- protected boolean awakenScrollBars(int fadeOutDelay) {
- return awakenScrollBars(fadeOutDelay, true);
+ protected boolean awakenScrollBars(int startDelay) {
+ return awakenScrollBars(startDelay, true);
}
/**
+ * <p>
* Trigger the scrollbars to draw. When invoked this method starts an
* animation to fade the scrollbars out after a fixed delay. If a subclass
* provides animated scrolling, the start delay should equal the duration of
* the scrolling animation.
+ * </p>
+ *
* <p>
* The animation starts only if at least one of the scrollbars is enabled,
* as specified by {@link #isHorizontalScrollBarEnabled()} and
@@ -11614,18 +11650,21 @@
* started, this method calls {@link #invalidate()} if the invalidate parameter
* is set to true; in that case the caller
* should not call {@link #invalidate()}.
+ * </p>
+ *
* <p>
* This method should be invoked every time a subclass directly updates the
* scroll parameters.
- * <p>
- * <strong>Note:</strong> If the view has not explicitly requested
- * scrollbars prior calling this method, this is a no-op.
+ * </p>
*
- * @param fadeOutDelay the delay in milliseconds before the fade out
- * animation should start, or 0 to start the animation
- * immediately
- * @param invalidate whether this method should call invalidate
+ * @param startDelay the delay, in milliseconds, after which the animation
+ * should start; when the delay is 0, the animation starts
+ * immediately
+ *
+ * @param invalidate Whether this method should call invalidate
+ *
* @return true if the animation is played, false otherwise
+ *
* @see #scrollBy(int, int)
* @see #scrollTo(int, int)
* @see #isHorizontalScrollBarEnabled()
@@ -11633,15 +11672,50 @@
* @see #setHorizontalScrollBarEnabled(boolean)
* @see #setVerticalScrollBarEnabled(boolean)
*/
- protected boolean awakenScrollBars(int fadeOutDelay, boolean invalidate) {
- if (mScrollCache == null
- || (!isHorizontalScrollBarEnabled() && !isVerticalScrollBarEnabled())) {
- // We're not supposed to show scroll bars right now.
+ protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
+ final ScrollabilityCache scrollCache = mScrollCache;
+
+ if (scrollCache == null || !scrollCache.fadeScrollBars) {
return false;
}
- mScrollCache.awakenScrollBars(fadeOutDelay);
- return true;
+ if (scrollCache.scrollBar == null) {
+ scrollCache.scrollBar = new ScrollBarDrawable();
+ scrollCache.scrollBar.setCallback(this);
+ scrollCache.scrollBar.setState(getDrawableState());
+ }
+
+ if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
+
+ if (invalidate) {
+ // Invalidate to show the scrollbars
+ postInvalidateOnAnimation();
+ }
+
+ if (scrollCache.state == ScrollabilityCache.OFF) {
+ // FIXME: this is copied from WindowManagerService.
+ // We should get this value from the system when it
+ // is possible to do so.
+ final int KEY_REPEAT_FIRST_DELAY = 750;
+ startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
+ }
+
+ // Tell mScrollCache when we should start fading. This may
+ // extend the fade start time if one was already scheduled
+ long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay;
+ scrollCache.fadeStartTime = fadeStartTime;
+ scrollCache.state = ScrollabilityCache.ON;
+
+ // Schedule our fader to run, unscheduling any old ones first
+ if (mAttachInfo != null) {
+ mAttachInfo.mHandler.removeCallbacks(scrollCache);
+ mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
+ }
+
+ return true;
+ }
+
+ return false;
}
/**
@@ -12322,7 +12396,7 @@
public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) {
if (isHorizontalFadingEdgeEnabled() != horizontalFadingEdgeEnabled) {
if (horizontalFadingEdgeEnabled) {
- getScrollCache();
+ initScrollCache();
}
mViewFlags ^= FADING_EDGE_HORIZONTAL;
@@ -12359,7 +12433,7 @@
public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) {
if (isVerticalFadingEdgeEnabled() != verticalFadingEdgeEnabled) {
if (verticalFadingEdgeEnabled) {
- getScrollCache();
+ initScrollCache();
}
mViewFlags ^= FADING_EDGE_VERTICAL;
@@ -12499,7 +12573,14 @@
* @attr ref android.R.styleable#View_fadeScrollbars
*/
public void setScrollbarFadingEnabled(boolean fadeScrollbars) {
- getScrollCache().setFadingEnabled(fadeScrollbars);
+ initScrollCache();
+ final ScrollabilityCache scrollabilityCache = mScrollCache;
+ scrollabilityCache.fadeScrollBars = fadeScrollbars;
+ if (fadeScrollbars) {
+ scrollabilityCache.state = ScrollabilityCache.OFF;
+ } else {
+ scrollabilityCache.state = ScrollabilityCache.ON;
+ }
}
/**
@@ -12511,7 +12592,7 @@
* @attr ref android.R.styleable#View_fadeScrollbars
*/
public boolean isScrollbarFadingEnabled() {
- return mScrollCache != null && mScrollCache.isFadingEnabled();
+ return mScrollCache != null && mScrollCache.fadeScrollBars;
}
/**
@@ -12793,85 +12874,129 @@
}
/**
- * Request the drawing of the horizontal and the vertical scrollbar. The
- * scrollbars are painted only if they have been awakened first.
+ * <p>Request the drawing of the horizontal and the vertical scrollbar. The
+ * scrollbars are painted only if they have been awakened first.</p>
*
* @param canvas the canvas on which to draw the scrollbars
+ *
* @see #awakenScrollBars(int)
*/
protected final void onDrawScrollBars(Canvas canvas) {
+ // scrollbars are drawn only when the animation is running
final ScrollabilityCache cache = mScrollCache;
- if (cache == null) {
- // This view does not currently support scrolling.
- return;
- }
+ if (cache != null) {
- final int viewFlags = mViewFlags;
- final boolean drawHorizontalScrollBar =
- (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
- final boolean drawVerticalScrollBar =
- (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
- && !isVerticalScrollBarHidden();
- if (!drawVerticalScrollBar && !drawHorizontalScrollBar) {
- // This view does not currently draw scrollbars.
- return;
- }
+ int state = cache.state;
- final ScrollBarDrawable scrollBar = cache.scrollBar;
- final int width = mRight - mLeft;
- final int height = mBottom - mTop;
- final int scrollX = mScrollX;
- final int scrollY = mScrollY;
- final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
-
- if (drawHorizontalScrollBar) {
- int size = scrollBar.getSize(false);
- if (size <= 0) {
- size = cache.scrollBarSize;
+ if (state == ScrollabilityCache.OFF) {
+ return;
}
- scrollBar.setParameters(computeHorizontalScrollRange(), computeHorizontalScrollOffset(),
- computeHorizontalScrollExtent(), false);
- final int verticalScrollBarGap = drawVerticalScrollBar ?
- getVerticalScrollbarWidth() : 0;
+ boolean invalidate = false;
- final int left = scrollX + (mPaddingLeft & inside);
- final int right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
- final int top = scrollY + height - size - (mUserPaddingBottom & inside);
- final int bottom = top + size;
+ if (state == ScrollabilityCache.FADING) {
+ // We're fading -- get our fade interpolation
+ if (cache.interpolatorValues == null) {
+ cache.interpolatorValues = new float[1];
+ }
- onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
- }
+ float[] values = cache.interpolatorValues;
- if (drawVerticalScrollBar) {
- int size = scrollBar.getSize(true);
- if (size <= 0) {
- size = cache.scrollBarSize;
- }
+ // Stops the animation if we're done
+ if (cache.scrollBarInterpolator.timeToValues(values) ==
+ Interpolator.Result.FREEZE_END) {
+ cache.state = ScrollabilityCache.OFF;
+ } else {
+ cache.scrollBar.mutate().setAlpha(Math.round(values[0]));
+ }
- scrollBar.setParameters(computeVerticalScrollRange(), computeVerticalScrollOffset(),
- computeVerticalScrollExtent(), true);
-
- final int verticalScrollbarPosition;
- if (mVerticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
- verticalScrollbarPosition = isLayoutRtl() ?
- SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
+ // This will make the scroll bars inval themselves after
+ // drawing. We only want this when we're fading so that
+ // we prevent excessive redraws
+ invalidate = true;
} else {
- verticalScrollbarPosition = mVerticalScrollbarPosition;
+ // We're just on -- but we may have been fading before so
+ // reset alpha
+ cache.scrollBar.mutate().setAlpha(255);
}
- final int left;
- if (verticalScrollbarPosition == SCROLLBAR_POSITION_LEFT) {
- left = scrollX + (mUserPaddingLeft & inside);
- } else {
- left = scrollX + width - size - (mUserPaddingRight & inside);
+
+ final int viewFlags = mViewFlags;
+
+ final boolean drawHorizontalScrollBar =
+ (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
+ final boolean drawVerticalScrollBar =
+ (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
+ && !isVerticalScrollBarHidden();
+
+ if (drawVerticalScrollBar || drawHorizontalScrollBar) {
+ final int width = mRight - mLeft;
+ final int height = mBottom - mTop;
+
+ final ScrollBarDrawable scrollBar = cache.scrollBar;
+
+ final int scrollX = mScrollX;
+ final int scrollY = mScrollY;
+ final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
+
+ int left;
+ int top;
+ int right;
+ int bottom;
+
+ if (drawHorizontalScrollBar) {
+ int size = scrollBar.getSize(false);
+ if (size <= 0) {
+ size = cache.scrollBarSize;
+ }
+
+ scrollBar.setParameters(computeHorizontalScrollRange(),
+ computeHorizontalScrollOffset(),
+ computeHorizontalScrollExtent(), false);
+ final int verticalScrollBarGap = drawVerticalScrollBar ?
+ getVerticalScrollbarWidth() : 0;
+ top = scrollY + height - size - (mUserPaddingBottom & inside);
+ left = scrollX + (mPaddingLeft & inside);
+ right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
+ bottom = top + size;
+ onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
+ if (invalidate) {
+ invalidate(left, top, right, bottom);
+ }
+ }
+
+ if (drawVerticalScrollBar) {
+ int size = scrollBar.getSize(true);
+ if (size <= 0) {
+ size = cache.scrollBarSize;
+ }
+
+ scrollBar.setParameters(computeVerticalScrollRange(),
+ computeVerticalScrollOffset(),
+ computeVerticalScrollExtent(), true);
+ int verticalScrollbarPosition = mVerticalScrollbarPosition;
+ if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
+ verticalScrollbarPosition = isLayoutRtl() ?
+ SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
+ }
+ switch (verticalScrollbarPosition) {
+ default:
+ case SCROLLBAR_POSITION_RIGHT:
+ left = scrollX + width - size - (mUserPaddingRight & inside);
+ break;
+ case SCROLLBAR_POSITION_LEFT:
+ left = scrollX + (mUserPaddingLeft & inside);
+ break;
+ }
+ top = scrollY + (mPaddingTop & inside);
+ right = left + size;
+ bottom = scrollY + height - (mUserPaddingBottom & inside);
+ onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
+ if (invalidate) {
+ invalidate(left, top, right, bottom);
+ }
+ }
}
-
- final int top = scrollY + (mPaddingTop & inside);
- final int right = left + size;
- final int bottom = scrollY + height - (mUserPaddingBottom & inside);
-
- onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
}
}
@@ -12978,7 +13103,9 @@
if (isFocused()) {
InputMethodManager imm = InputMethodManager.peekInstance();
- imm.focusIn(this);
+ if (imm != null) {
+ imm.focusIn(this);
+ }
}
}
@@ -15235,7 +15362,7 @@
canvas.saveLayer(right - length, top, right, bottom, null, flags);
}
} else {
- scrollabilityCache.setFadingEdgeColor(solidColor);
+ scrollabilityCache.setFadeColor(solidColor);
}
// Step 3, draw the content
@@ -15245,9 +15372,9 @@
dispatchDraw(canvas);
// Step 5, draw the fade effect and restore layers
- final Paint p = scrollabilityCache.fadingEdgePaint;
+ final Paint p = scrollabilityCache.paint;
final Matrix matrix = scrollabilityCache.matrix;
- final Shader fade = scrollabilityCache.fadingEdgeShader;
+ final Shader fade = scrollabilityCache.shader;
if (drawTop) {
matrix.setScale(1, fadeHeight * topFadeStrength);
@@ -20507,164 +20634,121 @@
}
/**
- * ScrollabilityCache holds various fields used by a View when scrolling
+ * <p>ScrollabilityCache holds various fields used by a View when scrolling
* is supported. This avoids keeping too many unused fields in most
- * instances of View.
+ * instances of View.</p>
*/
- private static class ScrollabilityCache {
- public final Paint fadingEdgePaint = new Paint();
- public final Matrix matrix = new Matrix();
-
- /** The view that owns this cache. */
- private final View mHost;
+ private static class ScrollabilityCache implements Runnable {
/**
- * Minimum delay in milliseconds before the fade-out animation begins.
- * Only used if the scrollbar was previously invisible.
+ * Scrollbars are not visible
*/
- private static final int MIN_FADE_DELAY_FROM_OFF = 750;
+ public static final int OFF = 0;
/**
- * Default delay in milliseconds before the fade-out animation begins.
+ * Scrollbars are visible
*/
+ public static final int ON = 1;
+
+ /**
+ * Scrollbars are fading away
+ */
+ public static final int FADING = 2;
+
+ public boolean fadeScrollBars;
+
+ public int fadingEdgeLength;
public int scrollBarDefaultDelayBeforeFade;
-
- /**
- * Delay in milliseconds before the fade-out animation begins. Only
- * used if the scrollbar is being shown to the user for the first time.
- */
- public int scrollBarDelayBeforeInitialFade;
-
- /** Duration in milliseconds of the fade-out animation. */
public int scrollBarFadeDuration;
- public ScrollBarDrawable scrollBar;
- public Shader fadingEdgeShader;
- public int fadingEdgeLength;
public int scrollBarSize;
+ public ScrollBarDrawable scrollBar;
+ public float[] interpolatorValues;
+ public View host;
+
+ public final Paint paint;
+ public final Matrix matrix;
+ public Shader shader;
+
+ public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
+
+ private static final float[] OPAQUE = { 255 };
+ private static final float[] TRANSPARENT = { 0.0f };
/**
- * Whether scrollbar fading is enabled. If false, scrollbars are always
- * visible.
+ * When fading should start. This time moves into the future every time
+ * a new scroll happens. Measured based on SystemClock.uptimeMillis()
*/
- private boolean mIsFadingEnabled;
+ public long fadeStartTime;
- private Animator mFadeAnim;
- private int mFadingEdgeLastColor;
- public ScrollabilityCache(View host) {
- mHost = host;
+ /**
+ * The current state of the scrollbars: ON, OFF, or FADING
+ */
+ public int state = OFF;
- scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
- scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
- scrollBarDelayBeforeInitialFade = ViewConfiguration.getScrollDefaultInitialDelay();
+ private int mLastColor;
- final ViewConfiguration configuration = ViewConfiguration.get(host.getContext());
- scrollBarSize = configuration.getScaledScrollBarSize();
+ public ScrollabilityCache(ViewConfiguration configuration, View host) {
fadingEdgeLength = configuration.getScaledFadingEdgeLength();
+ scrollBarSize = configuration.getScaledScrollBarSize();
+ scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
+ scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
- // Force the fading edge color to change.
- mFadingEdgeLastColor = -1;
- setFadingEdgeColor(0);
+ paint = new Paint();
+ matrix = new Matrix();
+ // use use a height of 1, and then wack the matrix each time we
+ // actually use it.
+ shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+
+ this.host = host;
}
- public void setFadingEdgeColor(int color) {
- if (mFadingEdgeLastColor != color) {
- mFadingEdgeLastColor = color;
+ public void setFadeColor(int color) {
+ if (color != mLastColor) {
+ mLastColor = color;
- final int color0;
- final int color1;
- final PorterDuffXfermode xfermode;
if (color != 0) {
- color0 = color | 0xFF000000;
- color1 = color & 0x00FFFFFF;
- xfermode = null;
+ shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
+ color & 0x00FFFFFF, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ // Restore the default transfer mode (src_over)
+ paint.setXfermode(null);
} else {
- color0 = 0xFF000000;
- color1 = 0;
- xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
+ shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
-
- // Use a height of 1 and then whack the matrix each time we
- // actually use it.
- fadingEdgeShader = new LinearGradient(
- 0, 0, 0, 1, color0, color1, Shader.TileMode.CLAMP);
- fadingEdgePaint.setShader(fadingEdgeShader);
- fadingEdgePaint.setXfermode(xfermode);
}
}
- public void setFadingEnabled(boolean enabled) {
- if (mIsFadingEnabled != enabled) {
- mIsFadingEnabled = enabled;
+ public void run() {
+ long now = AnimationUtils.currentAnimationTimeMillis();
+ if (now >= fadeStartTime) {
- setFadingAlpha(enabled ? 0 : 255);
+ // the animation fades the scrollbars out by changing
+ // the opacity (alpha) from fully opaque to fully
+ // transparent
+ int nextFrame = (int) now;
+ int framesCount = 0;
+
+ Interpolator interpolator = scrollBarInterpolator;
+
+ // Start opaque
+ interpolator.setKeyFrame(framesCount++, nextFrame, OPAQUE);
+
+ // End transparent
+ nextFrame += scrollBarFadeDuration;
+ interpolator.setKeyFrame(framesCount, nextFrame, TRANSPARENT);
+
+ state = FADING;
+
+ // Kick off the fade animation
+ host.invalidate(true);
}
}
-
- public boolean isFadingEnabled() {
- return mIsFadingEnabled;
- }
-
- /**
- * Cancels any ongoing or pending fade animations and immediately sets
- * the scroll bar alpha value.
- *
- * @param alpha the scrollbar alpha value
- */
- public void setFadingAlpha(int alpha) {
- if (mFadeAnim != null) {
- mFadeAnim.cancel();
- mFadeAnim = null;
- }
- mHost.removeCallbacks(mFadeOutRunnable);
-
- scrollBar.setAlpha(alpha);
- }
-
- /**
- * If fading is enabled, cancels any ongoing or pending fade animations
- * and immediately sets the scroll bar alpha value to the maximum, then
- * posts a delayed fade-out animation.
- *
- * @param fadeOutDelay the delay before the fade-out animation starts
- * @return {@code true} if the scroll bars changed, false otherwise
- */
- public boolean awakenScrollBars(int fadeOutDelay) {
- if (!mIsFadingEnabled) {
- return false;
- }
-
- if (scrollBar == null) {
- scrollBar = new ScrollBarDrawable();
- scrollBar.setCallback(mHost);
- scrollBar.setState(mHost.getDrawableState());
- }
-
- // Removes pending callbacks.
- setFadingAlpha(255);
-
- final int startingAlpha = scrollBar.getAlpha();
- if (startingAlpha == 0) {
- fadeOutDelay = Math.max(ScrollabilityCache.MIN_FADE_DELAY_FROM_OFF, fadeOutDelay);
- }
-
- mHost.postDelayed(mFadeOutRunnable, fadeOutDelay);
-
- return true;
- }
-
- private final Runnable mFadeOutRunnable = new Runnable() {
- @Override
- public void run() {
- final ObjectAnimator anim = ObjectAnimator.ofInt(
- scrollBar, ScrollBarDrawable.ALPHA, 0);
- anim.setDuration(scrollBarFadeDuration);
- anim.start();
-
- mFadeAnim = anim;
- }
- };
}
/**
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index d733513..4e91ad4 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -47,12 +47,6 @@
private static final int SCROLL_BAR_DEFAULT_DELAY = 300;
/**
- * Default delay before the scrollbars fade in milliseconds for the first
- * time they are shown to the user.
- */
- private static final int SCROLL_BAR_DEFAULT_INITIAL_DELAY = 1500;
-
- /**
* Defines the length of the fading edges in dips
*/
private static final int FADING_EDGE_LENGTH = 12;
@@ -401,23 +395,13 @@
}
/**
- * @return Default delay in milliseconds before the scrollbars fade out
- * after they have been awoken.
+ * @return Default delay before the scrollbars fade in milliseconds
*/
public static int getScrollDefaultDelay() {
return SCROLL_BAR_DEFAULT_DELAY;
}
/**
- * @return Default delay in milliseconds before the scrollbars fade out
- * after they are initially shown to the user.
- * @hide Pending cleanup of ViewConfiguration values.
- */
- public static int getScrollDefaultInitialDelay() {
- return SCROLL_BAR_DEFAULT_INITIAL_DELAY;
- }
-
- /**
* @return the length of the fading edges in dips
*
* @deprecated Use {@link #getScaledFadingEdgeLength()} instead.
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 79ad6e3..1892184 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -403,23 +403,26 @@
}
private void updateThumbAndTrackPos(int w, int h) {
+ final int paddedHeight = h - mPaddingTop - mPaddingBottom;
final Drawable track = getCurrentDrawable();
final Drawable thumb = mThumb;
// The max height does not incorporate padding, whereas the height
// parameter does.
- final int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom);
+ final int trackHeight = Math.min(mMaxHeight, paddedHeight);
final int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight();
// Apply offset to whichever item is taller.
final int trackOffset;
final int thumbOffset;
if (thumbHeight > trackHeight) {
- trackOffset = (thumbHeight - trackHeight) / 2;
- thumbOffset = 0;
+ final int offsetHeight = (paddedHeight - thumbHeight) / 2;
+ trackOffset = offsetHeight + (thumbHeight - trackHeight) / 2;
+ thumbOffset = offsetHeight + 0;
} else {
- trackOffset = 0;
- thumbOffset = (trackHeight - thumbHeight) / 2;
+ final int offsetHeight = (paddedHeight - trackHeight) / 2;
+ trackOffset = offsetHeight + 0;
+ thumbOffset = offsetHeight + (trackHeight - thumbHeight) / 2;
}
if (track != null) {
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index 94827dd..4fadc19 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -17,10 +17,10 @@
package android.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Matrix;
-import android.graphics.Rect;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -55,7 +55,7 @@
implements ActionProvider.SubUiVisibilityListener {
private static final String TAG = "ActionMenuPresenter";
- private View mOverflowButton;
+ private OverflowMenuButton mOverflowButton;
private boolean mReserveOverflow;
private boolean mReserveOverflowSet;
private int mWidthLimit;
@@ -79,6 +79,8 @@
private OpenOverflowRunnable mPostedOpenRunnable;
private ActionMenuPopupCallback mPopupCallback;
+ private TintInfo mOverflowTintInfo;
+
final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
int mOpenSubMenuId;
@@ -113,6 +115,7 @@
mOverflowButton = new OverflowMenuButton(mSystemContext);
final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
mOverflowButton.measure(spec, spec);
+ applyOverflowTint();
}
width -= mOverflowButton.getMeasuredWidth();
} else {
@@ -236,6 +239,7 @@
if (hasOverflow) {
if (mOverflowButton == null) {
mOverflowButton = new OverflowMenuButton(mSystemContext);
+ applyOverflowTint();
}
ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
if (parent != mMenuView) {
@@ -550,6 +554,40 @@
menuView.initialize(mMenu);
}
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintList = tint;
+ mOverflowTintInfo.mHasTintList = true;
+
+ applyOverflowTint();
+ }
+
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintMode = tintMode;
+ mOverflowTintInfo.mHasTintMode = true;
+
+ applyOverflowTint();
+ }
+
+ private void applyOverflowTint() {
+ final TintInfo tintInfo = mOverflowTintInfo;
+ if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) {
+ if (mOverflowButton != null) {
+ if (tintInfo.mHasTintList) {
+ mOverflowButton.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mOverflowButton.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
private static class SavedState implements Parcelable {
public int openSubMenuId;
@@ -774,4 +812,11 @@
return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
}
}
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 403e4ac..9d3a5dc 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -16,7 +16,9 @@
package android.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
+import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
@@ -546,6 +548,31 @@
mReserveOverflow = reserveOverflow;
}
+ /**
+ * Applies a tint to the overflow drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mPresenter != null) {
+ mPresenter.setOverflowTintList(tint);
+ }
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setOverflowTintList(ColorStateList)} to the overflow drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ */
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mPresenter != null) {
+ mPresenter.setOverflowTintMode(tintMode);
+ }
+ }
+
@Override
protected LayoutParams generateDefaultLayoutParams() {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 42bc7f2..3568522 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -154,34 +154,23 @@
dateLayout.setBackground(a.getDrawable(R.styleable.DatePicker_headerBackground));
- final int headerSelectedTextColor = a.getColor(
- R.styleable.DatePicker_headerSelectedTextColor, defaultHighlightColor);
final int monthTextAppearanceResId = a.getResourceId(
R.styleable.DatePicker_headerMonthTextAppearance, 0);
if (monthTextAppearanceResId != 0) {
mHeaderMonthTextView.setTextAppearance(context, monthTextAppearanceResId);
}
- mHeaderMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
- mHeaderMonthTextView.getTextColors(), R.attr.state_selected,
- headerSelectedTextColor));
final int dayOfMonthTextAppearanceResId = a.getResourceId(
R.styleable.DatePicker_headerDayOfMonthTextAppearance, 0);
if (dayOfMonthTextAppearanceResId != 0) {
mHeaderDayOfMonthTextView.setTextAppearance(context, dayOfMonthTextAppearanceResId);
}
- mHeaderDayOfMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
- mHeaderDayOfMonthTextView.getTextColors(), R.attr.state_selected,
- headerSelectedTextColor));
final int headerYearTextAppearanceResId = a.getResourceId(
R.styleable.DatePicker_headerYearTextAppearance, 0);
if (headerYearTextAppearanceResId != 0) {
mHeaderYearTextView.setTextAppearance(context, headerYearTextAppearanceResId);
}
- mHeaderYearTextView.setTextColor(ColorStateList.addFirstIfMissing(
- mHeaderYearTextView.getTextColors(), R.attr.state_selected,
- headerSelectedTextColor));
mDayPickerView = new DayPickerView(mContext);
mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 1ba11da..7e0dfa0 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -131,6 +131,7 @@
private final UndoManager mUndoManager = new UndoManager();
private UndoOwner mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this);
final InputFilter mUndoInputFilter = new UndoInputFilter(this);
+ boolean mAllowUndo = true;
// Cursor Controllers.
InsertionPointCursorController mInsertionPointCursorController;
@@ -243,20 +244,26 @@
boolean canUndo() {
UndoOwner[] owners = { mUndoOwner };
- return mUndoManager.countUndos(owners) > 0;
+ return mAllowUndo && mUndoManager.countUndos(owners) > 0;
}
boolean canRedo() {
UndoOwner[] owners = { mUndoOwner };
- return mUndoManager.countRedos(owners) > 0;
+ return mAllowUndo && mUndoManager.countRedos(owners) > 0;
}
void undo() {
+ if (!mAllowUndo) {
+ return;
+ }
UndoOwner[] owners = { mUndoOwner };
mUndoManager.undo(owners, 1); // Undo 1 action.
}
void redo() {
+ if (!mAllowUndo) {
+ return;
+ }
UndoOwner[] owners = { mUndoOwner };
mUndoManager.redo(owners, 1); // Redo 1 action.
}
@@ -4223,6 +4230,12 @@
Log.d(TAG, "filter: source=" + source + " (" + start + "-" + end + ") " +
"dest=" + dest + " (" + dstart + "-" + dend + ")");
}
+
+ if (!mEditor.mAllowUndo) {
+ if (DEBUG_UNDO) Log.d(TAG, "filter: undo is disabled");
+ return null;
+ }
+
final UndoManager um = mEditor.mUndoManager;
if (um.isInUndo()) {
if (DEBUG_UNDO) Log.d(TAG, "filter: skipping, currently performing undo/redo");
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 03878fc..9f98965 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -1235,24 +1235,6 @@
}
}
- private void setDrawableTint(int id, ColorStateList tint, Mode tintMode, boolean fallback) {
- Drawable layer = null;
-
- // We expect a layer drawable, so try to find the target ID.
- final Drawable d = mCurrentDrawable;
- if (d instanceof LayerDrawable) {
- layer = ((LayerDrawable) d).findDrawableByLayerId(id);
- }
-
- if (fallback && layer == null) {
- layer = d;
- }
-
- layer.mutate();
- layer.setTintList(tint);
- layer.setTintMode(tintMode);
- }
-
private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
boolean callBackToApp) {
float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index 3068de9..25b301f 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -37,8 +37,6 @@
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
/**
* Widget used to show an image with the standard QuickContact badge
@@ -52,6 +50,7 @@
private QueryHandler mQueryHandler;
private Drawable mDefaultAvatar;
private Bundle mExtras = null;
+ private String mPrioritizedMimeType;
protected String[] mExcludeMimes = null;
@@ -126,6 +125,15 @@
public void setMode(int size) {
}
+ /**
+ * Set which mimetype should be prioritized in the QuickContacts UI. For example, passing the
+ * value {@link Email#CONTENT_ITEM_TYPE} can cause emails to be displayed more prominently in
+ * QuickContacts.
+ */
+ public void setPrioritizedMimeType(String prioritizedMimeType) {
+ mPrioritizedMimeType = prioritizedMimeType;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
@@ -287,7 +295,7 @@
final Bundle extras = (mExtras == null) ? new Bundle() : mExtras;
if (mContactUri != null) {
QuickContact.showQuickContact(getContext(), QuickContactBadge.this, mContactUri,
- QuickContact.MODE_LARGE, mExcludeMimes);
+ mExcludeMimes, mPrioritizedMimeType);
} else if (mContactEmail != null && mQueryHandler != null) {
extras.putString(EXTRA_URI_CONTENT, mContactEmail);
mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, extras,
@@ -370,10 +378,10 @@
mContactUri = lookupUri;
onContactUriChanged();
- if (trigger && lookupUri != null) {
+ if (trigger && mContactUri != null) {
// Found contact, so trigger QuickContact
- QuickContact.showQuickContact(getContext(), QuickContactBadge.this, lookupUri,
- QuickContact.MODE_LARGE, mExcludeMimes);
+ QuickContact.showQuickContact(getContext(), QuickContactBadge.this, mContactUri,
+ mExcludeMimes, mPrioritizedMimeType);
} else if (createUri != null) {
// Prompt user to add this person to contacts
final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, createUri);
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index dc4d932..28b4db2 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -157,6 +157,7 @@
private boolean mIsOnInnerCircle;
private int mSelectorRadius;
+ private int mSelectorStroke;
private int mSelectorDotRadius;
private int mCenterDotRadius;
@@ -377,6 +378,7 @@
mPaintBackground.setAntiAlias(true);
mSelectorRadius = res.getDimensionPixelSize(R.dimen.timepicker_selector_radius);
+ mSelectorStroke = res.getDimensionPixelSize(R.dimen.timepicker_selector_stroke);
mSelectorDotRadius = res.getDimensionPixelSize(R.dimen.timepicker_selector_dot_radius);
mCenterDotRadius = res.getDimensionPixelSize(R.dimen.timepicker_center_dot_radius);
@@ -772,6 +774,7 @@
alpha = (int) (mAlphaSelector[index % 2][SELECTOR_LINE].getValue() * alphaMod + 0.5f);
paint = mPaintSelector[index % 2][SELECTOR_LINE];
paint.setColor(color);
+ paint.setStrokeWidth(mSelectorStroke);
paint.setAlpha(getMultipliedAlpha(color, alpha));
canvas.drawLine(mXCenter, mYCenter, pointX, pointY, paint);
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index fef56b8..6166c02 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1358,6 +1358,7 @@
* {@link android.widget.RelativeLayout RelativeLayout}, such as
* ALIGN_WITH_PARENT_LEFT.
* @see #addRule(int, int)
+ * @see #getRule(int)
*/
public void addRule(int verb) {
mRules[verb] = TRUE;
@@ -1378,6 +1379,7 @@
* for true or 0 for false). For verbs that don't refer to another sibling
* (for example, ALIGN_WITH_PARENT_BOTTOM) just use -1.
* @see #addRule(int)
+ * @see #getRule(int)
*/
public void addRule(int verb, int anchor) {
mRules[verb] = anchor;
@@ -1393,6 +1395,7 @@
* ALIGN_WITH_PARENT_LEFT.
* @see #addRule(int)
* @see #addRule(int, int)
+ * @see #getRule(int)
*/
public void removeRule(int verb) {
mRules[verb] = 0;
@@ -1400,6 +1403,22 @@
mRulesChanged = true;
}
+ /**
+ * Returns the layout rule associated with a specific verb.
+ *
+ * @param verb one of the verbs defined by {@link RelativeLayout}, such
+ * as ALIGN_WITH_PARENT_LEFT
+ * @return the id of another view to use as an anchor, a boolean value
+ * (represented as {@link RelativeLayout#TRUE} for true
+ * or 0 for false), or -1 for verbs that don't refer to another
+ * sibling (for example, ALIGN_WITH_PARENT_BOTTOM)
+ * @see #addRule(int)
+ * @see #addRule(int, int)
+ */
+ public int getRule(int verb) {
+ return mRules[verb];
+ }
+
private boolean hasRelativeRules() {
return (mInitialRules[START_OF] != 0 || mInitialRules[END_OF] != 0 ||
mInitialRules[ALIGN_START] != 0 || mInitialRules[ALIGN_END] != 0 ||
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2d0a9cb..632f5c7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1055,6 +1055,11 @@
inputType = a.getInt(attr, EditorInfo.TYPE_NULL);
break;
+ case com.android.internal.R.styleable.TextView_allowUndo:
+ createEditorIfNeeded();
+ mEditor.mAllowUndo = a.getBoolean(attr, true);
+ break;
+
case com.android.internal.R.styleable.TextView_imeOptions:
createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index ed052af..3b88b21 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -132,19 +132,19 @@
mPmText = amPmStrings[1];
final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout,
- R.layout.time_picker_holo);
+ R.layout.time_picker_material);
final View mainView = inflater.inflate(layoutResourceId, delegator);
mHeaderView = mainView.findViewById(R.id.time_header);
mHeaderView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground));
// Set up hour/minute labels.
- mHourView = (TextView) mHeaderView.findViewById(R.id.hours);
+ mHourView = (TextView) mainView.findViewById(R.id.hours);
mHourView.setOnClickListener(mClickListener);
mHourView.setAccessibilityDelegate(
new ClickActionDelegate(context, R.string.select_hours));
- mSeparatorView = (TextView) mHeaderView.findViewById(R.id.separator);
- mMinuteView = (TextView) mHeaderView.findViewById(R.id.minutes);
+ mSeparatorView = (TextView) mainView.findViewById(R.id.separator);
+ mMinuteView = (TextView) mainView.findViewById(R.id.minutes);
mMinuteView.setOnClickListener(mClickListener);
mMinuteView.setAccessibilityDelegate(
new ClickActionDelegate(context, R.string.select_minutes));
@@ -162,17 +162,8 @@
mHourView.setMinWidth(computeStableWidth(mHourView, 24));
mMinuteView.setMinWidth(computeStableWidth(mMinuteView, 60));
- // TODO: This can be removed once we support themed color state lists.
- final int headerSelectedTextColor = a.getColor(
- R.styleable.TimePicker_headerSelectedTextColor,
- res.getColor(R.color.timepicker_default_selector_color_material));
- mHourView.setTextColor(ColorStateList.addFirstIfMissing(mHourView.getTextColors(),
- R.attr.state_selected, headerSelectedTextColor));
- mMinuteView.setTextColor(ColorStateList.addFirstIfMissing(mMinuteView.getTextColors(),
- R.attr.state_selected, headerSelectedTextColor));
-
// Set up AM/PM labels.
- mAmPmLayout = mHeaderView.findViewById(R.id.ampm_layout);
+ mAmPmLayout = mainView.findViewById(R.id.ampm_layout);
mAmLabel = (CheckedTextView) mAmPmLayout.findViewById(R.id.am_label);
mAmLabel.setText(amPmStrings[0]);
mAmLabel.setOnClickListener(mClickListener);
@@ -304,12 +295,15 @@
final RelativeLayout.LayoutParams params =
(RelativeLayout.LayoutParams) mAmPmLayout.getLayoutParams();
- if (isAmPmAtStart) {
- params.removeRule(RelativeLayout.RIGHT_OF);
- params.addRule(RelativeLayout.LEFT_OF, mHourView.getId());
- } else {
- params.removeRule(RelativeLayout.LEFT_OF);
- params.addRule(RelativeLayout.RIGHT_OF, mMinuteView.getId());
+ if (params.getRule(RelativeLayout.RIGHT_OF) != 0 ||
+ params.getRule(RelativeLayout.LEFT_OF) != 0) {
+ if (isAmPmAtStart) {
+ params.removeRule(RelativeLayout.RIGHT_OF);
+ params.addRule(RelativeLayout.LEFT_OF, mHourView.getId());
+ } else {
+ params.removeRule(RelativeLayout.LEFT_OF);
+ params.addRule(RelativeLayout.RIGHT_OF, mMinuteView.getId());
+ }
}
mAmPmLayout.setLayoutParams(params);
@@ -613,11 +607,11 @@
private void updateAmPmLabelStates(int amOrPm) {
final boolean isAm = amOrPm == AM;
mAmLabel.setChecked(isAm);
- mAmLabel.setAlpha(isAm ? 1 : mDisabledAlpha);
+ mAmLabel.setSelected(isAm);
final boolean isPm = amOrPm == PM;
mPmLabel.setChecked(isPm);
- mPmLabel.setAlpha(isPm ? 1 : mDisabledAlpha);
+ mPmLabel.setSelected(isPm);
}
/**
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index c5325c4..9bc2aab 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -20,8 +20,9 @@
import android.annotation.Nullable;
import android.app.ActionBar;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
-import android.graphics.RectF;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -104,6 +105,9 @@
private ImageButton mNavButtonView;
private ImageView mLogoView;
+ private TintInfo mOverflowTintInfo;
+ private TintInfo mNavTintInfo;
+
private Drawable mCollapseIcon;
private CharSequence mCollapseDescription;
private ImageButton mCollapseButtonView;
@@ -266,6 +270,21 @@
if (!TextUtils.isEmpty(navDesc)) {
setNavigationContentDescription(navDesc);
}
+
+ if (a.hasValue(R.styleable.Toolbar_overflowTint)) {
+ setOverflowTintList(a.getColorStateList(R.styleable.Toolbar_overflowTint));
+ }
+ if (a.hasValue(R.styleable.Toolbar_overflowTintMode)) {
+ setOverflowTintMode(Drawable.parseTintMode(
+ a.getInt(R.styleable.Toolbar_overflowTintMode, -1), null));
+ }
+ if (a.hasValue(R.styleable.Toolbar_navigationTint)) {
+ setNavigationTintList(a.getColorStateList(R.styleable.Toolbar_navigationTint));
+ }
+ if (a.hasValue(R.styleable.Toolbar_navigationTintMode)) {
+ setNavigationTintMode(Drawable.parseTintMode(
+ a.getInt(R.styleable.Toolbar_navigationTintMode, -1), null));
+ }
a.recycle();
}
@@ -806,6 +825,91 @@
}
/**
+ * Applies a tint to the icon drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link #setNavigationIcon(Drawable)} will automatically mutate
+ * the drawable and apply the specified tint and tint mode.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_navigationTint
+ */
+ public void setNavigationTintList(ColorStateList tint) {
+ if (mNavTintInfo == null) {
+ mNavTintInfo = new TintInfo();
+ }
+ mNavTintInfo.mTintList = tint;
+ mNavTintInfo.mHasTintList = true;
+
+ applyNavigationTint();
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setNavigationTintList(ColorStateList)} to the navigation drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_navigationTintMode
+ */
+ public void setNavigationTintMode(PorterDuff.Mode tintMode) {
+ if (mNavTintInfo == null) {
+ mNavTintInfo = new TintInfo();
+ }
+ mNavTintInfo.mTintMode = tintMode;
+ mNavTintInfo.mHasTintMode = true;
+
+ applyNavigationTint();
+ }
+
+ /**
+ * Applies a tint to the overflow drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_overflowTint
+ */
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mMenuView != null) {
+ // If the menu view is available, directly set the tint
+ mMenuView.setOverflowTintList(tint);
+ } else {
+ // Otherwise we will record the value
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintList = tint;
+ mOverflowTintInfo.mHasTintList = true;
+ }
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setOverflowTintList(ColorStateList)} to the overflow drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_overflowTintMode
+ */
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mMenuView != null) {
+ // If the menu view is available, directly set the tint mode
+ mMenuView.setOverflowTintMode(tintMode);
+ } else {
+ // Otherwise we will record the value
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintMode = tintMode;
+ mOverflowTintInfo.mHasTintMode = true;
+ }
+ }
+
+ /**
* Return the Menu shown in the toolbar.
*
* <p>Applications that wish to populate the toolbar's menu can do so from here. To use
@@ -841,6 +945,17 @@
lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mMenuView.setLayoutParams(lp);
addSystemView(mMenuView);
+
+ if (mOverflowTintInfo != null) {
+ // If we have tint info for the overflow, set it on the menu view now
+ if (mOverflowTintInfo.mHasTintList) {
+ mMenuView.setOverflowTintList(mOverflowTintInfo.mTintList);
+ }
+ if (mOverflowTintInfo.mHasTintMode) {
+ mMenuView.setOverflowTintMode(mOverflowTintInfo.mTintMode);
+ }
+ mOverflowTintInfo = null;
+ }
}
}
@@ -994,6 +1109,7 @@
final LayoutParams lp = generateDefaultLayoutParams();
lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mNavButtonView.setLayoutParams(lp);
+ applyNavigationTint();
}
}
@@ -1012,6 +1128,7 @@
collapseActionView();
}
});
+ applyNavigationTint();
}
}
@@ -1763,6 +1880,30 @@
return mPopupContext;
}
+ private void applyNavigationTint() {
+ final TintInfo tintInfo = mNavTintInfo;
+ if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) {
+ if (mNavButtonView != null) {
+ if (tintInfo.mHasTintList) {
+ mNavButtonView.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mNavButtonView.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+
+ if (mCollapseButtonView != null) {
+ // We will use the same tint for the collapse button
+ if (tintInfo.mHasTintList) {
+ mCollapseButtonView.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mCollapseButtonView.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
/**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
@@ -1990,4 +2131,11 @@
public void onRestoreInstanceState(Parcelable state) {
}
}
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/core/java/android/alsa/AlsaCardsParser.java b/core/java/com/android/internal/alsa/AlsaCardsParser.java
similarity index 99%
rename from core/java/android/alsa/AlsaCardsParser.java
rename to core/java/com/android/internal/alsa/AlsaCardsParser.java
index 5e88bca..5c0a888 100644
--- a/core/java/android/alsa/AlsaCardsParser.java
+++ b/core/java/com/android/internal/alsa/AlsaCardsParser.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.alsa;
+package com.android.internal.alsa;
import android.util.Slog;
import java.io.BufferedReader;
diff --git a/core/java/android/alsa/AlsaDevicesParser.java b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
similarity index 99%
rename from core/java/android/alsa/AlsaDevicesParser.java
rename to core/java/com/android/internal/alsa/AlsaDevicesParser.java
index b140d3d..81b7943 100644
--- a/core/java/android/alsa/AlsaDevicesParser.java
+++ b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.alsa;
+package com.android.internal.alsa;
import android.util.Slog;
import java.io.BufferedReader;
diff --git a/core/java/android/alsa/LineTokenizer.java b/core/java/com/android/internal/alsa/LineTokenizer.java
similarity index 97%
rename from core/java/android/alsa/LineTokenizer.java
rename to core/java/com/android/internal/alsa/LineTokenizer.java
index 78c91b5..43047a9 100644
--- a/core/java/android/alsa/LineTokenizer.java
+++ b/core/java/com/android/internal/alsa/LineTokenizer.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.alsa;
+package com.android.internal.alsa;
/**
* @hide
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 20d209f..9dabb4e 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -20,6 +20,7 @@
import com.android.internal.R;
+import android.annotation.Nullable;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -38,7 +39,7 @@
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
-import android.view.ViewTreeObserver;
+import android.view.ViewStub;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -450,27 +451,107 @@
}
}
+ /**
+ * Resolves whether a custom or default panel should be used. Removes the
+ * default panel if a custom panel should be used. If the resolved panel is
+ * a view stub, inflates before returning.
+ *
+ * @param customPanel the custom panel
+ * @param defaultPanel the default panel
+ * @return the panel to use
+ */
+ @Nullable
+ private ViewGroup resolvePanel(@Nullable View customPanel, @Nullable View defaultPanel) {
+ if (customPanel == null) {
+ // Inflate the default panel, if needed.
+ if (defaultPanel instanceof ViewStub) {
+ defaultPanel = ((ViewStub) defaultPanel).inflate();
+ }
+
+ return (ViewGroup) defaultPanel;
+ }
+
+ // Remove the default panel entirely.
+ if (defaultPanel != null) {
+ final ViewParent parent = defaultPanel.getParent();
+ if (parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(defaultPanel);
+ }
+ }
+
+ // Inflate the custom panel, if needed.
+ if (customPanel instanceof ViewStub) {
+ customPanel = ((ViewStub) customPanel).inflate();
+ }
+
+ return (ViewGroup) customPanel;
+ }
+
private void setupView() {
- final ViewGroup contentPanel = (ViewGroup) mWindow.findViewById(R.id.contentPanel);
+ final View parentPanel = mWindow.findViewById(R.id.parentPanel);
+ final View defaultTopPanel = parentPanel.findViewById(R.id.topPanel);
+ final View defaultContentPanel = parentPanel.findViewById(R.id.contentPanel);
+ final View defaultButtonPanel = parentPanel.findViewById(R.id.buttonPanel);
+
+ // Install custom content before setting up the title or buttons so
+ // that we can handle panel overrides.
+ final ViewGroup customPanel = (ViewGroup) parentPanel.findViewById(R.id.customPanel);
+ setupCustomContent(customPanel);
+
+ final View customTopPanel = customPanel.findViewById(R.id.topPanel);
+ final View customContentPanel = customPanel.findViewById(R.id.contentPanel);
+ final View customButtonPanel = customPanel.findViewById(R.id.buttonPanel);
+
+ // Resolve the correct panels and remove the defaults, if needed.
+ final ViewGroup topPanel = resolvePanel(customTopPanel, defaultTopPanel);
+ final ViewGroup contentPanel = resolvePanel(customContentPanel, defaultContentPanel);
+ final ViewGroup buttonPanel = resolvePanel(customButtonPanel, defaultButtonPanel);
+
setupContent(contentPanel);
- final boolean hasButtons = setupButtons();
+ setupButtons(buttonPanel);
+ setupTitle(topPanel);
- final ViewGroup topPanel = (ViewGroup) mWindow.findViewById(R.id.topPanel);
- final TypedArray a = mContext.obtainStyledAttributes(
- null, R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
- final boolean hasTitle = setupTitle(topPanel);
+ final boolean hasCustomPanel = customPanel != null
+ && customPanel.getVisibility() != View.GONE;
+ final boolean hasTopPanel = topPanel != null
+ && topPanel.getVisibility() != View.GONE;
+ final boolean hasButtonPanel = buttonPanel != null
+ && buttonPanel.getVisibility() != View.GONE;
- final View buttonPanel = mWindow.findViewById(R.id.buttonPanel);
- if (!hasButtons) {
- buttonPanel.setVisibility(View.GONE);
- final View spacer = mWindow.findViewById(R.id.textSpacerNoButtons);
- if (spacer != null) {
- spacer.setVisibility(View.VISIBLE);
+ // Only display the text spacer if we don't have buttons.
+ if (!hasButtonPanel) {
+ if (contentPanel != null) {
+ final View spacer = contentPanel.findViewById(R.id.textSpacerNoButtons);
+ if (spacer != null) {
+ spacer.setVisibility(View.VISIBLE);
+ }
}
mWindow.setCloseOnTouchOutsideIfNotSet(true);
}
- final FrameLayout customPanel = (FrameLayout) mWindow.findViewById(R.id.customPanel);
+ // Only display the divider if we have a title and a custom view or a
+ // message.
+ if (hasTopPanel) {
+ final View divider;
+ if (mMessage != null || hasCustomPanel || mListView != null) {
+ divider = topPanel.findViewById(R.id.titleDivider);
+ } else {
+ divider = topPanel.findViewById(R.id.titleDividerTop);
+ }
+
+ if (divider != null) {
+ divider.setVisibility(View.VISIBLE);
+ }
+ }
+
+ final TypedArray a = mContext.obtainStyledAttributes(
+ null, R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
+ setBackground(a, topPanel, contentPanel, customPanel, buttonPanel,
+ hasTopPanel, hasCustomPanel, hasButtonPanel);
+ a.recycle();
+ }
+
+ private void setupCustomContent(ViewGroup customPanel) {
final View customView;
if (mView != null) {
customView = mView;
@@ -502,30 +583,9 @@
} else {
customPanel.setVisibility(View.GONE);
}
-
- // Only display the divider if we have a title and a custom view or a
- // message.
- if (hasTitle) {
- final View divider;
- if (mMessage != null || customView != null || mListView != null) {
- divider = mWindow.findViewById(R.id.titleDivider);
- } else {
- divider = mWindow.findViewById(R.id.titleDividerTop);
- }
-
- if (divider != null) {
- divider.setVisibility(View.VISIBLE);
- }
- }
-
- setBackground(a, topPanel, contentPanel, customPanel, buttonPanel, hasTitle, hasCustomView,
- hasButtons);
- a.recycle();
}
- private boolean setupTitle(ViewGroup topPanel) {
- boolean hasTitle = true;
-
+ private void setupTitle(ViewGroup topPanel) {
if (mCustomTitleView != null) {
// Add the custom title view directly to the topPanel layout
LayoutParams lp = new LayoutParams(
@@ -567,18 +627,16 @@
titleTemplate.setVisibility(View.GONE);
mIconView.setVisibility(View.GONE);
topPanel.setVisibility(View.GONE);
- hasTitle = false;
}
}
- return hasTitle;
}
private void setupContent(ViewGroup contentPanel) {
- mScrollView = (ScrollView) mWindow.findViewById(R.id.scrollView);
+ mScrollView = (ScrollView) contentPanel.findViewById(R.id.scrollView);
mScrollView.setFocusable(false);
// Special case for users that only want to display a String
- mMessageView = (TextView) mWindow.findViewById(R.id.message);
+ mMessageView = (TextView) contentPanel.findViewById(R.id.message);
if (mMessageView == null) {
return;
}
@@ -601,8 +659,8 @@
}
// Set up scroll indicators (if present).
- final View indicatorUp = mWindow.findViewById(R.id.scrollIndicatorUp);
- final View indicatorDown = mWindow.findViewById(R.id.scrollIndicatorDown);
+ final View indicatorUp = contentPanel.findViewById(R.id.scrollIndicatorUp);
+ final View indicatorDown = contentPanel.findViewById(R.id.scrollIndicatorDown);
if (indicatorUp != null || indicatorDown != null) {
if (mMessage != null) {
// We're just showing the ScrollView, set up listener.
@@ -663,12 +721,12 @@
}
}
- private boolean setupButtons() {
+ private void setupButtons(ViewGroup buttonPanel) {
int BIT_BUTTON_POSITIVE = 1;
int BIT_BUTTON_NEGATIVE = 2;
int BIT_BUTTON_NEUTRAL = 4;
int whichButtons = 0;
- mButtonPositive = (Button) mWindow.findViewById(R.id.button1);
+ mButtonPositive = (Button) buttonPanel.findViewById(R.id.button1);
mButtonPositive.setOnClickListener(mButtonHandler);
if (TextUtils.isEmpty(mButtonPositiveText)) {
@@ -679,7 +737,7 @@
whichButtons = whichButtons | BIT_BUTTON_POSITIVE;
}
- mButtonNegative = (Button) mWindow.findViewById(R.id.button2);
+ mButtonNegative = (Button) buttonPanel.findViewById(R.id.button2);
mButtonNegative.setOnClickListener(mButtonHandler);
if (TextUtils.isEmpty(mButtonNegativeText)) {
@@ -691,7 +749,7 @@
whichButtons = whichButtons | BIT_BUTTON_NEGATIVE;
}
- mButtonNeutral = (Button) mWindow.findViewById(R.id.button3);
+ mButtonNeutral = (Button) buttonPanel.findViewById(R.id.button3);
mButtonNeutral.setOnClickListener(mButtonHandler);
if (TextUtils.isEmpty(mButtonNeutralText)) {
@@ -717,7 +775,10 @@
}
}
- return whichButtons != 0;
+ final boolean hasButtons = whichButtons != 0;
+ if (!hasButtons) {
+ buttonPanel.setVisibility(View.GONE);
+ }
}
private void centerButton(Button button) {
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index ed676bb..00af401 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -18,6 +18,8 @@
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.ActionProvider;
import android.view.ContextMenu.ContextMenuInfo;
@@ -42,6 +44,7 @@
private Drawable mIconDrawable;
private int mIconResId = NO_ICON;
+ private TintInfo mIconTintInfo;
private Context mContext;
@@ -158,12 +161,14 @@
public MenuItem setIcon(Drawable icon) {
mIconDrawable = icon;
mIconResId = NO_ICON;
+ applyIconTint();
return this;
}
public MenuItem setIcon(int iconRes) {
mIconResId = iconRes;
mIconDrawable = mContext.getDrawable(iconRes);
+ applyIconTint();
return this;
}
@@ -274,4 +279,48 @@
// No need to save the listener; ActionMenuItem does not support collapsing items.
return this;
}
+
+ @Override
+ public MenuItem setIconTintList(ColorStateList tintList) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintList = tintList;
+ mIconTintInfo.mHasTintList = true;
+ applyIconTint();
+ return this;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintMode = tintMode;
+ mIconTintInfo.mHasTintMode = true;
+ applyIconTint();
+ return this;
+ }
+
+ private void applyIconTint() {
+ final TintInfo tintInfo = mIconTintInfo;
+ if (mIconDrawable != null && tintInfo != null) {
+ if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
+ mIconDrawable = mIconDrawable.mutate();
+ if (tintInfo.mHasTintList) {
+ mIconDrawable.setTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mIconDrawable.setTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 3b1f20d..ef4e546 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -21,6 +21,8 @@
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.ActionProvider;
@@ -60,6 +62,11 @@
* needed).
*/
private int mIconResId = NO_ICON;
+
+ /**
+ * Tint info for the icon
+ */
+ private TintInfo mIconTintInfo;
/** The menu to which this item belongs */
private MenuBuilder mMenu;
@@ -385,10 +392,10 @@
}
if (mIconResId != NO_ICON) {
- Drawable icon = mMenu.getContext().getDrawable(mIconResId);
+ mIconDrawable = mMenu.getContext().getDrawable(mIconResId);
mIconResId = NO_ICON;
- mIconDrawable = icon;
- return icon;
+ applyIconTint();
+ return mIconDrawable;
}
return null;
@@ -397,6 +404,7 @@
public MenuItem setIcon(Drawable icon) {
mIconResId = NO_ICON;
mIconDrawable = icon;
+ applyIconTint();
mMenu.onItemsChanged(false);
return this;
@@ -670,4 +678,48 @@
public boolean isActionViewExpanded() {
return mIsActionViewExpanded;
}
+
+ @Override
+ public MenuItem setIconTintList(ColorStateList tintList) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintList = tintList;
+ mIconTintInfo.mHasTintList = true;
+ applyIconTint();
+ return this;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintMode = tintMode;
+ mIconTintInfo.mHasTintMode = true;
+ applyIconTint();
+ return this;
+ }
+
+ private void applyIconTint() {
+ final TintInfo tintInfo = mIconTintInfo;
+ if (mIconDrawable != null && tintInfo != null) {
+ if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
+ mIconDrawable = mIconDrawable.mutate();
+ if (tintInfo.mHasTintList) {
+ mIconDrawable.setTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mIconDrawable.setTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 7497d8b..87896df 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -52,12 +52,12 @@
* Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02
*/
static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane,
- uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) {
+ uint8_t* crPlane, uint8_t* cbPlane, size_t chromaStep, size_t yStride, size_t chromaStride) {
uint8_t R, G, B;
size_t index = 0;
for (size_t j = 0; j < height; j++) {
- uint8_t* u = uPlane;
- uint8_t* v = vPlane;
+ uint8_t* cr = crPlane;
+ uint8_t* cb = cbPlane;
uint8_t* y = yPlane;
bool jEven = (j & 1) == 0;
for (size_t i = 0; i < width; i++) {
@@ -66,18 +66,18 @@
B = rgbBuf[index++];
*y++ = (77 * R + 150 * G + 29 * B) >> 8;
if (jEven && (i & 1) == 0) {
- *v = (( -43 * R - 85 * G + 128 * B) >> 8) + 128;
- *u = (( 128 * R - 107 * G - 21 * B) >> 8) + 128;
- u += chromaStep;
- v += chromaStep;
+ *cb = (( -43 * R - 85 * G + 128 * B) >> 8) + 128;
+ *cr = (( 128 * R - 107 * G - 21 * B) >> 8) + 128;
+ cr += chromaStep;
+ cb += chromaStep;
}
// Skip alpha
index++;
}
yPlane += yStride;
if (jEven) {
- uPlane += chromaStride;
- vPlane += chromaStride;
+ crPlane += chromaStride;
+ cbPlane += chromaStride;
}
}
}
diff --git a/core/jni/android_server_FingerprintManager.cpp b/core/jni/android_server_FingerprintManager.cpp
index 24f8f67..853425c 100644
--- a/core/jni/android_server_FingerprintManager.cpp
+++ b/core/jni/android_server_FingerprintManager.cpp
@@ -20,10 +20,11 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
+#include <android_os_MessageQueue.h>
#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include <utils/Log.h>
-
+#include <utils/Looper.h>
#include "core_jni_helpers.h"
namespace android {
@@ -34,7 +35,6 @@
static struct {
jclass clazz;
jmethodID notify;
- jobject callbackObject;
} gFingerprintServiceClassInfo;
static struct {
@@ -42,11 +42,26 @@
fingerprint_device_t *device;
} gContext;
+static sp<Looper> gLooper;
+static jobject gCallback;
+
+class CallbackHandler : public MessageHandler {
+ int type;
+ int arg1, arg2;
+public:
+ CallbackHandler(int type, int arg1, int arg2) : type(type), arg1(arg1), arg2(arg2) { }
+
+ virtual void handleMessage(const Message& message) {
+ //ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2);
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(gCallback, gFingerprintServiceClassInfo.notify, type, arg1, arg2);
+ }
+};
+
// Called by the HAL to notify us of fingerprint events
static void hal_notify_callback(fingerprint_msg_t msg) {
uint32_t arg1 = 0;
uint32_t arg2 = 0;
- uint32_t arg3 = 0; // TODO
switch (msg.type) {
case FINGERPRINT_ERROR:
arg1 = msg.data.error;
@@ -60,7 +75,6 @@
case FINGERPRINT_TEMPLATE_ENROLLING:
arg1 = msg.data.enroll.finger.fid;
arg2 = msg.data.enroll.samples_remaining;
- arg3 = 0;
break;
case FINGERPRINT_TEMPLATE_REMOVED:
arg1 = msg.data.removed.finger.fid;
@@ -69,32 +83,16 @@
ALOGE("fingerprint: invalid msg: %d", msg.type);
return;
}
- (void)arg3;
- //ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2);
-
- // TODO: fix gross hack to attach JNI to calling thread
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (env == NULL) {
- JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
- JavaVM* vm = AndroidRuntime::getJavaVM();
- int result = vm->AttachCurrentThread(&env, (void*) &args);
- if (result != JNI_OK) {
- ALOGE("Can't call JNI method: attach failed: %#x", result);
- return;
- }
- }
- env->CallVoidMethod(gFingerprintServiceClassInfo.callbackObject,
- gFingerprintServiceClassInfo.notify, msg.type, arg1, arg2);
+ // This call potentially comes in on a thread not owned by us. Hand it off to our
+ // looper so it runs on our thread when calling back to FingerprintService.
+ // CallbackHandler object is reference-counted, so no cleanup necessary.
+ gLooper->sendMessage(new CallbackHandler(msg.type, arg1, arg2), Message());
}
-static void nativeInit(JNIEnv *env, jobject clazz, jobject callbackObj) {
+static void nativeInit(JNIEnv *env, jobject clazz, jobject mQueue, jobject callbackObj) {
ALOG(LOG_VERBOSE, LOG_TAG, "nativeInit()\n");
- gFingerprintServiceClassInfo.clazz = FindClassOrDie(env, FINGERPRINT_SERVICE);
- gFingerprintServiceClassInfo.clazz = MakeGlobalRefOrDie(env,
- gFingerprintServiceClassInfo.clazz);
- gFingerprintServiceClassInfo.notify = GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,
- "notify", "(III)V");
- gFingerprintServiceClassInfo.callbackObject = MakeGlobalRefOrDie(env, callbackObj);
+ gCallback = MakeGlobalRefOrDie(env, callbackObj);
+ gLooper = android_os_MessageQueue_getMessageQueue(env, mQueue)->getLooper();
}
static jint nativeEnroll(JNIEnv* env, jobject clazz, jint timeout) {
@@ -179,14 +177,15 @@
{ "nativeRemove", "(I)I", (void*)nativeRemove },
{ "nativeOpenHal", "()I", (void*)nativeOpenHal },
{ "nativeCloseHal", "()I", (void*)nativeCloseHal },
- { "nativeInit", "(Lcom/android/server/fingerprint/FingerprintService;)V", (void*)nativeInit }
+ { "nativeInit","(Landroid/os/MessageQueue;"
+ "Lcom/android/server/fingerprint/FingerprintService;)V", (void*)nativeInit }
};
int register_android_server_fingerprint_FingerprintService(JNIEnv* env) {
jclass clazz = FindClassOrDie(env, FINGERPRINT_SERVICE);
gFingerprintServiceClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
- gFingerprintServiceClassInfo.notify = GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,
- "notify", "(III)V");
+ gFingerprintServiceClassInfo.notify =
+ GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,"notify", "(III)V");
int result = RegisterMethodsOrDie(env, FINGERPRINT_SERVICE, g_methods, NELEM(g_methods));
ALOG(LOG_VERBOSE, LOG_TAG, "FingerprintManager JNI ready.\n");
return result;
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 6c95b8a..5cb8b2e 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -188,6 +188,10 @@
break;
}
+ if (log_msg.id() != LOG_ID_EVENTS) {
+ continue;
+ }
+
int32_t tag = * (int32_t *) log_msg.msg();
int found = 0;
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 13c373f..a8355c2 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -150,7 +150,7 @@
switch (screenshot->getFormat()) {
case PIXEL_FORMAT_RGBX_8888: {
screenshotInfo.fColorType = kRGBA_8888_SkColorType;
- screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+ screenshotInfo.fAlphaType = kOpaque_SkAlphaType;
break;
}
case PIXEL_FORMAT_RGBA_8888: {
@@ -160,7 +160,7 @@
}
case PIXEL_FORMAT_RGB_565: {
screenshotInfo.fColorType = kRGB_565_SkColorType;
- screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+ screenshotInfo.fAlphaType = kOpaque_SkAlphaType;
break;
}
default: {
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 011c326..c2bd0b3c4 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -88,12 +88,15 @@
case WINDOW_FORMAT_RGBX_8888:
info.fColorType = kN32_SkColorType;
info.fAlphaType = kOpaque_SkAlphaType;
+ break;
case WINDOW_FORMAT_RGB_565:
info.fColorType = kRGB_565_SkColorType;
info.fAlphaType = kOpaque_SkAlphaType;
+ break;
default:
info.fColorType = kUnknown_SkColorType;
- info.fAlphaType = kIgnore_SkAlphaType;
+ // switch to kUnknown_SkAlphaType when its in skia
+ info.fAlphaType = kOpaque_SkAlphaType;
break;
}
return info;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4b97138..0d15ae54 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2835,6 +2835,18 @@
android:label="@string/permlab_access_keyguard_secure_storage"
android:description="@string/permdesc_access_keyguard_secure_storage" />
+ <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
+ <permission android:name="android.permission.MANAGE_FINGERPRINT"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_manageFingerprint"
+ android:description="@string/permdesc_manageFingerprint" />
+
+ <!-- Allows an app to use fingerprint hardware. -->
+ <permission android:name="android.permission.USE_FINGERPRINT"
+ android:protectionLevel="dangerous"
+ android:label="@string/permlab_useFingerprint"
+ android:description="@string/permdesc_useFingerprint" />
+
<!-- Allows an application to control keyguard. Only allowed for system processes.
@hide -->
<permission android:name="android.permission.CONTROL_KEYGUARD"
diff --git a/core/res/res/color/date_picker_calendar_holo_dark.xml b/core/res/res/color/date_picker_calendar_holo_dark.xml
deleted file mode 100644
index 6749ea1..0000000
--- a/core/res/res/color/date_picker_calendar_holo_dark.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_enabled="false"
- android:color="@color/datepicker_default_disabled_text_color_holo_dark" />
- <item android:state_activated="true"
- android:color="@color/holo_blue_light" />
- <item android:color="@color/datepicker_default_normal_text_color_holo_dark" />
-
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color/date_picker_calendar_holo_light.xml b/core/res/res/color/date_picker_calendar_holo_light.xml
deleted file mode 100644
index 0aa116a..0000000
--- a/core/res/res/color/date_picker_calendar_holo_light.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_enabled="false"
- android:color="@color/datepicker_default_disabled_text_color_holo_light" />
- <item android:state_activated="true"
- android:color="@color/holo_blue_light" />
- <item android:color="@color/datepicker_default_normal_text_color_holo_light" />
-
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color/date_picker_header_text_material.xml b/core/res/res/color/date_picker_header_text_material.xml
new file mode 100644
index 0000000..cda894b
--- /dev/null
+++ b/core/res/res/color/date_picker_header_text_material.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_selected="true"
+ android:color="?attr/textColorPrimaryInverse" />
+ <item
+ android:color="?attr/textColorSecondaryInverse" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/color/date_picker_selector_holo_dark.xml b/core/res/res/color/date_picker_selector_holo_dark.xml
deleted file mode 100644
index 9e5a5bd..0000000
--- a/core/res/res/color/date_picker_selector_holo_dark.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="true"
- android:color="@color/datepicker_default_pressed_text_color_holo_dark"/>
- <item android:state_pressed="false" android:state_selected="true"
- android:color="@color/datepicker_default_selected_text_color_holo_dark"/>
- <item android:state_pressed="false" android:state_selected="false"
- android:color="@color/datepicker_default_normal_text_color_holo_dark"/>
-
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color/date_picker_selector_holo_light.xml b/core/res/res/color/date_picker_selector_holo_light.xml
deleted file mode 100644
index bf8667c..0000000
--- a/core/res/res/color/date_picker_selector_holo_light.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="true"
- android:color="@color/datepicker_default_pressed_text_color_holo_light"/>
- <item android:state_pressed="false" android:state_selected="true"
- android:color="@color/datepicker_default_selected_text_color_holo_light"/>
- <item android:state_pressed="false" android:state_selected="false"
- android:color="@color/datepicker_default_normal_text_color_holo_light"/>
-
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color/date_picker_year_selector_holo_dark.xml b/core/res/res/color/date_picker_year_selector_holo_dark.xml
deleted file mode 100644
index ce519b2..0000000
--- a/core/res/res/color/date_picker_year_selector_holo_dark.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="true"
- android:color="@color/datepicker_default_pressed_text_color_holo_dark"/>
- <item android:state_pressed="false" android:state_selected="false"
- android:color="@color/datepicker_default_normal_text_color_holo_dark"/>
-
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color/date_picker_year_selector_holo_light.xml b/core/res/res/color/date_picker_year_selector_holo_light.xml
deleted file mode 100644
index c228711..0000000
--- a/core/res/res/color/date_picker_year_selector_holo_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="true"
- android:color="@color/datepicker_default_pressed_text_color_holo_light"/>
- <item android:state_pressed="false" android:state_selected="false"
- android:color="@color/datepicker_default_normal_text_color_holo_light"/>
-
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color/time_picker_header_text_material.xml b/core/res/res/color/time_picker_header_text_material.xml
new file mode 100644
index 0000000..cda894b
--- /dev/null
+++ b/core/res/res/color/time_picker_header_text_material.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_selected="true"
+ android:color="?attr/textColorPrimaryInverse" />
+ <item
+ android:color="?attr/textColorSecondaryInverse" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/layout-land/time_picker_holo.xml b/core/res/res/layout-land/time_picker_holo.xml
deleted file mode 100644
index f6923ee..0000000
--- a/core/res/res/layout-land/time_picker_holo.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:minWidth="@dimen/timepicker_left_side_width"
- android:orientation="vertical">
- <include
- layout="@layout/time_header_label"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center" />
- </FrameLayout>
- <android.widget.RadialTimePickerView
- android:id="@+id/radial_picker"
- android:layout_width="@dimen/timepicker_radial_picker_dimen"
- android:layout_height="match_parent"
- android:layout_gravity="center" />
-</LinearLayout>
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
new file mode 100644
index 0000000..1b85e8f
--- /dev/null
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <View
+ android:id="@+id/time_header"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_column="0"
+ android:layout_row="0"
+ android:layout_rowSpan="3"
+ android:layout_gravity="center|fill"
+ tools:background="@color/accent_material_light" />
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="0"
+ android:layout_row="1"
+ android:layout_gravity="center|fill"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding">
+
+ <LinearLayout
+ android:id="@+id/time_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_centerInParent="true"
+ android:paddingTop="@dimen/timepicker_radial_picker_top_margin">
+
+ <!-- The hour should always be to the left of the separator,
+ regardless of the current locale's layout direction. -->
+ <TextView
+ android:id="@+id/hours"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:gravity="right"
+ tools:text="23"
+ tools:textSize="@dimen/timepicker_time_label_size"
+ tools:textColor="@color/white" />
+
+ <TextView
+ android:id="@+id/separator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:importantForAccessibility="no"
+ tools:text=":"
+ tools:textSize="@dimen/timepicker_time_label_size"
+ tools:textColor="@color/white" />
+
+ <!-- The minutes should always be to the right of the separator,
+ regardless of the current locale's layout direction. -->
+ <TextView
+ android:id="@+id/minutes"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:gravity="left"
+ tools:text="59"
+ tools:textSize="@dimen/timepicker_time_label_size"
+ tools:textColor="@color/white" />
+ </LinearLayout>
+
+ <!-- The layout alignment of this view will switch between toRightOf
+ @id/minutes and toLeftOf @id/hours depending on the locale. -->
+ <LinearLayout
+ android:id="@+id/ampm_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/time_layout"
+ android:layout_centerHorizontal="true"
+ android:orientation="vertical">
+
+ <CheckedTextView
+ android:id="@+id/am_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingTop="@dimen/timepicker_am_top_padding"
+ android:lines="1"
+ android:ellipsize="none"
+ android:includeFontPadding="false"
+ tools:text="AM"
+ tools:textSize="@dimen/timepicker_ampm_label_size"
+ tools:textColor="@color/white" />
+
+ <CheckedTextView
+ android:id="@+id/pm_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
+ android:paddingTop="@dimen/timepicker_pm_top_padding"
+ android:lines="1"
+ android:ellipsize="none"
+ android:includeFontPadding="false"
+ tools:text="PM"
+ tools:textSize="@dimen/timepicker_ampm_label_size"
+ tools:textColor="@color/white" />
+ </LinearLayout>
+ </RelativeLayout>
+
+ <ViewStub
+ android:id="@id/topPanel"
+ android:layout="@layout/alert_dialog_title_material"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="1"
+ android:layout_row="0"
+ android:layout_gravity="top|fill_horizontal" />
+
+ <android.widget.RadialTimePickerView
+ android:id="@+id/radial_picker"
+ android:layout_width="@dimen/timepicker_radial_picker_dimen"
+ android:layout_height="@dimen/timepicker_radial_picker_dimen"
+ android:layout_column="1"
+ android:layout_row="1"
+ android:layout_rowWeight="1"
+ android:layout_gravity="center|fill"
+ android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
+ android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
+ android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin" />
+
+ <ViewStub
+ android:id="@id/buttonPanel"
+ android:layout="@layout/alert_dialog_button_bar_material"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="1"
+ android:layout_row="2"
+ android:layout_gravity="bottom|fill_horizontal" />
+</GridLayout>
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index c8735b1..bf1e383 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -22,34 +22,7 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <LinearLayout android:id="@+id/topPanel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <LinearLayout android:id="@+id/title_template"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:gravity="center_vertical|start"
- android:paddingStart="?attr/dialogPreferredPadding"
- android:paddingEnd="?attr/dialogPreferredPadding"
- android:paddingTop="@dimen/dialog_padding_top_material">
- <ImageView android:id="@+id/icon"
- android:layout_width="32dip"
- android:layout_height="32dip"
- android:layout_marginEnd="8dip"
- android:scaleType="fitCenter"
- android:src="@null" />
- <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle"
- style="?attr/windowTitleStyle"
- android:singleLine="true"
- android:ellipsize="end"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAlignment="viewStart" />
- </LinearLayout>
- <!-- If the client uses a customTitle, it will be added here. -->
- </LinearLayout>
+ <include layout="@layout/alert_dialog_title_material" />
<FrameLayout android:id="@+id/contentPanel"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/alert_dialog_title_material.xml b/core/res/res/layout/alert_dialog_title_material.xml
new file mode 100644
index 0000000..f61b90b
--- /dev/null
+++ b/core/res/res/layout/alert_dialog_title_material.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/topPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/title_template"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical|start"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="32dip"
+ android:layout_height="32dip"
+ android:layout_marginEnd="8dip"
+ android:scaleType="fitCenter"
+ android:src="@null" />
+
+ <com.android.internal.widget.DialogTitle
+ android:id="@+id/alertTitle"
+ style="?attr/windowTitleStyle"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="viewStart" />
+ </LinearLayout>
+
+ <!-- If the client uses a customTitle, it will be added here. -->
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/time_header_label.xml b/core/res/res/layout/time_picker_header_material.xml
similarity index 68%
rename from core/res/res/layout/time_header_label.xml
rename to core/res/res/layout/time_picker_header_material.xml
index 46e7c54..0ef404d 100644
--- a/core/res/res/layout/time_header_label.xml
+++ b/core/res/res/layout/time_picker_header_material.xml
@@ -16,12 +16,13 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/time_header"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:orientation="horizontal"
- android:padding="@dimen/timepicker_separator_padding">
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/time_header"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:padding="@dimen/timepicker_separator_padding"
+ tools:background="@color/accent_material_light">
<!-- The hour should always be to the left of the separator,
regardless of the current locale's layout direction. -->
@@ -31,7 +32,12 @@
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/separator"
android:layout_alignBaseline="@+id/separator"
- android:gravity="right" />
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:gravity="right"
+ tools:text="23"
+ tools:textSize="@dimen/timepicker_time_label_size"
+ tools:textColor="@color/white" />
<TextView
android:id="@+id/separator"
@@ -40,7 +46,10 @@
android:layout_marginLeft="@dimen/timepicker_separator_padding"
android:layout_marginRight="@dimen/timepicker_separator_padding"
android:layout_centerInParent="true"
- android:importantForAccessibility="no" />
+ android:importantForAccessibility="no"
+ tools:text=":"
+ tools:textSize="@dimen/timepicker_time_label_size"
+ tools:textColor="@color/white" />
<!-- The minutes should always be to the left of the separator,
regardless of the current locale's layout direction. -->
@@ -50,7 +59,12 @@
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/separator"
android:layout_alignBaseline="@+id/separator"
- android:gravity="left" />
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:gravity="left"
+ tools:text="59"
+ tools:textSize="@dimen/timepicker_time_label_size"
+ tools:textColor="@color/white" />
<!-- The layout alignment of this view will switch between toRightOf
@id/minutes and toLeftOf @id/hours depending on the locale. -->
@@ -68,9 +82,12 @@
android:layout_height="wrap_content"
android:paddingStart="@dimen/timepicker_ampm_horizontal_padding"
android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
- android:paddingTop="@dimen/timepicker_ampm_vertical_padding"
+ android:paddingTop="@dimen/timepicker_am_top_padding"
android:lines="1"
- android:ellipsize="none" />
+ android:ellipsize="none"
+ tools:text="AM"
+ tools:textSize="@dimen/timepicker_ampm_label_size"
+ tools:textColor="@color/white" />
<CheckedTextView
android:id="@+id/pm_label"
android:layout_width="wrap_content"
@@ -79,6 +96,9 @@
android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding"
android:paddingTop="@dimen/timepicker_pm_top_padding"
android:lines="1"
- android:ellipsize="none" />
+ android:ellipsize="none"
+ tools:text="PM"
+ tools:textSize="@dimen/timepicker_ampm_label_size"
+ tools:textColor="@color/white" />
</LinearLayout>
</RelativeLayout>
diff --git a/core/res/res/layout/time_picker_legacy_holo.xml b/core/res/res/layout/time_picker_legacy_material.xml
similarity index 100%
rename from core/res/res/layout/time_picker_legacy_holo.xml
rename to core/res/res/layout/time_picker_legacy_material.xml
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_material.xml
similarity index 80%
rename from core/res/res/layout/time_picker_holo.xml
rename to core/res/res/layout/time_picker_material.xml
index cb25dbe..37a7384 100644
--- a/core/res/res/layout/time_picker_holo.xml
+++ b/core/res/res/layout/time_picker_material.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include
- layout="@layout/time_header_label"
+ layout="@layout/time_picker_header_material"
android:layout_width="match_parent"
android:layout_height="@dimen/timepicker_header_height"
android:layout_gravity="center" />
@@ -31,7 +31,7 @@
android:layout_width="wrap_content"
android:layout_height="@dimen/timepicker_radial_picker_dimen"
android:layout_gravity="center"
- android:layout_marginTop="?attr/dialogPreferredPadding"
- android:layout_marginStart="?attr/dialogPreferredPadding"
- android:layout_marginEnd="?attr/dialogPreferredPadding" />
+ android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
+ android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
+ android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin" />
</LinearLayout>
diff --git a/core/res/res/values-h320dp/bools.xml b/core/res/res/values-h320dp/bools.xml
index 8dbc2e1..3bbfe96 100644
--- a/core/res/res/values-h320dp/bools.xml
+++ b/core/res/res/values-h320dp/bools.xml
@@ -1,21 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
+
<resources>
<bool name="allow_stacked_button_bar">true</bool>
</resources>
diff --git a/core/res/res/values-h320dp/dimens.xml b/core/res/res/values-h320dp/dimens.xml
new file mode 100644
index 0000000..d0de6a1
--- /dev/null
+++ b/core/res/res/values-h320dp/dimens.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Used by RadialTimePicker in clock-style TimePicker. -->
+ <dimen name="timepicker_text_inset_inner">58dp</dimen>
+ <dimen name="timepicker_radial_picker_dimen">224dp</dimen>
+ <integer name="timepicker_title_visibility">2</integer>
+
+ <dimen name="floating_window_margin_left">16dp</dimen>
+ <dimen name="floating_window_margin_top">8dp</dimen>
+ <dimen name="floating_window_margin_right">16dp</dimen>
+ <dimen name="floating_window_margin_bottom">32dp</dimen>
+</resources>
diff --git a/core/res/res/values-land/dimens_material.xml b/core/res/res/values-land/dimens_material.xml
index 77719a6..379ccf6 100644
--- a/core/res/res/values-land/dimens_material.xml
+++ b/core/res/res/values-land/dimens_material.xml
@@ -24,4 +24,28 @@
<!-- Default text size for action bar subtitle.-->
<dimen name="text_size_subtitle_material_toolbar">12dp</dimen>
+ <!-- Floating window margins are small until we hit sw380dp-land. -->
+ <dimen name="floating_window_margin_left">16dp</dimen>
+ <dimen name="floating_window_margin_top">4dp</dimen>
+ <dimen name="floating_window_margin_right">16dp</dimen>
+ <dimen name="floating_window_margin_bottom">16dp</dimen>
+
+ <!-- Material time picker dimensions. -->
+ <!-- Text size for the time picker header HH:MM label. This value is large
+ enough that we don't need to use scaled pixels, dp is fine. -->
+ <dimen name="timepicker_time_label_size">48dp</dimen>
+ <dimen name="timepicker_ampm_label_size">16sp</dimen>
+ <dimen name="timepicker_am_top_padding">8dp</dimen>
+ <dimen name="timepicker_pm_top_padding">3dp</dimen>
+ <!-- Radial picker is small until we hit sw380dp-land. -->
+ <dimen name="timepicker_radial_picker_dimen">180dp</dimen>
+ <dimen name="timepicker_radial_picker_top_margin">16dp</dimen>
+ <dimen name="timepicker_radial_picker_horizontal_margin">24dp</dimen>
+
+ <!-- Used by RadialTimePicker in clock-style TimePicker. -->
+ <dimen name="timepicker_text_inset_normal">22dp</dimen>
+ <!-- Landscape inset is small until we hit sw380dp-land. -->
+ <dimen name="timepicker_text_inset_inner">46dp</dimen>
+ <dimen name="timepicker_text_size_normal">14sp</dimen>
+ <dimen name="timepicker_text_size_inner">12sp</dimen>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 09103e3..30ce271 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4215,6 +4215,8 @@
<enum name="marquee_forever" value="-1" />
</attr>
<attr name="inputType" />
+ <!-- Whether undo should be allowed for editable text. Defaults to true. -->
+ <attr name="allowUndo" format="boolean" />
<attr name="imeOptions" />
<!-- An addition content type description to supply to the input
method attached to the text view, which is private to the
@@ -4471,10 +4473,6 @@
<attr name="headerYearTextAppearance" format="reference" />
<!-- The background for the date selector. -->
<attr name="headerBackground" />
- <!-- @hide The selected text color for the date selector. Used as a
- backup if the text appearance does not explicitly have a color
- set for the selected state. -->
- <attr name="headerSelectedTextColor" />
<!-- The list year's text appearance in the list. -->
<attr name="yearListItemTextAppearance" format="reference" />
<!-- The list year's selected circle color in the list. -->
@@ -4774,10 +4772,6 @@
<attr name="headerAmPmTextAppearance" format="reference" />
<!-- The text appearance for the time header. -->
<attr name="headerTimeTextAppearance" format="reference" />
- <!-- @hide The text color for selected time header of the TimePicker.
- This will override the value from the text appearance if it does
- not explicitly have a color set for the selected state. -->
- <attr name="headerSelectedTextColor" format="color" />
<!-- The background for the header containing the currently selected time. -->
<attr name="headerBackground" />
<!-- The color for the hours/minutes numbers. -->
@@ -4790,10 +4784,6 @@
<attr name="amPmTextColor" format="color" />
<!-- The background color state list for the AM/PM selectors. -->
<attr name="amPmBackgroundColor" format="color" />
- <!-- @hide The background color for the AM/PM selectors of the
- TimePicker when selected. Used if the background color does not
- explicitly have a color set for the selected state. -->
- <attr name="amPmSelectedBackgroundColor" format="color" />
<!-- The color for the hours/minutes selector. -->
<attr name="numbersSelectorColor" format="color" />
<!-- Defines the look of the widget. Prior to the L release, the only choice was
@@ -6459,6 +6449,33 @@
for more info. -->
<attr name="actionProviderClass" format="string" />
+ <!-- An optional tint for the item's icon.
+ See {@link android.view.MenuItem#setIconTintList(android.content.res.ColorStateList)}
+ for more info. -->
+ <attr name="iconTint" format="color" />
+
+ <!-- The blending mode used for tinting the item's icon
+ See {@link android.view.MenuItem#setIconTintMode(android.graphics.PorterDuff.Mode)}
+ for more info. -->
+ <attr name="iconTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
+ </attr>
</declare-styleable>
<!-- Attrbitutes for a ActvityChooserView. -->
@@ -7562,6 +7579,52 @@
<!-- Text to set as the content description for the navigation button
located at the start of the toolbar. -->
<attr name="navigationContentDescription" format="string" />
+
+ <!-- Tint used for the navigation button -->
+ <attr name="navigationTint" format="color" />
+ <!-- The blending mode used for tinting the navigation button -->
+ <attr name="navigationTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D). Only works on APIv 11+ -->
+ <enum name="add" value="16" />
+ </attr>
+
+ <!-- Tint used for the overflow button -->
+ <attr name="overflowTint" format="color" />
+ <!-- The blending mode used for tinting the overflow button -->
+ <attr name="overflowTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D). Only works on APIv 11+ -->
+ <enum name="add" value="16" />
+ </attr>
</declare-styleable>
<declare-styleable name="Toolbar_LayoutParams">
diff --git a/core/res/res/values/colors_holo.xml b/core/res/res/values/colors_holo.xml
index eab1e3f..c29fec6 100644
--- a/core/res/res/values/colors_holo.xml
+++ b/core/res/res/values/colors_holo.xml
@@ -103,46 +103,4 @@
<color name="group_button_dialog_pressed_holo_light">#ffffffff</color>
<color name="group_button_dialog_focused_holo_light">#4699cc00</color>
- <!-- Time picker -->
- <eat-comment />
-
- <color name="timepicker_default_background_holo_light">@color/white</color>
- <color name="timepicker_default_background_holo_dark">#ff303030</color>
-
- <color name="timepicker_default_text_color_holo_light">#8c8c8c</color>
- <color name="timepicker_default_text_color_holo_dark">@color/white</color>
-
- <color name="timepicker_default_ampm_selected_background_color_holo_light">@color/holo_blue_light</color>
- <color name="timepicker_default_ampm_selected_background_color_holo_dark">@color/holo_blue_light</color>
-
- <color name="timepicker_default_ampm_unselected_background_color_holo_light">@color/white</color>
- <color name="timepicker_default_ampm_unselected_background_color_holo_dark">@color/transparent</color>
-
- <!-- DatePicker colors -->
- <eat-comment />
-
- <color name="datepicker_default_header_selector_background_holo_light">@android:color/white</color>
- <color name="datepicker_default_header_selector_background_holo_dark">#ff303030</color>
-
- <color name="datepicker_default_header_dayofweek_background_color_holo_light">#999999</color>
- <color name="datepicker_default_header_dayofweek_background_color_holo_dark">@android:color/white</color>
-
- <color name="datepicker_default_normal_text_color_holo_light">#ff999999</color>
- <color name="datepicker_default_normal_text_color_holo_dark">@android:color/white</color>
-
- <color name="datepicker_default_disabled_text_color_holo_light">#80999999</color>
- <color name="datepicker_default_disabled_text_color_holo_dark">#80999999</color>
-
- <color name="datepicker_default_selected_text_color_holo_light">#33b5e5</color>
- <color name="datepicker_default_selected_text_color_holo_dark">#33b5e5</color>
-
- <color name="datepicker_default_pressed_text_color_holo_light">#0099cc</color>
- <color name="datepicker_default_pressed_text_color_holo_dark">#0099cc</color>
-
- <color name="datepicker_default_circle_background_color_holo_light">@android:color/holo_blue_light</color>
- <color name="datepicker_default_circle_background_color_holo_dark">@android:color/holo_blue_light</color>
-
- <color name="datepicker_default_view_animator_color_holo_light">#f2f2f2</color>
- <color name="datepicker_default_view_animator_color_holo_dark">#ff303030</color>
-
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index d240047..e8a249e 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -356,44 +356,6 @@
<!-- Outline width for video subtitles. -->
<dimen name="subtitle_outline_width">2dp</dimen>
- <!-- New TimePicker dimensions. -->
- <dimen name="timepicker_selector_radius">24dp</dimen>
- <dimen name="timepicker_center_dot_radius">4dp</dimen>
- <dimen name="timepicker_selector_dot_radius">4dp</dimen>
- <dimen name="timepicker_text_inset_normal">26dp</dimen>
- <dimen name="timepicker_text_inset_inner">58dp</dimen>
- <dimen name="timepicker_text_size_normal">14sp</dimen>
- <dimen name="timepicker_text_size_inner">12sp</dimen>
-
- <!-- Text size for the time picker header HH:MM label. This value is large
- enough that we don't need to use scaled pixels, dp is fine. -->
- <dimen name="timepicker_time_label_size">60dp</dimen>
- <dimen name="timepicker_ampm_label_size">16sp</dimen>
- <dimen name="timepicker_ampm_horizontal_padding">12dp</dimen>
- <dimen name="timepicker_ampm_vertical_padding">16dp</dimen>
- <dimen name="timepicker_pm_top_padding">3dp</dimen>
- <dimen name="timepicker_separator_padding">4dp</dimen>
- <dimen name="timepicker_header_height">96dp</dimen>
- <dimen name="timepicker_radial_picker_dimen">270dp</dimen>
-
- <!-- Used by SimpleMonthView -->
- <dimen name="datepicker_day_number_size">12sp</dimen>
- <dimen name="datepicker_month_label_size">14sp</dimen>
- <dimen name="datepicker_month_day_label_text_size">12sp</dimen>
- <dimen name="datepicker_month_list_item_header_height">48dp</dimen>
- <dimen name="datepicker_view_animator_height">226dp</dimen>
-
- <dimen name="datepicker_year_picker_padding_top">8dp</dimen>
- <dimen name="datepicker_year_label_height">64dp</dimen>
- <dimen name="datepicker_year_label_text_size">22dp</dimen>
- <dimen name="datepicker_component_width">260dp</dimen>
- <dimen name="datepicker_dialog_width">520dp</dimen>
- <dimen name="datepicker_selected_date_day_size">88dp</dimen>
- <dimen name="datepicker_selected_date_month_size">24dp</dimen>
- <dimen name="datepicker_selected_date_year_size">24dp</dimen>
- <dimen name="datepicker_header_height">30dp</dimen>
- <dimen name="datepicker_header_text_size">14dp</dimen>
-
<!-- Minimum size of the fast scroller thumb's touch target. -->
<dimen name="fast_scroller_minimum_touch_target">48dp</dimen>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index b84249a..8d2afde 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -117,4 +117,47 @@
<dimen name="scrubber_track_height_material">2dp</dimen>
<dimen name="progress_bar_height_material">4dp</dimen>
+
+ <!-- Material time picker dimensions. -->
+ <!-- Text size for the time picker header HH:MM label. This value is large
+ enough that we don't need to use scaled pixels, dp is fine. -->
+ <dimen name="timepicker_time_label_size">60dp</dimen>
+ <dimen name="timepicker_ampm_label_size">16sp</dimen>
+ <dimen name="timepicker_ampm_horizontal_padding">16dp</dimen>
+ <dimen name="timepicker_am_top_padding">4dp</dimen>
+ <dimen name="timepicker_pm_top_padding">4dp</dimen>
+ <dimen name="timepicker_separator_padding">2dp</dimen>
+ <dimen name="timepicker_header_height">96dp</dimen>
+ <dimen name="timepicker_radial_picker_dimen">296dp</dimen>
+ <dimen name="timepicker_radial_picker_top_margin">16dp</dimen>
+ <dimen name="timepicker_radial_picker_horizontal_margin">16dp</dimen>
+
+ <!-- Used by RadialTimePicker in clock-style TimePicker. -->
+ <dimen name="timepicker_selector_radius">20dp</dimen>
+ <dimen name="timepicker_selector_stroke">2dp</dimen>
+ <dimen name="timepicker_center_dot_radius">3dp</dimen>
+ <dimen name="timepicker_selector_dot_radius">3dp</dimen>
+ <dimen name="timepicker_text_inset_normal">22dp</dimen>
+ <dimen name="timepicker_text_inset_inner">58dp</dimen>
+ <dimen name="timepicker_text_size_normal">16sp</dimen>
+ <dimen name="timepicker_text_size_inner">12sp</dimen>
+
+ <!-- Material date picker dimensions. -->
+ <dimen name="datepicker_year_picker_padding_top">8dp</dimen>
+ <dimen name="datepicker_year_label_height">64dp</dimen>
+ <dimen name="datepicker_year_label_text_size">22dp</dimen>
+ <dimen name="datepicker_component_width">260dp</dimen>
+ <dimen name="datepicker_dialog_width">520dp</dimen>
+ <dimen name="datepicker_selected_date_day_size">88dp</dimen>
+ <dimen name="datepicker_selected_date_month_size">24dp</dimen>
+ <dimen name="datepicker_selected_date_year_size">24dp</dimen>
+ <dimen name="datepicker_header_height">30dp</dimen>
+ <dimen name="datepicker_header_text_size">14dp</dimen>
+
+ <!-- Used by Material-style SimpleMonthView -->
+ <dimen name="datepicker_day_number_size">12sp</dimen>
+ <dimen name="datepicker_month_label_size">14sp</dimen>
+ <dimen name="datepicker_month_day_label_text_size">12sp</dimen>
+ <dimen name="datepicker_month_list_item_header_height">48dp</dimen>
+ <dimen name="datepicker_view_animator_height">226dp</dimen>
</resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index b6e79ad..d657bad 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -89,7 +89,7 @@
<item type="id" name="parentMatrix" />
<item type="id" name="statusBarBackground" />
<item type="id" name="navigationBarBackground" />
+ <item type="id" name="pasteAsPlainText" />
<item type="id" name="undo" />
<item type="id" name="redo" />
- <item type="id" name="pasteAsPlainText" />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 46e3d75..16f0676 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2615,6 +2615,12 @@
<public type="attr" name="end" />
<public type="attr" name="windowHasLightStatusBar" />
<public type="attr" name="numbersInnerTextColor" />
+ <public type="attr" name="iconTint" />
+ <public type="attr" name="iconTintMode" />
+ <public type="attr" name="overflowTint" />
+ <public type="attr" name="overflowTintMode" />
+ <public type="attr" name="navigationTint" />
+ <public type="attr" name="navigationTintMode" />
<public type="style" name="Widget.Material.Button.Colored" />
@@ -2636,12 +2642,15 @@
<public type="style" name="Theme.Material.Light.LightStatusBar" />
<public type="style" name="ThemeOverlay.Material.Dialog" />
+ <!-- Context menu ID for the "Paste as plain text" menu item to to copy the current contents
+ of the clipboard into the text view without formatting. -->
+ <public type="id" name="pasteAsPlainText" />
<!-- Context menu ID for the "Undo" menu item to undo the last text edit operation. -->
<public type="id" name="undo" />
<!-- Context menu ID for the "Redo" menu item to redo the last text edit operation. -->
<public type="id" name="redo" />
- <!-- Context menu ID for the "Paste as plain text" menu item to to copy the current contents
- of the clipboard into the text view without formatting. -->
- <public type="id" name="pasteAsPlainText" />
+
+ <!-- TextView attribute to control undo behavior. -->
+ <public type="attr" name="allowUndo" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 199b783..b1f51ef 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2209,6 +2209,15 @@
re-enables the keylock when the call is finished.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_manageFingerprint">manage fingerprint hardware</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_manageFingerprint">Allows the app to invoke methods to add and delete fingerprint templates for use.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_useFingerprint">use fingerprint hardware</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_useFingerprint">Allows the app to use fingerprint hardware for authentication</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readSyncSettings">read sync settings</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readSyncSettings">Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account.</string>
diff --git a/core/res/res/values/styles_holo.xml b/core/res/res/values/styles_holo.xml
index 4589fa3..6861069 100644
--- a/core/res/res/values/styles_holo.xml
+++ b/core/res/res/values/styles_holo.xml
@@ -463,40 +463,14 @@
<item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item>
</style>
- <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
+ <style name="Widget.Holo.TimePicker" parent="Widget.Material.TimePicker">
+ <!-- If the developer chooses "clock", they get the Material picker. -->
<item name="timePickerMode">spinner</item>
- <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
- <!-- Attributes for new-style TimePicker. -->
- <item name="internalLayout">@layout/time_picker_holo</item>
- <item name="headerTimeTextAppearance">@style/TextAppearance.Holo.TimePicker.TimeLabel</item>
- <item name="headerAmPmTextAppearance">@style/TextAppearance.Holo.TimePicker.AmPmLabel</item>
- <item name="headerBackground">@color/timepicker_default_background_holo_dark</item>
- <item name="headerSelectedTextColor">@color/holo_blue_light</item>
- <item name="numbersTextColor">@color/timepicker_default_text_color_holo_dark</item>
- <item name="numbersBackgroundColor">@color/timepicker_default_background_holo_dark</item>
- <item name="amPmTextColor">@color/timepicker_default_text_color_holo_dark</item>
- <item name="amPmBackgroundColor">@color/timepicker_default_background_holo_dark</item>
- <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
- <item name="numbersSelectorColor">@color/holo_blue_light</item>
</style>
- <style name="Widget.Holo.DatePicker" parent="Widget.DatePicker">
+ <style name="Widget.Holo.DatePicker" parent="Widget.Material.DatePicker">
+ <!-- If the developer chooses "calendar", they get the Material picker. -->
<item name="datePickerMode">spinner</item>
- <item name="legacyLayout">@layout/date_picker_legacy_holo</item>
- <item name="internalLayout">@layout/date_picker_holo</item>
- <item name="calendarViewShown">true</item>
- <!-- New-style date picker attributes. -->
- <item name="dayOfWeekBackground">@color/datepicker_default_header_dayofweek_background_color_holo_dark</item>
- <item name="dayOfWeekTextAppearance">@style/TextAppearance.Holo.DatePicker.DayOfWeekLabel</item>
- <item name="headerBackground">@color/datepicker_default_header_selector_background_holo_dark</item>
- <item name="headerMonthTextAppearance">@style/TextAppearance.Holo.DatePicker.Selector.MonthLabel</item>
- <item name="headerDayOfMonthTextAppearance">@style/TextAppearance.Holo.DatePicker.Selector.DayOfMonthLabel</item>
- <item name="headerYearTextAppearance">@style/TextAppearance.Holo.DatePicker.Selector.YearLabel</item>
- <item name="headerSelectedTextColor">@color/holo_blue_light</item>
- <item name="yearListItemTextAppearance">@style/TextAppearance.Holo.DatePicker.List.YearLabel</item>
- <item name="yearListSelectorColor">@color/datepicker_default_circle_background_color_holo_dark</item>
- <item name="calendarTextColor">@color/date_picker_calendar_holo_dark</item>
- <item name="calendarDayBackgroundColor">@color/holo_blue_dark</item>
</style>
<style name="Widget.Holo.ActivityChooserView" parent="Widget.ActivityChooserView" />
@@ -888,40 +862,14 @@
<style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker" />
- <style name="Widget.Holo.Light.TimePicker" parent="Widget.TimePicker">
+ <style name="Widget.Holo.Light.TimePicker" parent="Widget.Material.Light.TimePicker">
+ <!-- If the developer chooses "clock", they get the Material picker. -->
<item name="timePickerMode">spinner</item>
- <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
- <!-- Non-legacy styling -->
- <item name="internalLayout">@layout/time_picker_holo</item>
- <item name="headerTimeTextAppearance">@style/TextAppearance.Holo.Light.TimePicker.TimeLabel</item>
- <item name="headerAmPmTextAppearance">@style/TextAppearance.Holo.Light.TimePicker.AmPmLabel</item>
- <item name="headerBackground">@color/timepicker_default_background_holo_light</item>
- <item name="headerSelectedTextColor">@color/holo_blue_light</item>
- <item name="numbersTextColor">@color/timepicker_default_text_color_holo_light</item>
- <item name="numbersBackgroundColor">@color/timepicker_default_background_holo_light</item>
- <item name="amPmTextColor">@color/timepicker_default_text_color_holo_light</item>
- <item name="amPmBackgroundColor">@color/timepicker_default_background_holo_light</item>
- <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
- <item name="numbersSelectorColor">@color/holo_blue_light</item>
</style>
- <style name="Widget.Holo.Light.DatePicker" parent="Widget.DatePicker">
+ <style name="Widget.Holo.Light.DatePicker" parent="Widget.Material.Light.DatePicker">
+ <!-- If the developer chooses "calendar", they get the Material picker. -->
<item name="datePickerMode">spinner</item>
- <item name="legacyLayout">@layout/date_picker_legacy_holo</item>
- <item name="internalLayout">@layout/date_picker_holo</item>
- <item name="calendarViewShown">true</item>
- <!-- New-style date picker attributes. -->
- <item name="dayOfWeekBackground">@color/datepicker_default_header_dayofweek_background_color_holo_light</item>
- <item name="dayOfWeekTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.DayOfWeekLabel</item>
- <item name="headerMonthTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.Selector.MonthLabel</item>
- <item name="headerDayOfMonthTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.Selector.DayOfMonthLabel</item>
- <item name="headerYearTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.Selector.YearLabel</item>
- <item name="headerBackground">@color/datepicker_default_header_selector_background_holo_light</item>
- <item name="headerSelectedTextColor">@color/holo_blue_light</item>
- <item name="yearListItemTextAppearance">@style/TextAppearance.Holo.Light.DatePicker.List.YearLabel</item>
- <item name="yearListSelectorColor">@color/datepicker_default_circle_background_color_holo_light</item>
- <item name="calendarTextColor">@color/date_picker_calendar_holo_light</item>
- <item name="calendarDayBackgroundColor">@color/holo_blue_light</item>
</style>
<style name="Widget.Holo.Light.ActivityChooserView" parent="Widget.Holo.ActivityChooserView">
@@ -1221,86 +1169,6 @@
<item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
</style>
- <style name="TextAppearance.Holo.TimePicker.TimeLabel" parent="TextAppearance.Holo">
- <item name="textSize">@dimen/timepicker_time_label_size</item>
- <item name="textColor">@color/timepicker_default_text_color_holo_dark</item>
- </style>
-
- <style name="TextAppearance.Holo.TimePicker.AmPmLabel" parent="TextAppearance.Holo">
- <item name="textSize">@dimen/timepicker_ampm_label_size</item>
- <item name="textAllCaps">true</item>
- <item name="textColor">@color/timepicker_default_text_color_holo_dark</item>
- <item name="textStyle">bold</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.TimePicker.TimeLabel" parent="TextAppearance.Holo.Light">
- <item name="textSize">@dimen/timepicker_time_label_size</item>
- <item name="textColor">@color/timepicker_default_text_color_holo_light</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.TimePicker.AmPmLabel" parent="TextAppearance.Holo.Light">
- <item name="textSize">@dimen/timepicker_ampm_label_size</item>
- <item name="textAllCaps">true</item>
- <item name="textColor">@color/timepicker_default_text_color_holo_light</item>
- <item name="textStyle">bold</item>
- </style>
-
- <style name="TextAppearance.Holo.DatePicker.DayOfWeekLabel" parent="TextAppearance.Holo">
- <item name="includeFontPadding">false</item>
- <item name="textColor">@color/black</item>
- <item name="textSize">@dimen/datepicker_header_text_size</item>
- </style>
-
- <style name="TextAppearance.Holo.DatePicker.Selector" parent="TextAppearance.Holo">
- <item name="includeFontPadding">false</item>
- <item name="textColor">@color/date_picker_selector_holo_dark</item>
- </style>
-
- <style name="TextAppearance.Holo.DatePicker.Selector.MonthLabel" parent="TextAppearance.Holo.DatePicker.Selector">
- <item name="textSize">@dimen/datepicker_selected_date_month_size</item>
- </style>
-
- <style name="TextAppearance.Holo.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Holo.DatePicker.Selector">
- <item name="textSize">@dimen/datepicker_selected_date_day_size</item>
- </style>
-
- <style name="TextAppearance.Holo.DatePicker.Selector.YearLabel" parent="TextAppearance.Holo.DatePicker.Selector">
- <item name="textSize">@dimen/datepicker_selected_date_year_size</item>
- </style>
-
- <style name="TextAppearance.Holo.DatePicker.List.YearLabel" parent="TextAppearance.Holo">
- <item name="textColor">@color/date_picker_year_selector_holo_dark</item>
- <item name="textSize">@dimen/datepicker_year_label_text_size</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.DatePicker.DayOfWeekLabel" parent="TextAppearance.Holo">
- <item name="includeFontPadding">false</item>
- <item name="textColor">@color/white</item>
- <item name="textSize">@dimen/datepicker_header_text_size</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.DatePicker.Selector" parent="TextAppearance.Holo">
- <item name="includeFontPadding">false</item>
- <item name="textColor">@color/date_picker_selector_holo_light</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.DatePicker.Selector.MonthLabel" parent="TextAppearance.Holo.Light.DatePicker.Selector">
- <item name="textSize">@dimen/datepicker_selected_date_month_size</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.DatePicker.Selector.DayOfMonthLabel" parent="TextAppearance.Holo.Light.DatePicker.Selector">
- <item name="textSize">@dimen/datepicker_selected_date_day_size</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.DatePicker.Selector.YearLabel" parent="TextAppearance.Holo.Light.DatePicker.Selector">
- <item name="textSize">@dimen/datepicker_selected_date_year_size</item>
- </style>
-
- <style name="TextAppearance.Holo.Light.DatePicker.List.YearLabel" parent="TextAppearance.Holo">
- <item name="textColor">@color/date_picker_year_selector_holo_light</item>
- <item name="textSize">@dimen/datepicker_year_label_text_size</item>
- </style>
-
<style name="Widget.Holo.FastScroll" parent="Widget.FastScroll">
<item name="thumbMinWidth">0dp</item>
<item name="thumbMinHeight">0dp</item>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 9a64dec9..a8ab18d 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -37,7 +37,7 @@
</style>
<style name="PreferenceFragment.Material">
- <item name="layout">@android:layout/preference_list_fragment_material</item>
+ <item name="layout">@layout/preference_list_fragment_material</item>
<item name="paddingStart">@dimen/preference_fragment_padding_side_material</item>
<item name="paddingEnd">@dimen/preference_fragment_padding_side_material</item>
</style>
@@ -72,7 +72,7 @@
</style>
<style name="Preference.Material.SeekBarPreference">
- <item name="layout">@android:layout/preference_widget_seekbar_material</item>
+ <item name="layout">@layout/preference_widget_seekbar_material</item>
</style>
<style name="Preference.Material.PreferenceScreen"/>
@@ -379,14 +379,12 @@
<style name="TextAppearance.Material.TimePicker.TimeLabel" parent="TextAppearance.Material">
<item name="textSize">@dimen/timepicker_time_label_size</item>
- <item name="textColor">?attr/textColorSecondaryInverse</item>
+ <item name="textColor">@color/time_picker_header_text_material</item>
</style>
- <style name="TextAppearance.Material.TimePicker.AmPmLabel" parent="TextAppearance.Material">
+ <style name="TextAppearance.Material.TimePicker.AmPmLabel" parent="TextAppearance.Material.Button">
<item name="textSize">@dimen/timepicker_ampm_label_size</item>
- <item name="textAllCaps">true</item>
- <item name="textColor">?attr/textColorSecondaryInverse</item>
- <item name="textStyle">bold</item>
+ <item name="textColor">@color/time_picker_header_text_material</item>
</style>
<style name="TextAppearance.Material.DatePicker.DayOfWeekLabel" parent="TextAppearance.Material">
@@ -397,19 +395,19 @@
<style name="TextAppearance.Material.DatePicker.MonthLabel" parent="TextAppearance.Material">
<item name="includeFontPadding">false</item>
- <item name="textColor">?attr/textColorSecondaryInverse</item>
+ <item name="textColor">@color/date_picker_header_text_material</item>
<item name="textSize">@dimen/datepicker_selected_date_month_size</item>
</style>
<style name="TextAppearance.Material.DatePicker.DayOfMonthLabel" parent="TextAppearance.Material">
<item name="includeFontPadding">false</item>
- <item name="textColor">?attr/textColorSecondaryInverse</item>
+ <item name="textColor">@color/date_picker_header_text_material</item>
<item name="textSize">@dimen/datepicker_selected_date_day_size</item>
</style>
<style name="TextAppearance.Material.DatePicker.YearLabel" parent="TextAppearance.Material">
<item name="includeFontPadding">false</item>
- <item name="textColor">?attr/textColorSecondaryInverse</item>
+ <item name="textColor">@color/date_picker_header_text_material</item>
<item name="textSize">@dimen/datepicker_selected_date_year_size</item>
</style>
@@ -642,36 +640,32 @@
<item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item>
</style>
- <style name="Widget.Material.TimePicker" parent="Widget.TimePicker">
+ <style name="Widget.Material.TimePicker">
<item name="timePickerMode">clock</item>
- <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
+ <item name="legacyLayout">@layout/time_picker_legacy_material</item>
<!-- Attributes for new-style TimePicker. -->
- <item name="internalLayout">@layout/time_picker_holo</item>
+ <item name="internalLayout">@layout/time_picker_material</item>
<item name="headerTimeTextAppearance">@style/TextAppearance.Material.TimePicker.TimeLabel</item>
<item name="headerAmPmTextAppearance">@style/TextAppearance.Material.TimePicker.AmPmLabel</item>
- <item name="headerSelectedTextColor">?attr/textColorPrimaryInverse</item>
<item name="headerBackground">@drawable/time_picker_header_material</item>
<item name="numbersTextColor">?attr/textColorPrimaryActivated</item>
<item name="numbersInnerTextColor">?attr/textColorSecondaryActivated</item>
<item name="numbersBackgroundColor">#10ffffff</item>
<item name="numbersSelectorColor">?attr/colorControlActivated</item>
<item name="amPmTextColor">?attr/textColorSecondary</item>
- <item name="amPmBackgroundColor">@color/transparent</item>
- <item name="amPmSelectedBackgroundColor">?attr/colorControlActivated</item>
</style>
- <style name="Widget.Material.DatePicker" parent="Widget.DatePicker">
+ <style name="Widget.Material.DatePicker">
<item name="datePickerMode">calendar</item>
<item name="legacyLayout">@layout/date_picker_legacy_holo</item>
+ <item name="calendarViewShown">true</item>
<!-- Attributes for new-style DatePicker. -->
<item name="internalLayout">@layout/date_picker_holo</item>
- <item name="calendarViewShown">true</item>
<item name="dayOfWeekBackground">#10000000</item>
<item name="dayOfWeekTextAppearance">@style/TextAppearance.Material.DatePicker.DayOfWeekLabel</item>
<item name="headerMonthTextAppearance">@style/TextAppearance.Material.DatePicker.MonthLabel</item>
<item name="headerDayOfMonthTextAppearance">@style/TextAppearance.Material.DatePicker.DayOfMonthLabel</item>
<item name="headerYearTextAppearance">@style/TextAppearance.Material.DatePicker.YearLabel</item>
- <item name="headerSelectedTextColor">?attr/textColorPrimaryInverse</item>
<item name="headerBackground">?attr/colorAccent</item>
<item name="yearListItemTextAppearance">@style/TextAppearance.Material.DatePicker.List.YearLabel</item>
<item name="yearListSelectorColor">?attr/colorControlActivated</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 39c0e8f..86e46f6 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1975,10 +1975,8 @@
<java-symbol type="attr" name="nestedScrollingEnabled" />
- <java-symbol type="style" name="TextAppearance.Holo.TimePicker.TimeLabel" />
-
- <java-symbol type="layout" name="time_picker_holo" />
- <java-symbol type="layout" name="time_header_label" />
+ <java-symbol type="layout" name="time_picker_material" />
+ <java-symbol type="layout" name="time_picker_header_material" />
<java-symbol type="layout" name="year_label_text_view" />
<java-symbol type="layout" name="date_picker_holo" />
@@ -2045,22 +2043,6 @@
<java-symbol type="dimen" name="datepicker_year_label_height" />
<java-symbol type="dimen" name="datepicker_year_picker_padding_top" />
- <java-symbol type="color" name="timepicker_default_text_color_holo_light" />
- <java-symbol type="color" name="timepicker_default_ampm_unselected_background_color_holo_light" />
- <java-symbol type="color" name="timepicker_default_ampm_selected_background_color_holo_light" />
-
- <java-symbol type="color" name="datepicker_default_normal_text_color_holo_light" />
- <java-symbol type="color" name="datepicker_default_disabled_text_color_holo_light" />
- <java-symbol type="color" name="datepicker_default_circle_background_color_holo_light" />
- <java-symbol type="color" name="datepicker_default_header_dayofweek_background_color_holo_light" />
- <java-symbol type="color" name="datepicker_default_header_selector_background_holo_light" />
-
- <java-symbol type="color" name="datepicker_default_normal_text_color_material_light" />
- <java-symbol type="color" name="datepicker_default_disabled_text_color_material_light" />
- <java-symbol type="color" name="datepicker_default_circle_background_color_material_light" />
- <java-symbol type="color" name="datepicker_default_header_dayofweek_background_color_material_light" />
- <java-symbol type="color" name="datepicker_default_header_selector_background_material_light" />
-
<java-symbol type="array" name="config_clockTickVibePattern" />
<java-symbol type="array" name="config_calendarDateVibePattern" />
@@ -2106,8 +2088,6 @@
<java-symbol type="attr" name="ambientShadowAlpha" />
<java-symbol type="attr" name="spotShadowAlpha" />
<java-symbol type="array" name="config_cdma_home_system" />
- <java-symbol type="attr" name="headerSelectedTextColor" />
- <java-symbol type="attr" name="amPmSelectedBackgroundColor" />
<java-symbol type="bool" name="config_sms_decode_gsm_8bit_data" />
<java-symbol type="dimen" name="text_size_small_material" />
<java-symbol type="attr" name="checkMarkGravity" />
@@ -2169,4 +2149,5 @@
<java-symbol type="integer" name="config_screen_magnification_multi_tap_adjustment" />
<java-symbol type="dimen" name="config_screen_magnification_scaling_threshold" />
+ <java-symbol type="dimen" name="timepicker_selector_stroke"/>
</resources>
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 80fb1fd..38321a3 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -111,49 +111,11 @@
endef
font_src_files := \
- Roboto-Regular.ttf \
- Roboto-Bold.ttf \
- Roboto-Italic.ttf \
- Roboto-BoldItalic.ttf \
Clockopia.ttf \
AndroidClock.ttf \
AndroidClock_Highlight.ttf \
AndroidClock_Solid.ttf
-ifeq ($(MINIMAL_FONT_FOOTPRINT),true)
-
-$(eval $(call create-font-symlink,Roboto-Black.ttf,Roboto-Bold.ttf))
-$(eval $(call create-font-symlink,Roboto-BlackItalic.ttf,Roboto-BoldItalic.ttf))
-$(eval $(call create-font-symlink,Roboto-Light.ttf,Roboto-Regular.ttf))
-$(eval $(call create-font-symlink,Roboto-LightItalic.ttf,Roboto-Italic.ttf))
-$(eval $(call create-font-symlink,Roboto-Medium.ttf,Roboto-Regular.ttf))
-$(eval $(call create-font-symlink,Roboto-MediumItalic.ttf,Roboto-Italic.ttf))
-$(eval $(call create-font-symlink,Roboto-Thin.ttf,Roboto-Regular.ttf))
-$(eval $(call create-font-symlink,Roboto-ThinItalic.ttf,Roboto-Italic.ttf))
-$(eval $(call create-font-symlink,RobotoCondensed-Regular.ttf,Roboto-Regular.ttf))
-$(eval $(call create-font-symlink,RobotoCondensed-Bold.ttf,Roboto-Bold.ttf))
-$(eval $(call create-font-symlink,RobotoCondensed-Italic.ttf,Roboto-Italic.ttf))
-$(eval $(call create-font-symlink,RobotoCondensed-BoldItalic.ttf,Roboto-BoldItalic.ttf))
-
-else # !MINIMAL_FONT
-font_src_files += \
- Roboto-Black.ttf \
- Roboto-BlackItalic.ttf \
- Roboto-Light.ttf \
- Roboto-LightItalic.ttf \
- Roboto-Medium.ttf \
- Roboto-MediumItalic.ttf \
- Roboto-Thin.ttf \
- Roboto-ThinItalic.ttf \
- RobotoCondensed-Regular.ttf \
- RobotoCondensed-Bold.ttf \
- RobotoCondensed-Italic.ttf \
- RobotoCondensed-BoldItalic.ttf \
- RobotoCondensed-Light.ttf \
- RobotoCondensed-LightItalic.ttf
-
-endif # !MINIMAL_FONT
-
$(foreach f, $(font_src_files), $(call build-one-font-module, $(f)))
build-one-font-module :=
diff --git a/data/fonts/Roboto-Black.ttf b/data/fonts/Roboto-Black.ttf
deleted file mode 100644
index 79b5f74..0000000
--- a/data/fonts/Roboto-Black.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-BlackItalic.ttf b/data/fonts/Roboto-BlackItalic.ttf
deleted file mode 100644
index 4c58b7b..0000000
--- a/data/fonts/Roboto-BlackItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
deleted file mode 100644
index 58397cc..0000000
--- a/data/fonts/Roboto-Bold.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf
deleted file mode 100644
index 606252c..0000000
--- a/data/fonts/Roboto-BoldItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
deleted file mode 100644
index cc3fd40..0000000
--- a/data/fonts/Roboto-Italic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf
deleted file mode 100644
index e65c2d2..0000000
--- a/data/fonts/Roboto-Light.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf
deleted file mode 100644
index d5476e7..0000000
--- a/data/fonts/Roboto-LightItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-Medium.ttf b/data/fonts/Roboto-Medium.ttf
deleted file mode 100644
index 9263090..0000000
--- a/data/fonts/Roboto-Medium.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-MediumItalic.ttf b/data/fonts/Roboto-MediumItalic.ttf
deleted file mode 100644
index 329aab9..0000000
--- a/data/fonts/Roboto-MediumItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf
deleted file mode 100644
index c515eca..0000000
--- a/data/fonts/Roboto-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-Thin.ttf b/data/fonts/Roboto-Thin.ttf
deleted file mode 100644
index 35ab525..0000000
--- a/data/fonts/Roboto-Thin.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-ThinItalic.ttf b/data/fonts/Roboto-ThinItalic.ttf
deleted file mode 100644
index edada2e..0000000
--- a/data/fonts/Roboto-ThinItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Bold.ttf b/data/fonts/RobotoCondensed-Bold.ttf
deleted file mode 100644
index bcbeece..0000000
--- a/data/fonts/RobotoCondensed-Bold.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/RobotoCondensed-BoldItalic.ttf b/data/fonts/RobotoCondensed-BoldItalic.ttf
deleted file mode 100644
index 7680d0a..0000000
--- a/data/fonts/RobotoCondensed-BoldItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Italic.ttf b/data/fonts/RobotoCondensed-Italic.ttf
deleted file mode 100644
index 04c83a0..0000000
--- a/data/fonts/RobotoCondensed-Italic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Light.ttf b/data/fonts/RobotoCondensed-Light.ttf
deleted file mode 100644
index 9f57418..0000000
--- a/data/fonts/RobotoCondensed-Light.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/RobotoCondensed-LightItalic.ttf b/data/fonts/RobotoCondensed-LightItalic.ttf
deleted file mode 100644
index f9eac04..0000000
--- a/data/fonts/RobotoCondensed-LightItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Regular.ttf b/data/fonts/RobotoCondensed-Regular.ttf
deleted file mode 100644
index 3a06286..0000000
--- a/data/fonts/RobotoCondensed-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index f285ebe..a5939fa 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -21,24 +21,6 @@
PRODUCT_PACKAGES := \
DroidSansFallback.ttf \
- Roboto-Regular.ttf \
- Roboto-Bold.ttf \
- Roboto-Italic.ttf \
- Roboto-BoldItalic.ttf \
- Roboto-Black.ttf \
- Roboto-BlackItalic.ttf \
- Roboto-Light.ttf \
- Roboto-LightItalic.ttf \
- Roboto-Medium.ttf \
- Roboto-MediumItalic.ttf \
- Roboto-Thin.ttf \
- Roboto-ThinItalic.ttf \
- RobotoCondensed-Regular.ttf \
- RobotoCondensed-Bold.ttf \
- RobotoCondensed-Italic.ttf \
- RobotoCondensed-BoldItalic.ttf \
- RobotoCondensed-Light.ttf \
- RobotoCondensed-LightItalic.ttf \
DroidSansMono.ttf \
Clockopia.ttf \
AndroidClock.ttf \
diff --git a/docs/html-intl/intl/ja/distribute/index.jd b/docs/html-intl/intl/ja/distribute/index.jd
new file mode 100644
index 0000000..27f1cb4
--- /dev/null
+++ b/docs/html-intl/intl/ja/distribute/index.jd
@@ -0,0 +1,16 @@
+page.title=Google Play でアプリを配信する
+page.viewport_width=970
+section.landing=true
+header.hide=1
+nonavpage=true
+page.metaDescription=Google Play は最もよく利用されている Android アプリストアです。クラウドと同期された強力な基盤により、ユーザーは簡単に あなたのアプリを見つけてダウンロードできます。
+
+@jd:body
+
+ <div class="resource-widget resource-flow-layout col-16"
+ style="margin-top:20px"
+ data-query="collection:launch/static/ja"
+ data-sortOrder=""
+ data-cardSizes="6x6,6x6,6x2x3,12x6,6x6,6x2x3,6x6,6x6,12x6,6x6"
+ data-maxResults="24"></div>
+
diff --git a/docs/html-intl/intl/ja/training/tv/start/index.jd b/docs/html-intl/intl/ja/training/tv/start/index.jd
index 8f946a1..e8db099 100755
--- a/docs/html-intl/intl/ja/training/tv/start/index.jd
+++ b/docs/html-intl/intl/ja/training/tv/start/index.jd
@@ -1,5 +1,7 @@
-page.title=TV アプリのビルド
+page.title=Android TV アプリ開発
page.tags=tv, leanback
+page.metaDescription=Android TV 対応アプリ開発の手順が日本語化。
+page.image=design/tv/images/atv-home.jpg
startpage=true
@jd:body
diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd
index da9178d..01e680f 100644
--- a/docs/html/google/play/billing/billing_reference.jd
+++ b/docs/html/google/play/billing/billing_reference.jd
@@ -12,6 +12,7 @@
<ol>
<li><a href="#getSkuDetails">getSkuDetails()</a></li>
<li><a href="#getBuyIntent">getBuyIntent()</a></li>
+ <li><a href="#upgrade-getBuyIntentToReplaceSkus">getBuyIntentToReplaceSkus()</a></li>
<li><a href="#getPurchases">getPurchases()</a></li>
</ol>
</li>
@@ -107,8 +108,8 @@
</tr>
<tr>
<td>{@code type}</td>
- <td>Value must be “inapp” for an in-app product or "subs" for
-subscriptions.</td>
+ <td>Value must be <code>“inapp”</code> for an in-app product or
+ <code>"subs"</code> for subscriptions.</td>
</tr>
<tr>
<td>{@code price}</td>
@@ -140,7 +141,17 @@
</p>
<h3 id="getBuyIntent">The getBuyIntent() method</h3>
-<p>This method returns a response code integer mapped to the {@code RESPONSE_CODE} key, and a {@code PendingIntent} to launch the puchase flow for the in-app item mapped to the {@code BUY_INTENT} key. When it receives the {@code PendingIntent}, Google Play sends a response {@code Intent} with the data for that purchase order. The data that is returned in the response {@code Intent} is summarized in table 3.</p>
+<p>
+ This method returns a response code integer mapped to the {@code
+ RESPONSE_CODE} key, and a {@link android.app.PendingIntent} to launch the
+ purchase flow for the in-app item mapped to the {@code BUY_INTENT} key, as
+ described in <a href=
+ "{@docRoot}google/play/billing/billing_integrate.html#purchase">Purchasing an
+ Item</a>. When it receives the {@link android.app.PendingIntent}, Google Play
+ sends a response {@code Intent} with the data for that purchase order. The
+ data that is returned in the response {@code Intent} is summarized in table
+ 3.
+</p>
<p class="table-caption" id="purchase-pendingintent-response-table">
<strong>Table 3.</strong> Response data from an In-app Billing Version 3 purchase request.</p>
@@ -151,7 +162,7 @@
</tr>
<tr>
<td>{@code RESPONSE_CODE}</td>
- <td>0 if the purchase was success, error otherwise.</td>
+ <td>Value is <code>0</code> if the purchase was success, error otherwise.</td>
</tr>
<tr>
<td>{@code INAPP_PURCHASE_DATA}</td>
@@ -176,9 +187,22 @@
<th scope="col">Field</th>
<th scope="col">Description</th>
</tr>
+ <tr>
+ <td>{@code autoRenewing}</td>
+ <td>Indicates whether the subscription renews automatically. If
+ <code>true</code>, the subscription is active, and will
+ automatically renew on the next billing date. If <code>false</code>,
+ indicates that the user has canceled the subscription. The user has
+ access to subscription content until the next billing date and will
+ lose access at that time unless they re-enable automatic renewal
+ (or manually renew, as described in
+ <a href="{@docRoot}google/play/billing/billing_subscriptions.html#manual-renewal">Manual
+ Renewal</a>).</td>
+ </tr>
<tr>
<td>{@code orderId}</td>
- <td>A unique order identifier for the transaction. This corresponds to the Google Wallet Order ID.</td>
+ <td>A unique order identifier for the transaction. This identifier
+ corresponds to the Google Wallet Order ID.</td>
</tr>
<tr>
<td>{@code packageName}</td>
@@ -194,7 +218,8 @@
</tr>
<tr>
<td>{@code purchaseState}</td>
- <td>The purchase state of the order. Possible values are 0 (purchased), 1 (canceled), or 2 (refunded).</td>
+ <td>The purchase state of the order. Possible values are <code>0</code>
+ (purchased), <code>1</code> (canceled), or <code>2</code> (refunded).</td>
</tr>
<tr>
<td>{@code developerPayload}</td>
@@ -202,20 +227,48 @@
</tr>
<tr>
<td>{@code purchaseToken}</td>
- <td>A token that uniquely identifies a purchase for a given item and user
- pair. This token may be up to 1,000 characters long.
- Pass this entire token to other methods, such as when you consume the
- purchase (as described in
-<a href="{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consume
- a Purchase</a>). Do not abbreviate or truncate this token.</td>
+ <td>A token that uniquely identifies a purchase for a given item and user pair. </td>
</tr>
</table>
</p>
-<h3 id="getPurchases">The getPurchases() method</h3>
-<p>This method returns the current un-consumed products owned by the user. Table 5 lists the response data that is returned in the {@code Bundle}.</p>
-<p class="table-caption" id="getpurchases-response-table">
-<strong>Table 5.</strong> Response data from a {@code getPurchases} request.</p>
+<h3 id="upgrade-getBuyIntentToReplaceSkus">The getBuyIntentToReplaceSkus()
+ method</h3>
+
+<p>This method is used to upgrade or downgrade a subscription purchase. The method
+is similar to <a href="#getBuyIntent"><code>getBuyIntent()</code></a>, except
+that it takes a list of already-purchased SKUs that are to be
+replaced with the SKU being purchased. When the user completes the purchase,
+Google Play cancels the old SKUs and credits the user with the unused value of
+their subscription time on a pro-rated basis. Google Play applies this credit
+to the new subscription, and does not begin billing the user for the new
+subscription until after the credit is used up.</p>
+
+<p>This method was added with version 5 of the in-app billing API. To verify
+that the method is reported, send an <code>isBillingSupported</code> AIDL
+request.</p>
+
+<p class="note"><strong>Note:</strong> You can only use this method for
+subscription purchases. If the passed <code>type</code> parameter is anything
+other than <code>"subs"</code>, the method returns
+<a href="#billing-codes"><code>BILLING_RESPONSE_RESULT_DEVELOPER_ERROR</code></a>.
+Furthermore, the passed SKUs may not include SKUs for seasonal
+subscriptions.</p>
+
+<p>
+ This method returns a response code integer mapped to the {@code
+ RESPONSE_CODE} key, and a {@link android.app.PendingIntent} to launch the
+ purchase flow for the in-app subscription mapped to the {@code BUY_INTENT}
+ key, as described in <a href=
+ "{@docRoot}google/play/billing/billing_integrate.html#purchase">Purchasing an
+ Item</a>. When it receives the {@link android.app.PendingIntent}, Google Play
+ sends a response {@code Intent} with the data for that purchase order. The
+ data that is returned in the response {@code Intent} is summarized in table
+ 5.
+</p>
+
+<p class="table-caption" id="upgrade-purchase-pendingintent-response-table">
+<strong>Table 5.</strong> Response data from an In-app Billing Version 5 purchase request.</p>
<table>
<tr>
<th scope="col">Key</th>
@@ -223,7 +276,39 @@
</tr>
<tr>
<td>{@code RESPONSE_CODE}</td>
- <td>0 if the request was successful, error otherwise.</td>
+ <td>Value is <code>0</code> if the purchase succeeds. If the purchase fails, contains an error
+ code.</td>
+ </tr>
+ <tr>
+ <td>{@code INAPP_PURCHASE_DATA}</td>
+ <td>
+ A String in JSON format that contains details about the purchase order.
+ See <a href="#purchase-data-table">table 4</a> for a description of the JSON fields.
+ </td>
+ </tr>
+ <tr>
+ <td>{@code INAPP_DATA_SIGNATURE}</td>
+ <td>String containing the signature of the purchase data that the developer
+ signed with their private key. The data signature uses the
+ RSASSA-PKCS1-v1_5 scheme.</td>
+ </tr>
+</table>
+</p>
+
+</p>
+
+<h3 id="getPurchases">The getPurchases() method</h3>
+<p>This method returns the current un-consumed products owned by the user. Table 5 lists the response data that is returned in the {@code Bundle}.</p>
+<p class="table-caption" id="getpurchases-response-table">
+<strong>Table 6.</strong> Response data from a {@code getPurchases} request.</p>
+<table>
+ <tr>
+ <th scope="col">Key</th>
+ <th scope="col">Description</th>
+ </tr>
+ <tr>
+ <td>{@code RESPONSE_CODE}</td>
+ <td>Value is <code>0</code> if the request was successful, error otherwise.</td>
</tr>
<tr>
<td>{@code INAPP_PURCHASE_ITEM_LIST}</td>
diff --git a/docs/html/google/play/billing/billing_subscriptions.jd b/docs/html/google/play/billing/billing_subscriptions.jd
index b9b77df..8f55354e 100644
--- a/docs/html/google/play/billing/billing_subscriptions.jd
+++ b/docs/html/google/play/billing/billing_subscriptions.jd
@@ -1,4 +1,4 @@
-page.title=In-App Subscriptions
+page.title=In-app Subscriptions
parent.title=In-app Billing
parent.link=index.html
page.metaDescription=Subscriptions let you sell content or features in your app with automated, recurring billing.
@@ -21,6 +21,11 @@
Developer API</a>.</li>
<li>Users purchase your subscriptions from inside your apps, rather than
directly from Google Play.</li>
+ <li>Users can renew their subscriptions while a current subscription is
+ active.</li>
+ <li>Users can upgrade or downgrade a subscription in the middle of a
+ subscription period. The old subscription's cost is pro-rated, and the
+ unused portion is applied to the replacement subscription.</li>
<li>You can defer billing for a particular user's subscription, to manage
accounts or offer rewards.</li>
</ul>
@@ -206,6 +211,65 @@
billing errors that may occur. Your backend servers can use the server-side API
to query and update your records and follow up with customers directly, if needed.</p>
+<h3 id="manual-renewal">Manual Renewal</h3>
+
+<p>With version 5 of the In-app Billing API, users can renew a subscription
+during its active period even if the subscription is not set to
+automatically renew. If the user purchases a subscription while the subscription
+is active, it is extended by the appropriate period at the current rate.</p>
+
+<p>For example, Achilles has a subscription to the <em>Modern Hoplite</em> app.
+His subscription is currently due to expire on August 1. On July 10, he
+purchases a 3-month subscription at the current rate. Those three months are
+added to his existing subscription, so the subscription now expires on November
+1.</p>
+
+<p>It is up to the app to convey this with an appropriate UI. For example, if a
+user does not have an active subscription, the app might have a
+<strong>buy</strong> button, but if the user has a subscription the button might
+say <strong>renew</strong>.</p>
+
+<h3 id="upgrade">Subscription Upgrade/Downgrade</h3>
+
+<p>
+ With version 5 of the In-app Billing API, users can upgrade or downgrade a
+ subscription during its active period. When the user does this, the active
+ subscription is canceled and a new subscription is created. The unused
+ balance of the old subscription is applied on a pro-rated basis to the new
+ subscription. The first billing period for the new subscription begins after
+ that balance is used up. (The new subscription does not need to have a period
+ of the same length as the old one.)
+</p>
+
+<p>For example, Samwise has a subscription to online content from the
+<em>Country Gardener</em> app. He currently has a monthly subscription to the
+Tier 1
+version of the content (which has text-only content). This subscription costs
+him £2/month, and renews on the first of the month. On April
+15, he chooses to upgrade to the Tier 2 subscription (which includes video
+updates), costing £3/month. His Tier 1 subscription is immediately ended.
+Since he paid for a full month (April 1-30), but only used half of it, half of a
+month's subscription (£1) is applied to his new subscription. However, since
+that new subscription costs £3/month, the £1 credit balance only pays for ten
+days. So Samwise's credit pays for his subscription from April 15-25. On April
+26, he is charged £3 for his new subscription, and another £3 on the 26th of
+each month following.</p>
+
+<p class="note">
+ <strong>Note:</strong> The new subscription's billing date depends on when
+ the subscriber's pro-rated credit runs out, so the subscriber cannot upgrade
+ or downgrade to a seasonal subscription, which has fixed and predetermined
+ beginning and end dates.
+</p>
+
+<p>When a user upgrades or downgrades a subscription, your app calls
+<a href="{@docRoot}google/play/billing/billing_reference.html#upgrade-getBuyIntentToReplaceSkus">
+<code>getBuyIntentToReplaceSkus()</code></a>.
+This method is passed the new SKU the user wants to buy, and all
+the old SKUs that are superseded by it. The remaining portions of the old SKUs
+are used to pay for the new subscription, and billing begins when this credit
+is used up.</p>
+
<h3 id="deferred-billing">Deferred Billing</h3>
<p>Using the
@@ -316,7 +380,7 @@
<p>When the user cancels a subscription, Google Play does not offer a refund for
the current billing cycle. Instead, it allows the user to have access to the
-cancelled subscription until the end of the current billing cycle, at which time
+canceled subscription until the end of the current billing cycle, at which time
it terminates the subscription. For example, if a user purchases a monthly
subscription and cancels it on the 15th day of the cycle, Google Play will
consider the subscription valid until the end of the 30th day (or other day,
@@ -357,12 +421,12 @@
<p>If you receive requests for refunds, you can use the
<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play
Developer API</a> or the Merchant Center to cancel the subscription, verify that it
-is already cancelled, or refund the user's payment without cancelling it. You
+is already canceled, or refund the user's payment without canceling it. You
can also use the
<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google
Play Developer API</a> to <em>refund and revoke</em> a
user's subscription. If you refund and revoke a subscription, the user's
-subscription is immediately cancelled, and the user's most recent subscription
+subscription is immediately canceled, and the user's most recent subscription
payment is refunded. (If you want to refund more than the most recent payment,
you can process additional refunds through the Merchant Center.)</p>
@@ -423,7 +487,7 @@
<li>Remotely query the validity of a specific subscription at any time</li>
<li>Cancel a subscription</li>
<li>Defer a subscription's next billing date</li>
- <li>Refund a subscription payment without cancelling the subscription</li>
+ <li>Refund a subscription payment without canceling the subscription</li>
<li>Refund and revoke a subscription</li>
</ul>
diff --git a/docs/html/google/play/billing/billing_testing.jd b/docs/html/google/play/billing/billing_testing.jd
index 36456cc..44b3286 100644
--- a/docs/html/google/play/billing/billing_testing.jd
+++ b/docs/html/google/play/billing/billing_testing.jd
@@ -25,8 +25,8 @@
implementation:</p>
<ul>
-<li>Test purchases, which let test account users make real purchase your published in-app items,
-but without any actual charges to the user accounts.</li>
+<li>Test purchases, which let license-test users purchase your published in-app
+ items, but without any actual charges to their accounts.</li>
<li>Static billing responses from Google Play, for testing in early development</p>
</ul>
@@ -43,14 +43,13 @@
<p>When your In-app Billing implementation is ready, you can test purchasing of your in-app SKUs in two ways:</p>
-<ul>
-<li><strong>Test purchases</strong>, which let your selected license test users
-purchase your in-app products before the app is published, but without any
-resulting charges to the user, and </li>
+<ul> <li><strong>Test purchases</strong>, which let your selected license-test
+users purchase your in-app products without any resulting charges to the user.
+Test purchases can be used in alpha/beta releases or in published apps. </li>
<li><strong>Real purchases</strong>, which let regular users make real purchases
of your in-app products with actual charges to the user’s payment instruments.
-In this case, you can use Google Play’s alpha and beta release groups to manage
-the users who can make “live” purchases using your implementation. </li>
+You can use Google Play’s alpha and beta release groups to manage
+the users who can make live purchases using your implementation. </li>
</ul>
<p>The sections below provide more detail about how to use these approaches for
@@ -61,16 +60,21 @@
<p>Test purchases offer a secure, convenient way to enable larger-scale testing
of your In-app Billing implementation during development or in preparation for
launch. They let authorized user accounts make purchases of your in-app products
-through Google Play while the app is still unpublished, without incurring any
-actual charges to the user accounts.</p>
+through Google Play without incurring any actual charges to the user
+accounts.</p>
-<p>Once authorized with testing access, those users can side-load your app and
-test the full merchandising, purchase, and fulfillment flow for your products.
+<p>Once authorized for testing access, those users can make purchases without
+being charged.
Test purchases are real orders and Google Play processes them in the same way as
other orders. When purchases are complete, Google Play prevents the orders from
going to financial processing, ensuring that there are no actual charges to user
accounts, and automatically canceling the completed orders after 14 days. </p>
+<p class="note">
+ <strong>Note:</strong> Test subscription purchases recur daily, regardless of
+ the product's subscription period.
+</p>
+
<h4 id="setup">Setting up test purchases</h4>
<p>It’s easy to set up test purchases—any user account can be chosen to be
@@ -91,14 +95,13 @@
<p>Once you’ve added the users as license tester accounts and saved the change,
within 15 minutes those users can begin making test purchases of your in-app
-products. You can then distribute your app to your testers and provide a means
-of getting feedback. </p>
+products.</p>
<p class="note"><strong>Note</strong>: To make test purchases, the license test
account must be on the user’s Android device. If the device has more than one
account, the purchase will be made with the account that downloaded the app. If
none of the accounts has downloaded the app, the purchase is made with the first
-account.Users can confirm the account that is making a purchase by expanding the
+account. Users can confirm the account that is making a purchase by expanding the
purchase dialog.</p>
<h4 id="tp-account">Test purchases and developer account</h4>
@@ -114,13 +117,13 @@
with a notice across the center of the purchase dialog, for easy identification.
</p>
-<h4 id="cancelling">Cancelling completed test purchases</h4>
+<h4 id="cancelling">Canceling completed test purchases</h4>
<p>Google Play accumulates completed test purchases for each user but does not
pass them on to financial processing. Over time, it automatically clears out
-the purchases by cancelling them. </p>
+the purchases by canceling them. </p>
<p>In some cases, you might want to manually cancel a test purchase to continue
-testing. For cancelling purchases, you have these options:</p>
+testing. For canceling purchases, you have these options:</p>
<ul>
<li>Wait for the transactions to expire—Google Play clears completed test
@@ -130,13 +133,6 @@
by looking up their order numbers.</li>
</ul>
-<h4 id="requirements">Requirements for using test purchases</h4>
-<p>If you plan to use test purchases, please note the requirements and limitations below: </p>
-<ul>
-<li>Test purchases is only supported for license test accounts when the app is using the In-app Billing v3 API.</li>
-<li>Test purchases are only supported for in-app products, not for in-app subscriptions.</li>
-</ul>
-
<h3 id="transations">Testing with real transactions</h3>
<p>As you prepare to launch an app that uses In-app Billing, you can make use of
Google Play alpha/beta release options to do validation and load testing on your
@@ -276,8 +272,8 @@
href="{@docRoot}google/play/billing/billing_admin.html#billing-testing-setup">Setting up test
accounts</a>.</p>
-<p>Also, a test account can purchase an item in your product list only if the item is published. The
-application does not need to be published, but the item does need to be published.</p>
+<p>A test account can purchase an item in your product list only if the
+item is published.</p>
<p>To test your In-app Billing implementation with actual purchases, follow these steps:</p>
diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd
index bdbf5c7..47620c8 100644
--- a/docs/html/google/play/billing/index.jd
+++ b/docs/html/google/play/billing/index.jd
@@ -14,6 +14,16 @@
<div class="sidebox">
<h2><strong>New in In-App Billing</strong></h2>
<ul>
+ <li><strong>Subscription Upgrade/Downgrade</strong>—A user can
+ subscribe to a higher or lower tier of subscription while their current
+ subscription is active. The old subscription is canceled, and the unused
+ portion is applied on a pro-rated basis to the new subscription.</li>
+ <li><strong>Manual Subscription Renewal</strong>—A user can purchase
+ a subscription at the current rate while their existing subscription is
+ still active. The existing subscription is extended by the appropriate
+ period.</li>
+ <li><strong>IAB Sandbox</strong>—The In-app Billing Sandbox now supports
+ testing subscription purchases.</li>
<li><strong>IAB v2 shutdown</strong>—In-app Billing v2 API is deprecated and will be shut down in January 2015. If your app is still using In-app Billing v2, please migrate to the v3 API as soon as possible.</li>
<li><strong>Seasonal subscriptions</strong>—You can now set up a
recurring <a href="billing_subscriptions.html#user-billing">seasonal
@@ -35,7 +45,6 @@
subscription ends
immediately, and his or her most recent subscription payment is
refunded.</li>
- <li><strong>In-app Billing Version 3</strong>—The <a href="{@docRoot}google/play/billing/api.html">latest version</a> of In-app Billing features a synchronous API that is easier to implement and lets you manage in-app products and subscriptions more effectively.</li>
</ul>
</div>
</div>
diff --git a/docs/html/google/play/billing/versions.jd b/docs/html/google/play/billing/versions.jd
index dbe3ea3..aa35501 100644
--- a/docs/html/google/play/billing/versions.jd
+++ b/docs/html/google/play/billing/versions.jd
@@ -11,10 +11,30 @@
<p>At run time, your app can query the Google Play Store app to determine what version of the API it supports and what features are available. </p>
<ul>
-<li>If you are using in-app billing version 3, the version information is not directly returned the Google Play. Instead, you can check if Google Play supports the version of the In-app Billing API that you are using by sending a {@code isBillingSupported} request.</li>
+
+<li>If you are using in-app billing version 3 or later, the version information
+is not directly returned by Google Play. Instead, you can check if Google Play
+supports the version of the In-app Billing API that you are using by sending an
+{@code isBillingSupported} request.</li>
+
<li>If the In-app Billing API version that you are using is earlier than version 3, the version information is returned in the <code>API_VERSION</code> key of the Bundle object passed in the {@code sendBillingRequest} method. For more information, see <a href="{@docRoot}google/play/billing/v2/billing_reference.html#billing-interface-v2">In-app Billing Service Interface</a>.</li>
</ul>
+<h3 id="version_5">In-app Billing version 5</h3>
+<p><em>February 2015</em></p>
+<ul>
+<li>A user can manually extend an existing subscription. The subscription
+is extended by the appropriate amount of time.</li>
+<li>A user can upgrade or downgrade a subscription while it is active. The
+old subscription is canceled, and the unused portion is applied on a pro-rata
+basis to the new subscription.</li>
+</ul>
+
+<h3 id="version_4">In-app Billing version 4</h3>
+
+<p>Version 4 of the In-app Billing API did not introduce any public
+functionality.</p>
+
<h3 id="version_3">In-app Billing version 3</h3>
<p><em>February 2013</em></p>
<ul>
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 9caf938..127134f 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -56,6 +56,25 @@
"distribute/googleplay/developer-console.html"
]
},
+ "launch/static/ja": {
+ "title": "",
+ "resources": [
+ "https://www.youtube.com/watch?v=xelYnWcYkuE",
+ "https://www.youtube.com/playlist?list=PLCOC_kP3nqGIHEgwm9mybvA04Vn4Cg9nn",
+ "http://googledevjp.blogspot.jp/2014/12/android-wear.html",
+ "http://googledevjp.blogspot.jp/2014/12/android-studio-10.html",
+ "http://googledevjp.blogspot.jp/2014/12/google-play-65.html",
+ "intl/ja/distribute/googleplay/developer-console.html#alpha-beta",
+ "intl/ja/distribute/googleplay/guide.html",
+ "intl/ja/distribute/essentials/quality/core.html",
+ "http://support.google.com/googleplay/android-developer/answer/4430948?hl=ja",
+ "intl/ja/support.html",
+ "intl/ja/distribute/essentials/quality/wear.html",
+ "intl/ja/training/tv/start/index.html",
+ "http://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html",
+ "intl/ja/distribute/monetize/ads.html"
+ ]
+ },
"distribute/gp/gplanding": {
"resources": [
"distribute/googleplay/about.html",
@@ -1203,4 +1222,4 @@
"samples/BasicManagedProfile/index.html"
]
}
-}
\ No newline at end of file
+}
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index e2a0539..288b614 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -1988,5 +1988,161 @@
"keywords": ["analytics"],
"type": "Guide",
"titleFriendly": ""
+ },
+ {
+ "lang": "ja",
+ "title": "Gaming Everywhere",
+ "titleFriendly": "",
+ "summary": "東京ゲームショウ 2014 の基調講演より。",
+ "url": "https://www.youtube.com/watch?v=xelYnWcYkuE",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "http://img.youtube.com/vi/xelYnWcYkuE/hqdefault.jpg",
+ "type": "youtube"
+ },
+ {
+ "lang": "ja",
+ "title": "Playtime Tokyo",
+ "titleFriendly": "",
+ "summary": "アプリビジネスのノウハウを各担当者が講演しました。",
+ "url": "https://www.youtube.com/playlist?list=PLCOC_kP3nqGIHEgwm9mybvA04Vn4Cg9nn",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "http://img.youtube.com/vi/lJdjY3z6-LY/hqdefault.jpg",
+ "type": "youtube"
+ },
+ {
+ "lang": "ja",
+ "title": "Android Wear 関連の動画に日本語字幕が付きました",
+ "titleFriendly": "",
+ "summary": "",
+ "url": "http://googledevjp.blogspot.jp/2014/12/android-wear.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "http://i1.ytimg.com/vi/4JcDYkgqksY/maxresdefault.jpg",
+ "type": "blog"
+ },
+ {
+ "lang": "ja",
+ "title": "Android Studio 1.0 をリリースしました",
+ "titleFriendly": "",
+ "summary": "",
+ "url": "http://googledevjp.blogspot.jp/2014/12/android-studio-10.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "http://3.bp.blogspot.com/-1hV3sD1At74/VIaQSWBasUI/AAAAAAAABAU/9vYLJMsmMuQ/s1600/studio-logo.png",
+ "type": "blog"
+ },
+ {
+ "lang": "ja",
+ "title": "Google Play 開発者サービス 6.5 のご紹介",
+ "titleFriendly": "",
+ "summary": "",
+ "url": "http://googledevjp.blogspot.jp/2014/12/google-play-65.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "http://1.bp.blogspot.com/-4BNREC0Jojo/VGo7ahW35wI/AAAAAAAABAc/9thZl94F6fY/s1600/GMS%2B-%2BRelease%2BBlog%2BNacho%2B-%2BMap%2BToolbar.png",
+ "type": "blog"
+ },
+ {
+ "lang": "ja",
+ "title": "Alpha and Beta Testing",
+ "titleFriendly": "",
+ "summary": "アプリのローンチにまつわるリスクを最小限にするために必須のツールです。[英語コンテンツ]",
+ "url": "intl/ja/distribute/googleplay/developer-console.html#alpha-beta",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "images/gp-dc-ab.png",
+ "type": "distribute"
+ },
+ {
+ "lang": "ja",
+ "title": "Finding Success on Google Play",
+ "titleFriendly": "",
+ "summary": "Google Play での成功の秘訣がこの一冊に。[英語コンテンツ]",
+ "url": "intl/ja/distribute/googleplay/guide.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "distribute/images/play_dev_guide_b.jpg",
+ "type": "distribute"
+ },
+ {
+ "lang": "ja",
+ "title": "Core App Quality",
+ "titleFriendly": "",
+ "summary": "",
+ "url": "intl/ja/distribute/essentials/quality/core.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "images/gp-core-quality.png",
+ "type": "distribute"
+ },
+ {
+ "lang": "ja",
+ "title": "Google Play アプリ ポリシー センター",
+ "titleFriendly": "",
+ "summary": "",
+ "url": "http://support.google.com/googleplay/android-developer/answer/4430948?hl=ja",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "https://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389356_en_v0",
+ "type": "distribute"
+ },
+ {
+ "lang": "ja",
+ "title": "Developer Support",
+ "titleFriendly": "",
+ "summary": "",
+ "url": "intl/ja/support.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "",
+ "type": "distribute"
+ },
+ {
+ "lang": "ja",
+ "title": "Wear App Quality",
+ "titleFriendly": "",
+ "summary": "いよいよウェアラブルの時代が到来。[英語コンテンツ]",
+ "url": "intl/ja/distribute/essentials/quality/wear.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "distribute/images/gp-wear-quality.png",
+ "type": "distribute"
+ },
+ {
+ "lang": "ja",
+ "title": "Google Cloud Platform が支える、新感覚リアルタイム RPG ユニゾンリーグ - 株式会社エイチームの GCP 導入事例",
+ "titleFriendly": "",
+ "summary": "スケーラブルなバックエンドを実現する Google Cloud Platform の最新導入事例。",
+ "url": "http://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "http://3.bp.blogspot.com/-xp7KoPkbne4/VI_PfoFil3I/AAAAAAAAA3U/-k1UZ0zjCBc/s1600/unison-league.jpeg",
+ "type": "distribute"
+ },
+ {
+ "lang": "ja",
+ "title": "Monetize with Ads",
+ "titleFriendly": "",
+ "summary": "アプリ内広告成功のコツがここに。[英語コンテンツ]",
+ "url": "intl/ja/distribute/monetize/ads.html",
+ "group": "",
+ "keywords": [],
+ "tags": [],
+ "image": "distribute/images/advertising.jpg",
+ "type": "distribute"
}
]);
\ No newline at end of file
diff --git a/docs/html/tools/revisions/gradle-plugin.jd b/docs/html/tools/revisions/gradle-plugin.jd
index ebca5c7..e083792 100644
--- a/docs/html/tools/revisions/gradle-plugin.jd
+++ b/docs/html/tools/revisions/gradle-plugin.jd
@@ -36,10 +36,79 @@
<p>For a summary of known issues in Android Plugin for Gradle, see <a
href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
-
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>Android Plugin for Gradle, Revision 1.1.2</a> <em>(February 2015)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+ <dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Gradle 2.2.1 or higher.</li>
+ <li>Build Tools 21.1.1 or higher.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Normalized path when creating a mockable JAR for unit testing. </li>
+ <li>Fixed the <code>archivesBaseName</code> setting in the <code>build.gradle</code> file. </li>
+ <li>Fixed the unresolved placeholder failure in manifest merger when building a library
+ test application.</li>
+ </ul>
+ </dd>
+ </div>
+</div>
+
+
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
+ alt=""/>Android Plugin for Gradle, Revision 1.1.1</a> <em>(February 2015)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+ <dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Gradle 2.2.1 or higher.</li>
+ <li>Build Tools 21.1.1 or higher.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Modified build variants so only variants that package a
+ <a href="{@docRoot}training/wearables/apps/index.html">Wear</a> app trigger Wear-specific
+ build tasks. </li>
+ <li>Changed dependency related issues to fail at build time rather than at debug time.
+ This behavior allows you to run diagnostic diagnostic tasks (such as 'dependencies') to help
+ resolve the conflict. </li>
+ <li>Fixed the <code>android.getBootClasspath()</code> method to return a value. </li>
+ </ul>
+ </dd>
+ </div>
+</div>
+
+
+
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>Android Plugin for Gradle, Revision 1.1.0</a> <em>(February 2015)</em>
</p>
@@ -185,11 +254,11 @@
<p>The Android Plugin for Gradle version is specified in the
<strong>File > Project Structure</strong> menu or the project-level
<code>build.gradle</code> file. The plugin version applies to all modules built in that
-Android Studio project. This example updates the Android Plugin for Gradle to version 1.1:
+Android Studio project. This example updates the Android Plugin for Gradle to version 1.1.0:
<pre>
...
dependencies {
- classpath 'com.android.tools.build:gradle:1.1'
+ classpath 'com.android.tools.build:gradle:1.1.0'
}
...
</pre>
@@ -197,8 +266,7 @@
<p class="caution"><strong>Caution:</strong> You should not use dynamic dependencies (+) in
version numbers. Using this feature can cause unexpected version updates and difficulty
-resolving version differences.
-</p>
+resolving version differences. </p>
<p>If you're building with Gradle but using not Android Studio, the build process downloads the
latest Android Plugin for Gradle plugin when it runs. </p>
diff --git a/docs/html/tools/revisions/studio.jd b/docs/html/tools/revisions/studio.jd
index af25d9c..3982f2e 100644
--- a/docs/html/tools/revisions/studio.jd
+++ b/docs/html/tools/revisions/studio.jd
@@ -43,7 +43,7 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
- alt=""/>Android Studio v1.1</a> <em>(February 2015)</em>
+ alt=""/>Android Studio v1.1.0</a> <em>(February 2015)</em>
</p>
<div class="toggle-content-toggleme">
diff --git a/docs/html/training/wearables/apps/creating.jd b/docs/html/training/wearables/apps/creating.jd
index c12ffa7..487615b 100644
--- a/docs/html/training/wearables/apps/creating.jd
+++ b/docs/html/training/wearables/apps/creating.jd
@@ -106,6 +106,15 @@
<li>Follow the app's instructions to pair your handheld with your wearable.
This allows you to test out synced handheld notifications, if you're building them.</li>
<li>Leave the Android Wear app open on your phone.</li>
+ <li>Enable adb debugging on the Android Wear device.</li>
+ <ol>
+ <li>Go to <strong>Settings > About</strong>.</li>
+ <li>Tap <strong>Build number</strong> seven times.</li>
+ <li>Swipe right to return to the Settings menu.</li>
+ <li>Go to <strong>Developer options</strong> at the bottom of the screen.
+ </li>
+ <li>Tap <strong>ADB Debugging</strong> to enable adb.</li>
+ </ol>
<li>Connect the wearable to your machine through USB, so you can install apps directly to it
as you develop. A message appears on both the wearable and the Android Wear app prompting you to allow debugging.</li>
<p class="note"><strong>Note:</strong> If you can not connect your wearable to your machine via USB,
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index 4af5946..2c603e2 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -594,7 +594,7 @@
mTransitions.append(keyToFrom, pos | REVERSED_BIT | reversibleBit);
}
- return addChild(anim);
+ return pos;
}
int addStateSet(@NonNull int[] stateSet, @NonNull Drawable drawable, int id) {
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 98767a7..247f94a 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -39,7 +39,6 @@
import android.os.Trace;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.util.IntProperty;
import android.util.StateSet;
import android.util.TypedValue;
import android.util.Xml;
@@ -1372,20 +1371,5 @@
default: return defaultMode;
}
}
-
- /** @hide */
- public static final IntProperty<Drawable> ALPHA = new IntProperty<Drawable>("alpha") {
- @Override
- public void setValue(Drawable object, int value) {
- object.mutate();
- object.setAlpha(value);
- object.invalidateSelf();
- }
-
- @Override
- public Integer get(Drawable object) {
- return object.getAlpha();
- }
- };
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index c4794d9..434134a 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -685,7 +685,7 @@
DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
Resources res) {
mOwner = owner;
- mRes = res;
+ mRes = res != null ? res : orig != null ? orig.mRes : null;
if (orig != null) {
mChangingConfigurations = orig.mChangingConfigurations;
diff --git a/packages/Keyguard/AndroidManifest.xml b/packages/Keyguard/AndroidManifest.xml
index 352317d..e19246c 100644
--- a/packages/Keyguard/AndroidManifest.xml
+++ b/packages/Keyguard/AndroidManifest.xml
@@ -40,6 +40,7 @@
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
<uses-permission android:name="android.permission.TRUST_LISTENER" />
+ <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<application android:label="@string/app_name"
android:process="com.android.systemui"
diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
index c023dc6..ca947af 100644
--- a/packages/Keyguard/src/com/android/keyguard/CarrierText.java
+++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
@@ -20,6 +20,8 @@
import java.util.Locale;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.net.ConnectivityManager;
import android.telephony.SubscriptionInfo;
@@ -33,6 +35,7 @@
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.widget.LockPatternUtils;
public class CarrierText extends TextView {
@@ -122,10 +125,27 @@
subs.get(0).getCarrierName());
} else {
// We don't have a SubscriptionInfo to get the emergency calls only from.
- // Lets just make it ourselves.
+ // Grab it from the old sticky broadcast if possible instead. We can use it
+ // here because no subscriptions are active, so we don't have
+ // to worry about MSIM clashing.
+ CharSequence text =
+ getContext().getText(com.android.internal.R.string.emergency_calls_only);
+ Intent i = getContext().registerReceiver(null,
+ new IntentFilter(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION));
+ if (i != null) {
+ String spn = "";
+ String plmn = "";
+ if (i.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
+ spn = i.getStringExtra(TelephonyIntents.EXTRA_SPN);
+ }
+ if (i.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
+ plmn = i.getStringExtra(TelephonyIntents.EXTRA_PLMN);
+ }
+ if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
+ text = concatenate(plmn, spn);
+ }
displayText = makeCarrierStringOnEmergencyCapable(
- getContext().getText(R.string.keyguard_missing_sim_message_short),
- getContext().getText(com.android.internal.R.string.emergency_calls_only));
+ getContext().getText(R.string.keyguard_missing_sim_message_short), text);
}
}
setText(displayText);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 035bb0e..e8260bb 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -103,6 +103,7 @@
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
<uses-permission android:name="android.permission.TRUST_LISTENER" />
+ <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<!-- Recents -->
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4c0cea8..d4aeab6 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -42,7 +42,8 @@
<color name="qs_tile_divider">#29ffffff</color><!-- 16% white -->
<color name="qs_tile_text">#B3FFFFFF</color><!-- 70% white -->
<color name="qs_subhead">#99FFFFFF</color><!-- 60% white -->
- <color name="qs_detail_empty">#24B0BEC5</color><!-- 14% blue grey 200-->
+ <color name="qs_detail_empty">#24B0BEC5</color><!-- 14% blue grey 200 -->
+ <color name="qs_detail_button">#FFB0BEC5</color><!-- 100% blue grey 200 -->
<color name="qs_detail_transition">#66FFFFFF</color>
<color name="qs_detail_progress_track">#99009688</color><!-- 60% deep teal 500 -->
<color name="data_usage_secondary">#99FFFFFF</color><!-- 60% white -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index bf19b8d..94f77c6 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -145,6 +145,7 @@
<style name="TextAppearance.QS.DetailButton">
<item name="android:textSize">@dimen/qs_detail_button_text_size</item>
+ <item name="android:textColor">@color/qs_detail_button</item>
<item name="android:textAllCaps">true</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:gravity">center</item>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
index 69a4932..602989a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
@@ -177,6 +177,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
mContext.registerReceiver(mBroadcastReceiver, filter);
@@ -196,13 +197,14 @@
+ " extras=" + bundleToString(intent.getExtras()));
if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
mHandler.sendEmptyMessage(MSG_START_SERVICE);
- } else if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) {
- PackageManager pm = mContext.getPackageManager();
- boolean serviceEnabled =
- pm.getApplicationEnabledSetting(mServiceName.getPackageName())
- != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ } else if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
+ || Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+ final PackageManager pm = mContext.getPackageManager();
+ final boolean serviceEnabled = isPackageAvailable()
+ && pm.getApplicationEnabledSetting(mServiceName.getPackageName())
+ != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
&& pm.getComponentEnabledSetting(mServiceName)
- != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+ != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
if (mBound && !serviceEnabled) {
stopService();
scheduleCheckBound();
@@ -289,4 +291,15 @@
Settings.Secure.putStringForUser(mContext.getContentResolver(),
mSettingKey, setting, UserHandle.USER_CURRENT);
}
+
+ public boolean isPackageAvailable() {
+ final ComponentName component = getComponent();
+ if (component == null) return false;
+ try {
+ return mContext.getPackageManager().isPackageAvailable(component.getPackageName());
+ } catch (RuntimeException e) {
+ Log.w(mTag, "Error checking package availability", e);
+ return false;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 97ebbf1..f7f3bd8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -112,12 +112,12 @@
private void setVolumeController(boolean register) {
if (register) {
- if (LOGD) Log.d(TAG, "Registering volume controller");
+ if (LOGD) Log.d(TAG, "Registering default volume controller");
mAudioManager.setVolumeController(mVolumeController);
mMediaSessionManager.setRemoteVolumeController(mRemoteVolumeController);
DndTile.setVisible(mContext, false);
} else {
- if (LOGD) Log.d(TAG, "Unregistering volume controller");
+ if (LOGD) Log.d(TAG, "Unregistering default volume controller");
mAudioManager.setVolumeController(null);
mMediaSessionManager.setRemoteVolumeController(null);
}
@@ -260,11 +260,16 @@
if (LOGD) Log.d(TAG, "onNoService");
setVolumeController(true);
mRestorationNotification.hide();
+ if (!mVolumeControllerService.isPackageAvailable()) {
+ mVolumeControllerService.setComponent(null);
+ }
}
@Override
public long onServiceStartAttempt() {
if (LOGD) Log.d(TAG, "onServiceStartAttempt");
+ // poke the setting to update the uid
+ mVolumeControllerService.setComponent(mVolumeControllerService.getComponent());
setVolumeController(false);
mVolumeController.dismissNow();
mRestorationNotification.show();
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 2941574..c44e39d 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -20,8 +20,11 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.MessageQueue;
import android.os.PowerManager;
import android.os.RemoteException;
import android.provider.Settings;
@@ -34,6 +37,8 @@
import android.service.fingerprint.FingerprintUtils;
import android.service.fingerprint.IFingerprintService;
import android.service.fingerprint.IFingerprintServiceReceiver;
+import static android.Manifest.permission.MANAGE_FINGERPRINT;
+import static android.Manifest.permission.USE_FINGERPRINT;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -68,14 +73,13 @@
}
};
private Context mContext;
+ private int mHalDeviceId;
private static final int STATE_IDLE = 0;
private static final int STATE_LISTENING = 1;
private static final int STATE_ENROLLING = 2;
private static final int STATE_REMOVING = 3;
private static final long MS_PER_SEC = 1000;
- public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
- public static final String ENROLL_FINGERPRINT = "android.permission.ENROLL_FINGERPRINT";
private static final class ClientData {
public IFingerprintServiceReceiver receiver;
@@ -113,17 +117,17 @@
public FingerprintService(Context context) {
super(context);
mContext = context;
- nativeInit(this);
+ nativeInit(Looper.getMainLooper().getQueue(), this);
}
// TODO: Move these into separate process
// JNI methods to communicate from FingerprintManagerService to HAL
- native int nativeEnroll(int timeout);
- native int nativeEnrollCancel();
- native int nativeRemove(int fingerprintId);
- native int nativeOpenHal();
- native int nativeCloseHal();
- native void nativeInit(FingerprintService service);
+ static native int nativeEnroll(int timeout);
+ static native int nativeEnrollCancel();
+ static native int nativeRemove(int fingerprintId);
+ static native int nativeOpenHal();
+ static native int nativeCloseHal();
+ static native void nativeInit(MessageQueue queue, FingerprintService service);
// JNI methods for communicating from HAL to clients
void notify(int msg, int arg1, int arg2) {
@@ -131,11 +135,13 @@
}
void handleNotify(int msg, int arg1, int arg2) {
- Slog.v(TAG, "handleNotify(msg=" + msg + ", arg1=" + arg1 + ", arg2=" + arg2 + ")");
+ Slog.v(TAG, "handleNotify(msg=" + msg + ", arg1=" + arg1 + ", arg2=" + arg2 + ")"
+ + ", " + mClients.size() + " clients");
for (int i = 0; i < mClients.size(); i++) {
+ if (DEBUG) Slog.v(TAG, "Client[" + i + "] binder token: " + mClients.keyAt(i));
ClientData clientData = mClients.valueAt(i);
if (clientData == null || clientData.receiver == null) {
- if (DEBUG) Slog.v(TAG, "clientData at " + i + " is invalid!!");
+ if (DEBUG) Slog.v(TAG, "clientData is invalid!!");
continue;
}
switch (msg) {
@@ -282,26 +288,27 @@
mClients.remove(token);
}
- void checkPermission(String permisison) {
- // TODO
+ void checkPermission(String permission) {
+ getContext().enforceCallingOrSelfPermission(permission, "Must have "
+ + permission + " permission.");
}
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@Override // Binder call
public void enroll(IBinder token, long timeout, int userId) {
- checkPermission(ENROLL_FINGERPRINT);
+ checkPermission(MANAGE_FINGERPRINT);
startEnroll(token, timeout, userId);
}
@Override // Binder call
public void enrollCancel(IBinder token,int userId) {
- checkPermission(ENROLL_FINGERPRINT);
+ checkPermission(MANAGE_FINGERPRINT);
startEnrollCancel(token, userId);
}
@Override // Binder call
public void remove(IBinder token, int fingerprintId, int userId) {
- checkPermission(ENROLL_FINGERPRINT); // TODO: Maybe have another permission
+ checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
startRemove(token, fingerprintId, userId);
}
@@ -317,12 +324,19 @@
checkPermission(USE_FINGERPRINT);
removeListener(token, userId);
}
+
+ @Override // Binder call
+ public boolean isHardwareDetected() {
+ checkPermission(USE_FINGERPRINT);
+ return mHalDeviceId != 0;
+ }
}
@Override
public void onStart() {
publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
- nativeOpenHal();
+ mHalDeviceId = nativeOpenHal();
+ if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index ef95a7b..bfb71c5 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -191,7 +191,7 @@
statsOut.events.clear();
}
- statsOut.endTime = XmlUtils.readLongAttribute(parser, END_TIME_ATTR);
+ statsOut.endTime = statsOut.beginTime + XmlUtils.readLongAttribute(parser, END_TIME_ATTR);
int eventCode;
int outerDepth = parser.getDepth();
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 0aa8862..f869841 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -16,8 +16,6 @@
package com.android.server.usb;
-import android.alsa.AlsaCardsParser;
-import android.alsa.AlsaDevicesParser;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -37,6 +35,8 @@
import android.provider.Settings;
import android.util.Slog;
+import com.android.internal.alsa.AlsaCardsParser;
+import com.android.internal.alsa.AlsaDevicesParser;
import com.android.server.audio.AudioService;
import libcore.io.IoUtils;
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index bcc1ccc4..9739d4e 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -77,6 +77,12 @@
"android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
/**
+ * The {@link android.content.Intent} action used to show the call accessibility settings page.
+ */
+ public static final String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS =
+ "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
+
+ /**
* The {@link android.content.Intent} action used to show the call settings page.
*/
public static final String ACTION_SHOW_CALL_SETTINGS =
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index ca3c636..37ffa06 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -62,7 +62,8 @@
private CharSequence mDisplayName;
/**
- * The string displayed to the user that identifies Subscription Provider Name
+ * String that identifies SPN/PLMN
+ * TODO : Add a new field that identifies only SPN for a sim
*/
private CharSequence mCarrierName;