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