DatabaseHelper.java revision d3c5e1eca12f4ca618e3f671dc6fae48307ec895
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.providers.settings;
18
19import android.content.ComponentName;
20import android.content.ContentValues;
21import android.content.Context;
22import android.content.Intent;
23import android.content.pm.ActivityInfo;
24import android.content.pm.PackageManager;
25import android.content.res.XmlResourceParser;
26import android.database.Cursor;
27import android.database.sqlite.SQLiteDatabase;
28import android.database.sqlite.SQLiteOpenHelper;
29import android.database.sqlite.SQLiteStatement;
30import android.media.AudioManager;
31import android.media.AudioService;
32import android.net.ConnectivityManager;
33import android.os.SystemProperties;
34import android.provider.Settings;
35import android.provider.Settings.Secure;
36import android.text.TextUtils;
37import android.util.Log;
38
39import com.android.internal.content.PackageHelper;
40import com.android.internal.telephony.BaseCommands;
41import com.android.internal.telephony.Phone;
42import com.android.internal.telephony.RILConstants;
43import com.android.internal.util.XmlUtils;
44import com.android.internal.widget.LockPatternUtils;
45import com.android.internal.widget.LockPatternView;
46
47import org.xmlpull.v1.XmlPullParser;
48import org.xmlpull.v1.XmlPullParserException;
49
50import java.io.IOException;
51import java.util.HashSet;
52import java.util.List;
53
54/**
55 * Database helper class for {@link SettingsProvider}.
56 * Mostly just has a bit {@link #onCreate} to initialize the database.
57 */
58public class DatabaseHelper extends SQLiteOpenHelper {
59    private static final String TAG = "SettingsProvider";
60    private static final String DATABASE_NAME = "settings.db";
61
62    // Please, please please. If you update the database version, check to make sure the
63    // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
64    // is properly propagated through your change.  Not doing so will result in a loss of user
65    // settings.
66    private static final int DATABASE_VERSION = 76;
67
68    private Context mContext;
69
70    private static final HashSet<String> mValidTables = new HashSet<String>();
71
72    static {
73        mValidTables.add("system");
74        mValidTables.add("secure");
75        mValidTables.add("bluetooth_devices");
76        mValidTables.add("bookmarks");
77
78        // These are old.
79        mValidTables.add("favorites");
80        mValidTables.add("gservices");
81        mValidTables.add("old_favorites");
82    }
83
84    public DatabaseHelper(Context context) {
85        super(context, DATABASE_NAME, null, DATABASE_VERSION);
86        mContext = context;
87    }
88
89    public static boolean isValidTable(String name) {
90        return mValidTables.contains(name);
91    }
92
93    private void createSecureTable(SQLiteDatabase db) {
94        db.execSQL("CREATE TABLE secure (" +
95                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
96                "name TEXT UNIQUE ON CONFLICT REPLACE," +
97                "value TEXT" +
98                ");");
99        db.execSQL("CREATE INDEX secureIndex1 ON secure (name);");
100    }
101
102    @Override
103    public void onCreate(SQLiteDatabase db) {
104        db.execSQL("CREATE TABLE system (" +
105                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
106                    "name TEXT UNIQUE ON CONFLICT REPLACE," +
107                    "value TEXT" +
108                    ");");
109        db.execSQL("CREATE INDEX systemIndex1 ON system (name);");
110
111        createSecureTable(db);
112
113        db.execSQL("CREATE TABLE bluetooth_devices (" +
114                    "_id INTEGER PRIMARY KEY," +
115                    "name TEXT," +
116                    "addr TEXT," +
117                    "channel INTEGER," +
118                    "type INTEGER" +
119                    ");");
120
121        db.execSQL("CREATE TABLE bookmarks (" +
122                    "_id INTEGER PRIMARY KEY," +
123                    "title TEXT," +
124                    "folder TEXT," +
125                    "intent TEXT," +
126                    "shortcut INTEGER," +
127                    "ordering INTEGER" +
128                    ");");
129
130        db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);");
131        db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);");
132
133        // Populate bookmarks table with initial bookmarks
134        loadBookmarks(db);
135
136        // Load initial volume levels into DB
137        loadVolumeLevels(db);
138
139        // Load inital settings values
140        loadSettings(db);
141    }
142
143    @Override
144    public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
145        Log.w(TAG, "Upgrading settings database from version " + oldVersion + " to "
146                + currentVersion);
147
148        int upgradeVersion = oldVersion;
149
150        // Pattern for upgrade blocks:
151        //
152        //    if (upgradeVersion == [the DATABASE_VERSION you set] - 1) {
153        //        .. your upgrade logic..
154        //        upgradeVersion = [the DATABASE_VERSION you set]
155        //    }
156
157        if (upgradeVersion == 20) {
158            /*
159             * Version 21 is part of the volume control refresh. There is no
160             * longer a UI-visible for setting notification vibrate on/off (in
161             * our design), but the functionality still exists. Force the
162             * notification vibrate to on.
163             */
164            loadVibrateSetting(db, true);
165
166            upgradeVersion = 21;
167        }
168
169        if (upgradeVersion < 22) {
170            upgradeVersion = 22;
171            // Upgrade the lock gesture storage location and format
172            upgradeLockPatternLocation(db);
173        }
174
175        if (upgradeVersion < 23) {
176            db.execSQL("UPDATE favorites SET iconResource=0 WHERE iconType=0");
177            upgradeVersion = 23;
178        }
179
180        if (upgradeVersion == 23) {
181            db.beginTransaction();
182            try {
183                db.execSQL("ALTER TABLE favorites ADD spanX INTEGER");
184                db.execSQL("ALTER TABLE favorites ADD spanY INTEGER");
185                // Shortcuts, applications, folders
186                db.execSQL("UPDATE favorites SET spanX=1, spanY=1 WHERE itemType<=0");
187                // Photo frames, clocks
188                db.execSQL(
189                    "UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
190                // Search boxes
191                db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001");
192                db.setTransactionSuccessful();
193            } finally {
194                db.endTransaction();
195            }
196            upgradeVersion = 24;
197        }
198
199        if (upgradeVersion == 24) {
200            db.beginTransaction();
201            try {
202                // The value of the constants for preferring wifi or preferring mobile have been
203                // swapped, so reload the default.
204                db.execSQL("DELETE FROM system WHERE name='network_preference'");
205                db.execSQL("INSERT INTO system ('name', 'value') values ('network_preference', '" +
206                        ConnectivityManager.DEFAULT_NETWORK_PREFERENCE + "')");
207                db.setTransactionSuccessful();
208            } finally {
209                db.endTransaction();
210            }
211            upgradeVersion = 25;
212        }
213
214        if (upgradeVersion == 25) {
215            db.beginTransaction();
216            try {
217                db.execSQL("ALTER TABLE favorites ADD uri TEXT");
218                db.execSQL("ALTER TABLE favorites ADD displayMode INTEGER");
219                db.setTransactionSuccessful();
220            } finally {
221                db.endTransaction();
222            }
223            upgradeVersion = 26;
224        }
225
226        if (upgradeVersion == 26) {
227            // This introduces the new secure settings table.
228            db.beginTransaction();
229            try {
230                createSecureTable(db);
231                db.setTransactionSuccessful();
232            } finally {
233                db.endTransaction();
234            }
235            upgradeVersion = 27;
236        }
237
238        if (upgradeVersion == 27) {
239            String[] settingsToMove = {
240                    Settings.Secure.ADB_ENABLED,
241                    Settings.Secure.ANDROID_ID,
242                    Settings.Secure.BLUETOOTH_ON,
243                    Settings.Secure.DATA_ROAMING,
244                    Settings.Secure.DEVICE_PROVISIONED,
245                    Settings.Secure.HTTP_PROXY,
246                    Settings.Secure.INSTALL_NON_MARKET_APPS,
247                    Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
248                    Settings.Secure.LOGGING_ID,
249                    Settings.Secure.NETWORK_PREFERENCE,
250                    Settings.Secure.PARENTAL_CONTROL_ENABLED,
251                    Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
252                    Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
253                    Settings.Secure.SETTINGS_CLASSNAME,
254                    Settings.Secure.USB_MASS_STORAGE_ENABLED,
255                    Settings.Secure.USE_GOOGLE_MAIL,
256                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
257                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
258                    Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT,
259                    Settings.Secure.WIFI_ON,
260                    Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE,
261                    Settings.Secure.WIFI_WATCHDOG_AP_COUNT,
262                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS,
263                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED,
264                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS,
265                    Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT,
266                    Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS,
267                    Settings.Secure.WIFI_WATCHDOG_ON,
268                    Settings.Secure.WIFI_WATCHDOG_PING_COUNT,
269                    Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS,
270                    Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS,
271                };
272            moveFromSystemToSecure(db, settingsToMove);
273            upgradeVersion = 28;
274        }
275
276        if (upgradeVersion == 28 || upgradeVersion == 29) {
277            // Note: The upgrade to 28 was flawed since it didn't delete the old
278            // setting first before inserting. Combining 28 and 29 with the
279            // fixed version.
280
281            // This upgrade adds the STREAM_NOTIFICATION type to the list of
282            // types affected by ringer modes (silent, vibrate, etc.)
283            db.beginTransaction();
284            try {
285                db.execSQL("DELETE FROM system WHERE name='"
286                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
287                int newValue = (1 << AudioManager.STREAM_RING)
288                        | (1 << AudioManager.STREAM_NOTIFICATION)
289                        | (1 << AudioManager.STREAM_SYSTEM);
290                db.execSQL("INSERT INTO system ('name', 'value') values ('"
291                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
292                        + String.valueOf(newValue) + "')");
293                db.setTransactionSuccessful();
294            } finally {
295                db.endTransaction();
296            }
297
298            upgradeVersion = 30;
299        }
300
301        if (upgradeVersion == 30) {
302            /*
303             * Upgrade 31 clears the title for all quick launch shortcuts so the
304             * activities' titles will be resolved at display time. Also, the
305             * folder is changed to '@quicklaunch'.
306             */
307            db.beginTransaction();
308            try {
309                db.execSQL("UPDATE bookmarks SET folder = '@quicklaunch'");
310                db.execSQL("UPDATE bookmarks SET title = ''");
311                db.setTransactionSuccessful();
312            } finally {
313                db.endTransaction();
314            }
315            upgradeVersion = 31;
316        }
317
318        if (upgradeVersion == 31) {
319            /*
320             * Animations are now managed in preferences, and may be
321             * enabled or disabled based on product resources.
322             */
323            db.beginTransaction();
324            SQLiteStatement stmt = null;
325            try {
326                db.execSQL("DELETE FROM system WHERE name='"
327                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
328                db.execSQL("DELETE FROM system WHERE name='"
329                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
330                stmt = db.compileStatement("INSERT INTO system(name,value)"
331                        + " VALUES(?,?);");
332                loadDefaultAnimationSettings(stmt);
333                db.setTransactionSuccessful();
334            } finally {
335                db.endTransaction();
336                if (stmt != null) stmt.close();
337            }
338            upgradeVersion = 32;
339        }
340
341        if (upgradeVersion == 32) {
342            // The Wi-Fi watchdog SSID list is now seeded with the value of
343            // the property ro.com.android.wifi-watchlist
344            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
345            if (!TextUtils.isEmpty(wifiWatchList)) {
346                db.beginTransaction();
347                try {
348                    db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
349                            Settings.Secure.WIFI_WATCHDOG_WATCH_LIST + "','" +
350                            wifiWatchList + "');");
351                    db.setTransactionSuccessful();
352                } finally {
353                    db.endTransaction();
354                }
355            }
356            upgradeVersion = 33;
357        }
358
359        if (upgradeVersion == 33) {
360            // Set the default zoom controls to: tap-twice to bring up +/-
361            db.beginTransaction();
362            try {
363                db.execSQL("INSERT INTO system(name,value) values('zoom','2');");
364                db.setTransactionSuccessful();
365            } finally {
366                db.endTransaction();
367            }
368            upgradeVersion = 34;
369        }
370
371        if (upgradeVersion == 34) {
372            db.beginTransaction();
373            SQLiteStatement stmt = null;
374            try {
375                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
376                        + " VALUES(?,?);");
377                loadSecure35Settings(stmt);
378                db.setTransactionSuccessful();
379            } finally {
380                db.endTransaction();
381                if (stmt != null) stmt.close();
382            }
383            upgradeVersion = 35;
384        }
385            // due to a botched merge from donut to eclair, the initialization of ASSISTED_GPS_ENABLED
386            // was accidentally done out of order here.
387            // to fix this, ASSISTED_GPS_ENABLED is now initialized while upgrading from 38 to 39,
388            // and we intentionally do nothing from 35 to 36 now.
389        if (upgradeVersion == 35) {
390            upgradeVersion = 36;
391        }
392
393        if (upgradeVersion == 36) {
394           // This upgrade adds the STREAM_SYSTEM_ENFORCED type to the list of
395            // types affected by ringer modes (silent, vibrate, etc.)
396            db.beginTransaction();
397            try {
398                db.execSQL("DELETE FROM system WHERE name='"
399                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
400                int newValue = (1 << AudioManager.STREAM_RING)
401                        | (1 << AudioManager.STREAM_NOTIFICATION)
402                        | (1 << AudioManager.STREAM_SYSTEM)
403                        | (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
404                db.execSQL("INSERT INTO system ('name', 'value') values ('"
405                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
406                        + String.valueOf(newValue) + "')");
407                db.setTransactionSuccessful();
408            } finally {
409                db.endTransaction();
410            }
411            upgradeVersion = 37;
412        }
413
414        if (upgradeVersion == 37) {
415            db.beginTransaction();
416            SQLiteStatement stmt = null;
417            try {
418                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
419                        + " VALUES(?,?);");
420                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
421                        R.string.airplane_mode_toggleable_radios);
422                db.setTransactionSuccessful();
423            } finally {
424                db.endTransaction();
425                if (stmt != null) stmt.close();
426            }
427            upgradeVersion = 38;
428        }
429
430        if (upgradeVersion == 38) {
431            db.beginTransaction();
432            try {
433                String value =
434                        mContext.getResources().getBoolean(R.bool.assisted_gps_enabled) ? "1" : "0";
435                db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
436                        Settings.Secure.ASSISTED_GPS_ENABLED + "','" + value + "');");
437                db.setTransactionSuccessful();
438            } finally {
439                db.endTransaction();
440            }
441
442            upgradeVersion = 39;
443        }
444
445        if (upgradeVersion == 39) {
446            upgradeAutoBrightness(db);
447            upgradeVersion = 40;
448        }
449
450        if (upgradeVersion == 40) {
451            /*
452             * All animations are now turned on by default!
453             */
454            db.beginTransaction();
455            SQLiteStatement stmt = null;
456            try {
457                db.execSQL("DELETE FROM system WHERE name='"
458                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
459                db.execSQL("DELETE FROM system WHERE name='"
460                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
461                stmt = db.compileStatement("INSERT INTO system(name,value)"
462                        + " VALUES(?,?);");
463                loadDefaultAnimationSettings(stmt);
464                db.setTransactionSuccessful();
465            } finally {
466                db.endTransaction();
467                if (stmt != null) stmt.close();
468            }
469            upgradeVersion = 41;
470        }
471
472        if (upgradeVersion == 41) {
473            /*
474             * Initialize newly public haptic feedback setting
475             */
476            db.beginTransaction();
477            SQLiteStatement stmt = null;
478            try {
479                db.execSQL("DELETE FROM system WHERE name='"
480                        + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'");
481                stmt = db.compileStatement("INSERT INTO system(name,value)"
482                        + " VALUES(?,?);");
483                loadDefaultHapticSettings(stmt);
484                db.setTransactionSuccessful();
485            } finally {
486                db.endTransaction();
487                if (stmt != null) stmt.close();
488            }
489            upgradeVersion = 42;
490        }
491
492        if (upgradeVersion == 42) {
493            /*
494             * Initialize new notification pulse setting
495             */
496            db.beginTransaction();
497            SQLiteStatement stmt = null;
498            try {
499                stmt = db.compileStatement("INSERT INTO system(name,value)"
500                        + " VALUES(?,?);");
501                loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
502                        R.bool.def_notification_pulse);
503                db.setTransactionSuccessful();
504            } finally {
505                db.endTransaction();
506                if (stmt != null) stmt.close();
507            }
508            upgradeVersion = 43;
509        }
510
511        if (upgradeVersion == 43) {
512            /*
513             * This upgrade stores bluetooth volume separately from voice volume
514             */
515            db.beginTransaction();
516            SQLiteStatement stmt = null;
517            try {
518                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
519                        + " VALUES(?,?);");
520                loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO,
521                        AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
522                db.setTransactionSuccessful();
523            } finally {
524                db.endTransaction();
525                if (stmt != null) stmt.close();
526            }
527            upgradeVersion = 44;
528        }
529
530        if (upgradeVersion == 44) {
531            /*
532             * Gservices was moved into vendor/google.
533             */
534            db.execSQL("DROP TABLE IF EXISTS gservices");
535            db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
536            upgradeVersion = 45;
537        }
538
539        if (upgradeVersion == 45) {
540             /*
541              * New settings for MountService
542              */
543            db.beginTransaction();
544            try {
545                db.execSQL("INSERT INTO secure(name,value) values('" +
546                        Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND + "','1');");
547                db.execSQL("INSERT INTO secure(name,value) values('" +
548                        Settings.Secure.MOUNT_UMS_AUTOSTART + "','0');");
549                db.execSQL("INSERT INTO secure(name,value) values('" +
550                        Settings.Secure.MOUNT_UMS_PROMPT + "','1');");
551                db.execSQL("INSERT INTO secure(name,value) values('" +
552                        Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED + "','1');");
553                db.setTransactionSuccessful();
554            } finally {
555                db.endTransaction();
556            }
557            upgradeVersion = 46;
558        }
559
560        if (upgradeVersion == 46) {
561            /*
562             * The password mode constants have changed; reset back to no
563             * password.
564             */
565            db.beginTransaction();
566            try {
567                db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
568                db.setTransactionSuccessful();
569            } finally {
570                db.endTransaction();
571            }
572           upgradeVersion = 47;
573       }
574
575
576        if (upgradeVersion == 47) {
577            /*
578             * The password mode constants have changed again; reset back to no
579             * password.
580             */
581            db.beginTransaction();
582            try {
583                db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
584                db.setTransactionSuccessful();
585            } finally {
586                db.endTransaction();
587            }
588           upgradeVersion = 48;
589       }
590
591       if (upgradeVersion == 48) {
592           /*
593            * Default recognition service no longer initialized here,
594            * moved to RecognitionManagerService.
595            */
596           upgradeVersion = 49;
597       }
598
599       if (upgradeVersion == 49) {
600           /*
601            * New settings for new user interface noises.
602            */
603           db.beginTransaction();
604           SQLiteStatement stmt = null;
605           try {
606                stmt = db.compileStatement("INSERT INTO system(name,value)"
607                        + " VALUES(?,?);");
608                loadUISoundEffectsSettings(stmt);
609                db.setTransactionSuccessful();
610            } finally {
611                db.endTransaction();
612                if (stmt != null) stmt.close();
613            }
614
615           upgradeVersion = 50;
616       }
617
618       if (upgradeVersion == 50) {
619           /*
620            * Install location no longer initiated here.
621            */
622           upgradeVersion = 51;
623       }
624
625       if (upgradeVersion == 51) {
626           /* Move the lockscreen related settings to Secure, including some private ones. */
627           String[] settingsToMove = {
628                   Secure.LOCK_PATTERN_ENABLED,
629                   Secure.LOCK_PATTERN_VISIBLE,
630                   Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
631                   "lockscreen.password_type",
632                   "lockscreen.lockoutattemptdeadline",
633                   "lockscreen.patterneverchosen",
634                   "lock_pattern_autolock",
635                   "lockscreen.lockedoutpermanently",
636                   "lockscreen.password_salt"
637           };
638           moveFromSystemToSecure(db, settingsToMove);
639           upgradeVersion = 52;
640       }
641
642        if (upgradeVersion == 52) {
643            // new vibration/silent mode settings
644            db.beginTransaction();
645            SQLiteStatement stmt = null;
646            try {
647                stmt = db.compileStatement("INSERT INTO system(name,value)"
648                        + " VALUES(?,?);");
649                loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
650                        R.bool.def_vibrate_in_silent);
651                db.setTransactionSuccessful();
652            } finally {
653                db.endTransaction();
654                if (stmt != null) stmt.close();
655            }
656
657            upgradeVersion = 53;
658        }
659
660        if (upgradeVersion == 53) {
661            /*
662             * New settings for set install location UI no longer initiated here.
663             */
664            upgradeVersion = 54;
665        }
666
667        if (upgradeVersion == 54) {
668            /*
669             * Update the screen timeout value if set to never
670             */
671            db.beginTransaction();
672            try {
673                upgradeScreenTimeoutFromNever(db);
674                db.setTransactionSuccessful();
675            } finally {
676                db.endTransaction();
677            }
678
679            upgradeVersion = 55;
680        }
681
682        if (upgradeVersion == 55) {
683            /* Move the install location settings. */
684            String[] settingsToMove = {
685                    Secure.SET_INSTALL_LOCATION,
686                    Secure.DEFAULT_INSTALL_LOCATION
687            };
688            moveFromSystemToSecure(db, settingsToMove);
689            db.beginTransaction();
690            SQLiteStatement stmt = null;
691            try {
692                stmt = db.compileStatement("INSERT INTO system(name,value)"
693                        + " VALUES(?,?);");
694                loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 0);
695                loadSetting(stmt, Secure.DEFAULT_INSTALL_LOCATION,
696                        PackageHelper.APP_INSTALL_AUTO);
697                db.setTransactionSuccessful();
698             } finally {
699                 db.endTransaction();
700                 if (stmt != null) stmt.close();
701             }
702            upgradeVersion = 56;
703        }
704
705        if (upgradeVersion == 56) {
706            /*
707             * Add Bluetooth to list of toggleable radios in airplane mode
708             */
709            db.beginTransaction();
710            SQLiteStatement stmt = null;
711            try {
712                db.execSQL("DELETE FROM system WHERE name='"
713                        + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
714                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
715                        + " VALUES(?,?);");
716                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
717                        R.string.airplane_mode_toggleable_radios);
718                db.setTransactionSuccessful();
719            } finally {
720                db.endTransaction();
721                if (stmt != null) stmt.close();
722            }
723            upgradeVersion = 57;
724        }
725
726        /************* The following are Honeycomb changes ************/
727
728        if (upgradeVersion == 57) {
729            /*
730             * New settings to:
731             *  1. Enable injection of accessibility scripts in WebViews.
732             *  2. Define the key bindings for traversing web content in WebViews.
733             */
734            db.beginTransaction();
735            SQLiteStatement stmt = null;
736            try {
737                stmt = db.compileStatement("INSERT INTO secure(name,value)"
738                        + " VALUES(?,?);");
739                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
740                        R.bool.def_accessibility_script_injection);
741                stmt.close();
742                stmt = db.compileStatement("INSERT INTO secure(name,value)"
743                        + " VALUES(?,?);");
744                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
745                        R.string.def_accessibility_web_content_key_bindings);
746                db.setTransactionSuccessful();
747            } finally {
748                db.endTransaction();
749                if (stmt != null) stmt.close();
750            }
751            upgradeVersion = 58;
752        }
753
754        if (upgradeVersion == 58) {
755            /* Add default for new Auto Time Zone */
756            int autoTimeValue = getIntValueFromSystem(db, Settings.System.AUTO_TIME, 0);
757            db.beginTransaction();
758            SQLiteStatement stmt = null;
759            try {
760                stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);");
761                loadSetting(stmt, Settings.System.AUTO_TIME_ZONE,
762                        autoTimeValue); // Sync timezone to NITZ if auto_time was enabled
763                db.setTransactionSuccessful();
764            } finally {
765                db.endTransaction();
766                if (stmt != null) stmt.close();
767            }
768            upgradeVersion = 59;
769        }
770
771        if (upgradeVersion == 59) {
772            // Persistence for the rotation lock feature.
773            db.beginTransaction();
774            SQLiteStatement stmt = null;
775            try {
776                stmt = db.compileStatement("INSERT INTO system(name,value)"
777                        + " VALUES(?,?);");
778                loadBooleanSetting(stmt, Settings.System.USER_ROTATION,
779                        R.integer.def_user_rotation); // should be zero degrees
780                db.setTransactionSuccessful();
781            } finally {
782                db.endTransaction();
783                if (stmt != null) stmt.close();
784            }
785            upgradeVersion = 60;
786        }
787
788        if (upgradeVersion == 60) {
789            // Don't do this for upgrades from Gingerbread
790            // Were only required for intra-Honeycomb upgrades for testing
791            // upgradeScreenTimeout(db);
792            upgradeVersion = 61;
793        }
794
795        if (upgradeVersion == 61) {
796            // Don't do this for upgrades from Gingerbread
797            // Were only required for intra-Honeycomb upgrades for testing
798            // upgradeScreenTimeout(db);
799            upgradeVersion = 62;
800        }
801
802        // Change the default for screen auto-brightness mode
803        if (upgradeVersion == 62) {
804            // Don't do this for upgrades from Gingerbread
805            // Were only required for intra-Honeycomb upgrades for testing
806            // upgradeAutoBrightness(db);
807            upgradeVersion = 63;
808        }
809
810        if (upgradeVersion == 63) {
811            // This upgrade adds the STREAM_MUSIC type to the list of
812             // types affected by ringer modes (silent, vibrate, etc.)
813             db.beginTransaction();
814             try {
815                 db.execSQL("DELETE FROM system WHERE name='"
816                         + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
817                 int newValue = (1 << AudioManager.STREAM_RING)
818                         | (1 << AudioManager.STREAM_NOTIFICATION)
819                         | (1 << AudioManager.STREAM_SYSTEM)
820                         | (1 << AudioManager.STREAM_SYSTEM_ENFORCED)
821                         | (1 << AudioManager.STREAM_MUSIC);
822                 db.execSQL("INSERT INTO system ('name', 'value') values ('"
823                         + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
824                         + String.valueOf(newValue) + "')");
825                 db.setTransactionSuccessful();
826             } finally {
827                 db.endTransaction();
828             }
829             upgradeVersion = 64;
830         }
831
832        if (upgradeVersion == 64) {
833            // New setting to configure the long press timeout.
834            db.beginTransaction();
835            SQLiteStatement stmt = null;
836            try {
837                stmt = db.compileStatement("INSERT INTO secure(name,value)"
838                        + " VALUES(?,?);");
839                loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
840                        R.integer.def_long_press_timeout_millis);
841                stmt.close();
842                db.setTransactionSuccessful();
843            } finally {
844                db.endTransaction();
845                if (stmt != null) stmt.close();
846            }
847            upgradeVersion = 65;
848        }
849
850        /************* The following are Ice Cream Sandwich changes ************/
851
852        if (upgradeVersion == 65) {
853            /*
854             * Animations are removed from Settings. Turned on by default
855             */
856            db.beginTransaction();
857            SQLiteStatement stmt = null;
858            try {
859                db.execSQL("DELETE FROM system WHERE name='"
860                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
861                db.execSQL("DELETE FROM system WHERE name='"
862                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
863                stmt = db.compileStatement("INSERT INTO system(name,value)"
864                        + " VALUES(?,?);");
865                loadDefaultAnimationSettings(stmt);
866                db.setTransactionSuccessful();
867            } finally {
868                db.endTransaction();
869                if (stmt != null) stmt.close();
870            }
871            upgradeVersion = 66;
872        }
873
874        if (upgradeVersion == 66) {
875            // This upgrade makes sure that MODE_RINGER_STREAMS_AFFECTED is set
876            // according to device voice capability
877            db.beginTransaction();
878            try {
879                int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
880                                                (1 << AudioManager.STREAM_NOTIFICATION) |
881                                                (1 << AudioManager.STREAM_SYSTEM) |
882                                                (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
883                if (!mContext.getResources().getBoolean(
884                        com.android.internal.R.bool.config_voice_capable)) {
885                    ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
886                }
887                db.execSQL("DELETE FROM system WHERE name='"
888                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
889                db.execSQL("INSERT INTO system ('name', 'value') values ('"
890                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
891                        + String.valueOf(ringerModeAffectedStreams) + "')");
892                db.setTransactionSuccessful();
893            } finally {
894                db.endTransaction();
895            }
896            upgradeVersion = 67;
897        }
898
899        if (upgradeVersion == 67) {
900            // New setting to enable touch exploration.
901            db.beginTransaction();
902            SQLiteStatement stmt = null;
903            try {
904                stmt = db.compileStatement("INSERT INTO secure(name,value)"
905                        + " VALUES(?,?);");
906                loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
907                        R.bool.def_touch_exploration_enabled);
908                stmt.close();
909                db.setTransactionSuccessful();
910            } finally {
911                db.endTransaction();
912                if (stmt != null) stmt.close();
913            }
914            upgradeVersion = 68;
915        }
916
917        if (upgradeVersion == 68) {
918            // Enable all system sounds by default
919            db.beginTransaction();
920            try {
921                db.execSQL("DELETE FROM system WHERE name='"
922                        + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "'");
923                db.setTransactionSuccessful();
924            } finally {
925                db.endTransaction();
926            }
927            upgradeVersion = 69;
928        }
929
930        if (upgradeVersion == 69) {
931            // Add RADIO_NFC to AIRPLANE_MODE_RADIO and AIRPLANE_MODE_TOGGLEABLE_RADIOS
932            String airplaneRadios = mContext.getResources().getString(
933                    R.string.def_airplane_mode_radios);
934            String toggleableRadios = mContext.getResources().getString(
935                    R.string.airplane_mode_toggleable_radios);
936            db.beginTransaction();
937            try {
938                db.execSQL("UPDATE system SET value='" + airplaneRadios + "' " +
939                        "WHERE name='" + Settings.System.AIRPLANE_MODE_RADIOS + "'");
940                db.execSQL("UPDATE system SET value='" + toggleableRadios + "' " +
941                        "WHERE name='" + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
942                db.setTransactionSuccessful();
943            } finally {
944                db.endTransaction();
945            }
946            upgradeVersion = 70;
947        }
948
949        if (upgradeVersion == 70) {
950            // Update all built-in bookmarks.  Some of the package names have changed.
951            loadBookmarks(db);
952            upgradeVersion = 71;
953        }
954
955        if (upgradeVersion == 71) {
956             // New setting to specify whether to speak passwords in accessibility mode.
957            db.beginTransaction();
958            SQLiteStatement stmt = null;
959            try {
960                stmt = db.compileStatement("INSERT INTO secure(name,value)"
961                        + " VALUES(?,?);");
962                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
963                        R.bool.def_accessibility_speak_password);
964                db.setTransactionSuccessful();
965            } finally {
966                db.endTransaction();
967                if (stmt != null) stmt.close();
968            }
969            upgradeVersion = 72;
970        }
971
972        if (upgradeVersion == 72) {
973            // update vibration settings
974            db.beginTransaction();
975            SQLiteStatement stmt = null;
976            try {
977                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
978                        + " VALUES(?,?);");
979                loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
980                        R.bool.def_vibrate_in_silent);
981                db.setTransactionSuccessful();
982            } finally {
983                db.endTransaction();
984                if (stmt != null) stmt.close();
985            }
986            upgradeVersion = 73;
987        }
988
989        if (upgradeVersion == 73) {
990            upgradeVibrateSettingFromNone(db);
991            upgradeVersion = 74;
992        }
993
994        if (upgradeVersion == 74) {
995            // URL from which WebView loads a JavaScript based screen-reader.
996            db.beginTransaction();
997            SQLiteStatement stmt = null;
998            try {
999                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
1000                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
1001                        R.string.def_accessibility_screen_reader_url);
1002                db.setTransactionSuccessful();
1003            } finally {
1004                db.endTransaction();
1005                if (stmt != null) stmt.close();
1006            }
1007            upgradeVersion = 75;
1008        }
1009        if (upgradeVersion == 75) {
1010            db.beginTransaction();
1011            SQLiteStatement stmt = null;
1012            Cursor c = null;
1013            try {
1014                c = db.query("secure", new String[] {"_id", "value"},
1015                        "name='lockscreen.disabled'",
1016                        null, null, null, null);
1017                // only set default if it has not yet been set
1018                if (c == null || c.getCount() == 0) {
1019                    stmt = db.compileStatement("INSERT INTO system(name,value)"
1020                            + " VALUES(?,?);");
1021                    loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
1022                            R.bool.def_lockscreen_disabled);
1023                }
1024                db.setTransactionSuccessful();
1025            } finally {
1026                db.endTransaction();
1027                if (c != null) c.close();
1028                if (stmt != null) stmt.close();
1029            }
1030            upgradeVersion = 76;
1031        }
1032
1033        // *** Remember to update DATABASE_VERSION above!
1034
1035        if (upgradeVersion != currentVersion) {
1036            Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
1037                    + ", must wipe the settings provider");
1038            db.execSQL("DROP TABLE IF EXISTS system");
1039            db.execSQL("DROP INDEX IF EXISTS systemIndex1");
1040            db.execSQL("DROP TABLE IF EXISTS secure");
1041            db.execSQL("DROP INDEX IF EXISTS secureIndex1");
1042            db.execSQL("DROP TABLE IF EXISTS gservices");
1043            db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
1044            db.execSQL("DROP TABLE IF EXISTS bluetooth_devices");
1045            db.execSQL("DROP TABLE IF EXISTS bookmarks");
1046            db.execSQL("DROP INDEX IF EXISTS bookmarksIndex1");
1047            db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
1048            db.execSQL("DROP TABLE IF EXISTS favorites");
1049            onCreate(db);
1050
1051            // Added for diagnosing settings.db wipes after the fact
1052            String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion;
1053            db.execSQL("INSERT INTO secure(name,value) values('" +
1054                    "wiped_db_reason" + "','" + wipeReason + "');");
1055        }
1056    }
1057
1058    private void moveFromSystemToSecure(SQLiteDatabase db, String [] settingsToMove) {
1059        // Copy settings values from 'system' to 'secure' and delete them from 'system'
1060        SQLiteStatement insertStmt = null;
1061        SQLiteStatement deleteStmt = null;
1062
1063        db.beginTransaction();
1064        try {
1065            insertStmt =
1066                db.compileStatement("INSERT INTO secure (name,value) SELECT name,value FROM "
1067                    + "system WHERE name=?");
1068            deleteStmt = db.compileStatement("DELETE FROM system WHERE name=?");
1069
1070
1071            for (String setting : settingsToMove) {
1072                insertStmt.bindString(1, setting);
1073                insertStmt.execute();
1074
1075                deleteStmt.bindString(1, setting);
1076                deleteStmt.execute();
1077            }
1078            db.setTransactionSuccessful();
1079        } finally {
1080            db.endTransaction();
1081            if (insertStmt != null) {
1082                insertStmt.close();
1083            }
1084            if (deleteStmt != null) {
1085                deleteStmt.close();
1086            }
1087        }
1088    }
1089
1090    private void upgradeLockPatternLocation(SQLiteDatabase db) {
1091        Cursor c = db.query("system", new String[] {"_id", "value"}, "name='lock_pattern'",
1092                null, null, null, null);
1093        if (c.getCount() > 0) {
1094            c.moveToFirst();
1095            String lockPattern = c.getString(1);
1096            if (!TextUtils.isEmpty(lockPattern)) {
1097                // Convert lock pattern
1098                try {
1099                    LockPatternUtils lpu = new LockPatternUtils(mContext);
1100                    List<LockPatternView.Cell> cellPattern =
1101                            LockPatternUtils.stringToPattern(lockPattern);
1102                    lpu.saveLockPattern(cellPattern);
1103                } catch (IllegalArgumentException e) {
1104                    // Don't want corrupted lock pattern to hang the reboot process
1105                }
1106            }
1107            c.close();
1108            db.delete("system", "name='lock_pattern'", null);
1109        } else {
1110            c.close();
1111        }
1112    }
1113
1114    private void upgradeScreenTimeoutFromNever(SQLiteDatabase db) {
1115        // See if the timeout is -1 (for "Never").
1116        Cursor c = db.query("system", new String[] { "_id", "value" }, "name=? AND value=?",
1117                new String[] { Settings.System.SCREEN_OFF_TIMEOUT, "-1" },
1118                null, null, null);
1119
1120        SQLiteStatement stmt = null;
1121        if (c.getCount() > 0) {
1122            c.close();
1123            try {
1124                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1125                        + " VALUES(?,?);");
1126
1127                // Set the timeout to 30 minutes in milliseconds
1128                loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
1129                        Integer.toString(30 * 60 * 1000));
1130            } finally {
1131                if (stmt != null) stmt.close();
1132            }
1133        } else {
1134            c.close();
1135        }
1136    }
1137
1138    private void upgradeVibrateSettingFromNone(SQLiteDatabase db) {
1139        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON, 0);
1140        // If the ringer vibrate value is invalid, set it to the default
1141        if ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_OFF) {
1142            vibrateSetting = AudioService.getValueForVibrateSetting(0,
1143                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
1144        }
1145        // Apply the same setting to the notification vibrate value
1146        vibrateSetting = AudioService.getValueForVibrateSetting(vibrateSetting,
1147                AudioManager.VIBRATE_TYPE_NOTIFICATION, vibrateSetting);
1148
1149        SQLiteStatement stmt = null;
1150        try {
1151            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1152                    + " VALUES(?,?);");
1153            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrateSetting);
1154        } finally {
1155            if (stmt != null)
1156                stmt.close();
1157        }
1158    }
1159
1160    private void upgradeScreenTimeout(SQLiteDatabase db) {
1161        // Change screen timeout to current default
1162        db.beginTransaction();
1163        SQLiteStatement stmt = null;
1164        try {
1165            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
1166                    + " VALUES(?,?);");
1167            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
1168                    R.integer.def_screen_off_timeout);
1169            db.setTransactionSuccessful();
1170        } finally {
1171            db.endTransaction();
1172            if (stmt != null)
1173                stmt.close();
1174        }
1175    }
1176
1177    private void upgradeAutoBrightness(SQLiteDatabase db) {
1178        db.beginTransaction();
1179        try {
1180            String value =
1181                    mContext.getResources().getBoolean(
1182                    R.bool.def_screen_brightness_automatic_mode) ? "1" : "0";
1183            db.execSQL("INSERT OR REPLACE INTO system(name,value) values('" +
1184                    Settings.System.SCREEN_BRIGHTNESS_MODE + "','" + value + "');");
1185            db.setTransactionSuccessful();
1186        } finally {
1187            db.endTransaction();
1188        }
1189    }
1190
1191    /**
1192     * Loads the default set of bookmarked shortcuts from an xml file.
1193     *
1194     * @param db The database to write the values into
1195     */
1196    private void loadBookmarks(SQLiteDatabase db) {
1197        ContentValues values = new ContentValues();
1198
1199        PackageManager packageManager = mContext.getPackageManager();
1200        try {
1201            XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
1202            XmlUtils.beginDocument(parser, "bookmarks");
1203
1204            final int depth = parser.getDepth();
1205            int type;
1206
1207            while (((type = parser.next()) != XmlPullParser.END_TAG ||
1208                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
1209
1210                if (type != XmlPullParser.START_TAG) {
1211                    continue;
1212                }
1213
1214                String name = parser.getName();
1215                if (!"bookmark".equals(name)) {
1216                    break;
1217                }
1218
1219                String pkg = parser.getAttributeValue(null, "package");
1220                String cls = parser.getAttributeValue(null, "class");
1221                String shortcutStr = parser.getAttributeValue(null, "shortcut");
1222                String category = parser.getAttributeValue(null, "category");
1223
1224                int shortcutValue = shortcutStr.charAt(0);
1225                if (TextUtils.isEmpty(shortcutStr)) {
1226                    Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
1227                    continue;
1228                }
1229
1230                final Intent intent;
1231                final String title;
1232                if (pkg != null && cls != null) {
1233                    ActivityInfo info = null;
1234                    ComponentName cn = new ComponentName(pkg, cls);
1235                    try {
1236                        info = packageManager.getActivityInfo(cn, 0);
1237                    } catch (PackageManager.NameNotFoundException e) {
1238                        String[] packages = packageManager.canonicalToCurrentPackageNames(
1239                                new String[] { pkg });
1240                        cn = new ComponentName(packages[0], cls);
1241                        try {
1242                            info = packageManager.getActivityInfo(cn, 0);
1243                        } catch (PackageManager.NameNotFoundException e1) {
1244                            Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
1245                            continue;
1246                        }
1247                    }
1248
1249                    intent = new Intent(Intent.ACTION_MAIN, null);
1250                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
1251                    intent.setComponent(cn);
1252                    title = info.loadLabel(packageManager).toString();
1253                } else if (category != null) {
1254                    intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
1255                    title = "";
1256                } else {
1257                    Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr
1258                            + ": missing package/class or category attributes");
1259                    continue;
1260                }
1261
1262                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1263                values.put(Settings.Bookmarks.INTENT, intent.toUri(0));
1264                values.put(Settings.Bookmarks.TITLE, title);
1265                values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
1266                db.delete("bookmarks", "shortcut = ?",
1267                        new String[] { Integer.toString(shortcutValue) });
1268                db.insert("bookmarks", null, values);
1269            }
1270        } catch (XmlPullParserException e) {
1271            Log.w(TAG, "Got execption parsing bookmarks.", e);
1272        } catch (IOException e) {
1273            Log.w(TAG, "Got execption parsing bookmarks.", e);
1274        }
1275    }
1276
1277    /**
1278     * Loads the default volume levels. It is actually inserting the index of
1279     * the volume array for each of the volume controls.
1280     *
1281     * @param db the database to insert the volume levels into
1282     */
1283    private void loadVolumeLevels(SQLiteDatabase db) {
1284        SQLiteStatement stmt = null;
1285        try {
1286            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
1287                    + " VALUES(?,?);");
1288
1289            loadSetting(stmt, Settings.System.VOLUME_MUSIC,
1290                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
1291            loadSetting(stmt, Settings.System.VOLUME_RING,
1292                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]);
1293            loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
1294                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
1295            loadSetting(
1296                    stmt,
1297                    Settings.System.VOLUME_VOICE,
1298                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
1299            loadSetting(stmt, Settings.System.VOLUME_ALARM,
1300                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]);
1301            loadSetting(
1302                    stmt,
1303                    Settings.System.VOLUME_NOTIFICATION,
1304                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]);
1305            loadSetting(
1306                    stmt,
1307                    Settings.System.VOLUME_BLUETOOTH_SCO,
1308                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
1309
1310            loadSetting(stmt, Settings.System.MODE_RINGER,
1311                    AudioManager.RINGER_MODE_NORMAL);
1312
1313            loadVibrateSetting(db, false);
1314
1315            // By default:
1316            // - ringtones, notification, system and music streams are affected by ringer mode
1317            // on non voice capable devices (tablets)
1318            // - ringtones, notification and system streams are affected by ringer mode
1319            // on voice capable devices (phones)
1320            int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
1321                                            (1 << AudioManager.STREAM_NOTIFICATION) |
1322                                            (1 << AudioManager.STREAM_SYSTEM) |
1323                                            (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
1324            if (!mContext.getResources().getBoolean(
1325                    com.android.internal.R.bool.config_voice_capable)) {
1326                ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
1327            }
1328            loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
1329                    ringerModeAffectedStreams);
1330
1331            loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
1332                    ((1 << AudioManager.STREAM_MUSIC) |
1333                     (1 << AudioManager.STREAM_RING) |
1334                     (1 << AudioManager.STREAM_NOTIFICATION) |
1335                     (1 << AudioManager.STREAM_SYSTEM)));
1336        } finally {
1337            if (stmt != null) stmt.close();
1338        }
1339    }
1340
1341    private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
1342        if (deleteOld) {
1343            db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
1344        }
1345
1346        SQLiteStatement stmt = null;
1347        try {
1348            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
1349                    + " VALUES(?,?);");
1350
1351            // Vibrate on by default for ringer, on for notification
1352            int vibrate = 0;
1353            vibrate = AudioService.getValueForVibrateSetting(vibrate,
1354                    AudioManager.VIBRATE_TYPE_NOTIFICATION,
1355                    AudioManager.VIBRATE_SETTING_ONLY_SILENT);
1356            vibrate |= AudioService.getValueForVibrateSetting(vibrate,
1357                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
1358            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
1359        } finally {
1360            if (stmt != null) stmt.close();
1361        }
1362    }
1363
1364    private void loadSettings(SQLiteDatabase db) {
1365        loadSystemSettings(db);
1366        loadSecureSettings(db);
1367    }
1368
1369    private void loadSystemSettings(SQLiteDatabase db) {
1370        SQLiteStatement stmt = null;
1371        try {
1372            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
1373                    + " VALUES(?,?);");
1374
1375            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
1376                    R.bool.def_dim_screen);
1377            loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
1378                    ("1".equals(SystemProperties.get("ro.kernel.qemu")) ||
1379                        mContext.getResources().getBoolean(R.bool.def_stay_on_while_plugged_in))
1380                     ? 1 : 0);
1381            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
1382                    R.integer.def_screen_off_timeout);
1383
1384            // Set default cdma emergency tone
1385            loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
1386
1387            // Set default cdma call auto retry
1388            loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
1389
1390            // Set default cdma DTMF type
1391            loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
1392
1393            // Set default hearing aid
1394            loadSetting(stmt, Settings.System.HEARING_AID, 0);
1395
1396            // Set default tty mode
1397            loadSetting(stmt, Settings.System.TTY_MODE, 0);
1398
1399            loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
1400                    R.bool.def_airplane_mode_on);
1401
1402            loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
1403                    R.string.def_airplane_mode_radios);
1404
1405            loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
1406                    R.string.airplane_mode_toggleable_radios);
1407
1408            loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
1409                    R.bool.def_auto_time); // Sync time to NITZ
1410
1411            loadBooleanSetting(stmt, Settings.System.AUTO_TIME_ZONE,
1412                    R.bool.def_auto_time_zone); // Sync timezone to NITZ
1413
1414            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
1415                    R.integer.def_screen_brightness);
1416
1417            loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
1418                    R.bool.def_screen_brightness_automatic_mode);
1419
1420            loadDefaultAnimationSettings(stmt);
1421
1422            loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
1423                    R.bool.def_accelerometer_rotation);
1424
1425            loadDefaultHapticSettings(stmt);
1426
1427            loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
1428                    R.bool.def_notification_pulse);
1429            loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
1430            loadSetting(stmt, Settings.Secure.DEFAULT_INSTALL_LOCATION,
1431                    PackageHelper.APP_INSTALL_AUTO);
1432
1433            loadUISoundEffectsSettings(stmt);
1434
1435            loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
1436                    R.bool.def_vibrate_in_silent);
1437
1438            loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
1439                    R.integer.def_pointer_speed);
1440
1441        } finally {
1442            if (stmt != null) stmt.close();
1443        }
1444    }
1445
1446    private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
1447        loadIntegerSetting(stmt, Settings.System.POWER_SOUNDS_ENABLED,
1448            R.integer.def_power_sounds_enabled);
1449        loadStringSetting(stmt, Settings.System.LOW_BATTERY_SOUND,
1450            R.string.def_low_battery_sound);
1451        loadBooleanSetting(stmt, Settings.System.DTMF_TONE_WHEN_DIALING,
1452                R.bool.def_dtmf_tones_enabled);
1453        loadBooleanSetting(stmt, Settings.System.SOUND_EFFECTS_ENABLED,
1454                R.bool.def_sound_effects_enabled);
1455        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
1456                R.bool.def_haptic_feedback);
1457
1458        loadIntegerSetting(stmt, Settings.System.DOCK_SOUNDS_ENABLED,
1459            R.integer.def_dock_sounds_enabled);
1460        loadStringSetting(stmt, Settings.System.DESK_DOCK_SOUND,
1461            R.string.def_desk_dock_sound);
1462        loadStringSetting(stmt, Settings.System.DESK_UNDOCK_SOUND,
1463            R.string.def_desk_undock_sound);
1464        loadStringSetting(stmt, Settings.System.CAR_DOCK_SOUND,
1465            R.string.def_car_dock_sound);
1466        loadStringSetting(stmt, Settings.System.CAR_UNDOCK_SOUND,
1467            R.string.def_car_undock_sound);
1468
1469        loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
1470            R.integer.def_lockscreen_sounds_enabled);
1471        loadStringSetting(stmt, Settings.System.LOCK_SOUND,
1472            R.string.def_lock_sound);
1473        loadStringSetting(stmt, Settings.System.UNLOCK_SOUND,
1474            R.string.def_unlock_sound);
1475    }
1476
1477    private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
1478        loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
1479                R.fraction.def_window_animation_scale, 1);
1480        loadFractionSetting(stmt, Settings.System.TRANSITION_ANIMATION_SCALE,
1481                R.fraction.def_window_transition_scale, 1);
1482    }
1483
1484    private void loadDefaultHapticSettings(SQLiteStatement stmt) {
1485        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
1486                R.bool.def_haptic_feedback);
1487    }
1488
1489    private void loadSecureSettings(SQLiteDatabase db) {
1490        SQLiteStatement stmt = null;
1491        try {
1492            stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1493                    + " VALUES(?,?);");
1494
1495            loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
1496                    R.bool.def_bluetooth_on);
1497
1498            // Data roaming default, based on build
1499            loadSetting(stmt, Settings.Secure.DATA_ROAMING,
1500                    "true".equalsIgnoreCase(
1501                            SystemProperties.get("ro.com.android.dataroaming",
1502                                    "false")) ? 1 : 0);
1503
1504            loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
1505                    R.bool.def_install_non_market_apps);
1506
1507            loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
1508                    R.string.def_location_providers_allowed);
1509
1510            loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
1511                    R.bool.assisted_gps_enabled);
1512
1513            loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
1514                    R.integer.def_network_preference);
1515
1516            loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
1517                    R.bool.def_usb_mass_storage_enabled);
1518
1519            loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
1520                    R.bool.def_wifi_on);
1521            loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
1522                    R.bool.def_networks_available_notification_on);
1523
1524            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
1525            if (!TextUtils.isEmpty(wifiWatchList)) {
1526                loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
1527            }
1528
1529            // Set the preferred network mode to 0 = Global, CDMA default
1530            int type;
1531            if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
1532                type = Phone.NT_MODE_GLOBAL;
1533            } else {
1534                type = SystemProperties.getInt("ro.telephony.default_network",
1535                        RILConstants.PREFERRED_NETWORK_MODE);
1536            }
1537            loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
1538
1539            // Enable or disable Cell Broadcast SMS
1540            loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
1541                    RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
1542
1543            // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
1544            // persistent system property instead.
1545            //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
1546
1547            // Allow mock locations default, based on build
1548            loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
1549                    "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
1550
1551            loadSecure35Settings(stmt);
1552
1553            loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
1554                    R.bool.def_mount_play_notification_snd);
1555
1556            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
1557                    R.bool.def_mount_ums_autostart);
1558
1559            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
1560                    R.bool.def_mount_ums_prompt);
1561
1562            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
1563                    R.bool.def_mount_ums_notify_enabled);
1564
1565            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
1566                    R.bool.def_accessibility_script_injection);
1567
1568            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
1569                    R.string.def_accessibility_web_content_key_bindings);
1570
1571            final int maxBytes = mContext.getResources().getInteger(
1572                    R.integer.def_download_manager_max_bytes_over_mobile);
1573            if (maxBytes > 0) {
1574                loadSetting(stmt, Settings.Secure.DOWNLOAD_MAX_BYTES_OVER_MOBILE,
1575                        Integer.toString(maxBytes));
1576            }
1577
1578            final int recommendedMaxBytes = mContext.getResources().getInteger(
1579                    R.integer.def_download_manager_recommended_max_bytes_over_mobile);
1580            if (recommendedMaxBytes > 0) {
1581                loadSetting(stmt, Settings.Secure.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE,
1582                        Integer.toString(recommendedMaxBytes));
1583            }
1584
1585            loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
1586                    R.integer.def_long_press_timeout_millis);
1587
1588            loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
1589                    R.bool.def_touch_exploration_enabled);
1590
1591            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
1592                    R.bool.def_accessibility_speak_password);
1593
1594            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
1595                    R.string.def_accessibility_screen_reader_url);
1596
1597            loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
1598                    R.bool.def_lockscreen_disabled);
1599
1600            loadBooleanSetting(stmt, Settings.Secure.DEVICE_PROVISIONED,
1601                    R.bool.def_device_provisioned);
1602
1603            loadBooleanSetting(stmt, Settings.Secure.NETSTATS_ENABLED,
1604                    R.bool.def_netstats_enabled);
1605        } finally {
1606            if (stmt != null) stmt.close();
1607        }
1608    }
1609
1610    private void loadSecure35Settings(SQLiteStatement stmt) {
1611        loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED,
1612                R.bool.def_backup_enabled);
1613
1614        loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
1615                R.string.def_backup_transport);
1616    }
1617
1618    private void loadSetting(SQLiteStatement stmt, String key, Object value) {
1619        stmt.bindString(1, key);
1620        stmt.bindString(2, value.toString());
1621        stmt.execute();
1622    }
1623
1624    private void loadStringSetting(SQLiteStatement stmt, String key, int resid) {
1625        loadSetting(stmt, key, mContext.getResources().getString(resid));
1626    }
1627
1628    private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
1629        loadSetting(stmt, key,
1630                mContext.getResources().getBoolean(resid) ? "1" : "0");
1631    }
1632
1633    private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) {
1634        loadSetting(stmt, key,
1635                Integer.toString(mContext.getResources().getInteger(resid)));
1636    }
1637
1638    private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) {
1639        loadSetting(stmt, key,
1640                Float.toString(mContext.getResources().getFraction(resid, base, base)));
1641    }
1642
1643    private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) {
1644        int value = defaultValue;
1645        Cursor c = null;
1646        try {
1647            c = db.query("system", new String[] { Settings.System.VALUE }, "name='" + name + "'",
1648                    null, null, null, null);
1649            if (c != null && c.moveToFirst()) {
1650                String val = c.getString(0);
1651                value = val == null ? defaultValue : Integer.parseInt(val);
1652            }
1653        } finally {
1654            if (c != null) c.close();
1655        }
1656        return value;
1657    }
1658}
1659