DatabaseHelper.java revision 43765b77a0286403fd9f7f5305219f0d9a10c953
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.providers.settings;
18
19import android.content.ComponentName;
20import android.content.ContentValues;
21import android.content.Context;
22import android.content.Intent;
23import android.content.pm.ActivityInfo;
24import android.content.pm.IPackageManager;
25import android.content.pm.PackageManager;
26import android.content.res.XmlResourceParser;
27import android.database.Cursor;
28import android.database.sqlite.SQLiteDatabase;
29import android.database.sqlite.SQLiteOpenHelper;
30import android.database.sqlite.SQLiteStatement;
31import android.media.AudioSystem;
32import android.media.AudioManager;
33import android.net.ConnectivityManager;
34import android.os.Build;
35import android.os.Environment;
36import android.os.RemoteException;
37import android.os.ServiceManager;
38import android.os.SystemProperties;
39import android.os.UserHandle;
40import android.provider.Settings;
41import android.provider.Settings.Global;
42import android.provider.Settings.Secure;
43import android.text.TextUtils;
44import android.util.Log;
45
46import com.android.ims.ImsConfig;
47import com.android.internal.content.PackageHelper;
48import com.android.internal.telephony.RILConstants;
49import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
50import com.android.internal.util.XmlUtils;
51import com.android.internal.widget.LockPatternUtils;
52import com.android.internal.widget.LockPatternView;
53
54import org.xmlpull.v1.XmlPullParser;
55import org.xmlpull.v1.XmlPullParserException;
56
57import java.io.File;
58import java.io.IOException;
59import java.util.HashSet;
60import java.util.List;
61import java.util.Set;
62
63/**
64 * Legacy settings database helper class for {@link SettingsProvider}.
65 *
66 * IMPORTANT: Do not add any more upgrade steps here as the global,
67 * secure, and system settings are no longer stored in a database
68 * but are kept in memory and persisted to XML.
69 *
70 * See: SettingsProvider.UpgradeController#onUpgradeLocked
71 *
72 * @deprecated The implementation is frozen.  Do not add any new code to this class!
73 */
74@Deprecated
75class DatabaseHelper extends SQLiteOpenHelper {
76    private static final String TAG = "SettingsProvider";
77    private static final String DATABASE_NAME = "settings.db";
78
79    // Please, please please. If you update the database version, check to make sure the
80    // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
81    // is properly propagated through your change.  Not doing so will result in a loss of user
82    // settings.
83    private static final int DATABASE_VERSION = 118;
84
85    private Context mContext;
86    private int mUserHandle;
87
88    private static final HashSet<String> mValidTables = new HashSet<String>();
89
90    private static final String DATABASE_JOURNAL_SUFFIX = "-journal";
91    private static final String DATABASE_BACKUP_SUFFIX = "-backup";
92
93    private static final String TABLE_SYSTEM = "system";
94    private static final String TABLE_SECURE = "secure";
95    private static final String TABLE_GLOBAL = "global";
96
97    static {
98        mValidTables.add(TABLE_SYSTEM);
99        mValidTables.add(TABLE_SECURE);
100        mValidTables.add(TABLE_GLOBAL);
101
102        // These are old.
103        mValidTables.add("bluetooth_devices");
104        mValidTables.add("bookmarks");
105        mValidTables.add("favorites");
106        mValidTables.add("old_favorites");
107        mValidTables.add("android_metadata");
108    }
109
110    static String dbNameForUser(final int userHandle) {
111        // The owner gets the unadorned db name;
112        if (userHandle == UserHandle.USER_SYSTEM) {
113            return DATABASE_NAME;
114        } else {
115            // Place the database in the user-specific data tree so that it's
116            // cleaned up automatically when the user is deleted.
117            File databaseFile = new File(
118                    Environment.getUserSystemDirectory(userHandle), DATABASE_NAME);
119            return databaseFile.getPath();
120        }
121    }
122
123    public DatabaseHelper(Context context, int userHandle) {
124        super(context, dbNameForUser(userHandle), null, DATABASE_VERSION);
125        mContext = context;
126        mUserHandle = userHandle;
127    }
128
129    public static boolean isValidTable(String name) {
130        return mValidTables.contains(name);
131    }
132
133    public void dropDatabase() {
134        close();
135        File databaseFile = mContext.getDatabasePath(getDatabaseName());
136        if (databaseFile.exists()) {
137            databaseFile.delete();
138        }
139        File databaseJournalFile = mContext.getDatabasePath(getDatabaseName()
140                + DATABASE_JOURNAL_SUFFIX);
141        if (databaseJournalFile.exists()) {
142            databaseJournalFile.delete();
143        }
144    }
145
146    public void backupDatabase() {
147        close();
148        File databaseFile = mContext.getDatabasePath(getDatabaseName());
149        if (!databaseFile.exists()) {
150            return;
151        }
152        File backupFile = mContext.getDatabasePath(getDatabaseName()
153                + DATABASE_BACKUP_SUFFIX);
154        if (backupFile.exists()) {
155            return;
156        }
157        databaseFile.renameTo(backupFile);
158    }
159
160    private void createSecureTable(SQLiteDatabase db) {
161        db.execSQL("CREATE TABLE secure (" +
162                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
163                "name TEXT UNIQUE ON CONFLICT REPLACE," +
164                "value TEXT" +
165                ");");
166        db.execSQL("CREATE INDEX secureIndex1 ON secure (name);");
167    }
168
169    private void createGlobalTable(SQLiteDatabase db) {
170        db.execSQL("CREATE TABLE global (" +
171                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
172                "name TEXT UNIQUE ON CONFLICT REPLACE," +
173                "value TEXT" +
174                ");");
175        db.execSQL("CREATE INDEX globalIndex1 ON global (name);");
176    }
177
178    @Override
179    public void onCreate(SQLiteDatabase db) {
180        db.execSQL("CREATE TABLE system (" +
181                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
182                    "name TEXT UNIQUE ON CONFLICT REPLACE," +
183                    "value TEXT" +
184                    ");");
185        db.execSQL("CREATE INDEX systemIndex1 ON system (name);");
186
187        createSecureTable(db);
188
189        // Only create the global table for the singleton 'owner/system' user
190        if (mUserHandle == UserHandle.USER_SYSTEM) {
191            createGlobalTable(db);
192        }
193
194        db.execSQL("CREATE TABLE bluetooth_devices (" +
195                    "_id INTEGER PRIMARY KEY," +
196                    "name TEXT," +
197                    "addr TEXT," +
198                    "channel INTEGER," +
199                    "type INTEGER" +
200                    ");");
201
202        db.execSQL("CREATE TABLE bookmarks (" +
203                    "_id INTEGER PRIMARY KEY," +
204                    "title TEXT," +
205                    "folder TEXT," +
206                    "intent TEXT," +
207                    "shortcut INTEGER," +
208                    "ordering INTEGER" +
209                    ");");
210
211        db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);");
212        db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);");
213
214        // Populate bookmarks table with initial bookmarks
215        boolean onlyCore = false;
216        try {
217            onlyCore = IPackageManager.Stub.asInterface(ServiceManager.getService(
218                    "package")).isOnlyCoreApps();
219        } catch (RemoteException e) {
220        }
221        if (!onlyCore) {
222            loadBookmarks(db);
223        }
224
225        // Load initial volume levels into DB
226        loadVolumeLevels(db);
227
228        // Load inital settings values
229        loadSettings(db);
230    }
231
232    @Override
233    public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
234        Log.w(TAG, "Upgrading settings database from version " + oldVersion + " to "
235                + currentVersion);
236
237        int upgradeVersion = oldVersion;
238
239        // Pattern for upgrade blocks:
240        //
241        //    if (upgradeVersion == [the DATABASE_VERSION you set] - 1) {
242        //        .. your upgrade logic..
243        //        upgradeVersion = [the DATABASE_VERSION you set]
244        //    }
245
246        if (upgradeVersion == 20) {
247            /*
248             * Version 21 is part of the volume control refresh. There is no
249             * longer a UI-visible for setting notification vibrate on/off (in
250             * our design), but the functionality still exists. Force the
251             * notification vibrate to on.
252             */
253            loadVibrateSetting(db, true);
254
255            upgradeVersion = 21;
256        }
257
258        if (upgradeVersion < 22) {
259            upgradeVersion = 22;
260            // Upgrade the lock gesture storage location and format
261            upgradeLockPatternLocation(db);
262        }
263
264        if (upgradeVersion < 23) {
265            db.execSQL("UPDATE favorites SET iconResource=0 WHERE iconType=0");
266            upgradeVersion = 23;
267        }
268
269        if (upgradeVersion == 23) {
270            db.beginTransaction();
271            try {
272                db.execSQL("ALTER TABLE favorites ADD spanX INTEGER");
273                db.execSQL("ALTER TABLE favorites ADD spanY INTEGER");
274                // Shortcuts, applications, folders
275                db.execSQL("UPDATE favorites SET spanX=1, spanY=1 WHERE itemType<=0");
276                // Photo frames, clocks
277                db.execSQL(
278                    "UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
279                // Search boxes
280                db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001");
281                db.setTransactionSuccessful();
282            } finally {
283                db.endTransaction();
284            }
285            upgradeVersion = 24;
286        }
287
288        if (upgradeVersion == 24) {
289            db.beginTransaction();
290            try {
291                // The value of the constants for preferring wifi or preferring mobile have been
292                // swapped, so reload the default.
293                db.execSQL("DELETE FROM system WHERE name='network_preference'");
294                db.execSQL("INSERT INTO system ('name', 'value') values ('network_preference', '" +
295                        ConnectivityManager.DEFAULT_NETWORK_PREFERENCE + "')");
296                db.setTransactionSuccessful();
297            } finally {
298                db.endTransaction();
299            }
300            upgradeVersion = 25;
301        }
302
303        if (upgradeVersion == 25) {
304            db.beginTransaction();
305            try {
306                db.execSQL("ALTER TABLE favorites ADD uri TEXT");
307                db.execSQL("ALTER TABLE favorites ADD displayMode INTEGER");
308                db.setTransactionSuccessful();
309            } finally {
310                db.endTransaction();
311            }
312            upgradeVersion = 26;
313        }
314
315        if (upgradeVersion == 26) {
316            // This introduces the new secure settings table.
317            db.beginTransaction();
318            try {
319                createSecureTable(db);
320                db.setTransactionSuccessful();
321            } finally {
322                db.endTransaction();
323            }
324            upgradeVersion = 27;
325        }
326
327        if (upgradeVersion == 27) {
328            String[] settingsToMove = {
329                    Settings.Secure.ADB_ENABLED,
330                    Settings.Secure.ANDROID_ID,
331                    Settings.Secure.BLUETOOTH_ON,
332                    Settings.Secure.DATA_ROAMING,
333                    Settings.Secure.DEVICE_PROVISIONED,
334                    Settings.Secure.HTTP_PROXY,
335                    Settings.Secure.INSTALL_NON_MARKET_APPS,
336                    Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
337                    Settings.Secure.LOGGING_ID,
338                    Settings.Secure.NETWORK_PREFERENCE,
339                    Settings.Secure.PARENTAL_CONTROL_ENABLED,
340                    Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
341                    Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
342                    Settings.Secure.SETTINGS_CLASSNAME,
343                    Settings.Secure.USB_MASS_STORAGE_ENABLED,
344                    Settings.Secure.USE_GOOGLE_MAIL,
345                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
346                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
347                    Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT,
348                    Settings.Secure.WIFI_ON,
349                    Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE,
350                    Settings.Secure.WIFI_WATCHDOG_AP_COUNT,
351                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS,
352                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED,
353                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS,
354                    Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT,
355                    Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS,
356                    Settings.Secure.WIFI_WATCHDOG_ON,
357                    Settings.Secure.WIFI_WATCHDOG_PING_COUNT,
358                    Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS,
359                    Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS,
360                };
361            moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false);
362            upgradeVersion = 28;
363        }
364
365        if (upgradeVersion == 28 || upgradeVersion == 29) {
366            // Note: The upgrade to 28 was flawed since it didn't delete the old
367            // setting first before inserting. Combining 28 and 29 with the
368            // fixed version.
369
370            // This upgrade adds the STREAM_NOTIFICATION type to the list of
371            // types affected by ringer modes (silent, vibrate, etc.)
372            db.beginTransaction();
373            try {
374                db.execSQL("DELETE FROM system WHERE name='"
375                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
376                int newValue = (1 << AudioManager.STREAM_RING)
377                        | (1 << AudioManager.STREAM_NOTIFICATION)
378                        | (1 << AudioManager.STREAM_SYSTEM);
379                db.execSQL("INSERT INTO system ('name', 'value') values ('"
380                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
381                        + String.valueOf(newValue) + "')");
382                db.setTransactionSuccessful();
383            } finally {
384                db.endTransaction();
385            }
386
387            upgradeVersion = 30;
388        }
389
390        if (upgradeVersion == 30) {
391            /*
392             * Upgrade 31 clears the title for all quick launch shortcuts so the
393             * activities' titles will be resolved at display time. Also, the
394             * folder is changed to '@quicklaunch'.
395             */
396            db.beginTransaction();
397            try {
398                db.execSQL("UPDATE bookmarks SET folder = '@quicklaunch'");
399                db.execSQL("UPDATE bookmarks SET title = ''");
400                db.setTransactionSuccessful();
401            } finally {
402                db.endTransaction();
403            }
404            upgradeVersion = 31;
405        }
406
407        if (upgradeVersion == 31) {
408            /*
409             * Animations are now managed in preferences, and may be
410             * enabled or disabled based on product resources.
411             */
412            db.beginTransaction();
413            SQLiteStatement stmt = null;
414            try {
415                db.execSQL("DELETE FROM system WHERE name='"
416                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
417                db.execSQL("DELETE FROM system WHERE name='"
418                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
419                stmt = db.compileStatement("INSERT INTO system(name,value)"
420                        + " VALUES(?,?);");
421                loadDefaultAnimationSettings(stmt);
422                db.setTransactionSuccessful();
423            } finally {
424                db.endTransaction();
425                if (stmt != null) stmt.close();
426            }
427            upgradeVersion = 32;
428        }
429
430        if (upgradeVersion == 32) {
431            // The Wi-Fi watchdog SSID list is now seeded with the value of
432            // the property ro.com.android.wifi-watchlist
433            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
434            if (!TextUtils.isEmpty(wifiWatchList)) {
435                db.beginTransaction();
436                try {
437                    db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
438                            Settings.Secure.WIFI_WATCHDOG_WATCH_LIST + "','" +
439                            wifiWatchList + "');");
440                    db.setTransactionSuccessful();
441                } finally {
442                    db.endTransaction();
443                }
444            }
445            upgradeVersion = 33;
446        }
447
448        if (upgradeVersion == 33) {
449            // Set the default zoom controls to: tap-twice to bring up +/-
450            db.beginTransaction();
451            try {
452                db.execSQL("INSERT INTO system(name,value) values('zoom','2');");
453                db.setTransactionSuccessful();
454            } finally {
455                db.endTransaction();
456            }
457            upgradeVersion = 34;
458        }
459
460        if (upgradeVersion == 34) {
461            db.beginTransaction();
462            SQLiteStatement stmt = null;
463            try {
464                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
465                        + " VALUES(?,?);");
466                loadSecure35Settings(stmt);
467                db.setTransactionSuccessful();
468            } finally {
469                db.endTransaction();
470                if (stmt != null) stmt.close();
471            }
472            upgradeVersion = 35;
473        }
474            // due to a botched merge from donut to eclair, the initialization of ASSISTED_GPS_ENABLED
475            // was accidentally done out of order here.
476            // to fix this, ASSISTED_GPS_ENABLED is now initialized while upgrading from 38 to 39,
477            // and we intentionally do nothing from 35 to 36 now.
478        if (upgradeVersion == 35) {
479            upgradeVersion = 36;
480        }
481
482        if (upgradeVersion == 36) {
483           // This upgrade adds the STREAM_SYSTEM_ENFORCED type to the list of
484            // types affected by ringer modes (silent, vibrate, etc.)
485            db.beginTransaction();
486            try {
487                db.execSQL("DELETE FROM system WHERE name='"
488                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
489                int newValue = (1 << AudioManager.STREAM_RING)
490                        | (1 << AudioManager.STREAM_NOTIFICATION)
491                        | (1 << AudioManager.STREAM_SYSTEM)
492                        | (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
493                db.execSQL("INSERT INTO system ('name', 'value') values ('"
494                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
495                        + String.valueOf(newValue) + "')");
496                db.setTransactionSuccessful();
497            } finally {
498                db.endTransaction();
499            }
500            upgradeVersion = 37;
501        }
502
503        if (upgradeVersion == 37) {
504            db.beginTransaction();
505            SQLiteStatement stmt = null;
506            try {
507                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
508                        + " VALUES(?,?);");
509                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
510                        R.string.airplane_mode_toggleable_radios);
511                db.setTransactionSuccessful();
512            } finally {
513                db.endTransaction();
514                if (stmt != null) stmt.close();
515            }
516            upgradeVersion = 38;
517        }
518
519        if (upgradeVersion == 38) {
520            db.beginTransaction();
521            try {
522                String value =
523                        mContext.getResources().getBoolean(R.bool.assisted_gps_enabled) ? "1" : "0";
524                db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
525                        Settings.Global.ASSISTED_GPS_ENABLED + "','" + value + "');");
526                db.setTransactionSuccessful();
527            } finally {
528                db.endTransaction();
529            }
530
531            upgradeVersion = 39;
532        }
533
534        if (upgradeVersion == 39) {
535            upgradeAutoBrightness(db);
536            upgradeVersion = 40;
537        }
538
539        if (upgradeVersion == 40) {
540            /*
541             * All animations are now turned on by default!
542             */
543            db.beginTransaction();
544            SQLiteStatement stmt = null;
545            try {
546                db.execSQL("DELETE FROM system WHERE name='"
547                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
548                db.execSQL("DELETE FROM system WHERE name='"
549                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
550                stmt = db.compileStatement("INSERT INTO system(name,value)"
551                        + " VALUES(?,?);");
552                loadDefaultAnimationSettings(stmt);
553                db.setTransactionSuccessful();
554            } finally {
555                db.endTransaction();
556                if (stmt != null) stmt.close();
557            }
558            upgradeVersion = 41;
559        }
560
561        if (upgradeVersion == 41) {
562            /*
563             * Initialize newly public haptic feedback setting
564             */
565            db.beginTransaction();
566            SQLiteStatement stmt = null;
567            try {
568                db.execSQL("DELETE FROM system WHERE name='"
569                        + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'");
570                stmt = db.compileStatement("INSERT INTO system(name,value)"
571                        + " VALUES(?,?);");
572                loadDefaultHapticSettings(stmt);
573                db.setTransactionSuccessful();
574            } finally {
575                db.endTransaction();
576                if (stmt != null) stmt.close();
577            }
578            upgradeVersion = 42;
579        }
580
581        if (upgradeVersion == 42) {
582            /*
583             * Initialize new notification pulse setting
584             */
585            db.beginTransaction();
586            SQLiteStatement stmt = null;
587            try {
588                stmt = db.compileStatement("INSERT INTO system(name,value)"
589                        + " VALUES(?,?);");
590                loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
591                        R.bool.def_notification_pulse);
592                db.setTransactionSuccessful();
593            } finally {
594                db.endTransaction();
595                if (stmt != null) stmt.close();
596            }
597            upgradeVersion = 43;
598        }
599
600        if (upgradeVersion == 43) {
601            /*
602             * This upgrade stores bluetooth volume separately from voice volume
603             */
604            db.beginTransaction();
605            SQLiteStatement stmt = null;
606            try {
607                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
608                        + " VALUES(?,?);");
609                loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO,
610                        AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO));
611                db.setTransactionSuccessful();
612            } finally {
613                db.endTransaction();
614                if (stmt != null) stmt.close();
615            }
616            upgradeVersion = 44;
617        }
618
619        if (upgradeVersion == 44) {
620            /*
621             * Gservices was moved into vendor/google.
622             */
623            db.execSQL("DROP TABLE IF EXISTS gservices");
624            db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
625            upgradeVersion = 45;
626        }
627
628        if (upgradeVersion == 45) {
629             /*
630              * New settings for MountService
631              */
632            db.beginTransaction();
633            try {
634                db.execSQL("INSERT INTO secure(name,value) values('" +
635                        Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND + "','1');");
636                db.execSQL("INSERT INTO secure(name,value) values('" +
637                        Settings.Secure.MOUNT_UMS_AUTOSTART + "','0');");
638                db.execSQL("INSERT INTO secure(name,value) values('" +
639                        Settings.Secure.MOUNT_UMS_PROMPT + "','1');");
640                db.execSQL("INSERT INTO secure(name,value) values('" +
641                        Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED + "','1');");
642                db.setTransactionSuccessful();
643            } finally {
644                db.endTransaction();
645            }
646            upgradeVersion = 46;
647        }
648
649        if (upgradeVersion == 46) {
650            /*
651             * The password mode constants have changed; reset back to no
652             * password.
653             */
654            db.beginTransaction();
655            try {
656                db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
657                db.setTransactionSuccessful();
658            } finally {
659                db.endTransaction();
660            }
661           upgradeVersion = 47;
662       }
663
664
665        if (upgradeVersion == 47) {
666            /*
667             * The password mode constants have changed again; reset back to no
668             * password.
669             */
670            db.beginTransaction();
671            try {
672                db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
673                db.setTransactionSuccessful();
674            } finally {
675                db.endTransaction();
676            }
677           upgradeVersion = 48;
678       }
679
680       if (upgradeVersion == 48) {
681           /*
682            * Default recognition service no longer initialized here,
683            * moved to RecognitionManagerService.
684            */
685           upgradeVersion = 49;
686       }
687
688       if (upgradeVersion == 49) {
689           /*
690            * New settings for new user interface noises.
691            */
692           db.beginTransaction();
693           SQLiteStatement stmt = null;
694           try {
695                stmt = db.compileStatement("INSERT INTO system(name,value)"
696                        + " VALUES(?,?);");
697                loadUISoundEffectsSettings(stmt);
698                db.setTransactionSuccessful();
699            } finally {
700                db.endTransaction();
701                if (stmt != null) stmt.close();
702            }
703
704           upgradeVersion = 50;
705       }
706
707       if (upgradeVersion == 50) {
708           /*
709            * Install location no longer initiated here.
710            */
711           upgradeVersion = 51;
712       }
713
714       if (upgradeVersion == 51) {
715           /* Move the lockscreen related settings to Secure, including some private ones. */
716           String[] settingsToMove = {
717                   Secure.LOCK_PATTERN_ENABLED,
718                   Secure.LOCK_PATTERN_VISIBLE,
719                   Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
720                   "lockscreen.password_type",
721                   "lockscreen.lockoutattemptdeadline",
722                   "lockscreen.patterneverchosen",
723                   "lock_pattern_autolock",
724                   "lockscreen.lockedoutpermanently",
725                   "lockscreen.password_salt"
726           };
727           moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false);
728           upgradeVersion = 52;
729       }
730
731        if (upgradeVersion == 52) {
732            // new vibration/silent mode settings
733            db.beginTransaction();
734            SQLiteStatement stmt = null;
735            try {
736                stmt = db.compileStatement("INSERT INTO system(name,value)"
737                        + " VALUES(?,?);");
738                loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
739                        R.bool.def_vibrate_in_silent);
740                db.setTransactionSuccessful();
741            } finally {
742                db.endTransaction();
743                if (stmt != null) stmt.close();
744            }
745
746            upgradeVersion = 53;
747        }
748
749        if (upgradeVersion == 53) {
750            /*
751             * New settings for set install location UI no longer initiated here.
752             */
753            upgradeVersion = 54;
754        }
755
756        if (upgradeVersion == 54) {
757            /*
758             * Update the screen timeout value if set to never
759             */
760            db.beginTransaction();
761            try {
762                upgradeScreenTimeoutFromNever(db);
763                db.setTransactionSuccessful();
764            } finally {
765                db.endTransaction();
766            }
767
768            upgradeVersion = 55;
769        }
770
771        if (upgradeVersion == 55) {
772            /* Move the install location settings. */
773            String[] settingsToMove = {
774                    Global.SET_INSTALL_LOCATION,
775                    Global.DEFAULT_INSTALL_LOCATION
776            };
777            moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false);
778            db.beginTransaction();
779            SQLiteStatement stmt = null;
780            try {
781                stmt = db.compileStatement("INSERT INTO system(name,value)"
782                        + " VALUES(?,?);");
783                loadSetting(stmt, Global.SET_INSTALL_LOCATION, 0);
784                loadSetting(stmt, Global.DEFAULT_INSTALL_LOCATION,
785                        PackageHelper.APP_INSTALL_AUTO);
786                db.setTransactionSuccessful();
787             } finally {
788                 db.endTransaction();
789                 if (stmt != null) stmt.close();
790             }
791            upgradeVersion = 56;
792        }
793
794        if (upgradeVersion == 56) {
795            /*
796             * Add Bluetooth to list of toggleable radios in airplane mode
797             */
798            db.beginTransaction();
799            SQLiteStatement stmt = null;
800            try {
801                db.execSQL("DELETE FROM system WHERE name='"
802                        + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
803                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
804                        + " VALUES(?,?);");
805                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
806                        R.string.airplane_mode_toggleable_radios);
807                db.setTransactionSuccessful();
808            } finally {
809                db.endTransaction();
810                if (stmt != null) stmt.close();
811            }
812            upgradeVersion = 57;
813        }
814
815        /************* The following are Honeycomb changes ************/
816
817        if (upgradeVersion == 57) {
818            /*
819             * New settings to:
820             *  1. Enable injection of accessibility scripts in WebViews.
821             *  2. Define the key bindings for traversing web content in WebViews.
822             */
823            db.beginTransaction();
824            SQLiteStatement stmt = null;
825            try {
826                stmt = db.compileStatement("INSERT INTO secure(name,value)"
827                        + " VALUES(?,?);");
828                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
829                        R.bool.def_accessibility_script_injection);
830                stmt.close();
831                stmt = db.compileStatement("INSERT INTO secure(name,value)"
832                        + " VALUES(?,?);");
833                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
834                        R.string.def_accessibility_web_content_key_bindings);
835                db.setTransactionSuccessful();
836            } finally {
837                db.endTransaction();
838                if (stmt != null) stmt.close();
839            }
840            upgradeVersion = 58;
841        }
842
843        if (upgradeVersion == 58) {
844            /* Add default for new Auto Time Zone */
845            int autoTimeValue = getIntValueFromSystem(db, Settings.System.AUTO_TIME, 0);
846            db.beginTransaction();
847            SQLiteStatement stmt = null;
848            try {
849                stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);");
850                loadSetting(stmt, Settings.System.AUTO_TIME_ZONE,
851                        autoTimeValue); // Sync timezone to NITZ if auto_time was enabled
852                db.setTransactionSuccessful();
853            } finally {
854                db.endTransaction();
855                if (stmt != null) stmt.close();
856            }
857            upgradeVersion = 59;
858        }
859
860        if (upgradeVersion == 59) {
861            // Persistence for the rotation lock feature.
862            db.beginTransaction();
863            SQLiteStatement stmt = null;
864            try {
865                stmt = db.compileStatement("INSERT INTO system(name,value)"
866                        + " VALUES(?,?);");
867                loadBooleanSetting(stmt, Settings.System.USER_ROTATION,
868                        R.integer.def_user_rotation); // should be zero degrees
869                db.setTransactionSuccessful();
870            } finally {
871                db.endTransaction();
872                if (stmt != null) stmt.close();
873            }
874            upgradeVersion = 60;
875        }
876
877        if (upgradeVersion == 60) {
878            // Don't do this for upgrades from Gingerbread
879            // Were only required for intra-Honeycomb upgrades for testing
880            // upgradeScreenTimeout(db);
881            upgradeVersion = 61;
882        }
883
884        if (upgradeVersion == 61) {
885            // Don't do this for upgrades from Gingerbread
886            // Were only required for intra-Honeycomb upgrades for testing
887            // upgradeScreenTimeout(db);
888            upgradeVersion = 62;
889        }
890
891        // Change the default for screen auto-brightness mode
892        if (upgradeVersion == 62) {
893            // Don't do this for upgrades from Gingerbread
894            // Were only required for intra-Honeycomb upgrades for testing
895            // upgradeAutoBrightness(db);
896            upgradeVersion = 63;
897        }
898
899        if (upgradeVersion == 63) {
900            // This upgrade adds the STREAM_MUSIC type to the list of
901             // types affected by ringer modes (silent, vibrate, etc.)
902             db.beginTransaction();
903             try {
904                 db.execSQL("DELETE FROM system WHERE name='"
905                         + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
906                 int newValue = (1 << AudioManager.STREAM_RING)
907                         | (1 << AudioManager.STREAM_NOTIFICATION)
908                         | (1 << AudioManager.STREAM_SYSTEM)
909                         | (1 << AudioManager.STREAM_SYSTEM_ENFORCED)
910                         | (1 << AudioManager.STREAM_MUSIC);
911                 db.execSQL("INSERT INTO system ('name', 'value') values ('"
912                         + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
913                         + String.valueOf(newValue) + "')");
914                 db.setTransactionSuccessful();
915             } finally {
916                 db.endTransaction();
917             }
918             upgradeVersion = 64;
919         }
920
921        if (upgradeVersion == 64) {
922            // New setting to configure the long press timeout.
923            db.beginTransaction();
924            SQLiteStatement stmt = null;
925            try {
926                stmt = db.compileStatement("INSERT INTO secure(name,value)"
927                        + " VALUES(?,?);");
928                loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
929                        R.integer.def_long_press_timeout_millis);
930                stmt.close();
931                db.setTransactionSuccessful();
932            } finally {
933                db.endTransaction();
934                if (stmt != null) stmt.close();
935            }
936            upgradeVersion = 65;
937        }
938
939        /************* The following are Ice Cream Sandwich changes ************/
940
941        if (upgradeVersion == 65) {
942            /*
943             * Animations are removed from Settings. Turned on by default
944             */
945            db.beginTransaction();
946            SQLiteStatement stmt = null;
947            try {
948                db.execSQL("DELETE FROM system WHERE name='"
949                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
950                db.execSQL("DELETE FROM system WHERE name='"
951                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
952                stmt = db.compileStatement("INSERT INTO system(name,value)"
953                        + " VALUES(?,?);");
954                loadDefaultAnimationSettings(stmt);
955                db.setTransactionSuccessful();
956            } finally {
957                db.endTransaction();
958                if (stmt != null) stmt.close();
959            }
960            upgradeVersion = 66;
961        }
962
963        if (upgradeVersion == 66) {
964            // This upgrade makes sure that MODE_RINGER_STREAMS_AFFECTED is set
965            // according to device voice capability
966            db.beginTransaction();
967            try {
968                int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
969                                                (1 << AudioManager.STREAM_NOTIFICATION) |
970                                                (1 << AudioManager.STREAM_SYSTEM) |
971                                                (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
972                if (!mContext.getResources().getBoolean(
973                        com.android.internal.R.bool.config_voice_capable)) {
974                    ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
975                }
976                db.execSQL("DELETE FROM system WHERE name='"
977                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
978                db.execSQL("INSERT INTO system ('name', 'value') values ('"
979                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
980                        + String.valueOf(ringerModeAffectedStreams) + "')");
981                db.setTransactionSuccessful();
982            } finally {
983                db.endTransaction();
984            }
985            upgradeVersion = 67;
986        }
987
988        if (upgradeVersion == 67) {
989            // New setting to enable touch exploration.
990            db.beginTransaction();
991            SQLiteStatement stmt = null;
992            try {
993                stmt = db.compileStatement("INSERT INTO secure(name,value)"
994                        + " VALUES(?,?);");
995                loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
996                        R.bool.def_touch_exploration_enabled);
997                stmt.close();
998                db.setTransactionSuccessful();
999            } finally {
1000                db.endTransaction();
1001                if (stmt != null) stmt.close();
1002            }
1003            upgradeVersion = 68;
1004        }
1005
1006        if (upgradeVersion == 68) {
1007            // Enable all system sounds by default
1008            db.beginTransaction();
1009            try {
1010                db.execSQL("DELETE FROM system WHERE name='"
1011                        + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "'");
1012                db.setTransactionSuccessful();
1013            } finally {
1014                db.endTransaction();
1015            }
1016            upgradeVersion = 69;
1017        }
1018
1019        if (upgradeVersion == 69) {
1020            // Add RADIO_NFC to AIRPLANE_MODE_RADIO and AIRPLANE_MODE_TOGGLEABLE_RADIOS
1021            String airplaneRadios = mContext.getResources().getString(
1022                    R.string.def_airplane_mode_radios);
1023            String toggleableRadios = mContext.getResources().getString(
1024                    R.string.airplane_mode_toggleable_radios);
1025            db.beginTransaction();
1026            try {
1027                db.execSQL("UPDATE system SET value='" + airplaneRadios + "' " +
1028                        "WHERE name='" + Settings.System.AIRPLANE_MODE_RADIOS + "'");
1029                db.execSQL("UPDATE system SET value='" + toggleableRadios + "' " +
1030                        "WHERE name='" + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
1031                db.setTransactionSuccessful();
1032            } finally {
1033                db.endTransaction();
1034            }
1035            upgradeVersion = 70;
1036        }
1037
1038        if (upgradeVersion == 70) {
1039            // Update all built-in bookmarks.  Some of the package names have changed.
1040            loadBookmarks(db);
1041            upgradeVersion = 71;
1042        }
1043
1044        if (upgradeVersion == 71) {
1045             // New setting to specify whether to speak passwords in accessibility mode.
1046            db.beginTransaction();
1047            SQLiteStatement stmt = null;
1048            try {
1049                stmt = db.compileStatement("INSERT INTO secure(name,value)"
1050                        + " VALUES(?,?);");
1051                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
1052                        R.bool.def_accessibility_speak_password);
1053                db.setTransactionSuccessful();
1054            } finally {
1055                db.endTransaction();
1056                if (stmt != null) stmt.close();
1057            }
1058            upgradeVersion = 72;
1059        }
1060
1061        if (upgradeVersion == 72) {
1062            // update vibration settings
1063            db.beginTransaction();
1064            SQLiteStatement stmt = null;
1065            try {
1066                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1067                        + " VALUES(?,?);");
1068                loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
1069                        R.bool.def_vibrate_in_silent);
1070                db.setTransactionSuccessful();
1071            } finally {
1072                db.endTransaction();
1073                if (stmt != null) stmt.close();
1074            }
1075            upgradeVersion = 73;
1076        }
1077
1078        if (upgradeVersion == 73) {
1079            upgradeVibrateSettingFromNone(db);
1080            upgradeVersion = 74;
1081        }
1082
1083        if (upgradeVersion == 74) {
1084            // URL from which WebView loads a JavaScript based screen-reader.
1085            db.beginTransaction();
1086            SQLiteStatement stmt = null;
1087            try {
1088                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
1089                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
1090                        R.string.def_accessibility_screen_reader_url);
1091                db.setTransactionSuccessful();
1092            } finally {
1093                db.endTransaction();
1094                if (stmt != null) stmt.close();
1095            }
1096            upgradeVersion = 75;
1097        }
1098        if (upgradeVersion == 75) {
1099            db.beginTransaction();
1100            SQLiteStatement stmt = null;
1101            Cursor c = null;
1102            try {
1103                c = db.query(TABLE_SECURE, new String[] {"_id", "value"},
1104                        "name='lockscreen.disabled'",
1105                        null, null, null, null);
1106                // only set default if it has not yet been set
1107                if (c == null || c.getCount() == 0) {
1108                    stmt = db.compileStatement("INSERT INTO system(name,value)"
1109                            + " VALUES(?,?);");
1110                    loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
1111                            R.bool.def_lockscreen_disabled);
1112                }
1113                db.setTransactionSuccessful();
1114            } finally {
1115                db.endTransaction();
1116                if (c != null) c.close();
1117                if (stmt != null) stmt.close();
1118            }
1119            upgradeVersion = 76;
1120        }
1121
1122        /************* The following are Jelly Bean changes ************/
1123
1124        if (upgradeVersion == 76) {
1125            // Removed VIBRATE_IN_SILENT setting
1126            db.beginTransaction();
1127            try {
1128                db.execSQL("DELETE FROM system WHERE name='"
1129                                + Settings.System.VIBRATE_IN_SILENT + "'");
1130                db.setTransactionSuccessful();
1131            } finally {
1132                db.endTransaction();
1133            }
1134
1135            upgradeVersion = 77;
1136        }
1137
1138        if (upgradeVersion == 77) {
1139            // Introduce "vibrate when ringing" setting
1140            loadVibrateWhenRingingSetting(db);
1141
1142            upgradeVersion = 78;
1143        }
1144
1145        if (upgradeVersion == 78) {
1146            // The JavaScript based screen-reader URL changes in JellyBean.
1147            db.beginTransaction();
1148            SQLiteStatement stmt = null;
1149            try {
1150                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
1151                        + " VALUES(?,?);");
1152                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
1153                        R.string.def_accessibility_screen_reader_url);
1154                db.setTransactionSuccessful();
1155            } finally {
1156                db.endTransaction();
1157                if (stmt != null) stmt.close();
1158            }
1159            upgradeVersion = 79;
1160        }
1161
1162        if (upgradeVersion == 79) {
1163            // Before touch exploration was a global setting controlled by the user
1164            // via the UI. However, if the enabled accessibility services do not
1165            // handle touch exploration mode, enabling it makes no sense. Therefore,
1166            // now the services request touch exploration mode and the user is
1167            // presented with a dialog to allow that and if she does we store that
1168            // in the database. As a result of this change a user that has enabled
1169            // accessibility, touch exploration, and some accessibility services
1170            // may lose touch exploration state, thus rendering the device useless
1171            // unless sighted help is provided, since the enabled service(s) are
1172            // not in the list of services to which the user granted a permission
1173            // to put the device in touch explore mode. Here we are allowing all
1174            // enabled accessibility services to toggle touch exploration provided
1175            // accessibility and touch exploration are enabled and no services can
1176            // toggle touch exploration. Note that the user has already manually
1177            // enabled the services and touch exploration which means the she has
1178            // given consent to have these services work in touch exploration mode.
1179            final boolean accessibilityEnabled = getIntValueFromTable(db, TABLE_SECURE,
1180                    Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
1181            final boolean touchExplorationEnabled = getIntValueFromTable(db, TABLE_SECURE,
1182                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
1183            if (accessibilityEnabled && touchExplorationEnabled) {
1184                String enabledServices = getStringValueFromTable(db, TABLE_SECURE,
1185                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
1186                String touchExplorationGrantedServices = getStringValueFromTable(db, TABLE_SECURE,
1187                        Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, "");
1188                if (TextUtils.isEmpty(touchExplorationGrantedServices)
1189                        && !TextUtils.isEmpty(enabledServices)) {
1190                    SQLiteStatement stmt = null;
1191                    try {
1192                        db.beginTransaction();
1193                        stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
1194                                + " VALUES(?,?);");
1195                        loadSetting(stmt,
1196                                Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
1197                                enabledServices);
1198                        db.setTransactionSuccessful();
1199                    } finally {
1200                        db.endTransaction();
1201                        if (stmt != null) stmt.close();
1202                    }
1203                }
1204            }
1205            upgradeVersion = 80;
1206        }
1207
1208        // vvv Jelly Bean MR1 changes begin here vvv
1209
1210        if (upgradeVersion == 80) {
1211            // update screensaver settings
1212            db.beginTransaction();
1213            SQLiteStatement stmt = null;
1214            try {
1215                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
1216                        + " VALUES(?,?);");
1217                loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED,
1218                        com.android.internal.R.bool.config_dreamsEnabledByDefault);
1219                loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
1220                        com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
1221                loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
1222                        com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
1223                loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS,
1224                        com.android.internal.R.string.config_dreamsDefaultComponent);
1225                loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
1226                        com.android.internal.R.string.config_dreamsDefaultComponent);
1227
1228                db.setTransactionSuccessful();
1229            } finally {
1230                db.endTransaction();
1231                if (stmt != null) stmt.close();
1232            }
1233            upgradeVersion = 81;
1234        }
1235
1236        if (upgradeVersion == 81) {
1237            // Add package verification setting
1238            db.beginTransaction();
1239            SQLiteStatement stmt = null;
1240            try {
1241                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
1242                        + " VALUES(?,?);");
1243                loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE,
1244                        R.bool.def_package_verifier_enable);
1245                db.setTransactionSuccessful();
1246            } finally {
1247                db.endTransaction();
1248                if (stmt != null) stmt.close();
1249            }
1250            upgradeVersion = 82;
1251        }
1252
1253        if (upgradeVersion == 82) {
1254            // Move to per-user settings dbs
1255            if (mUserHandle == UserHandle.USER_SYSTEM) {
1256
1257                db.beginTransaction();
1258                SQLiteStatement stmt = null;
1259                try {
1260                    // Migrate now-global settings. Note that this happens before
1261                    // new users can be created.
1262                    createGlobalTable(db);
1263                    String[] settingsToMove = setToStringArray(
1264                            SettingsProvider.sSystemMovedToGlobalSettings);
1265                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, false);
1266                    settingsToMove = setToStringArray(
1267                            SettingsProvider.sSecureMovedToGlobalSettings);
1268                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, false);
1269
1270                    db.setTransactionSuccessful();
1271                } finally {
1272                    db.endTransaction();
1273                    if (stmt != null) stmt.close();
1274                }
1275            }
1276            upgradeVersion = 83;
1277        }
1278
1279        if (upgradeVersion == 83) {
1280            // 1. Setting whether screen magnification is enabled.
1281            // 2. Setting for screen magnification scale.
1282            // 3. Setting for screen magnification auto update.
1283            db.beginTransaction();
1284            SQLiteStatement stmt = null;
1285            try {
1286                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
1287                loadBooleanSetting(stmt,
1288                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
1289                        R.bool.def_accessibility_display_magnification_enabled);
1290                stmt.close();
1291                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
1292                loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
1293                        R.fraction.def_accessibility_display_magnification_scale, 1);
1294                stmt.close();
1295                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
1296                loadBooleanSetting(stmt,
1297                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
1298                        R.bool.def_accessibility_display_magnification_auto_update);
1299
1300                db.setTransactionSuccessful();
1301            } finally {
1302                db.endTransaction();
1303                if (stmt != null) stmt.close();
1304            }
1305            upgradeVersion = 84;
1306        }
1307
1308        if (upgradeVersion == 84) {
1309            if (mUserHandle == UserHandle.USER_SYSTEM) {
1310                db.beginTransaction();
1311                SQLiteStatement stmt = null;
1312                try {
1313                    // Patch up the slightly-wrong key migration from 82 -> 83 for those
1314                    // devices that missed it, ignoring if the move is redundant
1315                    String[] settingsToMove = {
1316                            Settings.Secure.ADB_ENABLED,
1317                            Settings.Secure.BLUETOOTH_ON,
1318                            Settings.Secure.DATA_ROAMING,
1319                            Settings.Secure.DEVICE_PROVISIONED,
1320                            Settings.Secure.INSTALL_NON_MARKET_APPS,
1321                            Settings.Secure.USB_MASS_STORAGE_ENABLED
1322                    };
1323                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1324                    db.setTransactionSuccessful();
1325                } finally {
1326                    db.endTransaction();
1327                    if (stmt != null) stmt.close();
1328                }
1329            }
1330            upgradeVersion = 85;
1331        }
1332
1333        if (upgradeVersion == 85) {
1334            if (mUserHandle == UserHandle.USER_SYSTEM) {
1335                db.beginTransaction();
1336                try {
1337                    // Fix up the migration, ignoring already-migrated elements, to snap up to
1338                    // date with new changes to the set of global versus system/secure settings
1339                    String[] settingsToMove = { Settings.System.STAY_ON_WHILE_PLUGGED_IN };
1340                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);
1341
1342                    db.setTransactionSuccessful();
1343                } finally {
1344                    db.endTransaction();
1345                }
1346            }
1347            upgradeVersion = 86;
1348        }
1349
1350        if (upgradeVersion == 86) {
1351            if (mUserHandle == UserHandle.USER_SYSTEM) {
1352                db.beginTransaction();
1353                try {
1354                    String[] settingsToMove = {
1355                            Settings.Global.PACKAGE_VERIFIER_ENABLE,
1356                            Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
1357                            Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE
1358                    };
1359                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1360
1361                    db.setTransactionSuccessful();
1362                } finally {
1363                    db.endTransaction();
1364                }
1365            }
1366            upgradeVersion = 87;
1367        }
1368
1369        if (upgradeVersion == 87) {
1370            if (mUserHandle == UserHandle.USER_SYSTEM) {
1371                db.beginTransaction();
1372                try {
1373                    String[] settingsToMove = {
1374                            Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
1375                            Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
1376                            Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS
1377                    };
1378                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1379
1380                    db.setTransactionSuccessful();
1381                } finally {
1382                    db.endTransaction();
1383                }
1384            }
1385            upgradeVersion = 88;
1386        }
1387
1388        if (upgradeVersion == 88) {
1389            if (mUserHandle == UserHandle.USER_SYSTEM) {
1390                db.beginTransaction();
1391                try {
1392                    String[] settingsToMove = {
1393                            Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD,
1394                            Settings.Global.BATTERY_DISCHARGE_THRESHOLD,
1395                            Settings.Global.SEND_ACTION_APP_ERROR,
1396                            Settings.Global.DROPBOX_AGE_SECONDS,
1397                            Settings.Global.DROPBOX_MAX_FILES,
1398                            Settings.Global.DROPBOX_QUOTA_KB,
1399                            Settings.Global.DROPBOX_QUOTA_PERCENT,
1400                            Settings.Global.DROPBOX_RESERVE_PERCENT,
1401                            Settings.Global.DROPBOX_TAG_PREFIX,
1402                            Settings.Global.ERROR_LOGCAT_PREFIX,
1403                            Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL,
1404                            Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD,
1405                            Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE,
1406                            Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES,
1407                            Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES,
1408                            Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS,
1409                            Settings.Global.CONNECTIVITY_CHANGE_DELAY,
1410                            Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED,
1411                            Settings.Global.CAPTIVE_PORTAL_SERVER,
1412                            Settings.Global.NSD_ON,
1413                            Settings.Global.SET_INSTALL_LOCATION,
1414                            Settings.Global.DEFAULT_INSTALL_LOCATION,
1415                            Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY,
1416                            Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY,
1417                            Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
1418                            Settings.Global.HTTP_PROXY,
1419                            Settings.Global.GLOBAL_HTTP_PROXY_HOST,
1420                            Settings.Global.GLOBAL_HTTP_PROXY_PORT,
1421                            Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
1422                            Settings.Global.SET_GLOBAL_HTTP_PROXY,
1423                            Settings.Global.DEFAULT_DNS_SERVER,
1424                    };
1425                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1426                    db.setTransactionSuccessful();
1427                } finally {
1428                    db.endTransaction();
1429                }
1430            }
1431            upgradeVersion = 89;
1432        }
1433
1434        if (upgradeVersion == 89) {
1435            if (mUserHandle == UserHandle.USER_SYSTEM) {
1436                db.beginTransaction();
1437                try {
1438                    String[] prefixesToMove = {
1439                            Settings.Global.BLUETOOTH_HEADSET_PRIORITY_PREFIX,
1440                            Settings.Global.BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX,
1441                            Settings.Global.BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX,
1442                    };
1443
1444                    movePrefixedSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, prefixesToMove);
1445
1446                    db.setTransactionSuccessful();
1447                } finally {
1448                    db.endTransaction();
1449                }
1450            }
1451            upgradeVersion = 90;
1452        }
1453
1454        if (upgradeVersion == 90) {
1455            if (mUserHandle == UserHandle.USER_SYSTEM) {
1456                db.beginTransaction();
1457                try {
1458                    String[] systemToGlobal = {
1459                            Settings.Global.WINDOW_ANIMATION_SCALE,
1460                            Settings.Global.TRANSITION_ANIMATION_SCALE,
1461                            Settings.Global.ANIMATOR_DURATION_SCALE,
1462                            Settings.Global.FANCY_IME_ANIMATIONS,
1463                            Settings.Global.COMPATIBILITY_MODE,
1464                            Settings.Global.EMERGENCY_TONE,
1465                            Settings.Global.CALL_AUTO_RETRY,
1466                            Settings.Global.DEBUG_APP,
1467                            Settings.Global.WAIT_FOR_DEBUGGER,
1468                            Settings.Global.SHOW_PROCESSES,
1469                            Settings.Global.ALWAYS_FINISH_ACTIVITIES,
1470                    };
1471                    String[] secureToGlobal = {
1472                            Settings.Global.PREFERRED_NETWORK_MODE,
1473                            Settings.Global.CDMA_SUBSCRIPTION_MODE,
1474                    };
1475
1476                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, systemToGlobal, true);
1477                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, secureToGlobal, true);
1478
1479                    db.setTransactionSuccessful();
1480                } finally {
1481                    db.endTransaction();
1482                }
1483            }
1484            upgradeVersion = 91;
1485        }
1486
1487        if (upgradeVersion == 91) {
1488            if (mUserHandle == UserHandle.USER_SYSTEM) {
1489                db.beginTransaction();
1490                try {
1491                    // Move ringer mode from system to global settings
1492                    String[] settingsToMove = { Settings.Global.MODE_RINGER };
1493                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);
1494
1495                    db.setTransactionSuccessful();
1496                } finally {
1497                    db.endTransaction();
1498                }
1499            }
1500            upgradeVersion = 92;
1501        }
1502
1503        if (upgradeVersion == 92) {
1504            SQLiteStatement stmt = null;
1505            try {
1506                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1507                        + " VALUES(?,?);");
1508                if (mUserHandle == UserHandle.USER_SYSTEM) {
1509                    // consider existing primary users to have made it through user setup
1510                    // if the globally-scoped device-provisioned bit is set
1511                    // (indicating they already made it through setup as primary)
1512                    int deviceProvisioned = getIntValueFromTable(db, TABLE_GLOBAL,
1513                            Settings.Global.DEVICE_PROVISIONED, 0);
1514                    loadSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
1515                            deviceProvisioned);
1516                } else {
1517                    // otherwise use the default
1518                    loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
1519                            R.bool.def_user_setup_complete);
1520                }
1521            } finally {
1522                if (stmt != null) stmt.close();
1523            }
1524            upgradeVersion = 93;
1525        }
1526
1527        if (upgradeVersion == 93) {
1528            // Redo this step, since somehow it didn't work the first time for some users
1529            if (mUserHandle == UserHandle.USER_SYSTEM) {
1530                db.beginTransaction();
1531                try {
1532                    // Migrate now-global settings
1533                    String[] settingsToMove = setToStringArray(
1534                            SettingsProvider.sSystemMovedToGlobalSettings);
1535                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);
1536                    settingsToMove = setToStringArray(
1537                            SettingsProvider.sSecureMovedToGlobalSettings);
1538                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1539
1540                    db.setTransactionSuccessful();
1541                } finally {
1542                    db.endTransaction();
1543                }
1544            }
1545            upgradeVersion = 94;
1546        }
1547
1548        if (upgradeVersion == 94) {
1549            // Add wireless charging started sound setting
1550            if (mUserHandle == UserHandle.USER_SYSTEM) {
1551                db.beginTransaction();
1552                SQLiteStatement stmt = null;
1553                try {
1554                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1555                            + " VALUES(?,?);");
1556                    loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
1557                            R.string.def_wireless_charging_started_sound);
1558                    db.setTransactionSuccessful();
1559                } finally {
1560                    db.endTransaction();
1561                    if (stmt != null) stmt.close();
1562                }
1563            }
1564            upgradeVersion = 95;
1565        }
1566
1567        if (upgradeVersion == 95) {
1568            if (mUserHandle == UserHandle.USER_SYSTEM) {
1569                db.beginTransaction();
1570                try {
1571                    String[] settingsToMove = { Settings.Global.BUGREPORT_IN_POWER_MENU };
1572                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1573                    db.setTransactionSuccessful();
1574                } finally {
1575                    db.endTransaction();
1576                }
1577            }
1578            upgradeVersion = 96;
1579        }
1580
1581        if (upgradeVersion == 96) {
1582            // NOP bump due to a reverted change that some people got on upgrade.
1583            upgradeVersion = 97;
1584        }
1585
1586        if (upgradeVersion == 97) {
1587            if (mUserHandle == UserHandle.USER_SYSTEM) {
1588                db.beginTransaction();
1589                SQLiteStatement stmt = null;
1590                try {
1591                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1592                            + " VALUES(?,?);");
1593                    loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
1594                            R.integer.def_low_battery_sound_timeout);
1595                    db.setTransactionSuccessful();
1596                } finally {
1597                    db.endTransaction();
1598                    if (stmt != null) stmt.close();
1599                }
1600            }
1601            upgradeVersion = 98;
1602        }
1603
1604        if (upgradeVersion == 98) {
1605            // no-op; LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
1606            upgradeVersion = 99;
1607        }
1608
1609        if (upgradeVersion == 99) {
1610            // no-op; HEADS_UP_NOTIFICATIONS_ENABLED now handled in version 100
1611            upgradeVersion = 100;
1612        }
1613
1614        if (upgradeVersion == 100) {
1615            // note: LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
1616            if (mUserHandle == UserHandle.USER_SYSTEM) {
1617                db.beginTransaction();
1618                SQLiteStatement stmt = null;
1619                try {
1620                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1621                            + " VALUES(?,?);");
1622                    loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
1623                            R.integer.def_heads_up_enabled);
1624                    db.setTransactionSuccessful();
1625                } finally {
1626                    db.endTransaction();
1627                    if (stmt != null) stmt.close();
1628                }
1629            }
1630            upgradeVersion = 101;
1631        }
1632
1633        if (upgradeVersion == 101) {
1634            if (mUserHandle == UserHandle.USER_SYSTEM) {
1635                db.beginTransaction();
1636                SQLiteStatement stmt = null;
1637                try {
1638                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
1639                            + " VALUES(?,?);");
1640                    loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());
1641                    db.setTransactionSuccessful();
1642                } finally {
1643                    db.endTransaction();
1644                    if (stmt != null) stmt.close();
1645                }
1646            }
1647            upgradeVersion = 102;
1648        }
1649
1650        if (upgradeVersion == 102) {
1651            db.beginTransaction();
1652            SQLiteStatement stmt = null;
1653            try {
1654                // The INSTALL_NON_MARKET_APPS setting is becoming per-user rather
1655                // than device-global.
1656                if (mUserHandle == UserHandle.USER_SYSTEM) {
1657                    // In the owner user, the global table exists so we can migrate the
1658                    // entry from there to the secure table, preserving its value.
1659                    String[] globalToSecure = {
1660                            Settings.Secure.INSTALL_NON_MARKET_APPS
1661                    };
1662                    moveSettingsToNewTable(db, TABLE_GLOBAL, TABLE_SECURE, globalToSecure, true);
1663                } else {
1664                    // Secondary users' dbs don't have the global table, so institute the
1665                    // default.
1666                    stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1667                            + " VALUES(?,?);");
1668                    loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
1669                            R.bool.def_install_non_market_apps);
1670                }
1671                db.setTransactionSuccessful();
1672            } finally {
1673                db.endTransaction();
1674                if (stmt != null) stmt.close();
1675            }
1676            upgradeVersion = 103;
1677        }
1678
1679        if (upgradeVersion == 103) {
1680            db.beginTransaction();
1681            SQLiteStatement stmt = null;
1682            try {
1683                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
1684                        + " VALUES(?,?);");
1685                loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
1686                        R.bool.def_wake_gesture_enabled);
1687                db.setTransactionSuccessful();
1688            } finally {
1689                db.endTransaction();
1690                if (stmt != null) stmt.close();
1691            }
1692            upgradeVersion = 104;
1693        }
1694
1695        if (upgradeVersion < 105) {
1696            if (mUserHandle == UserHandle.USER_SYSTEM) {
1697                db.beginTransaction();
1698                SQLiteStatement stmt = null;
1699                try {
1700                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
1701                            + " VALUES(?,?);");
1702                    loadBooleanSetting(stmt, Settings.Global.GUEST_USER_ENABLED,
1703                            R.bool.def_guest_user_enabled);
1704                    db.setTransactionSuccessful();
1705                } finally {
1706                    db.endTransaction();
1707                    if (stmt != null) stmt.close();
1708                }
1709            }
1710            upgradeVersion = 105;
1711        }
1712
1713        if (upgradeVersion < 106) {
1714            // LOCK_SCREEN_SHOW_NOTIFICATIONS is now per-user.
1715            db.beginTransaction();
1716            SQLiteStatement stmt = null;
1717            try {
1718                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1719                        + " VALUES(?,?);");
1720                loadIntegerSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
1721                        R.integer.def_lock_screen_show_notifications);
1722                if (mUserHandle == UserHandle.USER_SYSTEM) {
1723                    final int oldShow = getIntValueFromTable(db,
1724                            TABLE_GLOBAL, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, -1);
1725                    if (oldShow >= 0) {
1726                        // overwrite the default with whatever you had
1727                        loadSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, oldShow);
1728                        final SQLiteStatement deleteStmt
1729                                = db.compileStatement("DELETE FROM global WHERE name=?");
1730                        deleteStmt.bindString(1, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
1731                        deleteStmt.execute();
1732                    }
1733                }
1734                db.setTransactionSuccessful();
1735            } finally {
1736                db.endTransaction();
1737                if (stmt != null) stmt.close();
1738            }
1739            upgradeVersion = 106;
1740        }
1741
1742        if (upgradeVersion < 107) {
1743            // Add trusted sound setting
1744            if (mUserHandle == UserHandle.USER_SYSTEM) {
1745                db.beginTransaction();
1746                SQLiteStatement stmt = null;
1747                try {
1748                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1749                            + " VALUES(?,?);");
1750                    loadStringSetting(stmt, Settings.Global.TRUSTED_SOUND,
1751                            R.string.def_trusted_sound);
1752                    db.setTransactionSuccessful();
1753                } finally {
1754                    db.endTransaction();
1755                    if (stmt != null) stmt.close();
1756                }
1757            }
1758            upgradeVersion = 107;
1759        }
1760
1761        if (upgradeVersion < 108) {
1762            // Reset the auto-brightness setting to default since the behavior
1763            // of the feature is now quite different and is being presented to
1764            // the user in a new way as "adaptive brightness".
1765            db.beginTransaction();
1766            SQLiteStatement stmt = null;
1767            try {
1768                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1769                        + " VALUES(?,?);");
1770                loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
1771                        R.bool.def_screen_brightness_automatic_mode);
1772                db.setTransactionSuccessful();
1773            } finally {
1774                db.endTransaction();
1775                if (stmt != null) stmt.close();
1776            }
1777            upgradeVersion = 108;
1778        }
1779
1780        if (upgradeVersion < 109) {
1781            db.beginTransaction();
1782            SQLiteStatement stmt = null;
1783            try {
1784                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1785                        + " VALUES(?,?);");
1786                loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
1787                        R.bool.def_lock_screen_allow_private_notifications);
1788                db.setTransactionSuccessful();
1789            } finally {
1790                db.endTransaction();
1791                if (stmt != null) stmt.close();
1792            }
1793            upgradeVersion = 109;
1794        }
1795
1796        if (upgradeVersion < 110) {
1797            // The SIP_CALL_OPTIONS value SIP_ASK_EACH_TIME is being deprecated.
1798            // If the SIP_CALL_OPTIONS setting is set to SIP_ASK_EACH_TIME, default to
1799            // SIP_ADDRESS_ONLY.
1800            db.beginTransaction();
1801            SQLiteStatement stmt = null;
1802            try {
1803                stmt = db.compileStatement("UPDATE system SET value = ? " +
1804                        "WHERE name = ? AND value = ?;");
1805                stmt.bindString(1, Settings.System.SIP_ADDRESS_ONLY);
1806                stmt.bindString(2, Settings.System.SIP_CALL_OPTIONS);
1807                stmt.bindString(3, Settings.System.SIP_ASK_ME_EACH_TIME);
1808                stmt.execute();
1809                db.setTransactionSuccessful();
1810            } finally {
1811                db.endTransaction();
1812                if (stmt != null) stmt.close();
1813            }
1814            upgradeVersion = 110;
1815        }
1816
1817        if (upgradeVersion < 111) {
1818            // reset ringer mode, so it doesn't force zen mode to follow
1819            if (mUserHandle == UserHandle.USER_SYSTEM) {
1820                db.beginTransaction();
1821                SQLiteStatement stmt = null;
1822                try {
1823                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1824                            + " VALUES(?,?);");
1825                    loadSetting(stmt, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
1826                    db.setTransactionSuccessful();
1827                } finally {
1828                    db.endTransaction();
1829                    if (stmt != null) stmt.close();
1830                }
1831            }
1832            upgradeVersion = 111;
1833        }
1834
1835        if (upgradeVersion < 112) {
1836            if (mUserHandle == UserHandle.USER_SYSTEM) {
1837                // When device name was added, we went with Manufacturer + Model, device name should
1838                // actually be Model only.
1839                // Update device name to Model if it wasn't modified by user.
1840                db.beginTransaction();
1841                SQLiteStatement stmt = null;
1842                try {
1843                    stmt = db.compileStatement("UPDATE global SET value = ? "
1844                        + " WHERE name = ? AND value = ?");
1845                    stmt.bindString(1, getDefaultDeviceName()); // new default device name
1846                    stmt.bindString(2, Settings.Global.DEVICE_NAME);
1847                    stmt.bindString(3, getOldDefaultDeviceName()); // old default device name
1848                    stmt.execute();
1849                    db.setTransactionSuccessful();
1850                } finally {
1851                    db.endTransaction();
1852                    if (stmt != null) stmt.close();
1853                }
1854            }
1855            upgradeVersion = 112;
1856        }
1857
1858        if (upgradeVersion < 113) {
1859            db.beginTransaction();
1860            SQLiteStatement stmt = null;
1861            try {
1862                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1863                        + " VALUES(?,?);");
1864                loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
1865                        R.integer.def_sleep_timeout);
1866                db.setTransactionSuccessful();
1867            } finally {
1868                db.endTransaction();
1869                if (stmt != null) stmt.close();
1870            }
1871            upgradeVersion = 113;
1872        }
1873
1874        // We skipped 114 to handle a merge conflict with the introduction of theater mode.
1875
1876        if (upgradeVersion < 115) {
1877            if (mUserHandle == UserHandle.USER_SYSTEM) {
1878                db.beginTransaction();
1879                SQLiteStatement stmt = null;
1880                try {
1881                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
1882                            + " VALUES(?,?);");
1883                    loadBooleanSetting(stmt, Global.THEATER_MODE_ON,
1884                            R.bool.def_theater_mode_on);
1885                    db.setTransactionSuccessful();
1886                } finally {
1887                    db.endTransaction();
1888                    if (stmt != null) stmt.close();
1889                }
1890            }
1891            upgradeVersion = 115;
1892        }
1893
1894        if (upgradeVersion < 116) {
1895            if (mUserHandle == UserHandle.USER_SYSTEM) {
1896                db.beginTransaction();
1897                SQLiteStatement stmt = null;
1898                try {
1899                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
1900                            + " VALUES(?,?);");
1901                    loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
1902                            ImsConfig.FeatureValueConstants.ON);
1903                    db.setTransactionSuccessful();
1904                } finally {
1905                    db.endTransaction();
1906                    if (stmt != null) stmt.close();
1907                }
1908            }
1909            upgradeVersion = 116;
1910        }
1911
1912        if (upgradeVersion < 117) {
1913            db.beginTransaction();
1914            try {
1915                String[] systemToSecure = {
1916                        Settings.Secure.LOCK_TO_APP_EXIT_LOCKED
1917                };
1918                moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, systemToSecure, true);
1919                db.setTransactionSuccessful();
1920            } finally {
1921                db.endTransaction();
1922            }
1923            upgradeVersion = 117;
1924        }
1925
1926        if (upgradeVersion < 118) {
1927            // Reset rotation-lock-for-accessibility on upgrade, since it now hides the display
1928            // setting.
1929            db.beginTransaction();
1930            SQLiteStatement stmt = null;
1931            try {
1932                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1933                        + " VALUES(?,?);");
1934                loadSetting(stmt, Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0);
1935                db.setTransactionSuccessful();
1936            } finally {
1937                db.endTransaction();
1938                if (stmt != null) stmt.close();
1939            }
1940            upgradeVersion = 118;
1941        }
1942
1943        /*
1944         * IMPORTANT: Do not add any more upgrade steps here as the global,
1945         * secure, and system settings are no longer stored in a database
1946         * but are kept in memory and persisted to XML.
1947         *
1948         * See: SettingsProvider.UpgradeController#onUpgradeLocked
1949         */
1950
1951        if (upgradeVersion != currentVersion) {
1952            recreateDatabase(db, oldVersion, upgradeVersion, currentVersion);
1953        }
1954    }
1955
1956    public void recreateDatabase(SQLiteDatabase db, int oldVersion,
1957            int upgradeVersion, int currentVersion) {
1958        db.execSQL("DROP TABLE IF EXISTS global");
1959        db.execSQL("DROP TABLE IF EXISTS globalIndex1");
1960        db.execSQL("DROP TABLE IF EXISTS system");
1961        db.execSQL("DROP INDEX IF EXISTS systemIndex1");
1962        db.execSQL("DROP TABLE IF EXISTS secure");
1963        db.execSQL("DROP INDEX IF EXISTS secureIndex1");
1964        db.execSQL("DROP TABLE IF EXISTS gservices");
1965        db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
1966        db.execSQL("DROP TABLE IF EXISTS bluetooth_devices");
1967        db.execSQL("DROP TABLE IF EXISTS bookmarks");
1968        db.execSQL("DROP INDEX IF EXISTS bookmarksIndex1");
1969        db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
1970        db.execSQL("DROP TABLE IF EXISTS favorites");
1971
1972        onCreate(db);
1973
1974        // Added for diagnosing settings.db wipes after the fact
1975        String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion;
1976        db.execSQL("INSERT INTO secure(name,value) values('" +
1977                "wiped_db_reason" + "','" + wipeReason + "');");
1978    }
1979
1980    private String[] setToStringArray(Set<String> set) {
1981        String[] array = new String[set.size()];
1982        return set.toArray(array);
1983    }
1984
1985    private void moveSettingsToNewTable(SQLiteDatabase db,
1986            String sourceTable, String destTable,
1987            String[] settingsToMove, boolean doIgnore) {
1988        // Copy settings values from the source table to the dest, and remove from the source
1989        SQLiteStatement insertStmt = null;
1990        SQLiteStatement deleteStmt = null;
1991
1992        db.beginTransaction();
1993        try {
1994            insertStmt = db.compileStatement("INSERT "
1995                    + (doIgnore ? " OR IGNORE " : "")
1996                    + " INTO " + destTable + " (name,value) SELECT name,value FROM "
1997                    + sourceTable + " WHERE name=?");
1998            deleteStmt = db.compileStatement("DELETE FROM " + sourceTable + " WHERE name=?");
1999
2000            for (String setting : settingsToMove) {
2001                insertStmt.bindString(1, setting);
2002                insertStmt.execute();
2003
2004                deleteStmt.bindString(1, setting);
2005                deleteStmt.execute();
2006            }
2007            db.setTransactionSuccessful();
2008        } finally {
2009            db.endTransaction();
2010            if (insertStmt != null) {
2011                insertStmt.close();
2012            }
2013            if (deleteStmt != null) {
2014                deleteStmt.close();
2015            }
2016        }
2017    }
2018
2019    /**
2020     * Move any settings with the given prefixes from the source table to the
2021     * destination table.
2022     */
2023    private void movePrefixedSettingsToNewTable(
2024            SQLiteDatabase db, String sourceTable, String destTable, String[] prefixesToMove) {
2025        SQLiteStatement insertStmt = null;
2026        SQLiteStatement deleteStmt = null;
2027
2028        db.beginTransaction();
2029        try {
2030            insertStmt = db.compileStatement("INSERT INTO " + destTable
2031                    + " (name,value) SELECT name,value FROM " + sourceTable
2032                    + " WHERE substr(name,0,?)=?");
2033            deleteStmt = db.compileStatement(
2034                    "DELETE FROM " + sourceTable + " WHERE substr(name,0,?)=?");
2035
2036            for (String prefix : prefixesToMove) {
2037                insertStmt.bindLong(1, prefix.length() + 1);
2038                insertStmt.bindString(2, prefix);
2039                insertStmt.execute();
2040
2041                deleteStmt.bindLong(1, prefix.length() + 1);
2042                deleteStmt.bindString(2, prefix);
2043                deleteStmt.execute();
2044            }
2045            db.setTransactionSuccessful();
2046        } finally {
2047            db.endTransaction();
2048            if (insertStmt != null) {
2049                insertStmt.close();
2050            }
2051            if (deleteStmt != null) {
2052                deleteStmt.close();
2053            }
2054        }
2055    }
2056
2057    private void upgradeLockPatternLocation(SQLiteDatabase db) {
2058        Cursor c = db.query(TABLE_SYSTEM, new String[] {"_id", "value"}, "name='lock_pattern'",
2059                null, null, null, null);
2060        if (c.getCount() > 0) {
2061            c.moveToFirst();
2062            String lockPattern = c.getString(1);
2063            if (!TextUtils.isEmpty(lockPattern)) {
2064                // Convert lock pattern
2065                try {
2066                    LockPatternUtils lpu = new LockPatternUtils(mContext);
2067                    List<LockPatternView.Cell> cellPattern =
2068                            LockPatternUtils.stringToPattern(lockPattern);
2069                    lpu.saveLockPattern(cellPattern, null, UserHandle.USER_SYSTEM);
2070                } catch (IllegalArgumentException e) {
2071                    // Don't want corrupted lock pattern to hang the reboot process
2072                }
2073            }
2074            c.close();
2075            db.delete(TABLE_SYSTEM, "name='lock_pattern'", null);
2076        } else {
2077            c.close();
2078        }
2079    }
2080
2081    private void upgradeScreenTimeoutFromNever(SQLiteDatabase db) {
2082        // See if the timeout is -1 (for "Never").
2083        Cursor c = db.query(TABLE_SYSTEM, new String[] { "_id", "value" }, "name=? AND value=?",
2084                new String[] { Settings.System.SCREEN_OFF_TIMEOUT, "-1" },
2085                null, null, null);
2086
2087        SQLiteStatement stmt = null;
2088        if (c.getCount() > 0) {
2089            c.close();
2090            try {
2091                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
2092                        + " VALUES(?,?);");
2093
2094                // Set the timeout to 30 minutes in milliseconds
2095                loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
2096                        Integer.toString(30 * 60 * 1000));
2097            } finally {
2098                if (stmt != null) stmt.close();
2099            }
2100        } else {
2101            c.close();
2102        }
2103    }
2104
2105    private void upgradeVibrateSettingFromNone(SQLiteDatabase db) {
2106        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON, 0);
2107        // If the ringer vibrate value is invalid, set it to the default
2108        if ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_OFF) {
2109            vibrateSetting = AudioSystem.getValueForVibrateSetting(0,
2110                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
2111        }
2112        // Apply the same setting to the notification vibrate value
2113        vibrateSetting = AudioSystem.getValueForVibrateSetting(vibrateSetting,
2114                AudioManager.VIBRATE_TYPE_NOTIFICATION, vibrateSetting);
2115
2116        SQLiteStatement stmt = null;
2117        try {
2118            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
2119                    + " VALUES(?,?);");
2120            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrateSetting);
2121        } finally {
2122            if (stmt != null)
2123                stmt.close();
2124        }
2125    }
2126
2127    private void upgradeScreenTimeout(SQLiteDatabase db) {
2128        // Change screen timeout to current default
2129        db.beginTransaction();
2130        SQLiteStatement stmt = null;
2131        try {
2132            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
2133                    + " VALUES(?,?);");
2134            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
2135                    R.integer.def_screen_off_timeout);
2136            db.setTransactionSuccessful();
2137        } finally {
2138            db.endTransaction();
2139            if (stmt != null)
2140                stmt.close();
2141        }
2142    }
2143
2144    private void upgradeAutoBrightness(SQLiteDatabase db) {
2145        db.beginTransaction();
2146        try {
2147            String value =
2148                    mContext.getResources().getBoolean(
2149                    R.bool.def_screen_brightness_automatic_mode) ? "1" : "0";
2150            db.execSQL("INSERT OR REPLACE INTO system(name,value) values('" +
2151                    Settings.System.SCREEN_BRIGHTNESS_MODE + "','" + value + "');");
2152            db.setTransactionSuccessful();
2153        } finally {
2154            db.endTransaction();
2155        }
2156    }
2157
2158    /**
2159     * Loads the default set of bookmarked shortcuts from an xml file.
2160     *
2161     * @param db The database to write the values into
2162     */
2163    private void loadBookmarks(SQLiteDatabase db) {
2164        ContentValues values = new ContentValues();
2165
2166        PackageManager packageManager = mContext.getPackageManager();
2167        try {
2168            XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
2169            XmlUtils.beginDocument(parser, "bookmarks");
2170
2171            final int depth = parser.getDepth();
2172            int type;
2173
2174            while (((type = parser.next()) != XmlPullParser.END_TAG ||
2175                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
2176
2177                if (type != XmlPullParser.START_TAG) {
2178                    continue;
2179                }
2180
2181                String name = parser.getName();
2182                if (!"bookmark".equals(name)) {
2183                    break;
2184                }
2185
2186                String pkg = parser.getAttributeValue(null, "package");
2187                String cls = parser.getAttributeValue(null, "class");
2188                String shortcutStr = parser.getAttributeValue(null, "shortcut");
2189                String category = parser.getAttributeValue(null, "category");
2190
2191                int shortcutValue = shortcutStr.charAt(0);
2192                if (TextUtils.isEmpty(shortcutStr)) {
2193                    Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
2194                    continue;
2195                }
2196
2197                final Intent intent;
2198                final String title;
2199                if (pkg != null && cls != null) {
2200                    ActivityInfo info = null;
2201                    ComponentName cn = new ComponentName(pkg, cls);
2202                    try {
2203                        info = packageManager.getActivityInfo(cn, 0);
2204                    } catch (PackageManager.NameNotFoundException e) {
2205                        String[] packages = packageManager.canonicalToCurrentPackageNames(
2206                                new String[] { pkg });
2207                        cn = new ComponentName(packages[0], cls);
2208                        try {
2209                            info = packageManager.getActivityInfo(cn, 0);
2210                        } catch (PackageManager.NameNotFoundException e1) {
2211                            Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
2212                            continue;
2213                        }
2214                    }
2215
2216                    intent = new Intent(Intent.ACTION_MAIN, null);
2217                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
2218                    intent.setComponent(cn);
2219                    title = info.loadLabel(packageManager).toString();
2220                } else if (category != null) {
2221                    intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
2222                    title = "";
2223                } else {
2224                    Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr
2225                            + ": missing package/class or category attributes");
2226                    continue;
2227                }
2228
2229                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2230                values.put(Settings.Bookmarks.INTENT, intent.toUri(0));
2231                values.put(Settings.Bookmarks.TITLE, title);
2232                values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
2233                db.delete("bookmarks", "shortcut = ?",
2234                        new String[] { Integer.toString(shortcutValue) });
2235                db.insert("bookmarks", null, values);
2236            }
2237        } catch (XmlPullParserException e) {
2238            Log.w(TAG, "Got execption parsing bookmarks.", e);
2239        } catch (IOException e) {
2240            Log.w(TAG, "Got execption parsing bookmarks.", e);
2241        }
2242    }
2243
2244    /**
2245     * Loads the default volume levels. It is actually inserting the index of
2246     * the volume array for each of the volume controls.
2247     *
2248     * @param db the database to insert the volume levels into
2249     */
2250    private void loadVolumeLevels(SQLiteDatabase db) {
2251        SQLiteStatement stmt = null;
2252        try {
2253            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2254                    + " VALUES(?,?);");
2255
2256            loadSetting(stmt, Settings.System.VOLUME_MUSIC,
2257                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_MUSIC));
2258            loadSetting(stmt, Settings.System.VOLUME_RING,
2259                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_RING));
2260            loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
2261                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_SYSTEM));
2262            loadSetting(
2263                    stmt,
2264                    Settings.System.VOLUME_VOICE,
2265                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_VOICE_CALL));
2266            loadSetting(stmt, Settings.System.VOLUME_ALARM,
2267                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_ALARM));
2268            loadSetting(
2269                    stmt,
2270                    Settings.System.VOLUME_NOTIFICATION,
2271                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_NOTIFICATION));
2272            loadSetting(
2273                    stmt,
2274                    Settings.System.VOLUME_BLUETOOTH_SCO,
2275                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO));
2276
2277            // By default:
2278            // - ringtones, notification, system and music streams are affected by ringer mode
2279            // on non voice capable devices (tablets)
2280            // - ringtones, notification and system streams are affected by ringer mode
2281            // on voice capable devices (phones)
2282            int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
2283                                            (1 << AudioManager.STREAM_NOTIFICATION) |
2284                                            (1 << AudioManager.STREAM_SYSTEM) |
2285                                            (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
2286            if (!mContext.getResources().getBoolean(
2287                    com.android.internal.R.bool.config_voice_capable)) {
2288                ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
2289            }
2290            loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
2291                    ringerModeAffectedStreams);
2292
2293            loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
2294                    AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED);
2295        } finally {
2296            if (stmt != null) stmt.close();
2297        }
2298
2299        loadVibrateWhenRingingSetting(db);
2300    }
2301
2302    private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
2303        if (deleteOld) {
2304            db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
2305        }
2306
2307        SQLiteStatement stmt = null;
2308        try {
2309            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2310                    + " VALUES(?,?);");
2311
2312            // Vibrate on by default for ringer, on for notification
2313            int vibrate = 0;
2314            vibrate = AudioSystem.getValueForVibrateSetting(vibrate,
2315                    AudioManager.VIBRATE_TYPE_NOTIFICATION,
2316                    AudioManager.VIBRATE_SETTING_ONLY_SILENT);
2317            vibrate |= AudioSystem.getValueForVibrateSetting(vibrate,
2318                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
2319            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
2320        } finally {
2321            if (stmt != null) stmt.close();
2322        }
2323    }
2324
2325    private void loadVibrateWhenRingingSetting(SQLiteDatabase db) {
2326        // The default should be off. VIBRATE_SETTING_ONLY_SILENT should also be ignored here.
2327        // Phone app should separately check whether AudioManager#getRingerMode() returns
2328        // RINGER_MODE_VIBRATE, with which the device should vibrate anyway.
2329        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON,
2330                AudioManager.VIBRATE_SETTING_OFF);
2331        boolean vibrateWhenRinging = ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_ON);
2332
2333        SQLiteStatement stmt = null;
2334        try {
2335            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2336                    + " VALUES(?,?);");
2337            loadSetting(stmt, Settings.System.VIBRATE_WHEN_RINGING, vibrateWhenRinging ? 1 : 0);
2338        } finally {
2339            if (stmt != null) stmt.close();
2340        }
2341    }
2342
2343    private void loadSettings(SQLiteDatabase db) {
2344        loadSystemSettings(db);
2345        loadSecureSettings(db);
2346        // The global table only exists for the 'owner/system' user
2347        if (mUserHandle == UserHandle.USER_SYSTEM) {
2348            loadGlobalSettings(db);
2349        }
2350    }
2351
2352    private void loadSystemSettings(SQLiteDatabase db) {
2353        SQLiteStatement stmt = null;
2354        try {
2355            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2356                    + " VALUES(?,?);");
2357
2358            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
2359                    R.bool.def_dim_screen);
2360            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
2361                    R.integer.def_screen_off_timeout);
2362
2363            // Set default cdma DTMF type
2364            loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
2365
2366            // Set default hearing aid
2367            loadSetting(stmt, Settings.System.HEARING_AID, 0);
2368
2369            // Set default tty mode
2370            loadSetting(stmt, Settings.System.TTY_MODE, 0);
2371
2372            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
2373                    R.integer.def_screen_brightness);
2374
2375            loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
2376                    R.bool.def_screen_brightness_automatic_mode);
2377
2378            loadDefaultAnimationSettings(stmt);
2379
2380            loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
2381                    R.bool.def_accelerometer_rotation);
2382
2383            loadDefaultHapticSettings(stmt);
2384
2385            loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
2386                    R.bool.def_notification_pulse);
2387
2388            loadUISoundEffectsSettings(stmt);
2389
2390            loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
2391                    R.integer.def_pointer_speed);
2392
2393            /*
2394             * IMPORTANT: Do not add any more upgrade steps here as the global,
2395             * secure, and system settings are no longer stored in a database
2396             * but are kept in memory and persisted to XML.
2397             *
2398             * See: SettingsProvider.UpgradeController#onUpgradeLocked
2399             */
2400        } finally {
2401            if (stmt != null) stmt.close();
2402        }
2403    }
2404
2405    private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
2406        loadBooleanSetting(stmt, Settings.System.DTMF_TONE_WHEN_DIALING,
2407                R.bool.def_dtmf_tones_enabled);
2408        loadBooleanSetting(stmt, Settings.System.SOUND_EFFECTS_ENABLED,
2409                R.bool.def_sound_effects_enabled);
2410        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
2411                R.bool.def_haptic_feedback);
2412
2413        loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
2414            R.integer.def_lockscreen_sounds_enabled);
2415    }
2416
2417    private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
2418        loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
2419                R.fraction.def_window_animation_scale, 1);
2420        loadFractionSetting(stmt, Settings.System.TRANSITION_ANIMATION_SCALE,
2421                R.fraction.def_window_transition_scale, 1);
2422    }
2423
2424    private void loadDefaultHapticSettings(SQLiteStatement stmt) {
2425        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
2426                R.bool.def_haptic_feedback);
2427    }
2428
2429    private void loadSecureSettings(SQLiteDatabase db) {
2430        SQLiteStatement stmt = null;
2431        try {
2432            stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
2433                    + " VALUES(?,?);");
2434
2435            loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
2436                    R.string.def_location_providers_allowed);
2437
2438            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
2439            if (!TextUtils.isEmpty(wifiWatchList)) {
2440                loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
2441            }
2442
2443            // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
2444            // persistent system property instead.
2445            //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
2446
2447            // Allow mock locations default, based on build
2448            loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
2449                    "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
2450
2451            loadSecure35Settings(stmt);
2452
2453            loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
2454                    R.bool.def_mount_play_notification_snd);
2455
2456            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
2457                    R.bool.def_mount_ums_autostart);
2458
2459            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
2460                    R.bool.def_mount_ums_prompt);
2461
2462            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
2463                    R.bool.def_mount_ums_notify_enabled);
2464
2465            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
2466                    R.bool.def_accessibility_script_injection);
2467
2468            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
2469                    R.string.def_accessibility_web_content_key_bindings);
2470
2471            loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
2472                    R.integer.def_long_press_timeout_millis);
2473
2474            loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
2475                    R.bool.def_touch_exploration_enabled);
2476
2477            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
2478                    R.bool.def_accessibility_speak_password);
2479
2480            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
2481                    R.string.def_accessibility_screen_reader_url);
2482
2483            if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) {
2484                loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1");
2485            } else {
2486                loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
2487                        R.bool.def_lockscreen_disabled);
2488            }
2489
2490            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED,
2491                    com.android.internal.R.bool.config_dreamsEnabledByDefault);
2492            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
2493                    com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
2494            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
2495                    com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
2496            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS,
2497                    com.android.internal.R.string.config_dreamsDefaultComponent);
2498            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
2499                    com.android.internal.R.string.config_dreamsDefaultComponent);
2500
2501            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
2502                    R.bool.def_accessibility_display_magnification_enabled);
2503
2504            loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
2505                    R.fraction.def_accessibility_display_magnification_scale, 1);
2506
2507            loadBooleanSetting(stmt,
2508                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
2509                    R.bool.def_accessibility_display_magnification_auto_update);
2510
2511            loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
2512                    R.bool.def_user_setup_complete);
2513
2514            loadStringSetting(stmt, Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
2515                        R.string.def_immersive_mode_confirmations);
2516
2517            loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
2518                    R.bool.def_install_non_market_apps);
2519
2520            loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
2521                    R.bool.def_wake_gesture_enabled);
2522
2523            loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
2524                    R.integer.def_lock_screen_show_notifications);
2525
2526            loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
2527                    R.bool.def_lock_screen_allow_private_notifications);
2528
2529            loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
2530                    R.integer.def_sleep_timeout);
2531
2532            /*
2533             * IMPORTANT: Do not add any more upgrade steps here as the global,
2534             * secure, and system settings are no longer stored in a database
2535             * but are kept in memory and persisted to XML.
2536             *
2537             * See: SettingsProvider.UpgradeController#onUpgradeLocked
2538             */
2539        } finally {
2540            if (stmt != null) stmt.close();
2541        }
2542    }
2543
2544    private void loadSecure35Settings(SQLiteStatement stmt) {
2545        loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED,
2546                R.bool.def_backup_enabled);
2547
2548        loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
2549                R.string.def_backup_transport);
2550    }
2551
2552    private void loadGlobalSettings(SQLiteDatabase db) {
2553        SQLiteStatement stmt = null;
2554        try {
2555            stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
2556                    + " VALUES(?,?);");
2557
2558            // --- Previously in 'system'
2559            loadBooleanSetting(stmt, Settings.Global.AIRPLANE_MODE_ON,
2560                    R.bool.def_airplane_mode_on);
2561
2562            loadBooleanSetting(stmt, Settings.Global.THEATER_MODE_ON,
2563                    R.bool.def_theater_mode_on);
2564
2565            loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_RADIOS,
2566                    R.string.def_airplane_mode_radios);
2567
2568            loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
2569                    R.string.airplane_mode_toggleable_radios);
2570
2571            loadBooleanSetting(stmt, Settings.Global.ASSISTED_GPS_ENABLED,
2572                    R.bool.assisted_gps_enabled);
2573
2574            loadBooleanSetting(stmt, Settings.Global.AUTO_TIME,
2575                    R.bool.def_auto_time); // Sync time to NITZ
2576
2577            loadBooleanSetting(stmt, Settings.Global.AUTO_TIME_ZONE,
2578                    R.bool.def_auto_time_zone); // Sync timezone to NITZ
2579
2580            loadSetting(stmt, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
2581                    ("1".equals(SystemProperties.get("ro.kernel.qemu")) ||
2582                        mContext.getResources().getBoolean(R.bool.def_stay_on_while_plugged_in))
2583                     ? 1 : 0);
2584
2585            loadIntegerSetting(stmt, Settings.Global.WIFI_SLEEP_POLICY,
2586                    R.integer.def_wifi_sleep_policy);
2587
2588            loadSetting(stmt, Settings.Global.MODE_RINGER,
2589                    AudioManager.RINGER_MODE_NORMAL);
2590
2591            // --- Previously in 'secure'
2592            loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE,
2593                    R.bool.def_package_verifier_enable);
2594
2595            loadBooleanSetting(stmt, Settings.Global.WIFI_ON,
2596                    R.bool.def_wifi_on);
2597
2598            loadBooleanSetting(stmt, Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
2599                    R.bool.def_networks_available_notification_on);
2600
2601            loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_ON,
2602                    R.bool.def_bluetooth_on);
2603
2604            // Enable or disable Cell Broadcast SMS
2605            loadSetting(stmt, Settings.Global.CDMA_CELL_BROADCAST_SMS,
2606                    RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
2607
2608            // Data roaming default, based on build
2609            loadSetting(stmt, Settings.Global.DATA_ROAMING,
2610                    "true".equalsIgnoreCase(
2611                            SystemProperties.get("ro.com.android.dataroaming",
2612                                    "false")) ? 1 : 0);
2613
2614            loadBooleanSetting(stmt, Settings.Global.DEVICE_PROVISIONED,
2615                    R.bool.def_device_provisioned);
2616
2617            final int maxBytes = mContext.getResources().getInteger(
2618                    R.integer.def_download_manager_max_bytes_over_mobile);
2619            if (maxBytes > 0) {
2620                loadSetting(stmt, Settings.Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE,
2621                        Integer.toString(maxBytes));
2622            }
2623
2624            final int recommendedMaxBytes = mContext.getResources().getInteger(
2625                    R.integer.def_download_manager_recommended_max_bytes_over_mobile);
2626            if (recommendedMaxBytes > 0) {
2627                loadSetting(stmt, Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE,
2628                        Integer.toString(recommendedMaxBytes));
2629            }
2630
2631            // Mobile Data default, based on build
2632            loadSetting(stmt, Settings.Global.MOBILE_DATA,
2633                    "true".equalsIgnoreCase(
2634                            SystemProperties.get("ro.com.android.mobiledata",
2635                                    "true")) ? 1 : 0);
2636
2637            loadBooleanSetting(stmt, Settings.Global.NETSTATS_ENABLED,
2638                    R.bool.def_netstats_enabled);
2639
2640            loadBooleanSetting(stmt, Settings.Global.USB_MASS_STORAGE_ENABLED,
2641                    R.bool.def_usb_mass_storage_enabled);
2642
2643            loadIntegerSetting(stmt, Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
2644                    R.integer.def_max_dhcp_retries);
2645
2646            loadBooleanSetting(stmt, Settings.Global.WIFI_DISPLAY_ON,
2647                    R.bool.def_wifi_display_on);
2648
2649            loadStringSetting(stmt, Settings.Global.LOCK_SOUND,
2650                    R.string.def_lock_sound);
2651            loadStringSetting(stmt, Settings.Global.UNLOCK_SOUND,
2652                    R.string.def_unlock_sound);
2653            loadStringSetting(stmt, Settings.Global.TRUSTED_SOUND,
2654                    R.string.def_trusted_sound);
2655            loadIntegerSetting(stmt, Settings.Global.POWER_SOUNDS_ENABLED,
2656                    R.integer.def_power_sounds_enabled);
2657            loadStringSetting(stmt, Settings.Global.LOW_BATTERY_SOUND,
2658                    R.string.def_low_battery_sound);
2659            loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED,
2660                    R.integer.def_dock_sounds_enabled);
2661            loadStringSetting(stmt, Settings.Global.DESK_DOCK_SOUND,
2662                    R.string.def_desk_dock_sound);
2663            loadStringSetting(stmt, Settings.Global.DESK_UNDOCK_SOUND,
2664                    R.string.def_desk_undock_sound);
2665            loadStringSetting(stmt, Settings.Global.CAR_DOCK_SOUND,
2666                    R.string.def_car_dock_sound);
2667            loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND,
2668                    R.string.def_car_undock_sound);
2669            loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
2670                    R.string.def_wireless_charging_started_sound);
2671
2672            loadIntegerSetting(stmt, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED,
2673                    R.integer.def_dock_audio_media_enabled);
2674
2675            loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
2676            loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
2677                    PackageHelper.APP_INSTALL_AUTO);
2678
2679            // Set default cdma emergency tone
2680            loadSetting(stmt, Settings.Global.EMERGENCY_TONE, 0);
2681
2682            // Set default cdma call auto retry
2683            loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);
2684
2685            // Set the preferred network mode to target desired value or Default
2686            // value defined in RILConstants
2687            int type;
2688            type = RILConstants.PREFERRED_NETWORK_MODE;
2689            loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
2690
2691            // Set the preferred cdma subscription source to target desired value or default
2692            // value defined in CdmaSubscriptionSourceManager
2693            type = SystemProperties.getInt("ro.telephony.default_cdma_sub",
2694                        CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION);
2695            loadSetting(stmt, Settings.Global.CDMA_SUBSCRIPTION_MODE, type);
2696
2697            loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
2698                    R.integer.def_low_battery_sound_timeout);
2699
2700            loadIntegerSetting(stmt, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
2701                    R.integer.def_wifi_scan_always_available);
2702
2703            loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
2704                    R.integer.def_heads_up_enabled);
2705
2706            loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());
2707
2708            loadBooleanSetting(stmt, Settings.Global.GUEST_USER_ENABLED,
2709                    R.bool.def_guest_user_enabled);
2710            loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
2711                    ImsConfig.FeatureValueConstants.ON);
2712
2713            /*
2714             * IMPORTANT: Do not add any more upgrade steps here as the global,
2715             * secure, and system settings are no longer stored in a database
2716             * but are kept in memory and persisted to XML.
2717             *
2718             * See: SettingsProvider.UpgradeController#onUpgradeLocked
2719             */
2720        } finally {
2721            if (stmt != null) stmt.close();
2722        }
2723    }
2724
2725    private void loadSetting(SQLiteStatement stmt, String key, Object value) {
2726        stmt.bindString(1, key);
2727        stmt.bindString(2, value.toString());
2728        stmt.execute();
2729    }
2730
2731    private void loadStringSetting(SQLiteStatement stmt, String key, int resid) {
2732        loadSetting(stmt, key, mContext.getResources().getString(resid));
2733    }
2734
2735    private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
2736        loadSetting(stmt, key,
2737                mContext.getResources().getBoolean(resid) ? "1" : "0");
2738    }
2739
2740    private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) {
2741        loadSetting(stmt, key,
2742                Integer.toString(mContext.getResources().getInteger(resid)));
2743    }
2744
2745    private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) {
2746        loadSetting(stmt, key,
2747                Float.toString(mContext.getResources().getFraction(resid, base, base)));
2748    }
2749
2750    private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) {
2751        return getIntValueFromTable(db, TABLE_SYSTEM, name, defaultValue);
2752    }
2753
2754    private int getIntValueFromTable(SQLiteDatabase db, String table, String name,
2755            int defaultValue) {
2756        String value = getStringValueFromTable(db, table, name, null);
2757        return (value != null) ? Integer.parseInt(value) : defaultValue;
2758    }
2759
2760    private String getStringValueFromTable(SQLiteDatabase db, String table, String name,
2761            String defaultValue) {
2762        Cursor c = null;
2763        try {
2764            c = db.query(table, new String[] { Settings.System.VALUE }, "name='" + name + "'",
2765                    null, null, null, null);
2766            if (c != null && c.moveToFirst()) {
2767                String val = c.getString(0);
2768                return val == null ? defaultValue : val;
2769            }
2770        } finally {
2771            if (c != null) c.close();
2772        }
2773        return defaultValue;
2774    }
2775
2776    private String getOldDefaultDeviceName() {
2777        return mContext.getResources().getString(R.string.def_device_name,
2778                Build.MANUFACTURER, Build.MODEL);
2779    }
2780
2781    private String getDefaultDeviceName() {
2782        return mContext.getResources().getString(R.string.def_device_name_simple, Build.MODEL);
2783    }
2784}
2785