1501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master/* 2501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * Copyright (C) 2008 The Android Open Source Project 3501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * 4501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * Licensed under the Apache License, Version 2.0 (the "License"); 5501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * you may not use this file except in compliance with the License. 6501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * You may obtain a copy of the License at 7501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * 8501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * http://www.apache.org/licenses/LICENSE-2.0 9501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * 10501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * Unless required by applicable law or agreed to in writing, software 11501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * distributed under the License is distributed on an "AS IS" BASIS, 12501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * See the License for the specific language governing permissions and 14501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master * limitations under the License. 15501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master */ 16501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master 17501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterpackage com.android.providers.settings; 18501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master 190f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport com.android.internal.R; 200f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport com.android.internal.app.LocalePicker; 210f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport com.android.internal.annotations.VisibleForTesting; 220f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 230f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport android.annotation.NonNull; 24dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shankaimport android.app.ActivityManager; 258823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasaniimport android.app.IActivityManager; 264528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IBackupManager; 276597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.content.ContentResolver; 286597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.content.ContentValues; 29501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.content.Context; 306597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.content.Intent; 318823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasaniimport android.content.res.Configuration; 320f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport android.icu.util.ULocale; 3370c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasaniimport android.location.LocationManager; 34501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.media.AudioManager; 35622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasaniimport android.media.RingtoneManager; 36622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasaniimport android.net.Uri; 37237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwoodimport android.os.IPowerManager; 380f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport android.os.LocaleList; 39501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.os.RemoteException; 40501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.os.ServiceManager; 416597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.os.UserHandle; 426794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthallimport android.os.UserManager; 43501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.provider.Settings; 448fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paulimport android.telephony.TelephonyManager; 458823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasaniimport android.text.TextUtils; 466597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.util.ArraySet; 4745d17581844df55cfc85117819e41c33eb40ad96Christopher Tateimport android.util.Slog; 48501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master 490f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport java.util.ArrayList; 500f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport java.util.HashMap; 510f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonakaimport java.util.List; 526794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthallimport java.util.Locale; 536794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall 54501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterpublic class SettingsHelper { 5545d17581844df55cfc85117819e41c33eb40ad96Christopher Tate private static final String TAG = "SettingsHelper"; 56622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani private static final String SILENT_RINGTONE = "_silent"; 57501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master private Context mContext; 58501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master private AudioManager mAudioManager; 598fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul private TelephonyManager mTelephonyManager; 6070c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani 616597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate /** 626597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * A few settings elements are special in that a restore of those values needs to 636597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * be post-processed by relevant parts of the OS. A restore of any settings element 646597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * mentioned in this table will therefore cause the system to send a broadcast with 656597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * the {@link Intent#ACTION_SETTING_RESTORED} action, with extras naming the 666597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * affected setting and supplying its pre-restore value for comparison. 676597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * 686597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * @see Intent#ACTION_SETTING_RESTORED 696597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * @see System#SETTINGS_TO_BACKUP 706597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * @see Secure#SETTINGS_TO_BACKUP 716597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * @see Global#SETTINGS_TO_BACKUP 726597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * 736597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate * {@hide} 746597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate */ 756597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate private static final ArraySet<String> sBroadcastOnRestore; 766597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate static { 77767f05feea67e642a76bd3e2e7633a8f5273f077Stanley Tng sBroadcastOnRestore = new ArraySet<String>(5); 786597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); 79e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk sBroadcastOnRestore.add(Settings.Secure.ENABLED_VR_LISTENERS); 802d4aadca9487d76cb7220bdba90afa53119664eaChristopher Tate sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); 817b9a28c7f0a7b88ed1ea777edc05002d2d2b38b7Christopher Tate sBroadcastOnRestore.add(Settings.Secure.ENABLED_INPUT_METHODS); 82767f05feea67e642a76bd3e2e7633a8f5273f077Stanley Tng sBroadcastOnRestore.add(Settings.Global.BLUETOOTH_ON); 836597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 846597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 856597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate private interface SettingsLookup { 866597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate public String lookup(ContentResolver resolver, String name, int userHandle); 876597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 886597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 896597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate private static SettingsLookup sSystemLookup = new SettingsLookup() { 906597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate public String lookup(ContentResolver resolver, String name, int userHandle) { 916597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate return Settings.System.getStringForUser(resolver, name, userHandle); 926597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 936597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate }; 946597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 956597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate private static SettingsLookup sSecureLookup = new SettingsLookup() { 966597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate public String lookup(ContentResolver resolver, String name, int userHandle) { 976597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate return Settings.Secure.getStringForUser(resolver, name, userHandle); 986597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 996597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate }; 1006597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 1016597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate private static SettingsLookup sGlobalLookup = new SettingsLookup() { 1026597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate public String lookup(ContentResolver resolver, String name, int userHandle) { 1036597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate return Settings.Global.getStringForUser(resolver, name, userHandle); 1046597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 1056597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate }; 1066597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 107501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master public SettingsHelper(Context context) { 108501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master mContext = context; 109501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master mAudioManager = (AudioManager) context 110501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master .getSystemService(Context.AUDIO_SERVICE); 1118fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul mTelephonyManager = (TelephonyManager) context 1128fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul .getSystemService(Context.TELEPHONY_SERVICE); 113501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master } 114501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master 11570c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani /** 11670c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani * Sets the property via a call to the appropriate API, if any, and returns 11770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani * whether or not the setting should be saved to the database as well. 11870c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani * @param name the name of the setting 11970c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani * @param value the string value of the setting 12070c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani * @return whether to continue with writing the value to the database. In 12170c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani * some cases the data will be written by the call to the appropriate API, 12270c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani * and in some cases the property value needs to be modified before setting. 12370c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani */ 1246597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate public void restoreValue(Context context, ContentResolver cr, ContentValues contentValues, 1256135a265515801329c6df9ee2cf67e3b372f8d34Michal Karpinski Uri destination, String name, String value, int restoredFromSdkInt) { 1266597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // Will we need a post-restore broadcast for this element? 1276597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate String oldValue = null; 1286597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate boolean sendBroadcast = false; 1296597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate final SettingsLookup table; 1306597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 1316597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate if (destination.equals(Settings.Secure.CONTENT_URI)) { 1326597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate table = sSecureLookup; 1336597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } else if (destination.equals(Settings.System.CONTENT_URI)) { 1346597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate table = sSystemLookup; 1356597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } else { /* must be GLOBAL; this was preflighted by the caller */ 1366597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate table = sGlobalLookup; 1376597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 1386597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 1396597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate if (sBroadcastOnRestore.contains(name)) { 14043765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen // TODO: http://b/22388012 14143765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen oldValue = table.lookup(cr, name, UserHandle.USER_SYSTEM); 1426597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate sendBroadcast = true; 1436597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 1446597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 1456597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate try { 1466597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) { 1476597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate setBrightness(Integer.parseInt(value)); 1486597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // fall through to the ordinary write to settings 1496597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) { 1506597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate setSoundEffects(Integer.parseInt(value) == 1); 1516597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // fall through to the ordinary write to settings 1526597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) { 1536597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate setGpsLocation(value); 1546597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate return; 1556597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) { 1566597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate setAutoRestore(Integer.parseInt(value) == 1); 1576597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) { 1586597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate return; 1596597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } else if (Settings.System.RINGTONE.equals(name) 1606597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate || Settings.System.NOTIFICATION_SOUND.equals(name)) { 1616597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate setRingtone(name, value); 1626597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate return; 1636597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 1646597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate 1656597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // Default case: write the restored value to settings 1666597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate contentValues.clear(); 1676597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate contentValues.put(Settings.NameValueTable.NAME, name); 1686597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate contentValues.put(Settings.NameValueTable.VALUE, value); 1696597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate cr.insert(destination, contentValues); 1706597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } catch (Exception e) { 1716597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // If we fail to apply the setting, by definition nothing happened 1726597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate sendBroadcast = false; 1736597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } finally { 1746597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // If this was an element of interest, send the "we just restored it" 1756597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // broadcast with the historical value now that the new value has 1766597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate // been committed and observers kicked off. 1776597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate if (sendBroadcast) { 1786597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED) 1796597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate .setPackage("android").addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) 1806597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate .putExtra(Intent.EXTRA_SETTING_NAME, name) 1816597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, value) 1826135a265515801329c6df9ee2cf67e3b372f8d34Michal Karpinski .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue) 1836135a265515801329c6df9ee2cf67e3b372f8d34Michal Karpinski .putExtra(Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, restoredFromSdkInt); 184e4de5a0d3b6e0c897c1cea0912b58e11db962365Xiaohui Chen context.sendBroadcastAsUser(intent, UserHandle.SYSTEM, null); 1856597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate } 18670c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani } 18770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani } 18870c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani 189622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani public String onBackupValue(String name, String value) { 1908fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul // Special processing for backing up ringtones & notification sounds 191622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani if (Settings.System.RINGTONE.equals(name) 192622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani || Settings.System.NOTIFICATION_SOUND.equals(name)) { 193622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani if (value == null) { 1948fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul if (Settings.System.RINGTONE.equals(name)) { 1958fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul // For ringtones, we need to distinguish between non-telephony vs telephony 1968fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul if (mTelephonyManager != null && mTelephonyManager.isVoiceCapable()) { 1978fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul // Backup a null ringtone as silent on voice-capable devices 1988fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul return SILENT_RINGTONE; 1998fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul } else { 2008fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul // Skip backup of ringtone on non-telephony devices. 2018fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul return null; 2028fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul } 2038fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul } else { 2048fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul // Backup a null notification sound as silent 2058fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul return SILENT_RINGTONE; 2068fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul } 207622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } else { 208622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani return getCanonicalRingtoneValue(value); 209622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } 210622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } 211622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani // Return the original value 212622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani return value; 213622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } 214622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani 215622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani /** 216622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani * Sets the ringtone of type specified by the name. 217622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani * 218622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani * @param name should be Settings.System.RINGTONE or Settings.System.NOTIFICATION_SOUND. 219622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani * @param value can be a canonicalized uri or "_silent" to indicate a silent (null) ringtone. 220622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani */ 221622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani private void setRingtone(String name, String value) { 222622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani // If it's null, don't change the default 223622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani if (value == null) return; 224622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani Uri ringtoneUri = null; 225622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani if (SILENT_RINGTONE.equals(value)) { 226622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani ringtoneUri = null; 227622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } else { 228622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani Uri canonicalUri = Uri.parse(value); 229622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani ringtoneUri = mContext.getContentResolver().uncanonicalize(canonicalUri); 2302e804444d64bdf2763c682109c838a8372b17934Amith Yamasani if (ringtoneUri == null) { 2312e804444d64bdf2763c682109c838a8372b17934Amith Yamasani // Unrecognized or invalid Uri, don't restore 2322e804444d64bdf2763c682109c838a8372b17934Amith Yamasani return; 2332e804444d64bdf2763c682109c838a8372b17934Amith Yamasani } 234622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } 235622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani final int ringtoneType = Settings.System.RINGTONE.equals(name) 236622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani ? RingtoneManager.TYPE_RINGTONE : RingtoneManager.TYPE_NOTIFICATION; 237622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, ringtoneUri); 238622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } 239622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani 240622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani private String getCanonicalRingtoneValue(String value) { 241622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani final Uri ringtoneUri = Uri.parse(value); 242622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani final Uri canonicalUri = mContext.getContentResolver().canonicalize(ringtoneUri); 243622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani return canonicalUri == null ? null : canonicalUri.toString(); 244622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani } 245622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani 246818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov private boolean isAlreadyConfiguredCriticalAccessibilitySetting(String name) { 247fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza // These are the critical accessibility settings that are required for users with 248fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza // accessibility needs to be able to interact with the device. If these settings are 249818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov // already configured, we will not overwrite them. If they are already set, 250fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza // it means that the user has performed a global gesture to enable accessibility or set 251fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza // these settings in the Accessibility portion of the Setup Wizard, and definitely needs 252fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza // these features working after the restore. 25386b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt switch (name) { 25486b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.ACCESSIBILITY_ENABLED: 25586b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD: 25686b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.TOUCH_EXPLORATION_ENABLED: 25786b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED: 25886b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED: 25986b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.UI_NIGHT_MODE: 26086b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0; 26186b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES: 26286b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES: 26386b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER: 26486b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE: 26586b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt return !TextUtils.isEmpty(Settings.Secure.getString( 26686b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt mContext.getContentResolver(), name)); 26786b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt case Settings.System.FONT_SCALE: 26886b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt return Settings.System.getFloat(mContext.getContentResolver(), name, 1.0f) != 1.0f; 26986b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt default: 27086b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt return false; 271818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov } 272818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov } 273818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov 27403b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate private void setAutoRestore(boolean enabled) { 27503b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate try { 27603b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate IBackupManager bm = IBackupManager.Stub.asInterface( 27703b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate ServiceManager.getService(Context.BACKUP_SERVICE)); 27803b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate if (bm != null) { 27903b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate bm.setAutoRestore(enabled); 28003b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate } 28103b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate } catch (RemoteException e) {} 28203b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate } 28303b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate 28470c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani private void setGpsLocation(String value) { 2856794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 286a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall if (um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION)) { 2876794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall return; 2886794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall } 28970c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani final String GPS = LocationManager.GPS_PROVIDER; 290a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall boolean enabled = 29170c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani GPS.equals(value) || 29270c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani value.startsWith(GPS + ",") || 29370c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani value.endsWith("," + GPS) || 29470c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani value.contains("," + GPS + ","); 29570c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani Settings.Secure.setLocationProviderEnabled( 29670c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani mContext.getContentResolver(), GPS, enabled); 29770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani } 29870c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani 29970c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani private void setSoundEffects(boolean enable) { 30070c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani if (enable) { 30170c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani mAudioManager.loadSoundEffects(); 30270c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani } else { 30370c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani mAudioManager.unloadSoundEffects(); 304501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master } 305501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master } 306501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master 307501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master private void setBrightness(int brightness) { 308501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master try { 309237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwood IPowerManager power = IPowerManager.Stub.asInterface( 310237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwood ServiceManager.getService("power")); 311237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwood if (power != null) { 3129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown power.setTemporaryScreenBrightnessSettingOverride(brightness); 313501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master } 314501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master } catch (RemoteException doe) { 315501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master 316501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master } 317501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master } 318501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master 3190f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka /* package */ byte[] getLocaleData() { 3208823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani Configuration conf = mContext.getResources().getConfiguration(); 3210f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka return conf.getLocales().toLanguageTags().getBytes(); 3220f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka } 3230f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 3240f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka private static Locale toFullLocale(@NonNull Locale locale) { 3250f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka if (locale.getScript().isEmpty() || locale.getCountry().isEmpty()) { 3260f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka return ULocale.addLikelySubtags(ULocale.forLocale(locale)).toLocale(); 3278823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani } 3280f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka return locale; 3298823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani } 3308823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani 3318823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani /** 3320f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * Merging the locale came from backup server and current device locale. 3330f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * 3340f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * Merge works with following rules. 3350f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * - The backup locales are appended to the current locale with keeping order. 3360f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * e.g. current locale "en-US,zh-CN" and backup locale "ja-JP,ko-KR" are merged to 3370f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * "en-US,zh-CH,ja-JP,ko-KR". 3380f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * 3390f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * - Duplicated locales are dropped. 3400f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * e.g. current locale "en-US,zh-CN" and backup locale "ja-JP,zh-Hans-CN,en-US" are merged to 3410f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * "en-US,zh-CN,ja-JP". 3420f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * 3430f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * - Unsupported locales are dropped. 3440f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * e.g. current locale "en-US" and backup locale "ja-JP,zh-CN" but the supported locales 3450f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * are "en-US,zh-CN", the merged locale list is "en-US,zh-CN". 3460f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * 3470f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * - The final result locale list only contains the supported locales. 3480f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * e.g. current locale "en-US" and backup locale "zh-Hans-CN" and supported locales are 3490f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * "en-US,zh-CN", the merged locale list is "en-US,zh-CN". 3500f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * 3510f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * @param restore The locale list that came from backup server. 3520f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * @param current The device's locale setting. 3530f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * @param supportedLocales The list of language tags supported by this device. 3540f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka */ 3550f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka @VisibleForTesting 3560f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka public static LocaleList resolveLocales(LocaleList restore, LocaleList current, 3570f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka String[] supportedLocales) { 3580f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final HashMap<Locale, Locale> allLocales = new HashMap<>(supportedLocales.length); 3590f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka for (String supportedLocaleStr : supportedLocales) { 3600f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final Locale locale = Locale.forLanguageTag(supportedLocaleStr); 3610f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka allLocales.put(toFullLocale(locale), locale); 3620f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka } 3630f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 3640f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final ArrayList<Locale> filtered = new ArrayList<>(current.size()); 3650f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka for (int i = 0; i < current.size(); i++) { 3660f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final Locale locale = current.get(i); 3670f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka allLocales.remove(toFullLocale(locale)); 3680f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka filtered.add(locale); 3690f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka } 3700f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 3710f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka for (int i = 0; i < restore.size(); i++) { 3720f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final Locale locale = allLocales.remove(toFullLocale(restore.get(i))); 3730f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka if (locale != null) { 3740f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka filtered.add(locale); 3750f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka } 3760f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka } 3770f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 3780f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka if (filtered.size() == current.size()) { 3790f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka return current; // Nothing added to current locale list. 3800f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka } 3810f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 3820f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka return new LocaleList(filtered.toArray(new Locale[filtered.size()])); 3830f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka } 3840f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 3850f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka /** 3860f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * Sets the locale specified. Input data is the byte representation of comma separated 3870f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * multiple BCP-47 language tags. For backwards compatibility, strings of the form 38811bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath * {@code ll_CC} are also accepted, where {@code ll} is a two letter language 38911bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath * code and {@code CC} is a two letter country code. 39011bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath * 3910f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka * @param data the comma separated BCP-47 language tags in bytes. 3928823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani */ 3930f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka /* package */ void setLocaleData(byte[] data, int size) { 3940f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final Configuration conf = mContext.getResources().getConfiguration(); 3950f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 3960f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka // Replace "_" with "-" to deal with older backups. 3970f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final String localeCodes = new String(data, 0, size).replace('_', '-'); 3980f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final LocaleList localeList = LocaleList.forLanguageTags(localeCodes); 3990f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka if (localeList.isEmpty()) { 40045d17581844df55cfc85117819e41c33eb40ad96Christopher Tate return; 40145d17581844df55cfc85117819e41c33eb40ad96Christopher Tate } 4028823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani 4030f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final String[] supportedLocales = LocalePicker.getSupportedLocales(mContext); 4040f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final LocaleList currentLocales = conf.getLocales(); 4050f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka 4060f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka final LocaleList merged = resolveLocales(localeList, currentLocales, supportedLocales); 4070f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka if (merged.equals(currentLocales)) { 4080f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka return; 4098823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani } 4108823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani 4118823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani try { 412dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka IActivityManager am = ActivityManager.getService(); 4138823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani Configuration config = am.getConfiguration(); 4140f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka config.setLocales(merged); 4158823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani // indicate this isn't some passing default - the user wants this remembered 4168823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani config.userSetLocale = true; 4178823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani 4180f19cc779fb81bca0d00fd0a062f431cedb5f684Seigo Nonaka am.updatePersistentConfiguration(config); 4198823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani } catch (RemoteException e) { 4208823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani // Intentionally left blank 4218823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani } 422d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 4238823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani 424d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani /** 425d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani * Informs the audio service of changes to the settings so that 426d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani * they can be re-read and applied. 427d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani */ 428d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani void applyAudioSettings() { 429d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani AudioManager am = new AudioManager(mContext); 430d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani am.reloadAudioSettings(); 4318823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani } 432501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master} 433