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