Merge "Clarify AudioFormat sample rate and encoding documentation" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 774374e..a2dfb85 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30482,6 +30482,7 @@
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
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_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
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";
@@ -36922,8 +36923,7 @@
method public abstract void setStylusButtonPressable(boolean);
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
- method public abstract void setTextPaint(android.text.TextPaint);
- method public abstract void setTextStyle(int, int, int, int);
+ method public abstract void setTextStyle(float, int, int, int);
method public abstract void setVisibility(int);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index d75a9a0..a9c1f2a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -39181,8 +39181,7 @@
method public abstract void setStylusButtonPressable(boolean);
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
- method public abstract void setTextPaint(android.text.TextPaint);
- method public abstract void setTextStyle(int, int, int, int);
+ method public abstract void setTextStyle(float, int, int, int);
method public abstract void setVisibility(int);
}
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
index bb9cb3b..ca47a5e 100644
--- a/core/java/android/app/AssistStructure.java
+++ b/core/java/android/app/AssistStructure.java
@@ -607,35 +607,7 @@
}
@Override
- public void setTextPaint(TextPaint paint) {
- ViewNodeText t = getNodeText();
- t.mTextColor = paint.getColor();
- t.mTextBackgroundColor = paint.bgColor;
- t.mTextSize = paint.getTextSize();
- t.mTextStyle = 0;
- Typeface tf = paint.getTypeface();
- if (tf != null) {
- if (tf.isBold()) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
- }
- if (tf.isItalic()) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_ITALIC;
- }
- }
- int pflags = paint.getFlags();
- if ((pflags& Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
- }
- if ((pflags& Paint.UNDERLINE_TEXT_FLAG) != 0) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_UNDERLINE;
- }
- if ((pflags& Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
- t.mTextStyle |= ViewNode.TEXT_STYLE_STRIKE_THRU;
- }
- }
-
- @Override
- public void setTextStyle(int size, int fgColor, int bgColor, int style) {
+ public void setTextStyle(float size, int fgColor, int bgColor, int style) {
ViewNodeText t = getNodeText();
t.mTextColor = fgColor;
t.mTextBackgroundColor = bgColor;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 50eed3e..dfd523a 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -685,6 +685,8 @@
final String bootimage = SystemProperties.get("ro.bootimage.build.fingerprint");
final String requiredBootloader = SystemProperties.get("ro.build.expect.bootloader");
final String currentBootloader = SystemProperties.get("ro.bootloader");
+ final String requiredRecovery = SystemProperties.get("ro.expect.recovery_id");
+ final String currentRecovery = SystemProperties.get("ro.recovery_id");
final String requiredRadio = SystemProperties.get("ro.build.expect.baseband");
final String currentRadio = SystemProperties.get("gsm.version.baseband");
@@ -701,7 +703,6 @@
}
}
- /* TODO: Figure out issue with checks failing
if (!TextUtils.isEmpty(bootimage)) {
if (!Objects.equals(system, bootimage)) {
Slog.e(TAG, "Mismatched fingerprints; system reported " + system
@@ -718,6 +719,15 @@
}
}
+ if (!TextUtils.isEmpty(requiredRecovery)) {
+ if (!Objects.equals(currentRecovery, requiredRecovery)) {
+ Slog.e(TAG, "Mismatched recovery version: build requires " + requiredRecovery
+ + " but runtime reports " + currentRecovery);
+ return false;
+ }
+ }
+
+ /* TODO: uncomment when new bootloader lands b/20860620
if (!TextUtils.isEmpty(requiredRadio)) {
if (!Objects.equals(currentRadio, requiredRadio)) {
Slog.e(TAG, "Mismatched radio version: build requires " + requiredRadio
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 1da46d0..db19f7a 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -410,10 +410,10 @@
rt.allowMessagesFrom = DEFAULT_SOURCE;
}
} else if (MANUAL_TAG.equals(tag)) {
- rt.manualRule = readRuleXml(parser, false /*conditionRequired*/);
+ rt.manualRule = readRuleXml(parser);
} else if (AUTOMATIC_TAG.equals(tag)) {
final String id = parser.getAttributeValue(null, RULE_ATT_ID);
- final ZenRule automaticRule = readRuleXml(parser, true /*conditionRequired*/);
+ final ZenRule automaticRule = readRuleXml(parser);
if (id != null && automaticRule != null) {
rt.automaticRules.put(id, automaticRule);
}
@@ -455,7 +455,7 @@
out.endTag(null, ZEN_TAG);
}
- public static ZenRule readRuleXml(XmlPullParser parser, boolean conditionRequired) {
+ public static ZenRule readRuleXml(XmlPullParser parser) {
final ZenRule rt = new ZenRule();
rt.enabled = safeBoolean(parser, RULE_ATT_ENABLED, true);
rt.snoozing = safeBoolean(parser, RULE_ATT_SNOOZING, false);
@@ -801,7 +801,7 @@
.authority(SYSTEM_AUTHORITY)
.appendPath(EVENT_PATH)
.appendQueryParameter("userId", Long.toString(event.userId))
- .appendQueryParameter("calendar", Long.toString(event.calendar))
+ .appendQueryParameter("calendar", event.calendar != null ? event.calendar : "")
.appendQueryParameter("reply", Integer.toString(event.reply))
.build();
}
@@ -819,21 +819,21 @@
if (!isEvent) return null;
final EventInfo rt = new EventInfo();
rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL);
- rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"),
- EventInfo.ANY_CALENDAR);
+ rt.calendar = conditionId.getQueryParameter("calendar");
+ if (TextUtils.isEmpty(rt.calendar) || tryParseLong(rt.calendar, -1L) != -1L) {
+ rt.calendar = null;
+ }
rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0);
return rt;
}
public static class EventInfo {
- public static final long ANY_CALENDAR = 0;
-
public static final int REPLY_ANY_EXCEPT_NO = 0;
public static final int REPLY_YES_OR_MAYBE = 1;
public static final int REPLY_YES = 2;
public int userId = UserHandle.USER_NULL; // USER_NULL = unspecified - use current user
- public long calendar = ANY_CALENDAR; // CalendarContract.Calendars._ID, or ANY_CALENDAR
+ public String calendar; // CalendarContract.Calendars.OWNER_ACCOUNT, or null for any
public int reply;
@Override
@@ -846,7 +846,7 @@
if (!(o instanceof EventInfo)) return false;
final EventInfo other = (EventInfo) o;
return userId == other.userId
- && calendar == other.calendar
+ && Objects.equals(calendar, other.calendar)
&& reply == other.reply;
}
@@ -860,7 +860,6 @@
public static int resolveUserId(int userId) {
return userId == UserHandle.USER_NULL ? ActivityManager.getCurrentUser() : userId;
-
}
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index f176240..f7027f9 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1121,6 +1121,7 @@
* closest to the specified horizontal position.
*/
public int getOffsetForHorizontal(int line, float horiz) {
+ // TODO: use Paint.getOffsetForAdvance to avoid binary search
int max = getLineEnd(line) - 1;
int min = getLineStart(line);
Directions dirs = getLineDirections(line);
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 479242c..605b91d 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -739,16 +739,14 @@
float ret = 0;
- int contextLen = contextEnd - contextStart;
if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) {
if (mCharsValid) {
- ret = wp.getTextRunAdvances(mChars, start, runLen,
- contextStart, contextLen, runIsRtl, null, 0);
+ ret = wp.getRunAdvance(mChars, start, contextEnd, contextStart, contextEnd,
+ runIsRtl, end);
} else {
int delta = mStart;
- ret = wp.getTextRunAdvances(mText, delta + start,
- delta + end, delta + contextStart, delta + contextEnd,
- runIsRtl, null, 0);
+ ret = wp.getRunAdvance(mText, delta + start, delta + contextEnd,
+ delta + contextStart, delta + contextEnd, runIsRtl, delta + end);
}
}
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 5c8b023..886547a 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -145,13 +145,6 @@
public abstract void setText(CharSequence text, int selectionStart, int selectionEnd);
/**
- * Set default global style of the text previously set with
- * {@link #setText}, derived from the given TextPaint object. Size, foreground color,
- * background color, and style information will be extracted from the paint.
- */
- public abstract void setTextPaint(TextPaint paint);
-
- /**
* Explicitly set default global style information for text that was previously set with
* {@link #setText}.
*
@@ -160,7 +153,7 @@
* @param bgColor The background color, packed as 0xAARRGGBB.
* @param style Style flags, as defined by {@link android.app.AssistStructure.ViewNode}.
*/
- public abstract void setTextStyle(int size, int fgColor, int bgColor, int style);
+ public abstract void setTextStyle(float size, int fgColor, int bgColor, int style);
/**
* Set optional hint text associated with this view; this is for example the text that is
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f61e372..3f7bad6 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1306,16 +1306,12 @@
if (DEBUG) Log.v(TAG, "focusOut: " + view
+ " mServedView=" + mServedView
+ " winFocus=" + view.hasWindowFocus());
- if (mServedView != view) {
- // The following code would auto-hide the IME if we end up
- // with no more views with focus. This can happen, however,
- // whenever we go into touch mode, so it ends up hiding
- // at times when we don't really want it to. For now it
- // seems better to just turn it all off.
- if (false && view.hasWindowFocus()) {
- mNextServedView = null;
- scheduleCheckFocusLocked(view);
- }
+ // CAVEAT: We have ignored focusOut event in Android L MR-1 and prior. Need special
+ // care when changing the logic here because there are so many cases to be taken into
+ // consideration, e.g., WindowManager.LayoutParams.SOFT_INPUT_* flags.
+ if (mServedView == view && view.hasWindowFocus()) {
+ mNextServedView = null;
+ scheduleCheckFocusLocked(view);
}
}
}
diff --git a/core/java/android/webkit/ViewAssistStructure.java b/core/java/android/webkit/ViewAssistStructure.java
index bbaceee..afa5ab8 100644
--- a/core/java/android/webkit/ViewAssistStructure.java
+++ b/core/java/android/webkit/ViewAssistStructure.java
@@ -132,12 +132,7 @@
}
@Override
- public void setTextPaint(TextPaint paint) {
- mV.setTextPaint(paint);
- }
-
- @Override
- public void setTextStyle(int size, int fgColor, int bgColor, int style) {
+ public void setTextStyle(float size, int fgColor, int bgColor, int style) {
mV.setTextStyle(size, fgColor, bgColor, style);
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index f42959f..49226cd0 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -1374,7 +1374,9 @@
newText.append(oldText).append(' ').append(switchText);
structure.setText(newText);
}
- structure.setTextPaint(mTextPaint);
+ // The style of the label text is provided via the base TextView class. This is more
+ // relevant than the style of the (optional) on/off text on the switch button itself,
+ // so ignore the size/color/style stored this.mTextPaint.
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9de7778..15d796c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -25,6 +25,7 @@
import android.annotation.StyleRes;
import android.annotation.XmlRes;
import android.app.Activity;
+import android.app.AssistStructure;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -8785,7 +8786,33 @@
final boolean isPassword = hasPasswordTransformationMethod();
if (!isPassword) {
structure.setText(getText(), getSelectionStart(), getSelectionEnd());
- structure.setTextPaint(mTextPaint);
+
+ // Extract style information that applies to the TextView as a whole.
+ int style = 0;
+ int typefaceStyle = getTypefaceStyle();
+ if ((typefaceStyle & Typeface.BOLD) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
+ }
+ if ((typefaceStyle & Typeface.ITALIC) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_ITALIC;
+ }
+
+ // Global styles can also be set via TextView.setPaintFlags().
+ int paintFlags = mTextPaint.getFlags();
+ if ((paintFlags & Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
+ }
+ if ((paintFlags & Paint.UNDERLINE_TEXT_FLAG) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_UNDERLINE;
+ }
+ if ((paintFlags & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
+ style |= AssistStructure.ViewNode.TEXT_STYLE_STRIKE_THRU;
+ }
+
+ // TextView does not have its own text background color. A background is either part
+ // of the View (and can be any drawable) or a BackgroundColorSpan inside the text.
+ structure.setTextStyle(getTextSize(), getCurrentTextColor(),
+ AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
}
structure.setHint(getHint());
}
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index f01e3f8..9f3668d 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -141,6 +141,7 @@
<item name="expandableListPreferredItemIndicatorRight">0dip</item>
<item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
<item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+
<item name="findOnPageNextDrawable">@drawable/ic_find_next_material</item>
<item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_material</item>
@@ -160,8 +161,6 @@
<item name="windowTitleStyle">@style/WindowTitle.Material</item>
<item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
<item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
- <item name="windowContentTransitions">false</item>
- <item name="windowActivityTransitions">true</item>
<item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
<item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
<item name="windowActionBar">true</item>
@@ -173,6 +172,8 @@
<item name="windowEnterTransition">@transition/fade</item>
<item name="windowSharedElementEnterTransition">@transition/move</item>
<item name="windowSharedElementExitTransition">@transition/move</item>
+ <item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">true</item>
<!-- Dialog attributes -->
<item name="dialogTheme">@style/ThemeOverlay.Material.Dialog</item>
@@ -305,6 +306,9 @@
<item name="detailsElementBackground">?attr/colorBackground</item>
<item name="fingerprintDrawable">@drawable/ic_fingerprint_dark</item>
+ <!-- PreferenceFrameLayout attributes -->
+ <item name="preferenceFrameLayoutStyle">@style/Widget.Material.PreferenceFrameLayout</item>
+
<!-- Search widget styles -->
<item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
@@ -351,9 +355,6 @@
<item name="searchViewStyle">@style/Widget.Material.SearchView</item>
<item name="searchDialogTheme">@style/Theme.Material.SearchBar</item>
- <!-- PreferenceFrameLayout attributes -->
- <item name="preferenceFrameLayoutStyle">@style/Widget.Material.PreferenceFrameLayout</item>
-
<!-- NumberPicker style-->
<item name="numberPickerStyle">@style/Widget.Material.NumberPicker</item>
@@ -453,8 +454,8 @@
<item name="buttonStyleSmall">@style/Widget.Material.Light.Button.Small</item>
<item name="buttonStyleInset">@style/Widget.Material.Light.Button.Inset</item>
-
<item name="buttonStyleToggle">@style/Widget.Material.Light.Button.Toggle</item>
+
<item name="switchStyle">@style/Widget.Material.Light.CompoundButton.Switch</item>
<item name="mediaRouteButtonStyle">@style/Widget.Material.Light.MediaRouteButton</item>
@@ -487,6 +488,8 @@
<item name="listChoiceBackgroundIndicator">@drawable/list_choice_background_material</item>
<item name="activatedBackgroundIndicator">@drawable/activated_background_material</item>
+ <item name="listDividerAlertDialog">@null</item>
+
<item name="expandableListPreferredItemPaddingLeft">40dip</item>
<item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
@@ -495,7 +498,6 @@
<item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
<item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
- <item name="listDividerAlertDialog">@null</item>
<item name="findOnPageNextDrawable">@drawable/ic_find_next_material</item>
<item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_material</item>
@@ -632,6 +634,7 @@
<item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Material.QuickContactBadgeSmall.WindowLarge</item>
<item name="listPopupWindowStyle">@style/Widget.Material.Light.ListPopupWindow</item>
<item name="popupMenuStyle">@style/Widget.Material.Light.PopupMenu</item>
+ <item name="popupTheme">@null</item>
<item name="stackViewStyle">@style/Widget.Material.Light.StackView</item>
<item name="activityChooserViewStyle">@style/Widget.Material.Light.ActivityChooserView</item>
<item name="fragmentBreadCrumbsStyle">@style/Widget.Material.FragmentBreadCrumbs</item>
@@ -681,7 +684,10 @@
<item name="actionBarStyle">@style/Widget.Material.Light.ActionBar.Solid</item>
<item name="actionBarSize">@dimen/action_bar_default_height_material</item>
<item name="actionModePopupWindowStyle">@style/Widget.Material.Light.PopupWindow.ActionMode</item>
+ <item name="actionMenuTextAppearance">@style/TextAppearance.Material.Widget.ActionBar.Menu</item>
+ <item name="actionMenuTextColor">?attr/textColorPrimary</item>
<item name="actionBarWidgetTheme">@null</item>
+ <item name="actionBarPopupTheme">?attr/popupTheme</item>
<item name="actionBarTheme">@style/ThemeOverlay.Material.ActionBar</item>
<item name="actionBarItemBackground">@drawable/action_bar_item_background_material</item>
@@ -723,6 +729,7 @@
<!-- DatePicker dialog theme -->
<item name="datePickerDialogTheme">?attr/dialogTheme</item>
+ <!-- TODO: This belongs in a FastScroll style -->
<item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_material</item>
<item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_material</item>
<item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_material</item>
@@ -733,6 +740,7 @@
<item name="colorPrimaryDark">@color/primary_dark_material_light</item>
<item name="colorPrimary">@color/primary_material_light</item>
<item name="colorAccent">@color/accent_material_light</item>
+ <item name="colorEdgeEffect">?attr/colorPrimary</item>
<item name="colorControlNormal">?attr/textColorSecondary</item>
<item name="colorControlActivated">?attr/colorAccent</item>
diff --git a/docs/html-ndk/ndk/guides/application_mk.jd b/docs/html-ndk/ndk/guides/application_mk.jd
index fab611b..1294687 100644
--- a/docs/html-ndk/ndk/guides/application_mk.jd
+++ b/docs/html-ndk/ndk/guides/application_mk.jd
@@ -12,7 +12,7 @@
</div>
</div>
-<p>This document explains the syntax of the {@code Application.mk} build file, which describes the
+<p>This document explains the {@code Application.mk} build file, which describes the
native <em>modules</em> that your app requires. A module can be a static library, a shared library,
or an executable.</p>
diff --git a/docs/html-ndk/ndk/guides/concepts.jd b/docs/html-ndk/ndk/guides/concepts.jd
index c2eccd4..0601f21 100644
--- a/docs/html-ndk/ndk/guides/concepts.jd
+++ b/docs/html-ndk/ndk/guides/concepts.jd
@@ -115,20 +115,22 @@
</li>
</ul>
-<p>The following two items only apply in cases in which you are using the toolchains provided with
-the Android NDK as standalone compilers.</p>
+<p>The following two items are only required for building using the
+<a href="{@docRoot}ndk/guides/ndk-build.html">{@code ndk-build}</a> script,
+and for debugging using the <a href="{@docRoot}ndk/guides/ndk-gdb.html">
+{@code ndk-gdb}</a> script.
<ul>
-<li>{@code Android.mk}: You must create an <a href="{@docRoot}ndk/guides/android_mk.html">
-{@code Android.mk}</a> configuration file inside your {@code jni} folder. The ndk-build script
-looks at this file, which defines the module and its name, the source files to be compiled, build
-flags and libraries to link.</li>
+<li><a href="{@docRoot}ndk/guides/android_mk.html">{@code Android.mk}</a>:
+You must create an <a href="{@docRoot}ndk/guides/android_mk.html">
+{@code Android.mk}</a> configuration file inside your {@code jni} folder. The {@code ndk-build}
+script looks at this file, which defines the module and its name, the source files to be compiled,
+build flags and libraries to link.</li>
</ul>
<ul>
-<li>{@code Application.mk}: You may optionally create an
-<a href="{@docRoot}ndk/guides/application_mk.html">{@code Application.mk}</a> file. This file
-This file enumerates and describes the modules that your app requires. This information includes:
+<li><a href="{@docRoot}ndk/guides/application_mk.html">{@code Application.mk}</a>: This file
+enumerates and describes the modules that your app requires. This information includes:
<ul>
<li>ABIs used to compile for specific platforms.</li>
diff --git a/docs/html/distribute/googleplay/families/about.jd b/docs/html/distribute/googleplay/families/about.jd
index 38738b1..a3ef157 100644
--- a/docs/html/distribute/googleplay/families/about.jd
+++ b/docs/html/distribute/googleplay/families/about.jd
@@ -7,81 +7,134 @@
@jd:body
<p>
- If you've built great apps designed for kids or families, the family discovery experience
- on Google Play is a great way to surface them to parents.
+ If you've built great apps designed for kids or families, the family
+ discovery experience on Google Play is a great way to surface them to
+ parents.
</p>
-<p>Developers are invited to opt-in these apps and games to the new Designed for
- Families program. Apps that meet the <a href=
- "https://support.google.com/googleplay/android-developer/answer/6184502">program
- requirements</a> will be featured through Google Play's family-friendly browse
- and search experiences so that parents can find suitable, trusted, high-quality
- apps and games more easily.
-</p>
-
-<img src="{@docRoot}distribute/images/about-dff-sm.jpg">
-
<p>
-Opt-in your apps and games to Designed for Families from the <strong>All Applications</strong> page
-in the Developer Console, under <strong>Pricing and Distribution</strong>. For more information on
- opting-in, visit the Google Play Developer <a href="https://support.google.com/googleplay/android-developer/answer/6231938">Help Center</a>.
+ Developers are invited to opt-in these apps and games to the new Designed for
+ Families program. Apps that meet the <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6184502">program
+ requirements</a> will be featured through Google Play's family-friendly
+ browse and search experiences so that parents can find suitable, trusted,
+ high-quality apps and games more easily.
+</p>
+
+<div class="figure-center">
+<iframe width="640" height="360" src="https://www.youtube.com/embed/QDM52bblwlg?rel=0&controls=0&showinfo=0"
+frameborder="0" allowfullscreen></iframe>
+</div>
+
+<p>
+ Opt-in your apps and games to Designed for Families from the <strong>All
+ Applications</strong> page in the <a href=
+ "https://play.google.com/apps/publish/">Developer Console</a>, under
+ <strong>Pricing and Distribution</strong>. For more information on opting-in,
+ visit the Google Play Developer <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6231938">Help
+ Center</a>.
</p>
<h2 id="benefits">Benefits</h2>
- <div class="figure" style="width:300px;">
-
- <img src="{@docRoot}images/distribute/dff-browse.png" style="width:300px">
- <p class="figure-caption" style="text-align:center">New browsing categories give you improved visibility to parents.</p>
- </div>
-
-<p>
-Designed for Families expands the visibility of your family content on Google Play, helping parents easily find your family-friendly apps and games throughout the store. And new features create a trusted environment that empowers parents to make informed desicions and engage with your content.</p>
-
-
-
-
- <h3>Search</h3>
- <p>Only apps and games opted-in to the Designed for Families program will show up in searches initiated from the Family section in Apps Home. They’ll also be more visible when users search for family or kid related content from anywhere in the Play store.</p>
-
- <h3>Browse</h3>
- <p>The Family star button on Apps and Games Home points to an enhanced discovery experience for parents looking for family appropriate content. The new Family section includes uniquely merchandised content, new categories, and age-based browsing. Participating apps will receive this additional visibility on top of their existing categories, rankings, and reviews elsewhere on the Google Play store.</p>
-
-
-
-
- <h3>Character pages</h3>
-
-
- <div class="figure" style="width:300px;">
-
- <img src="{@docRoot}images/distribute/dff-character-group.png" style="width:500px">
- <p class="figure-caption" style="text-align:center">Character pages let parents discover your content based on familiar brands and characters.</p>
- </div>
-
-
- <p>Parents can now discover content for popular characters from around the globe in one place, including apps, games, movies, tv shows, books, and even music. This provides a powerful way for parents to discover content from familiar brands and beloved characters, and allows you to reach a highly relevant and targeted audience. </p>
-
- <h3>Merchandising</h3>
- <p>The family sections include their own merchandised collections. The themed collections on these pages are curated to ensure quality and limited only to content accepted into the Designed for Families program.</p>
-
- <h3>Badging</h3>
- <p>Apps participating in Designed for Families are marked with the family star badge, which reflects the target age you select for your apps and serves as a signal of quality for parents.</p>
-
-
- <div class="figure" style="width:300px;">
-
- <img src="{@docRoot}images/distribute/dff-badging.png" style="width:300px">
- <p class="figure-caption" style="text-align:center">Participating apps are marked with the family star badge.</p>
- </div>
-
-
-<h2 id="elibibility">Eligibility</h2>
+ <div class="figure" style="width:300px;">
+ <img src="{@docRoot}images/distribute/dff-browse.png" style="width:300px">
+ <p class="figure-caption" style="text-align:center">
+ New browsing categories give you improved visibility to parents.
+ </p>
+</div>
<p>
-The Designed for Families program is designed to be inclusive of apps that are made for kids as well as those that can be enjoyed by the entire family. General audience apps that have no specific benefit or relevance for audiences under the age of thirteen will not be accepted into the program. To participate, there are specific guidelines and policies your apps need to meet, which are assessed in an app content review.
+ Designed for Families expands the visibility of your family content on Google
+ Play, helping parents easily find your family-friendly apps and games
+ throughout the store. And new features create a trusted environment that
+ empowers parents to make informed desicions and engage with your content.
+</p>
+<h3>
+ Search
+</h3>
+<p>
+ Only apps and games opted-in to the Designed for Families program will show
+ up in searches initiated from the Family section in Apps Home. They’ll also
+ be more visible when users search for family or kid related content from
+ anywhere in the Play store.
+</p>
+
+<h3>
+ Browse
+</h3>
+
+<p>
+ The Family star button on Apps and Games Home points to an enhanced discovery
+ experience for parents looking for family appropriate content. The new Family
+ section includes uniquely merchandised content, new categories, and age-based
+ browsing. Participating apps will receive this additional visibility on top
+ of their existing categories, rankings, and reviews elsewhere on the Google
+ Play store.
+</p>
+
+<h3>
+ Character pages
+</h3>
+
+<div class="figure" style="width:300px;">
+ <img src="{@docRoot}images/distribute/dff-character-group.png" style=
+ "width:500px">
+ <p class="figure-caption" style="text-align:center">
+ Character pages let parents discover your content based on familiar brands
+ and characters.
+ </p>
+</div>
+
+<p>
+ Parents can now discover content for popular characters from around the globe
+ in one place, including apps, games, movies, tv shows, books, and even music.
+ This provides a powerful way for parents to discover content from familiar
+ brands and beloved characters, and allows you to reach a highly relevant and
+ targeted audience.
+</p>
+
+<h3>
+ Merchandising
+</h3>
+
+<p>
+ The family sections include their own merchandised collections. The themed
+ collections on these pages are curated to ensure quality and limited only to
+ content accepted into the Designed for Families program.
+</p>
+
+<h3>
+ Badging
+</h3>
+
+<p>
+ Apps participating in Designed for Families are marked with the family star
+ badge, which reflects the target age you select for your apps and serves as a
+ signal of quality for parents.
+</p>
+
+<div class="figure" style="width:300px;">
+ <img src="{@docRoot}images/distribute/dff-badging.png" style="width:300px">
+ <p class="figure-caption" style="text-align:center">
+ Participating apps are marked with the family star badge.
+ </p>
+</div>
+
+<h2 id="elibibility">
+ Eligibility
+</h2>
+
+<p>
+ The Designed for Families program is designed to be inclusive of apps that
+ are made for kids as well as those that can be enjoyed by the entire family.
+ General audience apps that have no specific benefit or relevance for
+ audiences under the age of thirteen will not be accepted into the program. To
+ participate, there are specific guidelines and policies your apps need to
+ meet, which are assessed in an app content review.
</p>
<p>
@@ -102,12 +155,19 @@
</p>
<p>
-To learn how to opt-in and find more details about the program, visit the Google Play Developer <a href="https://support.google.com/googleplay/android-developer/answer/6231938">Help Center</a>.
+ To learn how to opt-in and find more details about the program, visit the
+ Google Play Developer <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6231938">Help
+ Center</a>.
+</p>
-<h2 id="contact">Stay in Touch</h2>
+<h2 id="contact">
+ Stay in Touch
+</h2>
-<p>If you'd like to receive occasional emails with news relating to the Designed for Families
-program and Google Play opportunities, sign up using the <a
-href="https://docs.google.com/forms/d/1EtvUWqlkxS6RxHJjeI-3-7uzdbIZx6n9Cocy2D369B8/viewform">Designed
-for Families Interest Form</a>
+<p>
+ If you'd like to receive occasional emails with news relating to the Designed
+ for Families program and Google Play opportunities, sign up using the
+ <a href="https://docs.google.com/forms/d/1EtvUWqlkxS6RxHJjeI-3-7uzdbIZx6n9Cocy2D369B8/viewform">
+ Designed for Families Interest Form</a>
</p>
\ No newline at end of file
diff --git a/docs/html/google/index.jd b/docs/html/google/index.jd
index 2d3ee05..a2a6c50 100644
--- a/docs/html/google/index.jd
+++ b/docs/html/google/index.jd
@@ -72,6 +72,7 @@
<h2 class="norule">Videos</h2>
<div class="resource-widget resource-flow-layout col-16"
data-query="collection:google/landing/videos"
+ data-sortOrder="-timestamp"
data-cardSizes="6x6"
data-maxResults="3"></div>
</div>
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 073feb8..cac93afc 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -132,6 +132,7 @@
"google/landing/videos": {
"title": "",
"resources": [
+ "https://www.youtube.com/watch?v=M3Udfu6qidk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf",
"https://www.youtube.com/watch?v=FOn64iqlphk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf",
"https://www.youtube.com/watch?v=F0Kh_RnSM0w&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf",
"https://www.youtube.com/watch?v=fvtMtfCuEpw&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf"
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index 90a9875..87581e9 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -294,10 +294,23 @@
"image":"http://i1.ytimg.com/vi/K2dodTXARqc/maxresdefault.jpg",
"type":"video"
},
+
+ {
+ "title":"Google Play Services 7.5",
+ "titleFriendly":"",
+ "summary":"This update brings App Invites, topics to GCM, GCMNetworkManager, Cast Remote Display API, Smart Lock for Passwords, Maps API for Android Wear, Google Fit extensions and more.",
+ "url":"https://www.youtube.com/watch?v=M3Udfu6qidk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf",
+ "group":"",
+ "keywords": ["google play services"],
+ "tags": [
+ ],
+ "image":"http://i1.ytimg.com/vi/M3Udfu6qidk/maxresdefault.jpg",
+ "type":"video"
+ },
{
"title":"Google Play Services 7.3",
"titleFriendly":"",
- "summary":"Google Play Services 7.3 brings a ton of great new features to help you BUILD BETTER APPS! This update brings the ability to connect multiple wearables simultaneously to a single phone.",
+ "summary":"This update brings the ability to connect multiple wearables simultaneously to a single phone. There are also some great new updates to Google Fit, including nutrition types, and to Location.",
"url":"https://www.youtube.com/watch?v=FOn64iqlphk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf",
"group":"",
"keywords": ["google play services"],
diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd
index b8a6033..f9e63e3 100644
--- a/docs/html/preview/api-overview.jd
+++ b/docs/html/preview/api-overview.jd
@@ -61,7 +61,7 @@
<a href="{@docRoot}preview/setup-sdk.html">give the M Developer Preview a
try</a> and send us your feedback!</p>
-<p class="caution"><strong>Caution:</strong> Do not not publish apps
+<p class="caution"><strong>Caution:</strong> Do not publish apps
that use the M Developer Preview to the Google Play store.</p>
<p class="note"><strong>Note:</strong> This document often refers to classes and
@@ -530,4 +530,4 @@
<p class="note">
For a detailed view of all API changes in the M Developer Preview, see the <a href=
"{@docRoot}preview/download.html">API Differences Report</a>.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/preview/setup-sdk.jd b/docs/html/preview/setup-sdk.jd
index 1616053..62c3c58 100644
--- a/docs/html/preview/setup-sdk.jd
+++ b/docs/html/preview/setup-sdk.jd
@@ -46,7 +46,7 @@
Settings > Updates</strong> panel.</li>
<li> On the <strong>Updates</strong> panel, choose the option
- <strong>Automatically check updates for: Canary Chanel</strong>.
+ <strong>Automatically check updates for: Canary Channel</strong>.
</li>
<li>On the <strong>Updates</strong> panel, select <strong>Check Now</strong>
@@ -68,8 +68,8 @@
Settings > Updates</strong> panel.</li>
<li>On the <strong>Updates</strong> panel, choose the options
- <strong>Automatically check updates for: Canary Chanel</strong> and
- <strong>Automatically check updates for Android SDK: Preview Chanel</strong>.
+ <strong>Automatically check updates for: Canary Channel</strong> and
+ <strong>Automatically check updates for Android SDK: Preview Channel</strong>.
</li>
<li>Click the <strong>Android SDK Manager</strong> button to launch the SDK
diff --git a/docs/html/tools/data-binding/guide.jd b/docs/html/tools/data-binding/guide.jd
index 71409e4..ec16c6b 100644
--- a/docs/html/tools/data-binding/guide.jd
+++ b/docs/html/tools/data-binding/guide.jd
@@ -2,15 +2,6 @@
page.tags="databinding", "layouts"
@jd:body
-<div class="wrap">
-<p class="caution" style="background-color:#fffdeb;">
-The <strong>Android Data Binding Library</strong> is available as a <strong>developer
-preview</strong>. Expression syntax and behaviors may change prior to the full release
-of the library, currently planned for Q3 2015. If you have feedback or want to report
-issues, please use the <a href="https://code.google.com/p/android-developer-preview/">issue
-tracker</a>. Stay tuned for more information about Data Binding and examples of how to use it. </a>
-</p>
-</div>
<div id="qv-wrapper">
<div id="qv">
<h2>
@@ -140,17 +131,72 @@
</div><!-- qv -->
</div><!-- qv-wrapper -->
-
<p>
This document explains how to use the Data Binding Library to write
declarative layouts and minimize the glue code necessary to bind your
application logic and layouts.
</p>
+<p>The Data Binding Library offers both flexibility and broad comnpatibility
+— it's a support library, so you can use it with all Android platform
+versions back to <strong>Android 2.1</strong> (API level 7+).</p>
+
+<p>Android Studio <strong>1.3.0-beta1</strong> or higher is required.</p>
+
+<h4>Beta release</h4>
+
+<div class="caution">
+ <p>Please note that the Data Binding library is a <strong>beta release</strong>.
+ While Data Binding is in beta, developers should be aware of the following
+ caveats:</p>
+ <ul>
+ <li>
+ This is a beta release of the feature intended to generate developer
+ feedback. It might contain bugs, and it might not work for your use case,
+ so use it at your own risk. That said, we do want your feedback! Please
+ let us know what is or isn’t working for you using the <a
+ href="https://code.google.com/p/android-developer-preview/">issue
+ tracker</a>.
+ </li>
+ <li>
+ The Data Binding library beta release is subject to significant changes,
+ including those which are not source code compatible with your app. That is,
+ significant rework may be required to take updates to the library in the future.
+ </li>
+ <li>
+ Developers should feel free to publish apps built with the Data Binding
+ library beta release, with the caveats that the standard Android SDK and
+ Google Play terms of service apply, and it’s always a great idea to test your
+ app thoroughly when adopting new libraries or tools.
+ </li>
+ <li>
+ We’re just getting started with Android Studio support at this time.
+ Further Android Studio support will come in the future.
+ </li>
+ <li>
+ By using the Data Binding library beta release, you acknowledge these
+ caveats.</li>
+ </ul>
+</div>
+
<h2 id="build_environment">
Build Environment
</h2>
+<p>To get started with Data Binding, download the library from the Support
+repository in the Android SDK manager. </p>
+
+<p>Make sure you are using a compatible version of Android Studio.
+The Data Binding plugin for Android Studio requires Android Studio <strong>1.3.0-beta1
+or higher</strong>.</p>
+<h2 id="build_environment">
+ Build Environment
+</h2>
+
+<p>To get started with Data Binding, download the library from the Support repository in the Android SDK manager. </p>
+
+<p>Make sure you are using a <strong>compatible version of Android Studio</strong>. The Data Binding plugin for Android Studio requires <strong>Android 1.3.0-beta1 or higher</strong>.</p>
+
<p>
<strong>Setting Up Work Environment:</strong>
</p>
@@ -391,7 +437,7 @@
<<strong>variable name="userList" type="List&lt;User>"</strong>/>
</<strong>data</strong>>
</pre>
-<p class="note">
+<p class="caution">
<strong>Note</strong>: Android Studio does not yet handle imports so the
autocomplete for imported variables may not work in your IDE. Your
application will still compile fine and you can work around the IDE issue by
@@ -771,7 +817,7 @@
Have an orange
Have %d oranges
-android:text="<strong>&commat{&commatplurals/orange(orangeCount, orangeCount)}</strong>"
+android:text="<strong>@{@plurals/orange(orangeCount, orangeCount)}</strong>"
</pre>
<p>
Some resources require explicit type evaluation.
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index b8f64a4..073acd4 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -19,6 +19,7 @@
import android.animation.AnimatorSet;
import android.animation.Animator.AnimatorListener;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -128,15 +129,27 @@
* @attr ref android.R.styleable#AnimatedVectorDrawableTarget_animation
*/
public class AnimatedVectorDrawable extends Drawable implements Animatable {
- private static final String LOGTAG = AnimatedVectorDrawable.class.getSimpleName();
+ private static final String LOGTAG = "AnimatedVectorDrawable";
private static final String ANIMATED_VECTOR = "animated-vector";
private static final String TARGET = "target";
private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
+ /** Local, mutable animator set. */
+ private final AnimatorSet mAnimatorSet = new AnimatorSet();
+
+ /**
+ * The resources against which this drawable was created. Used to attempt
+ * to inflate animators if applyTheme() doesn't get called.
+ */
+ private Resources mRes;
+
private AnimatedVectorDrawableState mAnimatedVectorState;
+ /** Whether the animator set has been prepared. */
+ private boolean mHasAnimatorSet;
+
private boolean mMutated;
public AnimatedVectorDrawable() {
@@ -145,6 +158,7 @@
private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res) {
mAnimatedVectorState = new AnimatedVectorDrawableState(state, mCallback, res);
+ mRes = res;
}
@Override
@@ -162,7 +176,9 @@
*/
public void clearMutated() {
super.clearMutated();
- mAnimatedVectorState.mVectorDrawable.clearMutated();
+ if (mAnimatedVectorState.mVectorDrawable != null) {
+ mAnimatedVectorState.mVectorDrawable.clearMutated();
+ }
mMutated = false;
}
@@ -274,6 +290,7 @@
@Override
public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
+ final AnimatedVectorDrawableState state = mAnimatedVectorState;
int eventType = parser.getEventType();
float pathErrorScale = 1;
@@ -291,10 +308,10 @@
vectorDrawable.setAllowCaching(false);
vectorDrawable.setCallback(mCallback);
pathErrorScale = vectorDrawable.getPixelSize();
- if (mAnimatedVectorState.mVectorDrawable != null) {
- mAnimatedVectorState.mVectorDrawable.setCallback(null);
+ if (state.mVectorDrawable != null) {
+ state.mVectorDrawable.setCallback(null);
}
- mAnimatedVectorState.mVectorDrawable = vectorDrawable;
+ state.mVectorDrawable = vectorDrawable;
}
a.recycle();
} else if (TARGET.equals(tagName)) {
@@ -302,13 +319,21 @@
R.styleable.AnimatedVectorDrawableTarget);
final String target = a.getString(
R.styleable.AnimatedVectorDrawableTarget_name);
-
- int id = a.getResourceId(
+ final int animResId = a.getResourceId(
R.styleable.AnimatedVectorDrawableTarget_animation, 0);
- if (id != 0) {
- Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id,
- pathErrorScale);
- setupAnimatorsForTarget(target, objectAnimator);
+ if (animResId != 0) {
+ if (theme != null) {
+ final Animator objectAnimator = AnimatorInflater.loadAnimator(
+ res, theme, animResId, pathErrorScale);
+ state.addTargetAnimator(target, objectAnimator);
+ } else {
+ // The animation may be theme-dependent. As a
+ // workaround until Animator has full support for
+ // applyTheme(), postpone loading the animator
+ // until we have a theme in applyTheme().
+ state.addPendingAnimator(animResId, pathErrorScale, target);
+
+ }
}
a.recycle();
}
@@ -316,15 +341,10 @@
eventType = parser.next();
}
- setupAnimatorSet();
- }
- private void setupAnimatorSet() {
- if (mAnimatedVectorState.mTempAnimators != null) {
- mAnimatedVectorState.mAnimatorSet.playTogether(mAnimatedVectorState.mTempAnimators);
- mAnimatedVectorState.mTempAnimators.clear();
- mAnimatedVectorState.mTempAnimators = null;
- }
+ // If we don't have any pending animations, we don't need to hold a
+ // reference to the resources.
+ mRes = state.mPendingAnims == null ? null : res;
}
@Override
@@ -341,6 +361,16 @@
if (vectorDrawable != null && vectorDrawable.canApplyTheme()) {
vectorDrawable.applyTheme(t);
}
+
+ if (t != null) {
+ mAnimatedVectorState.inflatePendingAnimators(t.getResources(), t);
+ }
+
+ // If we don't have any pending animations, we don't need to hold a
+ // reference to the resources.
+ if (mAnimatedVectorState.mPendingAnims == null) {
+ mRes = null;
+ }
}
/**
@@ -350,7 +380,7 @@
* @param listener the listener to be added to the current set of listeners for this animation.
*/
public void addListener(AnimatorListener listener) {
- mAnimatedVectorState.mAnimatorSet.addListener(listener);
+ mAnimatorSet.addListener(listener);
}
/**
@@ -360,7 +390,7 @@
* animation.
*/
public void removeListener(AnimatorListener listener) {
- mAnimatedVectorState.mAnimatorSet.removeListener(listener);
+ mAnimatorSet.removeListener(listener);
}
/**
@@ -370,23 +400,27 @@
* @return List<AnimatorListener> The set of listeners.
*/
public List<AnimatorListener> getListeners() {
- return mAnimatedVectorState.mAnimatorSet.getListeners();
+ return mAnimatorSet.getListeners();
}
private static class AnimatedVectorDrawableState extends ConstantState {
int mChangingConfigurations;
VectorDrawable mVectorDrawable;
- // Always have a valid animatorSet to handle all the listeners call.
- AnimatorSet mAnimatorSet = new AnimatorSet();
- // When parsing the XML, we build individual animator and store in this array. At the end,
- // we add this array into the mAnimatorSet.
- private ArrayList<Animator> mTempAnimators;
+
+ /** Animators that require a theme before inflation. */
+ ArrayList<PendingAnimator> mPendingAnims;
+
+ /** Fully inflated animators awaiting cloning into an AnimatorSet. */
+ ArrayList<Animator> mAnimators;
+
+ /** Map of animators to their target object names */
ArrayMap<Animator, String> mTargetNameMap;
public AnimatedVectorDrawableState(AnimatedVectorDrawableState copy,
Callback owner, Resources res) {
if (copy != null) {
mChangingConfigurations = copy.mChangingConfigurations;
+
if (copy.mVectorDrawable != null) {
final ConstantState cs = copy.mVectorDrawable.getConstantState();
if (res != null) {
@@ -400,24 +434,17 @@
mVectorDrawable.setBounds(copy.mVectorDrawable.getBounds());
mVectorDrawable.setAllowCaching(false);
}
- if (copy.mAnimatorSet != null) {
- final int numAnimators = copy.mTargetNameMap.size();
- // Deep copy a animator set, and then setup the target map again.
- mAnimatorSet = copy.mAnimatorSet.clone();
- mTargetNameMap = new ArrayMap<Animator, String>(numAnimators);
- // Since the new AnimatorSet is cloned from the old one, the order must be the
- // same inside the array.
- ArrayList<Animator> oldAnim = copy.mAnimatorSet.getChildAnimations();
- ArrayList<Animator> newAnim = mAnimatorSet.getChildAnimations();
- for (int i = 0; i < numAnimators; ++i) {
- // Target name must be the same for new and old
- String targetName = copy.mTargetNameMap.get(oldAnim.get(i));
+ if (copy.mAnimators != null) {
+ mAnimators = new ArrayList<>(copy.mAnimators);
+ }
- Object newTargetObject = mVectorDrawable.getTargetByName(targetName);
- newAnim.get(i).setTarget(newTargetObject);
- mTargetNameMap.put(newAnim.get(i), targetName);
- }
+ if (copy.mTargetNameMap != null) {
+ mTargetNameMap = new ArrayMap<>(copy.mTargetNameMap);
+ }
+
+ if (copy.mPendingAnims != null) {
+ mPendingAnims = new ArrayList<>(copy.mPendingAnims);
}
} else {
mVectorDrawable = new VectorDrawable();
@@ -427,7 +454,7 @@
@Override
public boolean canApplyTheme() {
return (mVectorDrawable != null && mVectorDrawable.canApplyTheme())
- || super.canApplyTheme();
+ || mPendingAnims != null || super.canApplyTheme();
}
@Override
@@ -444,44 +471,157 @@
public int getChangingConfigurations() {
return mChangingConfigurations;
}
- }
- private void setupAnimatorsForTarget(String name, Animator animator) {
- Object target = mAnimatedVectorState.mVectorDrawable.getTargetByName(name);
- animator.setTarget(target);
- if (mAnimatedVectorState.mTempAnimators == null) {
- mAnimatedVectorState.mTempAnimators = new ArrayList<Animator>();
- mAnimatedVectorState.mTargetNameMap = new ArrayMap<Animator, String>();
+ public void addPendingAnimator(int resId, float pathErrorScale, String target) {
+ if (mPendingAnims == null) {
+ mPendingAnims = new ArrayList<>(1);
+ }
+ mPendingAnims.add(new PendingAnimator(resId, pathErrorScale, target));
}
- mAnimatedVectorState.mTempAnimators.add(animator);
- mAnimatedVectorState.mTargetNameMap.put(animator, name);
- if (DBG_ANIMATION_VECTOR_DRAWABLE) {
- Log.v(LOGTAG, "add animator for target " + name + " " + animator);
+
+ public void addTargetAnimator(String targetName, Animator animator) {
+ if (mAnimators == null) {
+ mAnimators = new ArrayList<>(1);
+ mTargetNameMap = new ArrayMap<>(1);
+ }
+ mAnimators.add(animator);
+ mTargetNameMap.put(animator, targetName);
+
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.v(LOGTAG, "add animator for target " + targetName + " " + animator);
+ }
+ }
+
+ /**
+ * Prepares a local set of mutable animators based on the constant
+ * state.
+ * <p>
+ * If there are any pending uninflated animators, attempts to inflate
+ * them immediately against the provided resources object.
+ *
+ * @param animatorSet the animator set to which the animators should
+ * be added
+ * @param res the resources against which to inflate any pending
+ * animators, or {@code null} if not available
+ */
+ public void prepareLocalAnimators(@NonNull AnimatorSet animatorSet,
+ @Nullable Resources res) {
+ // Check for uninflated animators. We can remove this after we add
+ // support for Animator.applyTheme(). See comments in inflate().
+ if (mPendingAnims != null) {
+ // Attempt to load animators without applying a theme.
+ if (res != null) {
+ inflatePendingAnimators(res, null);
+ } else {
+ Log.e(LOGTAG, "Failed to load animators. Either the AnimatedVectorDrawable"
+ + " must be created using a Resources object or applyTheme() must be"
+ + " called with a non-null Theme object.");
+ }
+
+ mPendingAnims = null;
+ }
+
+ // Perform a deep copy of the constant state's animators.
+ final int count = mAnimators == null ? 0 : mAnimators.size();
+ if (count > 0) {
+ final Animator firstAnim = prepareLocalAnimator(0);
+ final AnimatorSet.Builder builder = animatorSet.play(firstAnim);
+ for (int i = 1; i < count; ++i) {
+ final Animator nextAnim = prepareLocalAnimator(i);
+ builder.with(nextAnim);
+ }
+ }
+ }
+
+ /**
+ * Prepares a local animator for the given index within the constant
+ * state's list of animators.
+ *
+ * @param index the index of the animator within the constant state
+ */
+ private Animator prepareLocalAnimator(int index) {
+ final Animator animator = mAnimators.get(index);
+ final Animator localAnimator = animator.clone();
+ final String targetName = mTargetNameMap.get(animator);
+ final Object target = mVectorDrawable.getTargetByName(targetName);
+ localAnimator.setTarget(target);
+ return localAnimator;
+ }
+
+ /**
+ * Inflates pending animators, if any, against a theme. Clears the list of
+ * pending animators.
+ *
+ * @param t the theme against which to inflate the animators
+ */
+ public void inflatePendingAnimators(@NonNull Resources res, @Nullable Theme t) {
+ final ArrayList<PendingAnimator> pendingAnims = mPendingAnims;
+ if (pendingAnims != null) {
+ mPendingAnims = null;
+
+ for (int i = 0, count = pendingAnims.size(); i < count; i++) {
+ final PendingAnimator pendingAnimator = pendingAnims.get(i);
+ final Animator objectAnimator = pendingAnimator.newInstance(res, t);
+ addTargetAnimator(pendingAnimator.target, objectAnimator);
+ }
+ }
+ }
+
+ /**
+ * Basically a constant state for Animators until we actually implement
+ * constant states for Animators.
+ */
+ private static class PendingAnimator {
+ public final int animResId;
+ public final float pathErrorScale;
+ public final String target;
+
+ public PendingAnimator(int animResId, float pathErrorScale, String target) {
+ this.animResId = animResId;
+ this.pathErrorScale = pathErrorScale;
+ this.target = target;
+ }
+
+ public Animator newInstance(Resources res, Theme theme) {
+ return AnimatorInflater.loadAnimator(res, theme, animResId, pathErrorScale);
+ }
}
}
@Override
public boolean isRunning() {
- return mAnimatedVectorState.mAnimatorSet.isRunning();
+ return mAnimatorSet.isRunning();
}
private boolean isStarted() {
- return mAnimatedVectorState.mAnimatorSet.isStarted();
+ return mAnimatorSet.isStarted();
}
@Override
public void start() {
+ ensureAnimatorSet();
+
// If any one of the animator has not ended, do nothing.
if (isStarted()) {
return;
}
- mAnimatedVectorState.mAnimatorSet.start();
+
+ mAnimatorSet.start();
invalidateSelf();
}
+ @NonNull
+ private void ensureAnimatorSet() {
+ if (!mHasAnimatorSet) {
+ mAnimatedVectorState.prepareLocalAnimators(mAnimatorSet, mRes);
+ mHasAnimatorSet = true;
+ mRes = null;
+ }
+ }
+
@Override
public void stop() {
- mAnimatedVectorState.mAnimatorSet.end();
+ mAnimatorSet.end();
}
/**
@@ -492,20 +632,23 @@
* @hide
*/
public void reverse() {
- // Only reverse when all the animators can be reverse. Otherwise, partially
- // reverse is confusing.
+ ensureAnimatorSet();
+
+ // Only reverse when all the animators can be reversed.
if (!canReverse()) {
Log.w(LOGTAG, "AnimatedVectorDrawable can't reverse()");
return;
}
- mAnimatedVectorState.mAnimatorSet.reverse();
+
+ mAnimatorSet.reverse();
+ invalidateSelf();
}
/**
* @hide
*/
public boolean canReverse() {
- return mAnimatedVectorState.mAnimatorSet.canReverse();
+ return mAnimatorSet.canReverse();
}
private final Callback mCallback = new Callback() {
diff --git a/location/java/android/location/CountryDetector.java b/location/java/android/location/CountryDetector.java
index 0b780ce..ce3c56f 100644
--- a/location/java/android/location/CountryDetector.java
+++ b/location/java/android/location/CountryDetector.java
@@ -44,8 +44,6 @@
* You do not instantiate this class directly; instead, retrieve it through
* {@link android.content.Context#getSystemService
* Context.getSystemService(Context.COUNTRY_DETECTOR)}.
- * <p>
- * Both ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions are needed.
*
* @hide
*/
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index f76189c..7293c6c 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1990,9 +1990,24 @@
* The dead object error code is not returned if some data was successfully transferred.
* In this case, the error is returned at the next write().
*/
- public int write(ByteBuffer audioData, int sizeInBytes,
+ public int write(@NonNull ByteBuffer audioData, int sizeInBytes,
@WriteMode int writeMode, long timestamp) {
+ if (mState == STATE_UNINITIALIZED) {
+ Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
+ return ERROR_INVALID_OPERATION;
+ }
+
+ if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
+ Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
+ return ERROR_BAD_VALUE;
+ }
+
+ if (mDataLoadMode != MODE_STREAM) {
+ Log.e(TAG, "AudioTrack.write() with timestamp called for non-streaming mode track");
+ return ERROR_INVALID_OPERATION;
+ }
+
if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) == 0) {
Log.d(TAG, "AudioTrack.write() called on a regular AudioTrack. Ignoring pts...");
return write(audioData, sizeInBytes, writeMode);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 2acee04..b1a51a56 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -1018,7 +1018,9 @@
}
public void post(int what, Object obj, Bundle data) {
- obtainMessage(what, obj).sendToTarget();
+ Message msg = obtainMessage(what, obj);
+ msg.setData(data);
+ msg.sendToTarget();
}
}
diff --git a/packages/Keyguard/res/values-az-rAZ/strings.xml b/packages/Keyguard/res/values-az-rAZ/strings.xml
index 5c8f6ac..978f811 100644
--- a/packages/Keyguard/res/values-az-rAZ/strings.xml
+++ b/packages/Keyguard/res/values-az-rAZ/strings.xml
@@ -20,18 +20,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="719438068451601849">"Klaviatura kilidi"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PİN kodu daxil edin"</string>
- <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK və yeni PİN kod daxil edin"</string>
- <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kod"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Yeni PIN kodu"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM PUK və yeni PIN kodu yazın"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK kodu"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Yeni SIM PIN kodu"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Şifrə daxil etmək üçün toxunun"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Kilidi açmaq üçün parol yazın"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Kilidi açmaq üçün PIN daxil edin"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
- <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmaq üçün Menyu, sonra 0 basın."</string>
- <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Sifət kilidi cəhdləriniz bitdi"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Dolmuş"</string>
- <string name="keyguard_plugged_in" msgid="8117572000639998388">"Dolur, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="keyguard_plugged_in" msgid="9087497435553252863">"Enerji doldurulur"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Elektrikə qoşun."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmaq üçün Menyu düyməsinə baxın."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Şəbəkə kilidləndi"</string>
@@ -45,53 +44,17 @@
<string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kart kilidlənib."</string>
<string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SİM kart PUK ilə kilidlənib."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SİM kartın kilidi açılır..."</string>
- <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
- <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget əlavə edin."</string>
- <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
- <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Kilidi açma sahəsi genişləndi."</string>
- <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Kilidi açma sahəsi çökdü."</string>
- <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> vidcet."</string>
- <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"İstifadəçi selektoru"</string>
- <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
- <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
- <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media kontrolları"</string>
- <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Yenidən sıralama vidceti başladıldı."</string>
- <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidcetin təkrar sifarişi sona çatdı."</string>
- <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidcet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> silindi."</string>
- <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kilidi açma sahəsini genişləndir."</string>
- <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sürüşdürmə kilidi."</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Kild açma modeli."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Sifət Kilidi"</string>
<string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin kilid açması."</string>
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifrə kilidi."</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Model sahəsi."</string>
<string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sürüşdürmə sahəsi."</string>
- <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Əvvəlki izləmə düyməsi"</string>
- <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Növbəti izləmə düyməsi"</string>
- <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pauza düyməsi"</string>
- <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Oxutma düyməsi"</string>
- <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Dayandırma düyməsi"</string>
- <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
- <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
- <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
- <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ləğv et"</string>
+ <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN sahəsi"</string>
+ <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN sahəsi"</string>
+ <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK sahəsi"</string>
+ <string name="keyguard_accessibility_next_alarm" msgid="7269583073750518672">"Növbəti alarm vaxtı: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
- <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hazırdır"</string>
- <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Rejim dəyişikliyi"</string>
- <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Daxil olun"</string>
- <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
- <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
- <string name="description_target_silent" msgid="893551287746522182">"Səssiz"</string>
- <string name="description_target_soundon" msgid="30052466675500172">"Səs açıqdır"</string>
- <string name="description_target_search" msgid="3091587249776033139">"Axtar"</string>
- <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün yuxarı sürüşdürün."</string>
- <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün aşağı sürüşdürün."</string>
- <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string>
- <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sağa sürüşdür."</string>
- <string name="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
- <string name="kg_emergency_call_label" msgid="684946192523830531">"Təcili zəng"</string>
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Şablonu unutmuşam"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Model"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifrə"</string>
@@ -99,40 +62,51 @@
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"Şablonunuzu çəkin"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodu daxil edin"</string>
+ <string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" üçün SIM PIN daxil edin"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"PİN kodu daxil edin"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Parol daxil edin"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM indi deaktivdir. Davam etmək üçün PUK kodu daxil edin. Əlavə məlumat üçün operatora müraciət edin."</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" indi qeyri-aktiv edilib. Davam etmək üçün PUK kodu daxil edin. Təfərrüatlar üçün operatorunuzla əlaqə saxlayın."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"İstədiyiniz PİN kodu daxil edin"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"İstədiyiniz PIN kodu təsdiqləyin"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SİM kartın kilidi açılır..."</string>
- <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PİN kod."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-dən 8-ə qədər rəqəmi olan PIN yazın."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kod 8 rəqəm və ya daha çox olmalıdır."</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"Düzgün PUK kodu yenidən daxil edin. Təkrarlanan cəhdlər SIM\'i birdəfəlik sıradan çıxaracaq."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları uyğun deyil"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Həddindən çox cəhd edildi!"</string>
- <string name="kg_login_instructions" msgid="1100551261265506448">"Kilidi açmaq üçün Google hesabınız ilə daxil olun."</string>
- <string name="kg_login_username_hint" msgid="5718534272070920364">"İstifadəçi adı (e-poçt)"</string>
- <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifrə"</string>
- <string name="kg_login_submit_button" msgid="5355904582674054702">"Daxil ol"</string>
- <string name="kg_login_invalid_input" msgid="5754664119319872197">"Yanlış istifadəçi adı və ya parol."</string>
- <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
- <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesab yoxlanılır..."</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Modelinizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkmisiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. Planşet fabrik ayarlarına sıfırlanacaq."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Siz <xliff:g id="NUMBER_0">%d</xliff:g> dəfə planşetinizin kilidini açmaq üçün yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra bu planşet ilkin vəziyyətinə bərpa olunacaq və ondakı bütün məlumatlar silinəcəkdir."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Siz <xliff:g id="NUMBER_0">%d</xliff:g> dəfə telefonunuzun kilidini açmaq üçün yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra bu telefon ilkin vəziyyətinə bərpa olunacaq və ondakı bütün məlumatlar silinəcəkdir."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə planşetinizin kilidini açmaq üçün yanlış cəhdlər etdiniz. Bu planşet ilkin vəziyyətinə bərpa olunacaq və ondakı bütün məlumatlar silinəcəkdir."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə telefonunuzun kilidini açmaq üçün yanlış cəhdlər etdiniz. Bu telefon ilkin vəziyyətinə bərpa olunacaq və ondakı bütün məlumatlar silinəcəkdir."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"Siz <xliff:g id="NUMBER_0">%d</xliff:g> dəfə planşetinizin kilidini açmaq üçün yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra bütün istifadəçi məlumatlarını siləcək bu istifadəçi silinəcəkdir."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"Siz <xliff:g id="NUMBER_0">%d</xliff:g> dəfə telefonunuzun kilidini açmaq üçün yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra bütün istifadəçi məlumatlarını siləcək bu istifadəçi silinəcəkdir."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə planşetinizin kilidini açmaq üçün yanlış cəhdlər etdiniz. Bu istifadəçi və istifadəçi ilə bağlı bütün məlumatlar silinəcəkdir."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə telefonunuzun kilidini açmaq üçün yanlış cəhdlər etdiniz. Bu istifadəçi və istifadəçi ilə bağlı bütün məlumatlar silinəcəkdir."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"Siz <xliff:g id="NUMBER_0">%d</xliff:g> dəfə planşetinizin kilidini açmaq üçün yanlış cəhdlər etdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra bütün profil məlumatlarını siləcək iş profili silinəcəkdir."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Siz <xliff:g id="NUMBER_0">%d</xliff:g> dəfə telefonunuzun kilidini açmaq üçün yanlış cəhdlər etdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra bütün profil məlumatlarını siləcək iş profili silinəcəkdir."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə planşetinizin kilidini açmaq üçün yanlış cəhdlər etdiniz. Bütün profil məlumatlarınızı siləcək iş profili silinəcəkdir."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə telefonunuzun kilidini açmaq üçün yanlış cəhdlər etdiniz. Bütün profil məlumatlarınızı siləcək iş profili silinəcəkdir."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz artıq modeli <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
- <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
- <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Yığışdır"</string>
- <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Əvvəlki izləmə düyməsi"</string>
- <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Növbəti izləmə düyməsi"</string>
- <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pauza düyməsi"</string>
- <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Oxutma düyməsi"</string>
- <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Dayandırma düyməsi"</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Yanlış SIM PIN kodu cihazınızın açılması üçün operatorunuzla indi əlaqə saxlamalısınız."</string>
+ <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
+ <item quantity="other">Yanlış SIM PIN kodu, <xliff:g id="NUMBER_1">%d</xliff:g> cəhdiniz qalır.</item>
+ <item quantity="one">Yanlış SIM PIN kodu, cihazınızı kiliddən çıxarmaq üçün operatorunuzla əlaqə saxlamadan öncə <xliff:g id="NUMBER_0">%d</xliff:g> cəhdiniz qalır.</item>
+ </plurals>
+ <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM yararsızdır. Operatorunuzla əlaqə saxlayın."</string>
+ <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="7576227366999858780">
+ <item quantity="other">Yanlış SIM PUK kodu, SIM kartınızın daimi olaraq yararsız olmasından öncə <xliff:g id="NUMBER_1">%d</xliff:g> cəhdiniz qalır.</item>
+ <item quantity="one">Yanlış SIM PUK kodu, SIM kartınızın daimi olaraq yararsız olmasından öncə <xliff:g id="NUMBER_0">%d</xliff:g> cəhdiniz qalır.</item>
+ </plurals>
+ <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN əməliyyatı alınmadı!"</string>
+ <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK əməliyyatı alınmadı!"</string>
+ <string name="kg_pin_accepted" msgid="1448241673570020097">"Kod Qəbul Edildi!"</string>
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Xidmət yoxdur."</string>
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Daxiletmə metodu düyməsinə keç"</string>
+ <string name="airplane_mode" msgid="3122107900897202805">"Təyyarə rejimi"</string>
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Tanınmır"</string>
</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index 1c4b963..54467f3 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -203,8 +203,8 @@
final int wPadding = getPaddingLeft() + getPaddingRight();
final int hPadding = getPaddingTop() + getPaddingBottom();
- maxWidth -= wPadding;
- maxHeight -= hPadding;
+ maxWidth = Math.max(0, maxWidth - wPadding);
+ maxHeight = Math.max(0, maxHeight - hPadding);
int width = widthMode == MeasureSpec.EXACTLY ? widthSize : 0;
int height = heightMode == MeasureSpec.EXACTLY ? heightSize : 0;
diff --git a/packages/SettingsLib/res/xml/timezones.xml b/packages/SettingsLib/res/xml/timezones.xml
new file mode 100644
index 0000000..4426495
--- /dev/null
+++ b/packages/SettingsLib/res/xml/timezones.xml
@@ -0,0 +1,91 @@
+<timezones>
+ <timezone id="Pacific/Midway"></timezone>
+ <timezone id="Pacific/Honolulu"></timezone>
+ <timezone id="America/Anchorage"></timezone>
+ <timezone id="America/Los_Angeles"></timezone>
+ <timezone id="America/Tijuana"></timezone>
+ <timezone id="America/Phoenix"></timezone>
+ <timezone id="America/Chihuahua"></timezone>
+ <timezone id="America/Denver"></timezone>
+ <timezone id="America/Costa_Rica"></timezone>
+ <timezone id="America/Chicago"></timezone>
+ <timezone id="America/Mexico_City"></timezone>
+ <timezone id="America/Regina"></timezone>
+ <timezone id="America/Bogota"></timezone>
+ <timezone id="America/New_York"></timezone>
+ <timezone id="America/Caracas"></timezone>
+ <timezone id="America/Barbados"></timezone>
+ <timezone id="America/Halifax"></timezone>
+ <timezone id="America/Manaus"></timezone>
+ <timezone id="America/Santiago"></timezone>
+ <timezone id="America/St_Johns"></timezone>
+ <timezone id="America/Recife"></timezone>
+ <timezone id="America/Sao_Paulo"></timezone>
+ <timezone id="America/Buenos_Aires"></timezone>
+ <timezone id="America/Godthab"></timezone>
+ <timezone id="America/Montevideo"></timezone>
+ <timezone id="Atlantic/South_Georgia"></timezone>
+ <timezone id="Atlantic/Azores"></timezone>
+ <timezone id="Atlantic/Cape_Verde"></timezone>
+ <timezone id="Africa/Casablanca"></timezone>
+ <timezone id="Europe/London"></timezone>
+ <timezone id="Europe/Amsterdam"></timezone>
+ <timezone id="Europe/Belgrade"></timezone>
+ <timezone id="Europe/Brussels"></timezone>
+ <timezone id="Europe/Madrid"></timezone>
+ <timezone id="Europe/Sarajevo"></timezone>
+ <timezone id="Africa/Windhoek"></timezone>
+ <timezone id="Africa/Brazzaville"></timezone>
+ <timezone id="Asia/Amman"></timezone>
+ <timezone id="Europe/Athens"></timezone>
+ <timezone id="Europe/Istanbul"></timezone>
+ <timezone id="Asia/Beirut"></timezone>
+ <timezone id="Africa/Cairo"></timezone>
+ <timezone id="Europe/Helsinki"></timezone>
+ <timezone id="Asia/Jerusalem"></timezone>
+ <timezone id="Europe/Minsk"></timezone>
+ <timezone id="Africa/Harare"></timezone>
+ <timezone id="Asia/Baghdad"></timezone>
+ <timezone id="Europe/Moscow"></timezone>
+ <timezone id="Asia/Kuwait"></timezone>
+ <timezone id="Africa/Nairobi"></timezone>
+ <timezone id="Asia/Tehran"></timezone>
+ <timezone id="Asia/Baku"></timezone>
+ <timezone id="Asia/Tbilisi"></timezone>
+ <timezone id="Asia/Yerevan"></timezone>
+ <timezone id="Asia/Dubai"></timezone>
+ <timezone id="Asia/Kabul"></timezone>
+ <timezone id="Asia/Karachi"></timezone>
+ <timezone id="Asia/Oral"></timezone>
+ <timezone id="Asia/Yekaterinburg"></timezone>
+ <timezone id="Asia/Calcutta"></timezone>
+ <timezone id="Asia/Colombo"></timezone>
+ <timezone id="Asia/Katmandu"></timezone>
+ <timezone id="Asia/Almaty"></timezone>
+ <timezone id="Asia/Rangoon"></timezone>
+ <timezone id="Asia/Krasnoyarsk"></timezone>
+ <timezone id="Asia/Bangkok"></timezone>
+ <timezone id="Asia/Jakarta"></timezone>
+ <timezone id="Asia/Shanghai"></timezone>
+ <timezone id="Asia/Hong_Kong"></timezone>
+ <timezone id="Asia/Irkutsk"></timezone>
+ <timezone id="Asia/Kuala_Lumpur"></timezone>
+ <timezone id="Australia/Perth"></timezone>
+ <timezone id="Asia/Taipei"></timezone>
+ <timezone id="Asia/Seoul"></timezone>
+ <timezone id="Asia/Tokyo"></timezone>
+ <timezone id="Asia/Yakutsk"></timezone>
+ <timezone id="Australia/Adelaide"></timezone>
+ <timezone id="Australia/Darwin"></timezone>
+ <timezone id="Australia/Brisbane"></timezone>
+ <timezone id="Australia/Hobart"></timezone>
+ <timezone id="Australia/Sydney"></timezone>
+ <timezone id="Asia/Vladivostok"></timezone>
+ <timezone id="Pacific/Guam"></timezone>
+ <timezone id="Asia/Magadan"></timezone>
+ <timezone id="Pacific/Noumea"></timezone>
+ <timezone id="Pacific/Majuro"></timezone>
+ <timezone id="Pacific/Auckland"></timezone>
+ <timezone id="Pacific/Fiji"></timezone>
+ <timezone id="Pacific/Tongatapu"></timezone>
+</timezones>
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
new file mode 100644
index 0000000..12ead4e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -0,0 +1,147 @@
+/*
+ * 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
+ */
+
+package com.android.settingslib.datetime;
+
+import android.content.Context;
+import android.content.res.XmlResourceParser;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import com.android.settingslib.R;
+
+import libcore.icu.TimeZoneNames;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class ZoneGetter {
+ private static final String TAG = "ZoneGetter";
+
+ private static final String XMLTAG_TIMEZONE = "timezone";
+
+ public static final String KEY_ID = "id"; // value: String
+ public static final String KEY_DISPLAYNAME = "name"; // value: String
+ public static final String KEY_GMT = "gmt"; // value: String
+ public static final String KEY_OFFSET = "offset"; // value: int (Integer)
+
+ private final List<HashMap<String, Object>> mZones = new ArrayList<>();
+ private final HashSet<String> mLocalZones = new HashSet<>();
+ private final Date mNow = Calendar.getInstance().getTime();
+ private final SimpleDateFormat mZoneNameFormatter = new SimpleDateFormat("zzzz");
+
+ public List<HashMap<String, Object>> getZones(Context context) {
+ for (String olsonId : TimeZoneNames.forLocale(Locale.getDefault())) {
+ mLocalZones.add(olsonId);
+ }
+ try {
+ XmlResourceParser xrp = context.getResources().getXml(R.xml.timezones);
+ while (xrp.next() != XmlResourceParser.START_TAG) {
+ continue;
+ }
+ xrp.next();
+ while (xrp.getEventType() != XmlResourceParser.END_TAG) {
+ while (xrp.getEventType() != XmlResourceParser.START_TAG) {
+ if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
+ return mZones;
+ }
+ xrp.next();
+ }
+ if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
+ String olsonId = xrp.getAttributeValue(0);
+ addTimeZone(olsonId);
+ }
+ while (xrp.getEventType() != XmlResourceParser.END_TAG) {
+ xrp.next();
+ }
+ xrp.next();
+ }
+ xrp.close();
+ } catch (XmlPullParserException xppe) {
+ Log.e(TAG, "Ill-formatted timezones.xml file");
+ } catch (java.io.IOException ioe) {
+ Log.e(TAG, "Unable to read timezones.xml file");
+ }
+ return mZones;
+ }
+
+ private void addTimeZone(String olsonId) {
+ // We always need the "GMT-07:00" string.
+ final TimeZone tz = TimeZone.getTimeZone(olsonId);
+
+ // For the display name, we treat time zones within the country differently
+ // from other countries' time zones. So in en_US you'd get "Pacific Daylight Time"
+ // but in de_DE you'd get "Los Angeles" for the same time zone.
+ String displayName;
+ if (mLocalZones.contains(olsonId)) {
+ // Within a country, we just use the local name for the time zone.
+ mZoneNameFormatter.setTimeZone(tz);
+ displayName = mZoneNameFormatter.format(mNow);
+ } else {
+ // For other countries' time zones, we use the exemplar location.
+ final String localeName = Locale.getDefault().toString();
+ displayName = TimeZoneNames.getExemplarLocation(localeName, olsonId);
+ }
+
+ final HashMap<String, Object> map = new HashMap<>();
+ map.put(KEY_ID, olsonId);
+ map.put(KEY_DISPLAYNAME, displayName);
+ map.put(KEY_GMT, getTimeZoneText(tz, false));
+ map.put(KEY_OFFSET, tz.getOffset(mNow.getTime()));
+
+ mZones.add(map);
+ }
+
+ public static String getTimeZoneText(TimeZone tz, boolean includeName) {
+ Date now = new Date();
+
+ // Use SimpleDateFormat to format the GMT+00:00 string.
+ SimpleDateFormat gmtFormatter = new SimpleDateFormat("ZZZZ");
+ gmtFormatter.setTimeZone(tz);
+ String gmtString = gmtFormatter.format(now);
+
+ // Ensure that the "GMT+" stays with the "00:00" even if the digits are RTL.
+ BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+ Locale l = Locale.getDefault();
+ boolean isRtl = TextUtils.getLayoutDirectionFromLocale(l) == View.LAYOUT_DIRECTION_RTL;
+ gmtString = bidiFormatter.unicodeWrap(gmtString,
+ isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR);
+
+ if (!includeName) {
+ return gmtString;
+ }
+
+ // Optionally append the time zone name.
+ SimpleDateFormat zoneNameFormatter = new SimpleDateFormat("zzzz");
+ zoneNameFormatter.setTimeZone(tz);
+ String zoneNameString = zoneNameFormatter.format(now);
+
+ // We don't use punctuation here to avoid having to worry about localizing that too!
+ return gmtString + " " + zoneNameString;
+ }
+}
diff --git a/packages/SettingsProvider/res/values-az-rAZ/defaults.xml b/packages/SettingsProvider/res/values-az-rAZ/defaults.xml
new file mode 100644
index 0000000..22443a5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-az-rAZ/defaults.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+ <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 62e0f3d..18a19cb 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -307,7 +307,7 @@
<dimen name="unlock_falsing_threshold">80dp</dimen>
<!-- Lockscreen falsing threshold for quick settings. -->
- <dimen name="qs_falsing_threshold">40dp</dimen>
+ <dimen name="qs_falsing_threshold">60dp</dimen>
<!-- Falsing threshold used when dismissing notifications from the lockscreen. -->
<dimen name="swipe_helper_falsing_threshold">70dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f1bbb0d..5b1a5b3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1025,6 +1025,12 @@
<!-- Name of special SystemUI debug settings -->
<string name="system_ui_tuner">System UI tuner</string>
+ <!-- Preference to show/hide embedded battery percentage [CHAR LIMIT=50] -->
+ <string name="show_battery_percentage">Show embedded battery percentage</string>
+
+ <!-- Summary for battery percentage preference [CHAR LIMIT=NONE] -->
+ <string name="show_battery_percentage_summary">Show battery level percentage inside the status bar icon when not charging</string>
+
<!-- Name of quick settings -->
<string name="quick_settings">Quick Settings</string>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index deb3f4f..135cc82 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -17,10 +17,14 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/system_ui_tuner">
- <!-- Tuner prefs go here -->
-
<Preference
android:key="qs_tuner"
android:title="@string/quick_settings" />
+ <SwitchPreference
+ android:key="battery_pct"
+ android:title="@string/show_battery_percentage"
+ android:summary="@string/show_battery_percentage_summary"
+ android:persistent="false" />
+
</PreferenceScreen>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 0d331d1..95b58e5 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -23,16 +23,17 @@
import android.content.IntentFilter;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.Typeface;
+import android.net.Uri;
import android.os.BatteryManager;
import android.os.Bundle;
+import android.os.Handler;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
@@ -43,10 +44,9 @@
BatteryController.BatteryStateChangeCallback {
public static final String TAG = BatteryMeterView.class.getSimpleName();
public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
+ public static final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";
- private static final boolean ENABLE_PERCENT = true;
private static final boolean SINGLE_DIGIT_PERCENT = false;
- private static final boolean SHOW_100_PERCENT = false;
private static final int FULL = 96;
@@ -54,7 +54,7 @@
private final int[] mColors;
- boolean mShowPercent = true;
+ private boolean mShowPercent;
private float mButtonHeightFraction;
private float mSubpixelSmoothingLeft;
private float mSubpixelSmoothingRight;
@@ -87,103 +87,8 @@
private int mLightModeBackgroundColor;
private int mLightModeFillColor;
- private class BatteryTracker extends BroadcastReceiver {
- public static final int UNKNOWN_LEVEL = -1;
-
- // current battery status
- int level = UNKNOWN_LEVEL;
- String percentStr;
- int plugType;
- boolean plugged;
- int health;
- int status;
- String technology;
- int voltage;
- int temperature;
- boolean testmode = false;
-
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- if (testmode && ! intent.getBooleanExtra("testmode", false)) return;
-
- level = (int)(100f
- * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
- / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
-
- plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
- plugged = plugType != 0;
- health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH,
- BatteryManager.BATTERY_HEALTH_UNKNOWN);
- status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
- BatteryManager.BATTERY_STATUS_UNKNOWN);
- technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
- voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
- temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
-
- setContentDescription(
- context.getString(R.string.accessibility_battery_level, level));
- postInvalidate();
- } else if (action.equals(ACTION_LEVEL_TEST)) {
- testmode = true;
- post(new Runnable() {
- int curLevel = 0;
- int incr = 1;
- int saveLevel = level;
- int savePlugged = plugType;
- Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
- @Override
- public void run() {
- if (curLevel < 0) {
- testmode = false;
- dummy.putExtra("level", saveLevel);
- dummy.putExtra("plugged", savePlugged);
- dummy.putExtra("testmode", false);
- } else {
- dummy.putExtra("level", curLevel);
- dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC : 0);
- dummy.putExtra("testmode", true);
- }
- getContext().sendBroadcast(dummy);
-
- if (!testmode) return;
-
- curLevel += incr;
- if (curLevel == 100) {
- incr *= -1;
- }
- postDelayed(this, 200);
- }
- });
- }
- }
- }
-
- BatteryTracker mTracker = new BatteryTracker();
-
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_BATTERY_CHANGED);
- filter.addAction(ACTION_LEVEL_TEST);
- final Intent sticky = getContext().registerReceiver(mTracker, filter);
- if (sticky != null) {
- // preload the battery level
- mTracker.onReceive(getContext(), sticky);
- }
- mBatteryController.addStateChangedCallback(this);
- }
-
- @Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
- getContext().unregisterReceiver(mTracker);
- mBatteryController.removeStateChangedCallback(this);
- }
+ private BatteryTracker mTracker = new BatteryTracker();
+ private final SettingObserver mSettingObserver = new SettingObserver();
public BatteryMeterView(Context context) {
this(context, null, 0);
@@ -213,8 +118,7 @@
levels.recycle();
colors.recycle();
atts.recycle();
- mShowPercent = ENABLE_PERCENT && 0 != Settings.System.getInt(
- context.getContentResolver(), "status_bar_show_battery_percent", 0);
+ updateShowPercent();
mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
mCriticalLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -261,6 +165,32 @@
mLightModeFillColor = context.getColor(R.color.light_mode_icon_color_dual_tone_fill);
}
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(ACTION_LEVEL_TEST);
+ final Intent sticky = getContext().registerReceiver(mTracker, filter);
+ if (sticky != null) {
+ // preload the battery level
+ mTracker.onReceive(getContext(), sticky);
+ }
+ mBatteryController.addStateChangedCallback(this);
+ getContext().getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ getContext().unregisterReceiver(mTracker);
+ mBatteryController.removeStateChangedCallback(this);
+ getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
+ }
+
public void setBatteryController(BatteryController batteryController) {
mBatteryController = batteryController;
mPowerSaveEnabled = mBatteryController.isPowerSave();
@@ -300,6 +230,11 @@
mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
}
+ private void updateShowPercent() {
+ mShowPercent = 0 != Settings.System.getInt(getContext().getContentResolver(),
+ SHOW_PERCENT_SETTING, 0);
+ }
+
private int getColorForLevel(int percent) {
// If we are in power save mode, always use the normal color.
@@ -447,8 +382,7 @@
boolean pctOpaque = false;
float pctX = 0, pctY = 0;
String pctText = null;
- if (!tracker.plugged && level > mCriticalLevel && mShowPercent
- && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
+ if (!tracker.plugged && level > mCriticalLevel && mShowPercent) {
mTextPaint.setColor(getColorForLevel(level));
mTextPaint.setTextSize(height *
(SINGLE_DIGIT_PERCENT ? 0.75f
@@ -518,4 +452,92 @@
postInvalidate();
}
}
+
+ private final class BatteryTracker extends BroadcastReceiver {
+ public static final int UNKNOWN_LEVEL = -1;
+
+ // current battery status
+ int level = UNKNOWN_LEVEL;
+ String percentStr;
+ int plugType;
+ boolean plugged;
+ int health;
+ int status;
+ String technology;
+ int voltage;
+ int temperature;
+ boolean testmode = false;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ if (testmode && ! intent.getBooleanExtra("testmode", false)) return;
+
+ level = (int)(100f
+ * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
+ / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+
+ plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+ plugged = plugType != 0;
+ health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH,
+ BatteryManager.BATTERY_HEALTH_UNKNOWN);
+ status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
+ voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
+ temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
+
+ setContentDescription(
+ context.getString(R.string.accessibility_battery_level, level));
+ postInvalidate();
+ } else if (action.equals(ACTION_LEVEL_TEST)) {
+ testmode = true;
+ post(new Runnable() {
+ int curLevel = 0;
+ int incr = 1;
+ int saveLevel = level;
+ int savePlugged = plugType;
+ Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
+ @Override
+ public void run() {
+ if (curLevel < 0) {
+ testmode = false;
+ dummy.putExtra("level", saveLevel);
+ dummy.putExtra("plugged", savePlugged);
+ dummy.putExtra("testmode", false);
+ } else {
+ dummy.putExtra("level", curLevel);
+ dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
+ : 0);
+ dummy.putExtra("testmode", true);
+ }
+ getContext().sendBroadcast(dummy);
+
+ if (!testmode) return;
+
+ curLevel += incr;
+ if (curLevel == 100) {
+ incr *= -1;
+ }
+ postDelayed(this, 200);
+ }
+ });
+ }
+ }
+ }
+
+ private final class SettingObserver extends ContentObserver {
+ public SettingObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ updateShowPercent();
+ postInvalidate();
+ }
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
index 5cf0813..90c1897 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
@@ -160,7 +160,7 @@
else if (spec.equals("bt")) return R.string.quick_settings_bluetooth_label;
else if (spec.equals("inversion")) return R.string.quick_settings_inversion_label;
else if (spec.equals("cell")) return R.string.quick_settings_cellular_detail_title;
- else if (spec.equals("airplane")) return R.string.quick_settings_airplane_mode_label;
+ else if (spec.equals("airplane")) return R.string.airplane_mode;
else if (spec.equals("dnd")) return R.string.quick_settings_dnd_label;
else if (spec.equals("rotation")) return R.string.quick_settings_rotation_locked_label;
else if (spec.equals("flashlight")) return R.string.quick_settings_flashlight_label;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 457bade..b40adaf 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -15,11 +15,19 @@
*/
package com.android.systemui.tuner;
+import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING;
+
import android.app.FragmentTransaction;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
+import android.preference.SwitchPreference;
+import android.provider.Settings.System;
import android.view.MenuItem;
import com.android.systemui.R;
@@ -27,6 +35,11 @@
public class TunerFragment extends PreferenceFragment {
private static final String KEY_QS_TUNER = "qs_tuner";
+ private static final String KEY_BATTERY_PCT = "battery_pct";
+
+ private final SettingObserver mSettingObserver = new SettingObserver();
+
+ private SwitchPreference mBatteryPct;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -45,6 +58,21 @@
return false;
}
});
+ mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateBatteryPct();
+ getContext().getContentResolver().registerContentObserver(
+ System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
}
@Override
@@ -57,4 +85,31 @@
return super.onOptionsItemSelected(item);
}
+ private void updateBatteryPct() {
+ mBatteryPct.setOnPreferenceChangeListener(null);
+ mBatteryPct.setChecked(System.getInt(getContext().getContentResolver(),
+ SHOW_PERCENT_SETTING, 0) != 0);
+ mBatteryPct.setOnPreferenceChangeListener(mBatteryPctChange);
+ }
+
+ private final class SettingObserver extends ContentObserver {
+ public SettingObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ super.onChange(selfChange, uri, userId);
+ updateBatteryPct();
+ }
+ }
+
+ private final OnPreferenceChangeListener mBatteryPctChange = new OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean v = (Boolean) newValue;
+ System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
+ return true;
+ }
+ };
}
diff --git a/services/core/java/com/android/server/location/LocationBasedCountryDetector.java b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java
index 03db621..6527899f 100644
--- a/services/core/java/com/android/server/location/LocationBasedCountryDetector.java
+++ b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java
@@ -23,6 +23,7 @@
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
+import android.os.Binder;
import android.os.Bundle;
import android.util.Slog;
@@ -95,33 +96,48 @@
* Register a listener with a provider name
*/
protected void registerListener(String provider, LocationListener listener) {
- mLocationManager.requestLocationUpdates(provider, 0, 0, listener);
+ final long bid = Binder.clearCallingIdentity();
+ try {
+ mLocationManager.requestLocationUpdates(provider, 0, 0, listener);
+ } finally {
+ Binder.restoreCallingIdentity(bid);
+ }
}
/**
* Unregister an already registered listener
*/
protected void unregisterListener(LocationListener listener) {
- mLocationManager.removeUpdates(listener);
+ final long bid = Binder.clearCallingIdentity();
+ try {
+ mLocationManager.removeUpdates(listener);
+ } finally {
+ Binder.restoreCallingIdentity(bid);
+ }
}
/**
* @return the last known location from all providers
*/
protected Location getLastKnownLocation() {
- List<String> providers = mLocationManager.getAllProviders();
- Location bestLocation = null;
- for (String provider : providers) {
- Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
- if (lastKnownLocation != null) {
- if (bestLocation == null ||
- bestLocation.getElapsedRealtimeNanos() <
- lastKnownLocation.getElapsedRealtimeNanos()) {
- bestLocation = lastKnownLocation;
+ final long bid = Binder.clearCallingIdentity();
+ try {
+ List<String> providers = mLocationManager.getAllProviders();
+ Location bestLocation = null;
+ for (String provider : providers) {
+ Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
+ if (lastKnownLocation != null) {
+ if (bestLocation == null ||
+ bestLocation.getElapsedRealtimeNanos() <
+ lastKnownLocation.getElapsedRealtimeNanos()) {
+ bestLocation = lastKnownLocation;
+ }
}
}
+ return bestLocation;
+ } finally {
+ Binder.restoreCallingIdentity(bid);
}
- return bestLocation;
}
/**
diff --git a/services/core/java/com/android/server/notification/CalendarTracker.java b/services/core/java/com/android/server/notification/CalendarTracker.java
index de321fe..783b16f 100644
--- a/services/core/java/com/android/server/notification/CalendarTracker.java
+++ b/services/core/java/com/android/server/notification/CalendarTracker.java
@@ -16,8 +16,6 @@
package com.android.server.notification;
-import static android.service.notification.ZenModeConfig.EventInfo.ANY_CALENDAR;
-
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
@@ -183,7 +181,7 @@
calendarPrimary));
final boolean meetsTime = time >= begin && time < end;
final boolean meetsCalendar = calendarVisible && calendarPrimary
- && (filter.calendar == ANY_CALENDAR || filter.calendar == calendarId);
+ && (filter.calendar == null || Objects.equals(filter.calendar, owner));
final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE;
if (meetsCalendar && meetsAvailability) {
if (DEBUG) Log.d(TAG, " MEETS CALENDAR & AVAILABILITY");
diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java
index 46cc47b..88ef366 100644
--- a/services/core/java/com/android/server/notification/EventConditionProvider.java
+++ b/services/core/java/com/android/server/notification/EventConditionProvider.java
@@ -211,7 +211,7 @@
continue;
}
CheckEventResult result = null;
- if (event.calendar == EventInfo.ANY_CALENDAR) {
+ if (event.calendar == null) { // any calendar
// event could exist on any tracker
for (int i = 0; i < mTrackers.size(); i++) {
final CalendarTracker tracker = mTrackers.valueAt(i);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 755b2ea..efc447e 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -265,6 +265,13 @@
return;
}
config.manualRule = null; // don't restore the manual rule
+ if (config.automaticRules != null) {
+ for (ZenModeConfig.ZenRule automaticRule : config.automaticRules.values()) {
+ // don't restore transient state from restored automatic rules
+ automaticRule.snoozing = false;
+ automaticRule.condition = null;
+ }
+ }
}
if (DEBUG) Log.d(TAG, "readXml");
setConfig(config, "readXml");
@@ -498,7 +505,7 @@
if (config == null) return;
final EventInfo events = new EventInfo();
- events.calendar = EventInfo.ANY_CALENDAR;
+ events.calendar = null; // any calendar
events.reply = EventInfo.REPLY_YES_OR_MAYBE;
final ZenRule rule = new ZenRule();
rule.enabled = false;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3531796..f9bfe72 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -303,6 +303,7 @@
static final int SCAN_TRUSTED_OVERLAY = 1<<9;
static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
static final int SCAN_REQUIRE_KNOWN = 1<<12;
+ static final int SCAN_MOVE = 1<<13;
static final int REMOVE_CHATTY = 1<<16;
@@ -6347,16 +6348,19 @@
if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
} else {
- // TODO: We need this second call to derive in two cases :
- //
- // - To update the native library paths based on the final install location.
- // - We don't call dexopt when moving packages, and so we have to scan again.
- //
- // We can simplify this and avoid having to scan the package again by letting
- // scanPackageLI know if the current install was a move (and deriving things only
- // in that case) and by "reparenting" the native lib directory in the case of
- // a normal (non-move) install.
- deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, false /* extract libs */);
+ if ((scanFlags & SCAN_MOVE) != 0) {
+ // We haven't run dex-opt for this move (since we've moved the compiled output too)
+ // but we already have this packages package info in the PackageSetting. We just
+ // use that and derive the native library path based on the new codepath.
+ pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
+ pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
+ }
+
+ // Set native library paths again. For moves, the path will be updated based on the
+ // ABIs we've determined above. For non-moves, the path will be updated based on the
+ // ABIs we determined during compilation, but the path will depend on the final
+ // package path (after the rename away from the stage path).
+ setNativeLibraryPaths(pkg);
}
if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
@@ -11645,6 +11649,7 @@
if (args.move != null) {
// We did an in-place move, so dex is ready to roll
scanFlags |= SCAN_NO_DEX;
+ scanFlags |= SCAN_MOVE;
} else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
// Enable SCAN_NO_DEX flag to skip dexopt at a later stage
scanFlags |= SCAN_NO_DEX;
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 85dd9d4..e5981fb 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -238,7 +238,7 @@
// throw up an indeterminate system dialog to indicate radio is
// shutting down.
ProgressDialog pd = new ProgressDialog(context);
- if (mRebootReason.equals(PowerManager.REBOOT_RECOVERY)) {
+ if (PowerManager.REBOOT_RECOVERY.equals(mRebootReason)) {
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_recovery_title));
} else {
pd.setTitle(context.getText(com.android.internal.R.string.power_off));
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 145c993..4cf741d 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -69,9 +69,7 @@
/**
* The {@link android.content.Intent} action used to configure a
* {@link android.telecom.ConnectionService}.
- * @hide
*/
- @SystemApi
public static final String ACTION_CONNECTION_SERVICE_CONFIGURE =
"android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index aae3ff6..a41875f 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2351,12 +2351,12 @@
*
* @param s A {@code Spannable} to annotate.
* @param start The starting character position of the phone number in {@code s}.
- * @param end The ending character position of the phone number in {@code s}.
+ * @param endExclusive The position after the ending character in the phone number {@code s}.
*/
- public static void addPhoneTtsSpan(Spannable s, int start, int end) {
- s.setSpan(getPhoneTtsSpan(s.subSequence(start, end).toString()),
+ public static void addPhoneTtsSpan(Spannable s, int start, int endExclusive) {
+ s.setSpan(getPhoneTtsSpan(s.subSequence(start, endExclusive).toString()),
start,
- end,
+ endExclusive,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}