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