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