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