SettingsHelper.java revision 767f05feea67e642a76bd3e2e7633a8f5273f077
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
198823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasaniimport android.app.ActivityManagerNative;
208823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasaniimport android.app.IActivityManager;
214528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IBackupManager;
226597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.content.ContentResolver;
236597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.content.ContentValues;
24501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.content.Context;
256597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.content.Intent;
268823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasaniimport android.content.res.Configuration;
2770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasaniimport android.location.LocationManager;
28501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.media.AudioManager;
29622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasaniimport android.media.RingtoneManager;
30622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasaniimport android.net.Uri;
31237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwoodimport android.os.IPowerManager;
32501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.os.RemoteException;
33501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.os.ServiceManager;
346597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.os.UserHandle;
356794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthallimport android.os.UserManager;
36501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterimport android.provider.Settings;
378fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paulimport android.telephony.TelephonyManager;
388823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasaniimport android.text.TextUtils;
396597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tateimport android.util.ArraySet;
40501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master
416794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthallimport java.util.Locale;
426794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall
43501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b masterpublic class SettingsHelper {
44622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    private static final String SILENT_RINGTONE = "_silent";
45501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master    private Context mContext;
46501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master    private AudioManager mAudioManager;
478fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul    private TelephonyManager mTelephonyManager;
4870c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani
496597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    /**
506597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * A few settings elements are special in that a restore of those values needs to
516597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * be post-processed by relevant parts of the OS.  A restore of any settings element
526597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * mentioned in this table will therefore cause the system to send a broadcast with
536597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * the {@link Intent#ACTION_SETTING_RESTORED} action, with extras naming the
546597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * affected setting and supplying its pre-restore value for comparison.
556597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     *
566597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * @see Intent#ACTION_SETTING_RESTORED
576597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * @see System#SETTINGS_TO_BACKUP
586597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * @see Secure#SETTINGS_TO_BACKUP
596597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * @see Global#SETTINGS_TO_BACKUP
606597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     *
616597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     * {@hide}
626597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate     */
636597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    private static final ArraySet<String> sBroadcastOnRestore;
646597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    static {
65767f05feea67e642a76bd3e2e7633a8f5273f077Stanley Tng        sBroadcastOnRestore = new ArraySet<String>(5);
666597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
67e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk        sBroadcastOnRestore.add(Settings.Secure.ENABLED_VR_LISTENERS);
682d4aadca9487d76cb7220bdba90afa53119664eaChristopher Tate        sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
697b9a28c7f0a7b88ed1ea777edc05002d2d2b38b7Christopher Tate        sBroadcastOnRestore.add(Settings.Secure.ENABLED_INPUT_METHODS);
70767f05feea67e642a76bd3e2e7633a8f5273f077Stanley Tng        sBroadcastOnRestore.add(Settings.Global.BLUETOOTH_ON);
716597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    }
726597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
736597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    private interface SettingsLookup {
746597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        public String lookup(ContentResolver resolver, String name, int userHandle);
756597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    }
766597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
776597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    private static SettingsLookup sSystemLookup = new SettingsLookup() {
786597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        public String lookup(ContentResolver resolver, String name, int userHandle) {
796597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            return Settings.System.getStringForUser(resolver, name, userHandle);
806597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        }
816597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    };
826597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
836597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    private static SettingsLookup sSecureLookup = new SettingsLookup() {
846597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        public String lookup(ContentResolver resolver, String name, int userHandle) {
856597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            return Settings.Secure.getStringForUser(resolver, name, userHandle);
866597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        }
876597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    };
886597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
896597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    private static SettingsLookup sGlobalLookup = new SettingsLookup() {
906597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        public String lookup(ContentResolver resolver, String name, int userHandle) {
916597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            return Settings.Global.getStringForUser(resolver, name, userHandle);
926597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        }
936597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    };
946597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
95501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master    public SettingsHelper(Context context) {
96501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master        mContext = context;
97501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master        mAudioManager = (AudioManager) context
98501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master                .getSystemService(Context.AUDIO_SERVICE);
998fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul        mTelephonyManager = (TelephonyManager) context
1008fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                .getSystemService(Context.TELEPHONY_SERVICE);
101501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master    }
102501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master
10370c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani    /**
10470c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     * Sets the property via a call to the appropriate API, if any, and returns
10570c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     * whether or not the setting should be saved to the database as well.
10670c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     * @param name the name of the setting
10770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     * @param value the string value of the setting
10870c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     * @return whether to continue with writing the value to the database. In
10970c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     * some cases the data will be written by the call to the appropriate API,
11070c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     * and in some cases the property value needs to be modified before setting.
11170c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani     */
1126597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate    public void restoreValue(Context context, ContentResolver cr, ContentValues contentValues,
1136597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            Uri destination, String name, String value) {
1146597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        // Will we need a post-restore broadcast for this element?
1156597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        String oldValue = null;
1166597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        boolean sendBroadcast = false;
1176597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        final SettingsLookup table;
1186597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
1196597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        if (destination.equals(Settings.Secure.CONTENT_URI)) {
1206597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            table = sSecureLookup;
1216597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        } else if (destination.equals(Settings.System.CONTENT_URI)) {
1226597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            table = sSystemLookup;
1236597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        } else { /* must be GLOBAL; this was preflighted by the caller */
1246597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            table = sGlobalLookup;
1256597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        }
1266597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
1276597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        if (sBroadcastOnRestore.contains(name)) {
12843765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen            // TODO: http://b/22388012
12943765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen            oldValue = table.lookup(cr, name, UserHandle.USER_SYSTEM);
1306597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            sendBroadcast = true;
1316597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        }
1326597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
1336597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        try {
1346597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) {
1356597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                setBrightness(Integer.parseInt(value));
1366597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                // fall through to the ordinary write to settings
1376597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) {
1386597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                setSoundEffects(Integer.parseInt(value) == 1);
1396597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                // fall through to the ordinary write to settings
1406597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
1416597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                setGpsLocation(value);
1426597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                return;
1436597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) {
1446597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                setAutoRestore(Integer.parseInt(value) == 1);
1456597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
1466597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                return;
1476597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            } else if (Settings.System.RINGTONE.equals(name)
1486597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                    || Settings.System.NOTIFICATION_SOUND.equals(name)) {
1496597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                setRingtone(name, value);
1506597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                return;
1516597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            }
1526597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate
1536597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            // Default case: write the restored value to settings
1546597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            contentValues.clear();
1556597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            contentValues.put(Settings.NameValueTable.NAME, name);
1566597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            contentValues.put(Settings.NameValueTable.VALUE, value);
1576597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            cr.insert(destination, contentValues);
1586597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        } catch (Exception e) {
1596597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            // If we fail to apply the setting, by definition nothing happened
1606597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            sendBroadcast = false;
1616597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate        } finally {
1626597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            // If this was an element of interest, send the "we just restored it"
1636597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            // broadcast with the historical value now that the new value has
1646597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            // been committed and observers kicked off.
1656597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            if (sendBroadcast) {
1666597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED)
1676597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                        .setPackage("android").addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
1686597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                        .putExtra(Intent.EXTRA_SETTING_NAME, name)
1696597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                        .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, value)
1706597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate                        .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue);
171e4de5a0d3b6e0c897c1cea0912b58e11db962365Xiaohui Chen                context.sendBroadcastAsUser(intent, UserHandle.SYSTEM, null);
1726597e3435f8abfedbb9a4f1bfb10cc17ea7f38bfChristopher Tate            }
17370c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani        }
17470c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani    }
17570c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani
176622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    public String onBackupValue(String name, String value) {
1778fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul        // Special processing for backing up ringtones & notification sounds
178622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        if (Settings.System.RINGTONE.equals(name)
179622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
180622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani            if (value == null) {
1818fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                if (Settings.System.RINGTONE.equals(name)) {
1828fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                    // For ringtones, we need to distinguish between non-telephony vs telephony
1838fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                    if (mTelephonyManager != null && mTelephonyManager.isVoiceCapable()) {
1848fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                        // Backup a null ringtone as silent on voice-capable devices
1858fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                        return SILENT_RINGTONE;
1868fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                    } else {
1878fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                        // Skip backup of ringtone on non-telephony devices.
1888fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                        return null;
1898fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                    }
1908fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                } else {
1918fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                    // Backup a null notification sound as silent
1928fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                    return SILENT_RINGTONE;
1938fc5072524f088daedb36bb3e1a77b57d25d000bMarvin Paul                }
194622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani            } else {
195622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani                return getCanonicalRingtoneValue(value);
196622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani            }
197622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        }
198622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        // Return the original value
199622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        return value;
200622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    }
201622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani
202622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    /**
203622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani     * Sets the ringtone of type specified by the name.
204622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani     *
205622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani     * @param name should be Settings.System.RINGTONE or Settings.System.NOTIFICATION_SOUND.
206622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani     * @param value can be a canonicalized uri or "_silent" to indicate a silent (null) ringtone.
207622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani     */
208622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    private void setRingtone(String name, String value) {
209622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        // If it's null, don't change the default
210622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        if (value == null) return;
211622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        Uri ringtoneUri = null;
212622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        if (SILENT_RINGTONE.equals(value)) {
213622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani            ringtoneUri = null;
214622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        } else {
215622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani            Uri canonicalUri = Uri.parse(value);
216622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani            ringtoneUri = mContext.getContentResolver().uncanonicalize(canonicalUri);
2172e804444d64bdf2763c682109c838a8372b17934Amith Yamasani            if (ringtoneUri == null) {
2182e804444d64bdf2763c682109c838a8372b17934Amith Yamasani                // Unrecognized or invalid Uri, don't restore
2192e804444d64bdf2763c682109c838a8372b17934Amith Yamasani                return;
2202e804444d64bdf2763c682109c838a8372b17934Amith Yamasani            }
221622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        }
222622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        final int ringtoneType = Settings.System.RINGTONE.equals(name)
223622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani                ? RingtoneManager.TYPE_RINGTONE : RingtoneManager.TYPE_NOTIFICATION;
224622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, ringtoneUri);
225622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    }
226622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani
227622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    private String getCanonicalRingtoneValue(String value) {
228622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        final Uri ringtoneUri = Uri.parse(value);
229622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        final Uri canonicalUri = mContext.getContentResolver().canonicalize(ringtoneUri);
230622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani        return canonicalUri == null ? null : canonicalUri.toString();
231622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani    }
232622bf2220cf7fb9bb526afa39921ee2aa93e32caAmith Yamasani
233818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov    private boolean isAlreadyConfiguredCriticalAccessibilitySetting(String name) {
234fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza        // These are the critical accessibility settings that are required for users with
235fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza        // accessibility needs to be able to interact with the device. If these settings are
236818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov        // already configured, we will not overwrite them. If they are already set,
237fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza        // it means that the user has performed a global gesture to enable accessibility or set
238fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza        // these settings in the Accessibility portion of the Setup Wizard, and definitely needs
239fa7786cbe7e846841c2828d8143325144b75f619Anna Galusza        // these features working after the restore.
24086b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt        switch (name) {
24186b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ACCESSIBILITY_ENABLED:
24286b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION:
24386b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD:
24486b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.TOUCH_EXPLORATION_ENABLED:
24586b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:
24686b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED:
24786b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.UI_NIGHT_MODE:
24886b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt                return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
24986b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES:
25086b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES:
25186b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER:
25286b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE:
25386b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt                return !TextUtils.isEmpty(Settings.Secure.getString(
25486b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt                        mContext.getContentResolver(), name));
25586b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            case Settings.System.FONT_SCALE:
25686b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt                return Settings.System.getFloat(mContext.getContentResolver(), name, 1.0f) != 1.0f;
25786b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt            default:
25886b867fd45ce97f7ebe374396e91e679adf8633dCasey Burkhardt                return false;
259818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov        }
260818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov    }
261818d20459099ea75e9b8d27c341af482653847a1Svetoslav Ganov
26203b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate    private void setAutoRestore(boolean enabled) {
26303b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate        try {
26403b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate            IBackupManager bm = IBackupManager.Stub.asInterface(
26503b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate                    ServiceManager.getService(Context.BACKUP_SERVICE));
26603b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate            if (bm != null) {
26703b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate                bm.setAutoRestore(enabled);
26803b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate            }
26903b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate        } catch (RemoteException e) {}
27003b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate    }
27103b6d90db9acc531a945c57795b903a3b74dd0b7Christopher Tate
27270c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani    private void setGpsLocation(String value) {
2736794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
274a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall        if (um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION)) {
2756794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall            return;
2766794458f8626c3be27eac3db3a5c89d94f132675Maggie Benthall        }
27770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani        final String GPS = LocationManager.GPS_PROVIDER;
278a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall        boolean enabled =
27970c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani                GPS.equals(value) ||
28070c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani                value.startsWith(GPS + ",") ||
28170c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani                value.endsWith("," + GPS) ||
28270c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani                value.contains("," + GPS + ",");
28370c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani        Settings.Secure.setLocationProviderEnabled(
28470c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani                mContext.getContentResolver(), GPS, enabled);
28570c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani    }
28670c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani
28770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani    private void setSoundEffects(boolean enable) {
28870c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani        if (enable) {
28970c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani            mAudioManager.loadSoundEffects();
29070c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani        } else {
29170c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani            mAudioManager.unloadSoundEffects();
292501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master        }
293501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master    }
294501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master
295501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master    private void setBrightness(int brightness) {
296501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master        try {
297237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwood            IPowerManager power = IPowerManager.Stub.asInterface(
298237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwood                    ServiceManager.getService("power"));
299237a29923a05663a2195bf93b392768dbaf31ebfMike Lockwood            if (power != null) {
3009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                power.setTemporaryScreenBrightnessSettingOverride(brightness);
301501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master            }
302501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master        } catch (RemoteException doe) {
303501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master
304501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master        }
305501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master    }
306501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master
3078823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani    byte[] getLocaleData() {
3088823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        Configuration conf = mContext.getResources().getConfiguration();
3098823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        final Locale loc = conf.locale;
3108823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        String localeString = loc.getLanguage();
3118823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        String country = loc.getCountry();
3128823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        if (!TextUtils.isEmpty(country)) {
31311bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath            localeString += "-" + country;
3148823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        }
3158823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        return localeString.getBytes();
3168823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani    }
3178823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani
3188823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani    /**
31911bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath     * Sets the locale specified. Input data is the byte representation of a
32011bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath     * BCP-47 language tag. For backwards compatibility, strings of the form
32111bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath     * {@code ll_CC} are also accepted, where {@code ll} is a two letter language
32211bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath     * code and {@code CC} is a two letter country code.
32311bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath     *
3248823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani     * @param data the locale string in bytes.
3258823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani     */
32675a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate    void setLocaleData(byte[] data, int size) {
3278823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        // Check if locale was set by the user:
3288823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        Configuration conf = mContext.getResources().getConfiguration();
329d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani        // TODO: The following is not working as intended because the network is forcing a locale
330d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani        // change after registering. Need to find some other way to detect if the user manually
331d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani        // changed the locale
3328823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
3338823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani
3348823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        final String[] availableLocales = mContext.getAssets().getLocales();
33511bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath        // Replace "_" with "-" to deal with older backups.
33611bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath        String localeCode = new String(data, 0, size).replace('_', '-');
33711bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath        Locale loc = null;
3388823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        for (int i = 0; i < availableLocales.length; i++) {
3398823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            if (availableLocales[i].equals(localeCode)) {
34011bfc2261f653f1b3154b88bf692241dbd6fc477Narayan Kamath                loc = Locale.forLanguageTag(localeCode);
3418823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani                break;
3428823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            }
3438823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        }
3448823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        if (loc == null) return; // Couldn't find the saved locale in this version of the software
3458823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani
3468823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        try {
3478823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            IActivityManager am = ActivityManagerNative.getDefault();
3488823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            Configuration config = am.getConfiguration();
3498823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            config.locale = loc;
3508823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            // indicate this isn't some passing default - the user wants this remembered
3518823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            config.userSetLocale = true;
3528823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani
3538823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            am.updateConfiguration(config);
3548823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        } catch (RemoteException e) {
3558823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani            // Intentionally left blank
3568823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani        }
357d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani    }
3588823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani
359d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani    /**
360d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani     * Informs the audio service of changes to the settings so that
361d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani     * they can be re-read and applied.
362d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani     */
363d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani    void applyAudioSettings() {
364d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani        AudioManager am = new AudioManager(mContext);
365d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani        am.reloadAudioSettings();
3668823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani    }
367501eec92f9f4f206ad7972c63f2d0ef0285d8e34-b master}
368