OSDN Git Service

Add system wide management of core settings
[android-x86/frameworks-base.git] / packages / SettingsProvider / src / com / android / providers / settings / DatabaseHelper.java
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
17 package com.android.providers.settings;
18
19 import com.android.internal.content.PackageHelper;
20 import com.android.internal.telephony.RILConstants;
21 import com.android.internal.util.XmlUtils;
22 import com.android.internal.widget.LockPatternUtils;
23 import com.android.internal.widget.LockPatternView;
24
25 import org.xmlpull.v1.XmlPullParser;
26 import org.xmlpull.v1.XmlPullParserException;
27
28 import android.content.ComponentName;
29 import android.content.ContentValues;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.pm.ActivityInfo;
33 import android.content.pm.PackageManager;
34 import android.content.res.XmlResourceParser;
35 import android.database.Cursor;
36 import android.database.sqlite.SQLiteDatabase;
37 import android.database.sqlite.SQLiteOpenHelper;
38 import android.database.sqlite.SQLiteStatement;
39 import android.media.AudioManager;
40 import android.media.AudioService;
41 import android.net.ConnectivityManager;
42 import android.os.SystemProperties;
43 import android.provider.Settings;
44 import android.provider.Settings.Secure;
45 import android.text.TextUtils;
46 import android.util.Log;
47
48 import java.io.IOException;
49 import java.util.HashSet;
50 import 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  */
56 public 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 = 64;
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 }