2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.providers.settings;
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;
25 import org.xmlpull.v1.XmlPullParser;
26 import org.xmlpull.v1.XmlPullParserException;
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;
48 import java.io.IOException;
49 import java.util.HashSet;
50 import java.util.List;
53 * Database helper class for {@link SettingsProvider}.
54 * Mostly just has a bit {@link #onCreate} to initialize the database.
56 public class DatabaseHelper extends SQLiteOpenHelper {
57 private static final String TAG = "SettingsProvider";
58 private static final String DATABASE_NAME = "settings.db";
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
64 private static final int DATABASE_VERSION = 64;
66 private Context mContext;
68 private static final HashSet<String> mValidTables = new HashSet<String>();
71 mValidTables.add("system");
72 mValidTables.add("secure");
73 mValidTables.add("bluetooth_devices");
74 mValidTables.add("bookmarks");
77 mValidTables.add("favorites");
78 mValidTables.add("gservices");
79 mValidTables.add("old_favorites");
82 public DatabaseHelper(Context context) {
83 super(context, DATABASE_NAME, null, DATABASE_VERSION);
87 public static boolean isValidTable(String name) {
88 return mValidTables.contains(name);
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," +
97 db.execSQL("CREATE INDEX secureIndex1 ON secure (name);");
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," +
107 db.execSQL("CREATE INDEX systemIndex1 ON system (name);");
109 createSecureTable(db);
111 db.execSQL("CREATE TABLE bluetooth_devices (" +
112 "_id INTEGER PRIMARY KEY," +
119 db.execSQL("CREATE TABLE bookmarks (" +
120 "_id INTEGER PRIMARY KEY," +
124 "shortcut INTEGER," +
128 db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);");
129 db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);");
131 // Populate bookmarks table with initial bookmarks
134 // Load initial volume levels into DB
135 loadVolumeLevels(db);
137 // Load inital settings values
142 public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
143 Log.w(TAG, "Upgrading settings database from version " + oldVersion + " to "
146 int upgradeVersion = oldVersion;
148 // Pattern for upgrade blocks:
150 // if (upgradeVersion == [the DATABASE_VERSION you set] - 1) {
151 // .. your upgrade logic..
152 // upgradeVersion = [the DATABASE_VERSION you set]
155 if (upgradeVersion == 20) {
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.
162 loadVibrateSetting(db, true);
167 if (upgradeVersion < 22) {
169 // Upgrade the lock gesture storage location and format
170 upgradeLockPatternLocation(db);
173 if (upgradeVersion < 23) {
174 db.execSQL("UPDATE favorites SET iconResource=0 WHERE iconType=0");
178 if (upgradeVersion == 23) {
179 db.beginTransaction();
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
187 "UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
189 db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001");
190 db.setTransactionSuccessful();
197 if (upgradeVersion == 24) {
198 db.beginTransaction();
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();
212 if (upgradeVersion == 25) {
213 db.beginTransaction();
215 db.execSQL("ALTER TABLE favorites ADD uri TEXT");
216 db.execSQL("ALTER TABLE favorites ADD displayMode INTEGER");
217 db.setTransactionSuccessful();
224 if (upgradeVersion == 26) {
225 // This introduces the new secure settings table.
226 db.beginTransaction();
228 createSecureTable(db);
229 db.setTransactionSuccessful();
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,
270 moveFromSystemToSecure(db, settingsToMove);
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
279 // This upgrade adds the STREAM_NOTIFICATION type to the list of
280 // types affected by ringer modes (silent, vibrate, etc.)
281 db.beginTransaction();
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();
299 if (upgradeVersion == 30) {
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'.
305 db.beginTransaction();
307 db.execSQL("UPDATE bookmarks SET folder = '@quicklaunch'");
308 db.execSQL("UPDATE bookmarks SET title = ''");
309 db.setTransactionSuccessful();
316 if (upgradeVersion == 31) {
318 * Animations are now managed in preferences, and may be
319 * enabled or disabled based on product resources.
321 db.beginTransaction();
322 SQLiteStatement stmt = null;
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)"
330 loadDefaultAnimationSettings(stmt);
331 db.setTransactionSuccessful();
334 if (stmt != null) stmt.close();
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();
346 db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
347 Settings.Secure.WIFI_WATCHDOG_WATCH_LIST + "','" +
348 wifiWatchList + "');");
349 db.setTransactionSuccessful();
357 if (upgradeVersion == 33) {
358 // Set the default zoom controls to: tap-twice to bring up +/-
359 db.beginTransaction();
361 db.execSQL("INSERT INTO system(name,value) values('zoom','2');");
362 db.setTransactionSuccessful();
369 if (upgradeVersion == 34) {
370 db.beginTransaction();
371 SQLiteStatement stmt = null;
373 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
375 loadSecure35Settings(stmt);
376 db.setTransactionSuccessful();
379 if (stmt != null) stmt.close();
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) {
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();
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();
412 if (upgradeVersion == 37) {
413 db.beginTransaction();
414 SQLiteStatement stmt = null;
416 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
418 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
419 R.string.airplane_mode_toggleable_radios);
420 db.setTransactionSuccessful();
423 if (stmt != null) stmt.close();
428 if (upgradeVersion == 38) {
429 db.beginTransaction();
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();
443 if (upgradeVersion == 39) {
444 upgradeAutoBrightness(db);
448 if (upgradeVersion == 40) {
450 * All animations are now turned on by default!
452 db.beginTransaction();
453 SQLiteStatement stmt = null;
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)"
461 loadDefaultAnimationSettings(stmt);
462 db.setTransactionSuccessful();
465 if (stmt != null) stmt.close();
470 if (upgradeVersion == 41) {
472 * Initialize newly public haptic feedback setting
474 db.beginTransaction();
475 SQLiteStatement stmt = null;
477 db.execSQL("DELETE FROM system WHERE name='"
478 + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'");
479 stmt = db.compileStatement("INSERT INTO system(name,value)"
481 loadDefaultHapticSettings(stmt);
482 db.setTransactionSuccessful();
485 if (stmt != null) stmt.close();
490 if (upgradeVersion == 42) {
492 * Initialize new notification pulse setting
494 db.beginTransaction();
495 SQLiteStatement stmt = null;
497 stmt = db.compileStatement("INSERT INTO system(name,value)"
499 loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
500 R.bool.def_notification_pulse);
501 db.setTransactionSuccessful();
504 if (stmt != null) stmt.close();
509 if (upgradeVersion == 43) {
511 * This upgrade stores bluetooth volume separately from voice volume
513 db.beginTransaction();
514 SQLiteStatement stmt = null;
516 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
518 loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO,
519 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
520 db.setTransactionSuccessful();
523 if (stmt != null) stmt.close();
528 if (upgradeVersion == 44) {
530 * Gservices was moved into vendor/google.
532 db.execSQL("DROP TABLE IF EXISTS gservices");
533 db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
537 if (upgradeVersion == 45) {
539 * New settings for MountService
541 db.beginTransaction();
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();
558 if (upgradeVersion == 46) {
560 * The password mode constants have changed; reset back to no
563 db.beginTransaction();
565 db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
566 db.setTransactionSuccessful();
574 if (upgradeVersion == 47) {
576 * The password mode constants have changed again; reset back to no
579 db.beginTransaction();
581 db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
582 db.setTransactionSuccessful();
589 if (upgradeVersion == 48) {
591 * Default recognition service no longer initialized here,
592 * moved to RecognitionManagerService.
597 if (upgradeVersion == 49) {
599 * New settings for new user interface noises.
601 db.beginTransaction();
602 SQLiteStatement stmt = null;
604 stmt = db.compileStatement("INSERT INTO system(name,value)"
606 loadUISoundEffectsSettings(stmt);
607 db.setTransactionSuccessful();
610 if (stmt != null) stmt.close();
616 if (upgradeVersion == 50) {
618 * Install location no longer initiated here.
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"
636 moveFromSystemToSecure(db, settingsToMove);
640 if (upgradeVersion == 52) {
641 // new vibration/silent mode settings
642 db.beginTransaction();
643 SQLiteStatement stmt = null;
645 stmt = db.compileStatement("INSERT INTO system(name,value)"
647 loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
648 R.bool.def_vibrate_in_silent);
649 db.setTransactionSuccessful();
652 if (stmt != null) stmt.close();
658 if (upgradeVersion == 53) {
660 * New settings for set install location UI no longer initiated here.
665 if (upgradeVersion == 54) {
667 * Update the screen timeout value if set to never
669 db.beginTransaction();
671 upgradeScreenTimeoutFromNever(db);
672 db.setTransactionSuccessful();
680 if (upgradeVersion == 55) {
681 /* Move the install location settings. */
682 String[] settingsToMove = {
683 Secure.SET_INSTALL_LOCATION,
684 Secure.DEFAULT_INSTALL_LOCATION
686 moveFromSystemToSecure(db, settingsToMove);
687 db.beginTransaction();
688 SQLiteStatement stmt = null;
690 stmt = db.compileStatement("INSERT INTO system(name,value)"
692 loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 0);
693 loadSetting(stmt, Secure.DEFAULT_INSTALL_LOCATION,
694 PackageHelper.APP_INSTALL_AUTO);
695 db.setTransactionSuccessful();
698 if (stmt != null) stmt.close();
703 if (upgradeVersion == 56) {
705 * Add Bluetooth to list of toggleable radios in airplane mode
707 db.beginTransaction();
708 SQLiteStatement stmt = null;
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)"
714 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
715 R.string.airplane_mode_toggleable_radios);
716 db.setTransactionSuccessful();
719 if (stmt != null) stmt.close();
724 if (upgradeVersion == 57) {
727 * 1. Enable injection of accessibility scripts in WebViews.
728 * 2. Define the key bindings for traversing web content in WebViews.
730 db.beginTransaction();
731 SQLiteStatement stmt = null;
733 stmt = db.compileStatement("INSERT INTO secure(name,value)"
735 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
736 R.bool.def_accessibility_script_injection);
738 stmt = db.compileStatement("INSERT INTO secure(name,value)"
740 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
741 R.string.def_accessibility_web_content_key_bindings);
742 db.setTransactionSuccessful();
745 if (stmt != null) stmt.close();
750 if (upgradeVersion == 58) {
751 /* Add default for new Auto Time Zone */
752 db.beginTransaction();
753 SQLiteStatement stmt = null;
755 stmt = db.compileStatement("INSERT INTO secure(name,value)"
757 loadBooleanSetting(stmt, Settings.System.AUTO_TIME_ZONE,
758 R.bool.def_auto_time_zone); // Sync timezone to NITZ
759 db.setTransactionSuccessful();
762 if (stmt != null) stmt.close();
767 if (upgradeVersion == 59) {
768 // Persistence for the rotation lock feature.
769 db.beginTransaction();
770 SQLiteStatement stmt = null;
772 stmt = db.compileStatement("INSERT INTO system(name,value)"
774 loadBooleanSetting(stmt, Settings.System.USER_ROTATION,
775 R.integer.def_user_rotation); // should be zero degrees
776 db.setTransactionSuccessful();
779 if (stmt != null) stmt.close();
784 if (upgradeVersion == 60) {
785 upgradeScreenTimeout(db);
789 if (upgradeVersion == 61) {
790 upgradeScreenTimeout(db);
794 // Change the default for screen auto-brightness mode
795 if (upgradeVersion == 62) {
796 upgradeAutoBrightness(db);
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();
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();
822 if (upgradeVersion == 64) {
823 // New setting to configure the long press timeout.
824 db.beginTransaction();
825 SQLiteStatement stmt = null;
827 stmt = db.compileStatement("INSERT INTO secure(name,value)"
829 loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
830 R.integer.def_long_press_timeout_millis);
832 db.setTransactionSuccessful();
835 if (stmt != null) stmt.close();
840 // *** Remember to update DATABASE_VERSION above!
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");
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 + "');");
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;
870 db.beginTransaction();
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=?");
878 for (String setting : settingsToMove) {
879 insertStmt.bindString(1, setting);
880 insertStmt.execute();
882 deleteStmt.bindString(1, setting);
883 deleteStmt.execute();
885 db.setTransactionSuccessful();
888 if (insertStmt != null) {
891 if (deleteStmt != null) {
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) {
902 String lockPattern = c.getString(1);
903 if (!TextUtils.isEmpty(lockPattern)) {
904 // Convert lock pattern
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
915 db.delete("system", "name='lock_pattern'", null);
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" },
927 SQLiteStatement stmt = null;
928 if (c.getCount() > 0) {
931 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
934 // Set the timeout to 30 minutes in milliseconds
935 loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
936 Integer.toString(30 * 60 * 1000));
938 if (stmt != null) stmt.close();
945 private void upgradeScreenTimeout(SQLiteDatabase db) {
946 // Change screen timeout to current default
947 db.beginTransaction();
948 SQLiteStatement stmt = null;
950 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
952 loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
953 R.integer.def_screen_off_timeout);
954 db.setTransactionSuccessful();
962 private void upgradeAutoBrightness(SQLiteDatabase db) {
963 db.beginTransaction();
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();
977 * Loads the default set of bookmarked shortcuts from an xml file.
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
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();
987 PackageManager packageManager = mContext.getPackageManager();
988 int i = startingIndex;
991 XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
992 XmlUtils.beginDocument(parser, "bookmarks");
994 final int depth = parser.getDepth();
997 while (((type = parser.next()) != XmlPullParser.END_TAG ||
998 parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
1000 if (type != XmlPullParser.START_TAG) {
1004 String name = parser.getName();
1005 if (!"bookmark".equals(name)) {
1009 String pkg = parser.getAttributeValue(null, "package");
1010 String cls = parser.getAttributeValue(null, "class");
1011 String shortcutStr = parser.getAttributeValue(null, "shortcut");
1013 int shortcutValue = shortcutStr.charAt(0);
1014 if (TextUtils.isEmpty(shortcutStr)) {
1015 Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
1018 ActivityInfo info = null;
1019 ComponentName cn = new ComponentName(pkg, cls);
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);
1027 info = packageManager.getActivityInfo(cn, 0);
1028 } catch (PackageManager.NameNotFoundException e1) {
1029 Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
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);
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);
1054 * Loads the default set of bookmark packages.
1056 * @param db The database to write the values into
1058 private void loadBookmarks(SQLiteDatabase db) {
1059 loadBookmarks(db, 0);
1063 * Loads the default volume levels. It is actually inserting the index of
1064 * the volume array for each of the volume controls.
1066 * @param db the database to insert the volume levels into
1068 private void loadVolumeLevels(SQLiteDatabase db) {
1069 SQLiteStatement stmt = null;
1071 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
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]);
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]);
1088 Settings.System.VOLUME_NOTIFICATION,
1089 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]);
1092 Settings.System.VOLUME_BLUETOOTH_SCO,
1093 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
1095 loadSetting(stmt, Settings.System.MODE_RINGER,
1096 AudioManager.RINGER_MODE_NORMAL);
1098 loadVibrateSetting(db, false);
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));
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)));
1112 if (stmt != null) stmt.close();
1116 private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
1118 db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
1121 SQLiteStatement stmt = null;
1123 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
1126 // Vibrate off by default for ringer, on for notification
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);
1134 if (stmt != null) stmt.close();
1138 private void loadSettings(SQLiteDatabase db) {
1139 loadSystemSettings(db);
1140 loadSecureSettings(db);
1143 private void loadSystemSettings(SQLiteDatabase db) {
1144 SQLiteStatement stmt = null;
1146 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
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);
1156 // Set default cdma emergency tone
1157 loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
1159 // Set default cdma call auto retry
1160 loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
1162 // Set default cdma DTMF type
1163 loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
1165 // Set default hearing aid
1166 loadSetting(stmt, Settings.System.HEARING_AID, 0);
1168 // Set default tty mode
1169 loadSetting(stmt, Settings.System.TTY_MODE, 0);
1171 loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
1172 R.bool.def_airplane_mode_on);
1174 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
1175 R.string.def_airplane_mode_radios);
1177 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
1178 R.string.airplane_mode_toggleable_radios);
1180 loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
1181 R.bool.def_auto_time); // Sync time to NITZ
1183 loadBooleanSetting(stmt, Settings.System.AUTO_TIME_ZONE,
1184 R.bool.def_auto_time_zone); // Sync timezone to NITZ
1186 loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
1187 R.integer.def_screen_brightness);
1189 loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
1190 R.bool.def_screen_brightness_automatic_mode);
1192 loadDefaultAnimationSettings(stmt);
1194 loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
1195 R.bool.def_accelerometer_rotation);
1197 loadDefaultHapticSettings(stmt);
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);
1205 loadUISoundEffectsSettings(stmt);
1207 loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
1208 R.bool.def_vibrate_in_silent);
1210 loadBooleanSetting(stmt, Settings.System.USE_PTP_INTERFACE,
1211 R.bool.def_use_ptp_interface);
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);
1218 if (stmt != null) stmt.close();
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);
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);
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);
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);
1254 private void loadDefaultHapticSettings(SQLiteStatement stmt) {
1255 loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
1256 R.bool.def_haptic_feedback);
1259 private void loadSecureSettings(SQLiteDatabase db) {
1260 SQLiteStatement stmt = null;
1262 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1265 loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
1266 R.bool.def_bluetooth_on);
1268 // Data roaming default, based on build
1269 loadSetting(stmt, Settings.Secure.DATA_ROAMING,
1270 "true".equalsIgnoreCase(
1271 SystemProperties.get("ro.com.android.dataroaming",
1274 loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
1275 R.bool.def_install_non_market_apps);
1277 loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
1278 R.string.def_location_providers_allowed);
1280 loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
1281 R.bool.assisted_gps_enabled);
1283 loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
1284 R.integer.def_network_preference);
1286 loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
1287 R.bool.def_usb_mass_storage_enabled);
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);
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);
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);
1304 // Enable or disable Cell Broadcast SMS
1305 loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
1306 RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
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);
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);
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);
1320 loadSecure35Settings(stmt);
1322 loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
1323 R.bool.def_mount_play_notification_snd);
1325 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
1326 R.bool.def_mount_ums_autostart);
1328 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
1329 R.bool.def_mount_ums_prompt);
1331 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
1332 R.bool.def_mount_ums_notify_enabled);
1334 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
1335 R.bool.def_accessibility_script_injection);
1337 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
1338 R.string.def_accessibility_web_content_key_bindings);
1340 final int maxBytes = mContext.getResources().getInteger(
1341 R.integer.def_download_manager_max_bytes_over_mobile);
1343 loadSetting(stmt, Settings.Secure.DOWNLOAD_MAX_BYTES_OVER_MOBILE,
1344 Integer.toString(maxBytes));
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));
1354 loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
1355 R.integer.def_long_press_timeout_millis);
1357 if (stmt != null) stmt.close();
1361 private void loadSecure35Settings(SQLiteStatement stmt) {
1362 loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED,
1363 R.bool.def_backup_enabled);
1365 loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
1366 R.string.def_backup_transport);
1369 private void loadSetting(SQLiteStatement stmt, String key, Object value) {
1370 stmt.bindString(1, key);
1371 stmt.bindString(2, value.toString());
1375 private void loadStringSetting(SQLiteStatement stmt, String key, int resid) {
1376 loadSetting(stmt, key, mContext.getResources().getString(resid));
1379 private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
1380 loadSetting(stmt, key,
1381 mContext.getResources().getBoolean(resid) ? "1" : "0");
1384 private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) {
1385 loadSetting(stmt, key,
1386 Integer.toString(mContext.getResources().getInteger(resid)));
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)));