summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java77
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java32
2 files changed, 103 insertions, 6 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 6d375ac215a4..48259e165670 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -46,12 +46,16 @@ import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManage
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
+import java.util.Set;
public class SettingsHelper {
private static final String TAG = "SettingsHelper";
private static final String SILENT_RINGTONE = "_silent";
private static final String SETTINGS_REPLACED_KEY = "backup_skip_user_facing_data";
private static final String SETTING_ORIGINAL_KEY_SUFFIX = "_original";
+ private static final String UNICODE_LOCALE_EXTENSION_FW = "fw";
+ private static final String UNICODE_LOCALE_EXTENSION_MU = "mu";
+ private static final String UNICODE_LOCALE_EXTENSION_NU = "nu";
private static final float FLOAT_TOLERANCE = 0.01f;
/** See frameworks/base/core/res/res/values/config.xml#config_longPressOnPowerBehavior **/
@@ -97,6 +101,25 @@ public class SettingsHelper {
sBroadcastOnRestoreSystemUI.add(Settings.Secure.QS_AUTO_ADDED_TILES);
}
+ private static final ArraySet<String> UNICODE_LOCALE_SUPPORTED_EXTENSIONS = new ArraySet<>();
+
+ /**
+ * Current supported extensions are fw (first day of week) and mu (temperature unit) extension.
+ * User can set these extensions in Settings app, and it will be appended to the locale,
+ * for example: zh-Hant-TW-u-fw-mon-mu-celsius. So after the factory reset, these extensions
+ * should be restored as well because they are set by users.
+ * We do not put the nu (numbering system) extension here because it is an Android supported
+ * extension and defined in some particular locales, for example:
+ * ar-Arab-MA-u-nu-arab and ar-Arab-YE-u-nu-latn. See
+ * <code>frameworks/base/core/res/res/values/locale_config.xml</code>
+ * The nu extension should not be appended to the current/restored locale after factory reset
+ * if the current/restored locale does not have it.
+ */
+ static {
+ UNICODE_LOCALE_SUPPORTED_EXTENSIONS.add(UNICODE_LOCALE_EXTENSION_FW);
+ UNICODE_LOCALE_SUPPORTED_EXTENSIONS.add(UNICODE_LOCALE_EXTENSION_MU);
+ }
+
private interface SettingsLookup {
public String lookup(ContentResolver resolver, String name, int userHandle);
}
@@ -500,20 +523,25 @@ public class SettingsHelper {
allLocales.put(toFullLocale(locale), locale);
}
+ // After restoring to reset locales, need to get extensions from restored locale. Get the
+ // first restored locale to check its extension.
+ final Locale restoredLocale = restore.isEmpty()
+ ? Locale.ROOT
+ : restore.get(0);
final ArrayList<Locale> filtered = new ArrayList<>(current.size());
for (int i = 0; i < current.size(); i++) {
- final Locale locale = current.get(i);
+ Locale locale = copyExtensionToTargetLocale(restoredLocale, current.get(i));
allLocales.remove(toFullLocale(locale));
filtered.add(locale);
}
for (int i = 0; i < restore.size(); i++) {
- final Locale locale = allLocales.remove(toFullLocale(restore.get(i)));
- if (locale != null) {
- filtered.add(locale);
+ final Locale restoredLocaleWithExtension = copyExtensionToTargetLocale(restoredLocale,
+ getFilteredLocale(restore.get(i), allLocales));
+ if (restoredLocaleWithExtension != null) {
+ filtered.add(restoredLocaleWithExtension);
}
}
-
if (filtered.size() == current.size()) {
return current; // Nothing added to current locale list.
}
@@ -521,6 +549,45 @@ public class SettingsHelper {
return new LocaleList(filtered.toArray(new Locale[filtered.size()]));
}
+ private static Locale copyExtensionToTargetLocale(Locale restoredLocale,
+ Locale targetLocale) {
+ if (!restoredLocale.hasExtensions()) {
+ return targetLocale;
+ }
+
+ if (targetLocale == null) {
+ return null;
+ }
+
+ Locale.Builder builder = new Locale.Builder()
+ .setLocale(targetLocale);
+ Set<String> unicodeLocaleKeys = restoredLocale.getUnicodeLocaleKeys();
+ unicodeLocaleKeys.stream().forEach(key -> {
+ // Copy all supported extensions from restored locales except "nu" extension. The "nu"
+ // extension has been added in #getFilteredLocale(Locale, HashMap<Locale, Locale>)
+ // already, we don't need to add it again.
+ if (UNICODE_LOCALE_SUPPORTED_EXTENSIONS.contains(key)) {
+ builder.setUnicodeLocaleKeyword(key, restoredLocale.getUnicodeLocaleType(key));
+ }
+ });
+ return builder.build();
+ }
+
+ private static Locale getFilteredLocale(Locale restoreLocale,
+ HashMap<Locale, Locale> allLocales) {
+ Locale locale = allLocales.remove(toFullLocale(restoreLocale));
+ if (locale != null) {
+ return locale;
+ }
+
+ Locale filteredLocale = new Locale.Builder()
+ .setLocale(restoreLocale.stripExtensions())
+ .setUnicodeLocaleKeyword(UNICODE_LOCALE_EXTENSION_NU,
+ restoreLocale.getUnicodeLocaleType(UNICODE_LOCALE_EXTENSION_NU))
+ .build();
+ return allLocales.remove(toFullLocale(filteredLocale));
+ }
+
/**
* Sets the locale specified. Input data is the byte representation of comma separated
* multiple BCP-47 language tags. For backwards compatibility, strings of the form
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
index ee76dbf8ce70..bc81c4441af5 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
@@ -299,12 +299,42 @@ public class SettingsHelperTest {
LocaleList.forLanguageTags("en-US"), // current
new String[] { "en-US", "zh-Hans-CN" })); // supported
- // Old langauge code should be updated.
+ // Old language code should be updated.
assertEquals(LocaleList.forLanguageTags("en-US,he-IL,id-ID,yi"),
SettingsHelper.resolveLocales(
LocaleList.forLanguageTags("iw-IL,in-ID,ji"), // restore
LocaleList.forLanguageTags("en-US"), // current
new String[] { "he-IL", "id-ID", "yi" })); // supported
+
+ // No matter the current locale has "nu" extension or not, if the restored locale has fw
+ // (first day of week) or mu(temperature unit) extension, we should restore fw or mu
+ // extensions as well and append these to restore and current locales.
+ assertEquals(LocaleList.forLanguageTags(
+ "en-US-u-fw-mon-mu-celsius,zh-Hant-TW-u-fw-mon-mu-celsius"),
+ SettingsHelper.resolveLocales(
+ LocaleList.forLanguageTags("zh-Hant-TW-u-fw-mon-mu-celsius"), // restore
+ LocaleList.forLanguageTags("en-US"), // current
+ new String[] { "en-US", "zh-Hant-TW" })); // supported
+
+ // No matter the current locale has "nu" extension or not, if the restored locale has fw
+ // (first day of week) or mu(temperature unit) extension, we should restore fw or mu
+ // extensions as well and append these to restore and current locales.
+ assertEquals(LocaleList.forLanguageTags(
+ "fa-Arab-AF-u-nu-latn-fw-mon-mu-celsius,zh-Hant-TW-u-fw-mon-mu-celsius"),
+ SettingsHelper.resolveLocales(
+ LocaleList.forLanguageTags("zh-Hant-TW-u-fw-mon-mu-celsius"), // restore
+ LocaleList.forLanguageTags("fa-Arab-AF-u-nu-latn"), // current
+ new String[] { "fa-Arab-AF-u-nu-latn", "zh-Hant-TW" })); // supported
+
+ // If the restored locale only has nu extension, we should not restore the nu extensions to
+ // current locales.
+ assertEquals(LocaleList.forLanguageTags("zh-Hant-TW,fa-Arab-AF-u-nu-latn"),
+ SettingsHelper.resolveLocales(
+ LocaleList.forLanguageTags("fa-Arab-AF-u-nu-latn"), // restore
+ LocaleList.forLanguageTags("zh-Hant-TW"), // current
+ new String[] { "fa-Arab-AF-u-nu-latn", "zh-Hant-TW" })); // supported
+
+
}
@Test