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