Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +72 −5 Original line number Diff line number Diff line Loading @@ -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 **/ Loading Loading @@ -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); } Loading Loading @@ -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. } Loading @@ -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 Loading packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java +31 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +72 −5 Original line number Diff line number Diff line Loading @@ -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 **/ Loading Loading @@ -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); } Loading Loading @@ -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. } Loading @@ -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 Loading
packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java +31 −1 Original line number Diff line number Diff line Loading @@ -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 Loading