Merge "Introduce SuggestionSpan#getLocaleObject()."
diff --git a/api/current.txt b/api/current.txt
index 358d4d5..05c40d1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -38229,7 +38229,8 @@
ctor public SuggestionSpan(android.os.Parcel);
method public int describeContents();
method public int getFlags();
- method public java.lang.String getLocale();
+ method public deprecated java.lang.String getLocale();
+ method public java.util.Locale getLocaleObject();
method public int getSpanTypeId();
method public java.lang.String[] getSuggestions();
method public void setFlags(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 9b66945..fb47833 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -40588,7 +40588,8 @@
ctor public SuggestionSpan(android.os.Parcel);
method public int describeContents();
method public int getFlags();
- method public java.lang.String getLocale();
+ method public deprecated java.lang.String getLocale();
+ method public java.util.Locale getLocaleObject();
method public int getSpanTypeId();
method public java.lang.String[] getSuggestions();
method public void setFlags(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 41a77b3..3fb9b5f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -38245,7 +38245,8 @@
ctor public SuggestionSpan(android.os.Parcel);
method public int describeContents();
method public int getFlags();
- method public java.lang.String getLocale();
+ method public deprecated java.lang.String getLocale();
+ method public java.util.Locale getLocaleObject();
method public int getSpanTypeId();
method public java.lang.String[] getSuggestions();
method public void setFlags(int);
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 6b449f9..1b00db2 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -16,6 +16,8 @@
package android.text.style;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
@@ -84,7 +86,15 @@
private int mFlags;
private final String[] mSuggestions;
- private final String mLocaleString;
+ /**
+ * Kept for compatibility for apps that rely on invalid locale strings e.g.
+ * {@code new Locale(" an ", " i n v a l i d ", "data")}, which cannot be handled by
+ * {@link #mLanguageTag}.
+ */
+ @NonNull
+ private final String mLocaleStringForCompatibility;
+ @NonNull
+ private final String mLanguageTag;
private final String mNotificationTargetClassName;
private final String mNotificationTargetPackageName;
private final int mHashCode;
@@ -130,14 +140,18 @@
final int N = Math.min(SUGGESTIONS_MAX_SIZE, suggestions.length);
mSuggestions = Arrays.copyOf(suggestions, N);
mFlags = flags;
+ final Locale sourceLocale;
if (locale != null) {
- mLocaleString = locale.toString();
+ sourceLocale = locale;
} else if (context != null) {
- mLocaleString = context.getResources().getConfiguration().locale.toString();
+ // TODO: Consider to context.getResources().getResolvedLocale() instead.
+ sourceLocale = context.getResources().getConfiguration().locale;
} else {
Log.e("SuggestionSpan", "No locale or context specified in SuggestionSpan constructor");
- mLocaleString = "";
+ sourceLocale = null;
}
+ mLocaleStringForCompatibility = sourceLocale == null ? "" : sourceLocale.toString();
+ mLanguageTag = sourceLocale == null ? "" : sourceLocale.toLanguageTag();
if (context != null) {
mNotificationTargetPackageName = context.getPackageName();
@@ -150,7 +164,8 @@
} else {
mNotificationTargetClassName = "";
}
- mHashCode = hashCodeInternal(mSuggestions, mLocaleString, mNotificationTargetClassName);
+ mHashCode = hashCodeInternal(mSuggestions, mLanguageTag, mLocaleStringForCompatibility,
+ mNotificationTargetClassName);
initStyle(context);
}
@@ -194,7 +209,8 @@
public SuggestionSpan(Parcel src) {
mSuggestions = src.readStringArray();
mFlags = src.readInt();
- mLocaleString = src.readString();
+ mLocaleStringForCompatibility = src.readString();
+ mLanguageTag = src.readString();
mNotificationTargetClassName = src.readString();
mNotificationTargetPackageName = src.readString();
mHashCode = src.readInt();
@@ -214,10 +230,29 @@
}
/**
- * @return the locale of the suggestions
+ * @deprecated use {@link #getLocaleObject()} instead.
+ * @return the locale of the suggestions. An empty string is returned if no locale is specified.
*/
+ @NonNull
+ @Deprecated
public String getLocale() {
- return mLocaleString;
+ return mLocaleStringForCompatibility;
+ }
+
+ /**
+ * Returns a well-formed BCP 47 language tag representation of the suggestions, as a
+ * {@link Locale} object.
+ *
+ * <p><b>Caveat</b>: The returned object is guaranteed to be a a well-formed BCP 47 language tag
+ * representation. For example, this method can return an empty locale rather than returning a
+ * malformed data when this object is initialized with an malformed {@link Locale} object, e.g.
+ * {@code new Locale(" a ", " b c d ", " "}.</p>
+ *
+ * @return the locale of the suggestions. {@code null} is returned if no locale is specified.
+ */
+ @Nullable
+ public Locale getLocaleObject() {
+ return mLanguageTag.isEmpty() ? null : Locale.forLanguageTag(mLanguageTag);
}
/**
@@ -255,7 +290,8 @@
public void writeToParcelInternal(Parcel dest, int flags) {
dest.writeStringArray(mSuggestions);
dest.writeInt(mFlags);
- dest.writeString(mLocaleString);
+ dest.writeString(mLocaleStringForCompatibility);
+ dest.writeString(mLanguageTag);
dest.writeString(mNotificationTargetClassName);
dest.writeString(mNotificationTargetPackageName);
dest.writeInt(mHashCode);
@@ -290,10 +326,10 @@
return mHashCode;
}
- private static int hashCodeInternal(String[] suggestions, String locale,
- String notificationTargetClassName) {
+ private static int hashCodeInternal(String[] suggestions, @NonNull String languageTag,
+ @NonNull String localeStringForCompatibility, String notificationTargetClassName) {
return Arrays.hashCode(new Object[] {Long.valueOf(SystemClock.uptimeMillis()), suggestions,
- locale, notificationTargetClassName});
+ languageTag, localeStringForCompatibility, notificationTargetClassName});
}
public static final Parcelable.Creator<SuggestionSpan> CREATOR =