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.SHOW_PROCESSES,
1487                            Settings.Global.ALWAYS_FINISH_ACTIVITIES,
1488                    };
1489                    String[] secureToGlobal = {
1490                            Settings.Global.PREFERRED_NETWORK_MODE,
1491                            Settings.Global.CDMA_SUBSCRIPTION_MODE,
1492                    };
1493
1494                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, systemToGlobal, true);
1495                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, secureToGlobal, true);
1496
1497                    db.setTransactionSuccessful();
1498                } finally {
1499                    db.endTransaction();
1500                }
1501            }
1502            upgradeVersion = 91;
1503        }
1504
1505        if (upgradeVersion == 91) {
1506            if (mUserHandle == UserHandle.USER_SYSTEM) {
1507                db.beginTransaction();
1508                try {
1509                    // Move ringer mode from system to global settings
1510                    String[] settingsToMove = { Settings.Global.MODE_RINGER };
1511                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);
1512
1513                    db.setTransactionSuccessful();
1514                } finally {
1515                    db.endTransaction();
1516                }
1517            }
1518            upgradeVersion = 92;
1519        }
1520
1521        if (upgradeVersion == 92) {
1522            SQLiteStatement stmt = null;
1523            try {
1524                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1525                        + " VALUES(?,?);");
1526                if (mUserHandle == UserHandle.USER_SYSTEM) {
1527                    // consider existing primary users to have made it through user setup
1528                    // if the globally-scoped device-provisioned bit is set
1529                    // (indicating they already made it through setup as primary)
1530                    int deviceProvisioned = getIntValueFromTable(db, TABLE_GLOBAL,
1531                            Settings.Global.DEVICE_PROVISIONED, 0);
1532                    loadSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
1533                            deviceProvisioned);
1534                } else {
1535                    // otherwise use the default
1536                    loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
1537                            R.bool.def_user_setup_complete);
1538                }
1539            } finally {
1540                if (stmt != null) stmt.close();
1541            }
1542            upgradeVersion = 93;
1543        }
1544
1545        if (upgradeVersion == 93) {
1546            // Redo this step, since somehow it didn't work the first time for some users
1547            if (mUserHandle == UserHandle.USER_SYSTEM) {
1548                db.beginTransaction();
1549                try {
1550                    // Migrate now-global settings
1551                    String[] settingsToMove = setToStringArray(
1552                            SettingsProvider.sSystemMovedToGlobalSettings);
1553                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);
1554                    settingsToMove = setToStringArray(
1555                            SettingsProvider.sSecureMovedToGlobalSettings);
1556                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1557
1558                    db.setTransactionSuccessful();
1559                } finally {
1560                    db.endTransaction();
1561                }
1562            }
1563            upgradeVersion = 94;
1564        }
1565
1566        if (upgradeVersion == 94) {
1567            // Add wireless charging started sound setting
1568            if (mUserHandle == UserHandle.USER_SYSTEM) {
1569                db.beginTransaction();
1570                SQLiteStatement stmt = null;
1571                try {
1572                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1573                            + " VALUES(?,?);");
1574                    loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
1575                            R.string.def_wireless_charging_started_sound);
1576                    db.setTransactionSuccessful();
1577                } finally {
1578                    db.endTransaction();
1579                    if (stmt != null) stmt.close();
1580                }
1581            }
1582            upgradeVersion = 95;
1583        }
1584
1585        if (upgradeVersion == 95) {
1586            if (mUserHandle == UserHandle.USER_SYSTEM) {
1587                db.beginTransaction();
1588                try {
1589                    String[] settingsToMove = { Settings.Global.BUGREPORT_IN_POWER_MENU };
1590                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
1591                    db.setTransactionSuccessful();
1592                } finally {
1593                    db.endTransaction();
1594                }
1595            }
1596            upgradeVersion = 96;
1597        }
1598
1599        if (upgradeVersion == 96) {
1600            // NOP bump due to a reverted change that some people got on upgrade.
1601            upgradeVersion = 97;
1602        }
1603
1604        if (upgradeVersion == 97) {
1605            if (mUserHandle == UserHandle.USER_SYSTEM) {
1606                db.beginTransaction();
1607                SQLiteStatement stmt = null;
1608                try {
1609                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1610                            + " VALUES(?,?);");
1611                    loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
1612                            R.integer.def_low_battery_sound_timeout);
1613                    db.setTransactionSuccessful();
1614                } finally {
1615                    db.endTransaction();
1616                    if (stmt != null) stmt.close();
1617                }
1618            }
1619            upgradeVersion = 98;
1620        }
1621
1622        if (upgradeVersion == 98) {
1623            // no-op; LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
1624            upgradeVersion = 99;
1625        }
1626
1627        if (upgradeVersion == 99) {
1628            // no-op; HEADS_UP_NOTIFICATIONS_ENABLED now handled in version 100
1629            upgradeVersion = 100;
1630        }
1631
1632        if (upgradeVersion == 100) {
1633            // note: LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
1634            if (mUserHandle == UserHandle.USER_SYSTEM) {
1635                db.beginTransaction();
1636                SQLiteStatement stmt = null;
1637                try {
1638                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1639                            + " VALUES(?,?);");
1640                    loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
1641                            R.integer.def_heads_up_enabled);
1642                    db.setTransactionSuccessful();
1643                } finally {
1644                    db.endTransaction();
1645                    if (stmt != null) stmt.close();
1646                }
1647            }
1648            upgradeVersion = 101;
1649        }
1650
1651        if (upgradeVersion == 101) {
1652            if (mUserHandle == UserHandle.USER_SYSTEM) {
1653                db.beginTransaction();
1654                SQLiteStatement stmt = null;
1655                try {
1656                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
1657                            + " VALUES(?,?);");
1658                    loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());
1659                    db.setTransactionSuccessful();
1660                } finally {
1661                    db.endTransaction();
1662                    if (stmt != null) stmt.close();
1663                }
1664            }
1665            upgradeVersion = 102;
1666        }
1667
1668        if (upgradeVersion == 102) {
1669            db.beginTransaction();
1670            SQLiteStatement stmt = null;
1671            try {
1672                // The INSTALL_NON_MARKET_APPS setting is becoming per-user rather
1673                // than device-global.
1674                if (mUserHandle == UserHandle.USER_SYSTEM) {
1675                    // In the owner user, the global table exists so we can migrate the
1676                    // entry from there to the secure table, preserving its value.
1677                    String[] globalToSecure = {
1678                            Settings.Secure.INSTALL_NON_MARKET_APPS
1679                    };
1680                    moveSettingsToNewTable(db, TABLE_GLOBAL, TABLE_SECURE, globalToSecure, true);
1681                } else {
1682                    // Secondary users' dbs don't have the global table, so institute the
1683                    // default.
1684                    stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1685                            + " VALUES(?,?);");
1686                    loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
1687                            R.bool.def_install_non_market_apps);
1688                }
1689                db.setTransactionSuccessful();
1690            } finally {
1691                db.endTransaction();
1692                if (stmt != null) stmt.close();
1693            }
1694            upgradeVersion = 103;
1695        }
1696
1697        if (upgradeVersion == 103) {
1698            db.beginTransaction();
1699            SQLiteStatement stmt = null;
1700            try {
1701                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
1702                        + " VALUES(?,?);");
1703                loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
1704                        R.bool.def_wake_gesture_enabled);
1705                db.setTransactionSuccessful();
1706            } finally {
1707                db.endTransaction();
1708                if (stmt != null) stmt.close();
1709            }
1710            upgradeVersion = 104;
1711        }
1712
1713        if (upgradeVersion < 105) {
1714            // No-op: GUEST_USER_ENABLED setting was removed
1715            upgradeVersion = 105;
1716        }
1717
1718        if (upgradeVersion < 106) {
1719            // LOCK_SCREEN_SHOW_NOTIFICATIONS is now per-user.
1720            db.beginTransaction();
1721            SQLiteStatement stmt = null;
1722            try {
1723                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1724                        + " VALUES(?,?);");
1725                loadIntegerSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
1726                        R.integer.def_lock_screen_show_notifications);
1727                if (mUserHandle == UserHandle.USER_SYSTEM) {
1728                    final int oldShow = getIntValueFromTable(db,
1729                            TABLE_GLOBAL, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, -1);
1730                    if (oldShow >= 0) {
1731                        // overwrite the default with whatever you had
1732                        loadSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, oldShow);
1733                        final SQLiteStatement deleteStmt
1734                                = db.compileStatement("DELETE FROM global WHERE name=?");
1735                        deleteStmt.bindString(1, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
1736                        deleteStmt.execute();
1737                    }
1738                }
1739                db.setTransactionSuccessful();
1740            } finally {
1741                db.endTransaction();
1742                if (stmt != null) stmt.close();
1743            }
1744            upgradeVersion = 106;
1745        }
1746
1747        if (upgradeVersion < 107) {
1748            // Add trusted sound setting
1749            if (mUserHandle == UserHandle.USER_SYSTEM) {
1750                db.beginTransaction();
1751                SQLiteStatement stmt = null;
1752                try {
1753                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1754                            + " VALUES(?,?);");
1755                    loadStringSetting(stmt, Settings.Global.TRUSTED_SOUND,
1756                            R.string.def_trusted_sound);
1757                    db.setTransactionSuccessful();
1758                } finally {
1759                    db.endTransaction();
1760                    if (stmt != null) stmt.close();
1761                }
1762            }
1763            upgradeVersion = 107;
1764        }
1765
1766        if (upgradeVersion < 108) {
1767            // Reset the auto-brightness setting to default since the behavior
1768            // of the feature is now quite different and is being presented to
1769            // the user in a new way as "adaptive brightness".
1770            db.beginTransaction();
1771            SQLiteStatement stmt = null;
1772            try {
1773                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1774                        + " VALUES(?,?);");
1775                loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
1776                        R.bool.def_screen_brightness_automatic_mode);
1777                db.setTransactionSuccessful();
1778            } finally {
1779                db.endTransaction();
1780                if (stmt != null) stmt.close();
1781            }
1782            upgradeVersion = 108;
1783        }
1784
1785        if (upgradeVersion < 109) {
1786            db.beginTransaction();
1787            SQLiteStatement stmt = null;
1788            try {
1789                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1790                        + " VALUES(?,?);");
1791                loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
1792                        R.bool.def_lock_screen_allow_private_notifications);
1793                db.setTransactionSuccessful();
1794            } finally {
1795                db.endTransaction();
1796                if (stmt != null) stmt.close();
1797            }
1798            upgradeVersion = 109;
1799        }
1800
1801        if (upgradeVersion < 110) {
1802            // The SIP_CALL_OPTIONS value SIP_ASK_EACH_TIME is being deprecated.
1803            // If the SIP_CALL_OPTIONS setting is set to SIP_ASK_EACH_TIME, default to
1804            // SIP_ADDRESS_ONLY.
1805            db.beginTransaction();
1806            SQLiteStatement stmt = null;
1807            try {
1808                stmt = db.compileStatement("UPDATE system SET value = ? " +
1809                        "WHERE name = ? AND value = ?;");
1810                stmt.bindString(1, Settings.System.SIP_ADDRESS_ONLY);
1811                stmt.bindString(2, Settings.System.SIP_CALL_OPTIONS);
1812                stmt.bindString(3, Settings.System.SIP_ASK_ME_EACH_TIME);
1813                stmt.execute();
1814                db.setTransactionSuccessful();
1815            } finally {
1816                db.endTransaction();
1817                if (stmt != null) stmt.close();
1818            }
1819            upgradeVersion = 110;
1820        }
1821
1822        if (upgradeVersion < 111) {
1823            // reset ringer mode, so it doesn't force zen mode to follow
1824            if (mUserHandle == UserHandle.USER_SYSTEM) {
1825                db.beginTransaction();
1826                SQLiteStatement stmt = null;
1827                try {
1828                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
1829                            + " VALUES(?,?);");
1830                    loadSetting(stmt, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
1831                    db.setTransactionSuccessful();
1832                } finally {
1833                    db.endTransaction();
1834                    if (stmt != null) stmt.close();
1835                }
1836            }
1837            upgradeVersion = 111;
1838        }
1839
1840        if (upgradeVersion < 112) {
1841            if (mUserHandle == UserHandle.USER_SYSTEM) {
1842                // When device name was added, we went with Manufacturer + Model, device name should
1843                // actually be Model only.
1844                // Update device name to Model if it wasn't modified by user.
1845                db.beginTransaction();
1846                SQLiteStatement stmt = null;
1847                try {
1848                    stmt = db.compileStatement("UPDATE global SET value = ? "
1849                        + " WHERE name = ? AND value = ?");
1850                    stmt.bindString(1, getDefaultDeviceName()); // new default device name
1851                    stmt.bindString(2, Settings.Global.DEVICE_NAME);
1852                    stmt.bindString(3, getOldDefaultDeviceName()); // old default device name
1853                    stmt.execute();
1854                    db.setTransactionSuccessful();
1855                } finally {
1856                    db.endTransaction();
1857                    if (stmt != null) stmt.close();
1858                }
1859            }
1860            upgradeVersion = 112;
1861        }
1862
1863        if (upgradeVersion < 113) {
1864            db.beginTransaction();
1865            SQLiteStatement stmt = null;
1866            try {
1867                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1868                        + " VALUES(?,?);");
1869                loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
1870                        R.integer.def_sleep_timeout);
1871                db.setTransactionSuccessful();
1872            } finally {
1873                db.endTransaction();
1874                if (stmt != null) stmt.close();
1875            }
1876            upgradeVersion = 113;
1877        }
1878
1879        // We skipped 114 to handle a merge conflict with the introduction of theater mode.
1880
1881        if (upgradeVersion < 115) {
1882            if (mUserHandle == UserHandle.USER_SYSTEM) {
1883                db.beginTransaction();
1884                SQLiteStatement stmt = null;
1885                try {
1886                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
1887                            + " VALUES(?,?);");
1888                    loadBooleanSetting(stmt, Global.THEATER_MODE_ON,
1889                            R.bool.def_theater_mode_on);
1890                    db.setTransactionSuccessful();
1891                } finally {
1892                    db.endTransaction();
1893                    if (stmt != null) stmt.close();
1894                }
1895            }
1896            upgradeVersion = 115;
1897        }
1898
1899        if (upgradeVersion < 116) {
1900            if (mUserHandle == UserHandle.USER_SYSTEM) {
1901                db.beginTransaction();
1902                SQLiteStatement stmt = null;
1903                try {
1904                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
1905                            + " VALUES(?,?);");
1906                    loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
1907                            ImsConfig.FeatureValueConstants.ON);
1908                    db.setTransactionSuccessful();
1909                } finally {
1910                    db.endTransaction();
1911                    if (stmt != null) stmt.close();
1912                }
1913            }
1914            upgradeVersion = 116;
1915        }
1916
1917        if (upgradeVersion < 117) {
1918            db.beginTransaction();
1919            try {
1920                String[] systemToSecure = {
1921                        Settings.Secure.LOCK_TO_APP_EXIT_LOCKED
1922                };
1923                moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, systemToSecure, true);
1924                db.setTransactionSuccessful();
1925            } finally {
1926                db.endTransaction();
1927            }
1928            upgradeVersion = 117;
1929        }
1930
1931        if (upgradeVersion < 118) {
1932            // Reset rotation-lock-for-accessibility on upgrade, since it now hides the display
1933            // setting.
1934            db.beginTransaction();
1935            SQLiteStatement stmt = null;
1936            try {
1937                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1938                        + " VALUES(?,?);");
1939                loadSetting(stmt, Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0);
1940                db.setTransactionSuccessful();
1941            } finally {
1942                db.endTransaction();
1943                if (stmt != null) stmt.close();
1944            }
1945            upgradeVersion = 118;
1946        }
1947
1948        /*
1949         * IMPORTANT: Do not add any more upgrade steps here as the global,
1950         * secure, and system settings are no longer stored in a database
1951         * but are kept in memory and persisted to XML.
1952         *
1953         * See: SettingsProvider.UpgradeController#onUpgradeLocked
1954         */
1955
1956        if (upgradeVersion != currentVersion) {
1957            recreateDatabase(db, oldVersion, upgradeVersion, currentVersion);
1958        }
1959    }
1960
1961    public void recreateDatabase(SQLiteDatabase db, int oldVersion,
1962            int upgradeVersion, int currentVersion) {
1963        db.execSQL("DROP TABLE IF EXISTS global");
1964        db.execSQL("DROP TABLE IF EXISTS globalIndex1");
1965        db.execSQL("DROP TABLE IF EXISTS system");
1966        db.execSQL("DROP INDEX IF EXISTS systemIndex1");
1967        db.execSQL("DROP TABLE IF EXISTS secure");
1968        db.execSQL("DROP INDEX IF EXISTS secureIndex1");
1969        db.execSQL("DROP TABLE IF EXISTS gservices");
1970        db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
1971        db.execSQL("DROP TABLE IF EXISTS bluetooth_devices");
1972        db.execSQL("DROP TABLE IF EXISTS bookmarks");
1973        db.execSQL("DROP INDEX IF EXISTS bookmarksIndex1");
1974        db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
1975        db.execSQL("DROP TABLE IF EXISTS favorites");
1976
1977        onCreate(db);
1978
1979        // Added for diagnosing settings.db wipes after the fact
1980        String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion;
1981        db.execSQL("INSERT INTO secure(name,value) values('" +
1982                "wiped_db_reason" + "','" + wipeReason + "');");
1983    }
1984
1985    private String[] setToStringArray(Set<String> set) {
1986        String[] array = new String[set.size()];
1987        return set.toArray(array);
1988    }
1989
1990    private void moveSettingsToNewTable(SQLiteDatabase db,
1991            String sourceTable, String destTable,
1992            String[] settingsToMove, boolean doIgnore) {
1993        // Copy settings values from the source table to the dest, and remove from the source
1994        SQLiteStatement insertStmt = null;
1995        SQLiteStatement deleteStmt = null;
1996
1997        db.beginTransaction();
1998        try {
1999            insertStmt = db.compileStatement("INSERT "
2000                    + (doIgnore ? " OR IGNORE " : "")
2001                    + " INTO " + destTable + " (name,value) SELECT name,value FROM "
2002                    + sourceTable + " WHERE name=?");
2003            deleteStmt = db.compileStatement("DELETE FROM " + sourceTable + " WHERE name=?");
2004
2005            for (String setting : settingsToMove) {
2006                insertStmt.bindString(1, setting);
2007                insertStmt.execute();
2008
2009                deleteStmt.bindString(1, setting);
2010                deleteStmt.execute();
2011            }
2012            db.setTransactionSuccessful();
2013        } finally {
2014            db.endTransaction();
2015            if (insertStmt != null) {
2016                insertStmt.close();
2017            }
2018            if (deleteStmt != null) {
2019                deleteStmt.close();
2020            }
2021        }
2022    }
2023
2024    /**
2025     * Move any settings with the given prefixes from the source table to the
2026     * destination table.
2027     */
2028    private void movePrefixedSettingsToNewTable(
2029            SQLiteDatabase db, String sourceTable, String destTable, String[] prefixesToMove) {
2030        SQLiteStatement insertStmt = null;
2031        SQLiteStatement deleteStmt = null;
2032
2033        db.beginTransaction();
2034        try {
2035            insertStmt = db.compileStatement("INSERT INTO " + destTable
2036                    + " (name,value) SELECT name,value FROM " + sourceTable
2037                    + " WHERE substr(name,0,?)=?");
2038            deleteStmt = db.compileStatement(
2039                    "DELETE FROM " + sourceTable + " WHERE substr(name,0,?)=?");
2040
2041            for (String prefix : prefixesToMove) {
2042                insertStmt.bindLong(1, prefix.length() + 1);
2043                insertStmt.bindString(2, prefix);
2044                insertStmt.execute();
2045
2046                deleteStmt.bindLong(1, prefix.length() + 1);
2047                deleteStmt.bindString(2, prefix);
2048                deleteStmt.execute();
2049            }
2050            db.setTransactionSuccessful();
2051        } finally {
2052            db.endTransaction();
2053            if (insertStmt != null) {
2054                insertStmt.close();
2055            }
2056            if (deleteStmt != null) {
2057                deleteStmt.close();
2058            }
2059        }
2060    }
2061
2062    private void upgradeLockPatternLocation(SQLiteDatabase db) {
2063        Cursor c = db.query(TABLE_SYSTEM, new String[] {"_id", "value"}, "name='lock_pattern'",
2064                null, null, null, null);
2065        if (c.getCount() > 0) {
2066            c.moveToFirst();
2067            String lockPattern = c.getString(1);
2068            if (!TextUtils.isEmpty(lockPattern)) {
2069                // Convert lock pattern
2070                try {
2071                    LockPatternUtils lpu = new LockPatternUtils(mContext);
2072                    List<LockPatternView.Cell> cellPattern =
2073                            LockPatternUtils.stringToPattern(lockPattern);
2074                    lpu.saveLockPattern(cellPattern, null, UserHandle.USER_SYSTEM);
2075                } catch (IllegalArgumentException e) {
2076                    // Don't want corrupted lock pattern to hang the reboot process
2077                }
2078            }
2079            c.close();
2080            db.delete(TABLE_SYSTEM, "name='lock_pattern'", null);
2081        } else {
2082            c.close();
2083        }
2084    }
2085
2086    private void upgradeScreenTimeoutFromNever(SQLiteDatabase db) {
2087        // See if the timeout is -1 (for "Never").
2088        Cursor c = db.query(TABLE_SYSTEM, new String[] { "_id", "value" }, "name=? AND value=?",
2089                new String[] { Settings.System.SCREEN_OFF_TIMEOUT, "-1" },
2090                null, null, null);
2091
2092        SQLiteStatement stmt = null;
2093        if (c.getCount() > 0) {
2094            c.close();
2095            try {
2096                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
2097                        + " VALUES(?,?);");
2098
2099                // Set the timeout to 30 minutes in milliseconds
2100                loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
2101                        Integer.toString(30 * 60 * 1000));
2102            } finally {
2103                if (stmt != null) stmt.close();
2104            }
2105        } else {
2106            c.close();
2107        }
2108    }
2109
2110    private void upgradeVibrateSettingFromNone(SQLiteDatabase db) {
2111        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON, 0);
2112        // If the ringer vibrate value is invalid, set it to the default
2113        if ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_OFF) {
2114            vibrateSetting = AudioSystem.getValueForVibrateSetting(0,
2115                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
2116        }
2117        // Apply the same setting to the notification vibrate value
2118        vibrateSetting = AudioSystem.getValueForVibrateSetting(vibrateSetting,
2119                AudioManager.VIBRATE_TYPE_NOTIFICATION, vibrateSetting);
2120
2121        SQLiteStatement stmt = null;
2122        try {
2123            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
2124                    + " VALUES(?,?);");
2125            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrateSetting);
2126        } finally {
2127            if (stmt != null)
2128                stmt.close();
2129        }
2130    }
2131
2132    private void upgradeScreenTimeout(SQLiteDatabase db) {
2133        // Change screen timeout to current default
2134        db.beginTransaction();
2135        SQLiteStatement stmt = null;
2136        try {
2137            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
2138                    + " VALUES(?,?);");
2139            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
2140                    R.integer.def_screen_off_timeout);
2141            db.setTransactionSuccessful();
2142        } finally {
2143            db.endTransaction();
2144            if (stmt != null)
2145                stmt.close();
2146        }
2147    }
2148
2149    private void upgradeAutoBrightness(SQLiteDatabase db) {
2150        db.beginTransaction();
2151        try {
2152            String value =
2153                    mContext.getResources().getBoolean(
2154                    R.bool.def_screen_brightness_automatic_mode) ? "1" : "0";
2155            db.execSQL("INSERT OR REPLACE INTO system(name,value) values('" +
2156                    Settings.System.SCREEN_BRIGHTNESS_MODE + "','" + value + "');");
2157            db.setTransactionSuccessful();
2158        } finally {
2159            db.endTransaction();
2160        }
2161    }
2162
2163    /**
2164     * Loads the default set of bookmarked shortcuts from an xml file.
2165     *
2166     * @param db The database to write the values into
2167     */
2168    private void loadBookmarks(SQLiteDatabase db) {
2169        ContentValues values = new ContentValues();
2170
2171        PackageManager packageManager = mContext.getPackageManager();
2172        try {
2173            XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
2174            XmlUtils.beginDocument(parser, "bookmarks");
2175
2176            final int depth = parser.getDepth();
2177            int type;
2178
2179            while (((type = parser.next()) != XmlPullParser.END_TAG ||
2180                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
2181
2182                if (type != XmlPullParser.START_TAG) {
2183                    continue;
2184                }
2185
2186                String name = parser.getName();
2187                if (!"bookmark".equals(name)) {
2188                    break;
2189                }
2190
2191                String pkg = parser.getAttributeValue(null, "package");
2192                String cls = parser.getAttributeValue(null, "class");
2193                String shortcutStr = parser.getAttributeValue(null, "shortcut");
2194                String category = parser.getAttributeValue(null, "category");
2195
2196                int shortcutValue = shortcutStr.charAt(0);
2197                if (TextUtils.isEmpty(shortcutStr)) {
2198                    Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
2199                    continue;
2200                }
2201
2202                final Intent intent;
2203                final String title;
2204                if (pkg != null && cls != null) {
2205                    ActivityInfo info = null;
2206                    ComponentName cn = new ComponentName(pkg, cls);
2207                    try {
2208                        info = packageManager.getActivityInfo(cn, 0);
2209                    } catch (PackageManager.NameNotFoundException e) {
2210                        String[] packages = packageManager.canonicalToCurrentPackageNames(
2211                                new String[] { pkg });
2212                        cn = new ComponentName(packages[0], cls);
2213                        try {
2214                            info = packageManager.getActivityInfo(cn, 0);
2215                        } catch (PackageManager.NameNotFoundException e1) {
2216                            Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
2217                            continue;
2218                        }
2219                    }
2220
2221                    intent = new Intent(Intent.ACTION_MAIN, null);
2222                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
2223                    intent.setComponent(cn);
2224                    title = info.loadLabel(packageManager).toString();
2225                } else if (category != null) {
2226                    intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
2227                    title = "";
2228                } else {
2229                    Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr
2230                            + ": missing package/class or category attributes");
2231                    continue;
2232                }
2233
2234                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2235                values.put(Settings.Bookmarks.INTENT, intent.toUri(0));
2236                values.put(Settings.Bookmarks.TITLE, title);
2237                values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
2238                db.delete("bookmarks", "shortcut = ?",
2239                        new String[] { Integer.toString(shortcutValue) });
2240                db.insert("bookmarks", null, values);
2241            }
2242        } catch (XmlPullParserException e) {
2243            Log.w(TAG, "Got execption parsing bookmarks.", e);
2244        } catch (IOException e) {
2245            Log.w(TAG, "Got execption parsing bookmarks.", e);
2246        }
2247    }
2248
2249    /**
2250     * Loads the default volume levels. It is actually inserting the index of
2251     * the volume array for each of the volume controls.
2252     *
2253     * @param db the database to insert the volume levels into
2254     */
2255    private void loadVolumeLevels(SQLiteDatabase db) {
2256        SQLiteStatement stmt = null;
2257        try {
2258            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2259                    + " VALUES(?,?);");
2260
2261            loadSetting(stmt, Settings.System.VOLUME_MUSIC,
2262                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_MUSIC));
2263            loadSetting(stmt, Settings.System.VOLUME_RING,
2264                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_RING));
2265            loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
2266                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_SYSTEM));
2267            loadSetting(
2268                    stmt,
2269                    Settings.System.VOLUME_VOICE,
2270                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_VOICE_CALL));
2271            loadSetting(stmt, Settings.System.VOLUME_ALARM,
2272                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_ALARM));
2273            loadSetting(
2274                    stmt,
2275                    Settings.System.VOLUME_NOTIFICATION,
2276                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_NOTIFICATION));
2277            loadSetting(
2278                    stmt,
2279                    Settings.System.VOLUME_BLUETOOTH_SCO,
2280                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO));
2281
2282            // By default:
2283            // - ringtones, notification, system and music streams are affected by ringer mode
2284            // on non voice capable devices (tablets)
2285            // - ringtones, notification and system streams are affected by ringer mode
2286            // on voice capable devices (phones)
2287            int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
2288                                            (1 << AudioManager.STREAM_NOTIFICATION) |
2289                                            (1 << AudioManager.STREAM_SYSTEM) |
2290                                            (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
2291            if (!mContext.getResources().getBoolean(
2292                    com.android.internal.R.bool.config_voice_capable)) {
2293                ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
2294            }
2295            loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
2296                    ringerModeAffectedStreams);
2297
2298            loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
2299                    AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED);
2300        } finally {
2301            if (stmt != null) stmt.close();
2302        }
2303
2304        loadVibrateWhenRingingSetting(db);
2305    }
2306
2307    private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
2308        if (deleteOld) {
2309            db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
2310        }
2311
2312        SQLiteStatement stmt = null;
2313        try {
2314            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2315                    + " VALUES(?,?);");
2316
2317            // Vibrate on by default for ringer, on for notification
2318            int vibrate = 0;
2319            vibrate = AudioSystem.getValueForVibrateSetting(vibrate,
2320                    AudioManager.VIBRATE_TYPE_NOTIFICATION,
2321                    AudioManager.VIBRATE_SETTING_ONLY_SILENT);
2322            vibrate |= AudioSystem.getValueForVibrateSetting(vibrate,
2323                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
2324            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
2325        } finally {
2326            if (stmt != null) stmt.close();
2327        }
2328    }
2329
2330    private void loadVibrateWhenRingingSetting(SQLiteDatabase db) {
2331        // The default should be off. VIBRATE_SETTING_ONLY_SILENT should also be ignored here.
2332        // Phone app should separately check whether AudioManager#getRingerMode() returns
2333        // RINGER_MODE_VIBRATE, with which the device should vibrate anyway.
2334        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON,
2335                AudioManager.VIBRATE_SETTING_OFF);
2336        boolean vibrateWhenRinging = ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_ON);
2337
2338        SQLiteStatement stmt = null;
2339        try {
2340            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2341                    + " VALUES(?,?);");
2342            loadSetting(stmt, Settings.System.VIBRATE_WHEN_RINGING, vibrateWhenRinging ? 1 : 0);
2343        } finally {
2344            if (stmt != null) stmt.close();
2345        }
2346    }
2347
2348    private void loadSettings(SQLiteDatabase db) {
2349        loadSystemSettings(db);
2350        loadSecureSettings(db);
2351        // The global table only exists for the 'owner/system' user
2352        if (mUserHandle == UserHandle.USER_SYSTEM) {
2353            loadGlobalSettings(db);
2354        }
2355    }
2356
2357    private void loadSystemSettings(SQLiteDatabase db) {
2358        SQLiteStatement stmt = null;
2359        try {
2360            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
2361                    + " VALUES(?,?);");
2362
2363            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
2364                    R.bool.def_dim_screen);
2365            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
2366                    R.integer.def_screen_off_timeout);
2367
2368            // Set default cdma DTMF type
2369            loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
2370
2371            // Set default hearing aid
2372            loadSetting(stmt, Settings.System.HEARING_AID, 0);
2373
2374            // Set default tty mode
2375            loadSetting(stmt, Settings.System.TTY_MODE, 0);
2376
2377            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
2378                    R.integer.def_screen_brightness);
2379
2380            loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
2381                    R.bool.def_screen_brightness_automatic_mode);
2382
2383            loadDefaultAnimationSettings(stmt);
2384
2385            loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
2386                    R.bool.def_accelerometer_rotation);
2387
2388            loadDefaultHapticSettings(stmt);
2389
2390            loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
2391                    R.bool.def_notification_pulse);
2392
2393            loadUISoundEffectsSettings(stmt);
2394
2395            loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
2396                    R.integer.def_pointer_speed);
2397
2398            /*
2399             * IMPORTANT: Do not add any more upgrade steps here as the global,
2400             * secure, and system settings are no longer stored in a database
2401             * but are kept in memory and persisted to XML.
2402             *
2403             * See: SettingsProvider.UpgradeController#onUpgradeLocked
2404             */
2405        } finally {
2406            if (stmt != null) stmt.close();
2407        }
2408    }
2409
2410    private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
2411        loadBooleanSetting(stmt, Settings.System.DTMF_TONE_WHEN_DIALING,
2412                R.bool.def_dtmf_tones_enabled);
2413        loadBooleanSetting(stmt, Settings.System.SOUND_EFFECTS_ENABLED,
2414                R.bool.def_sound_effects_enabled);
2415        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
2416                R.bool.def_haptic_feedback);
2417
2418        loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
2419            R.integer.def_lockscreen_sounds_enabled);
2420    }
2421
2422    private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
2423        loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
2424                R.fraction.def_window_animation_scale, 1);
2425        loadFractionSetting(stmt, Settings.System.TRANSITION_ANIMATION_SCALE,
2426                R.fraction.def_window_transition_scale, 1);
2427    }
2428
2429    private void loadDefaultHapticSettings(SQLiteStatement stmt) {
2430        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
2431                R.bool.def_haptic_feedback);
2432    }
2433
2434    private void loadSecureSettings(SQLiteDatabase db) {
2435        SQLiteStatement stmt = null;
2436        try {
2437            stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
2438                    + " VALUES(?,?);");
2439
2440            loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
2441                    R.string.def_location_providers_allowed);
2442
2443            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
2444            if (!TextUtils.isEmpty(wifiWatchList)) {
2445                loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
2446            }
2447
2448            // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
2449            // persistent system property instead.
2450            //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
2451
2452            // Allow mock locations default, based on build
2453            loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
2454                    "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
2455
2456            loadSecure35Settings(stmt);
2457
2458            loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
2459                    R.bool.def_mount_play_notification_snd);
2460
2461            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
2462                    R.bool.def_mount_ums_autostart);
2463
2464            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
2465                    R.bool.def_mount_ums_prompt);
2466
2467            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
2468                    R.bool.def_mount_ums_notify_enabled);
2469
2470            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
2471                    R.bool.def_accessibility_script_injection);
2472
2473            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
2474                    R.string.def_accessibility_web_content_key_bindings);
2475
2476            loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
2477                    R.integer.def_long_press_timeout_millis);
2478
2479            loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
2480                    R.bool.def_touch_exploration_enabled);
2481
2482            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
2483                    R.bool.def_accessibility_speak_password);
2484
2485            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
2486                    R.string.def_accessibility_screen_reader_url);
2487
2488            if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) {
2489                loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1");
2490            } else {
2491                loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
2492                        R.bool.def_lockscreen_disabled);
2493            }
2494
2495            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED,
2496                    com.android.internal.R.bool.config_dreamsEnabledByDefault);
2497            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
2498                    com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
2499            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
2500                    com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
2501            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS,
2502                    com.android.internal.R.string.config_dreamsDefaultComponent);
2503            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
2504                    com.android.internal.R.string.config_dreamsDefaultComponent);
2505
2506            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
2507                    R.bool.def_accessibility_display_magnification_enabled);
2508
2509            loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
2510                    R.fraction.def_accessibility_display_magnification_scale, 1);
2511
2512            loadBooleanSetting(stmt,
2513                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
2514                    R.bool.def_accessibility_display_magnification_auto_update);
2515
2516            loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
2517                    R.bool.def_user_setup_complete);
2518
2519            loadStringSetting(stmt, Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
2520                        R.string.def_immersive_mode_confirmations);
2521
2522            loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
2523                    R.bool.def_install_non_market_apps);
2524
2525            loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
2526                    R.bool.def_wake_gesture_enabled);
2527
2528            loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
2529                    R.integer.def_lock_screen_show_notifications);
2530
2531            loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
2532                    R.bool.def_lock_screen_allow_private_notifications);
2533
2534            loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
2535                    R.integer.def_sleep_timeout);
2536
2537            /*
2538             * IMPORTANT: Do not add any more upgrade steps here as the global,
2539             * secure, and system settings are no longer stored in a database
2540             * but are kept in memory and persisted to XML.
2541             *
2542             * See: SettingsProvider.UpgradeController#onUpgradeLocked
2543             */
2544        } finally {
2545            if (stmt != null) stmt.close();
2546        }
2547    }
2548
2549    private void loadSecure35Settings(SQLiteStatement stmt) {
2550        loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED,
2551                R.bool.def_backup_enabled);
2552
2553        loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
2554                R.string.def_backup_transport);
2555    }
2556
2557    private void loadGlobalSettings(SQLiteDatabase db) {
2558        SQLiteStatement stmt = null;
2559        try {
2560            stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
2561                    + " VALUES(?,?);");
2562
2563            // --- Previously in 'system'
2564            loadBooleanSetting(stmt, Settings.Global.AIRPLANE_MODE_ON,
2565                    R.bool.def_airplane_mode_on);
2566
2567            loadBooleanSetting(stmt, Settings.Global.THEATER_MODE_ON,
2568                    R.bool.def_theater_mode_on);
2569
2570            loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_RADIOS,
2571                    R.string.def_airplane_mode_radios);
2572
2573            loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
2574                    R.string.airplane_mode_toggleable_radios);
2575
2576            loadBooleanSetting(stmt, Settings.Global.ASSISTED_GPS_ENABLED,
2577                    R.bool.assisted_gps_enabled);
2578
2579            loadBooleanSetting(stmt, Settings.Global.AUTO_TIME,
2580                    R.bool.def_auto_time); // Sync time to NITZ
2581
2582            loadBooleanSetting(stmt, Settings.Global.AUTO_TIME_ZONE,
2583                    R.bool.def_auto_time_zone); // Sync timezone to NITZ
2584
2585            loadSetting(stmt, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
2586                    ("1".equals(SystemProperties.get("ro.kernel.qemu")) ||
2587                        mContext.getResources().getBoolean(R.bool.def_stay_on_while_plugged_in))
2588                     ? 1 : 0);
2589
2590            loadIntegerSetting(stmt, Settings.Global.WIFI_SLEEP_POLICY,
2591                    R.integer.def_wifi_sleep_policy);
2592
2593            loadSetting(stmt, Settings.Global.MODE_RINGER,
2594                    AudioManager.RINGER_MODE_NORMAL);
2595
2596            // --- Previously in 'secure'
2597            loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE,
2598                    R.bool.def_package_verifier_enable);
2599
2600            loadBooleanSetting(stmt, Settings.Global.WIFI_ON,
2601                    R.bool.def_wifi_on);
2602
2603            loadBooleanSetting(stmt, Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
2604                    R.bool.def_networks_available_notification_on);
2605
2606            loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_ON,
2607                    R.bool.def_bluetooth_on);
2608
2609            // Enable or disable Cell Broadcast SMS
2610            loadSetting(stmt, Settings.Global.CDMA_CELL_BROADCAST_SMS,
2611                    RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
2612
2613            // Data roaming default, based on build
2614            loadSetting(stmt, Settings.Global.DATA_ROAMING,
2615                    "true".equalsIgnoreCase(
2616                            SystemProperties.get("ro.com.android.dataroaming",
2617                                    "false")) ? 1 : 0);
2618
2619            loadBooleanSetting(stmt, Settings.Global.DEVICE_PROVISIONED,
2620                    R.bool.def_device_provisioned);
2621
2622            final int maxBytes = mContext.getResources().getInteger(
2623                    R.integer.def_download_manager_max_bytes_over_mobile);
2624            if (maxBytes > 0) {
2625                loadSetting(stmt, Settings.Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE,
2626                        Integer.toString(maxBytes));
2627            }
2628
2629            final int recommendedMaxBytes = mContext.getResources().getInteger(
2630                    R.integer.def_download_manager_recommended_max_bytes_over_mobile);
2631            if (recommendedMaxBytes > 0) {
2632                loadSetting(stmt, Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE,
2633                        Integer.toString(recommendedMaxBytes));
2634            }
2635
2636            // Mobile Data default, based on build
2637            loadSetting(stmt, Settings.Global.MOBILE_DATA,
2638                    "true".equalsIgnoreCase(
2639                            SystemProperties.get("ro.com.android.mobiledata",
2640                                    "true")) ? 1 : 0);
2641
2642            loadBooleanSetting(stmt, Settings.Global.NETSTATS_ENABLED,
2643                    R.bool.def_netstats_enabled);
2644
2645            loadBooleanSetting(stmt, Settings.Global.USB_MASS_STORAGE_ENABLED,
2646                    R.bool.def_usb_mass_storage_enabled);
2647
2648            loadIntegerSetting(stmt, Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
2649                    R.integer.def_max_dhcp_retries);
2650
2651            loadBooleanSetting(stmt, Settings.Global.WIFI_DISPLAY_ON,
2652                    R.bool.def_wifi_display_on);
2653
2654            loadStringSetting(stmt, Settings.Global.LOCK_SOUND,
2655                    R.string.def_lock_sound);
2656            loadStringSetting(stmt, Settings.Global.UNLOCK_SOUND,
2657                    R.string.def_unlock_sound);
2658            loadStringSetting(stmt, Settings.Global.TRUSTED_SOUND,
2659                    R.string.def_trusted_sound);
2660            loadIntegerSetting(stmt, Settings.Global.POWER_SOUNDS_ENABLED,
2661                    R.integer.def_power_sounds_enabled);
2662            loadStringSetting(stmt, Settings.Global.LOW_BATTERY_SOUND,
2663                    R.string.def_low_battery_sound);
2664            loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED,
2665                    R.integer.def_dock_sounds_enabled);
2666            loadStringSetting(stmt, Settings.Global.DESK_DOCK_SOUND,
2667                    R.string.def_desk_dock_sound);
2668            loadStringSetting(stmt, Settings.Global.DESK_UNDOCK_SOUND,
2669                    R.string.def_desk_undock_sound);
2670            loadStringSetting(stmt, Settings.Global.CAR_DOCK_SOUND,
2671                    R.string.def_car_dock_sound);
2672            loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND,
2673                    R.string.def_car_undock_sound);
2674            loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
2675                    R.string.def_wireless_charging_started_sound);
2676
2677            loadIntegerSetting(stmt, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED,
2678                    R.integer.def_dock_audio_media_enabled);
2679
2680            loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
2681            loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
2682                    PackageHelper.APP_INSTALL_AUTO);
2683
2684            // Set default cdma emergency tone
2685            loadSetting(stmt, Settings.Global.EMERGENCY_TONE, 0);
2686
2687            // Set default cdma call auto retry
2688            loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);
2689
2690            // Set the preferred network mode to target desired value or Default
2691            // value defined in RILConstants
2692            int type;
2693            type = RILConstants.PREFERRED_NETWORK_MODE;
2694            loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
2695
2696            // Set the preferred cdma subscription source to target desired value or default
2697            // value defined in CdmaSubscriptionSourceManager
2698            type = SystemProperties.getInt("ro.telephony.default_cdma_sub",
2699                        CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION);
2700            loadSetting(stmt, Settings.Global.CDMA_SUBSCRIPTION_MODE, type);
2701
2702            loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
2703                    R.integer.def_low_battery_sound_timeout);
2704
2705            loadIntegerSetting(stmt, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
2706                    R.integer.def_wifi_scan_always_available);
2707
2708            loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
2709                    R.integer.def_heads_up_enabled);
2710
2711            loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());
2712
2713            loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
2714                    ImsConfig.FeatureValueConstants.ON);
2715
2716            /*
2717             * IMPORTANT: Do not add any more upgrade steps here as the global,
2718             * secure, and system settings are no longer stored in a database
2719             * but are kept in memory and persisted to XML.
2720             *
2721             * See: SettingsProvider.UpgradeController#onUpgradeLocked
2722             */
2723        } finally {
2724            if (stmt != null) stmt.close();
2725        }
2726    }
2727
2728    private void loadSetting(SQLiteStatement stmt, String key, Object value) {
2729        stmt.bindString(1, key);
2730        stmt.bindString(2, value.toString());
2731        stmt.execute();
2732    }
2733
2734    private void loadStringSetting(SQLiteStatement stmt, String key, int resid) {
2735        loadSetting(stmt, key, mContext.getResources().getString(resid));
2736    }
2737
2738    private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
2739        loadSetting(stmt, key,
2740                mContext.getResources().getBoolean(resid) ? "1" : "0");
2741    }
2742
2743    private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) {
2744        loadSetting(stmt, key,
2745                Integer.toString(mContext.getResources().getInteger(resid)));
2746    }
2747
2748    private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) {
2749        loadSetting(stmt, key,
2750                Float.toString(mContext.getResources().getFraction(resid, base, base)));
2751    }
2752
2753    private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) {
2754        return getIntValueFromTable(db, TABLE_SYSTEM, name, defaultValue);
2755    }
2756
2757    private int getIntValueFromTable(SQLiteDatabase db, String table, String name,
2758            int defaultValue) {
2759        String value = getStringValueFromTable(db, table, name, null);
2760        return (value != null) ? Integer.parseInt(value) : defaultValue;
2761    }
2762
2763    private String getStringValueFromTable(SQLiteDatabase db, String table, String name,
2764            String defaultValue) {
2765        Cursor c = null;
2766        try {
2767            c = db.query(table, new String[] { Settings.System.VALUE }, "name='" + name + "'",
2768                    null, null, null, null);
2769            if (c != null && c.moveToFirst()) {
2770                String val = c.getString(0);
2771                return val == null ? defaultValue : val;
2772            }
2773        } finally {
2774            if (c != null) c.close();
2775        }
2776        return defaultValue;
2777    }
2778
2779    private String getOldDefaultDeviceName() {
2780        return mContext.getResources().getString(R.string.def_device_name,
2781                Build.MANUFACTURER, Build.MODEL);
2782    }
2783
2784    private String getDefaultDeviceName() {
2785        return mContext.getResources().getString(R.string.def_device_name_simple, Build.MODEL);
2786    }
2787}
2788