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.BaseCommands;
21 import com.android.internal.telephony.Phone;
22 import com.android.internal.telephony.RILConstants;
23 import com.android.internal.util.XmlUtils;
24 import com.android.internal.widget.LockPatternUtils;
25 import com.android.internal.widget.LockPatternView;
27 import org.xmlpull.v1.XmlPullParser;
28 import org.xmlpull.v1.XmlPullParserException;
30 import android.content.ComponentName;
31 import android.content.ContentValues;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.pm.ActivityInfo;
35 import android.content.pm.PackageManager;
36 import android.content.res.XmlResourceParser;
37 import android.database.Cursor;
38 import android.database.sqlite.SQLiteDatabase;
39 import android.database.sqlite.SQLiteOpenHelper;
40 import android.database.sqlite.SQLiteStatement;
41 import android.media.AudioManager;
42 import android.media.AudioService;
43 import android.net.ConnectivityManager;
44 import android.os.SystemProperties;
45 import android.provider.Settings;
46 import android.provider.Settings.Secure;
47 import android.text.TextUtils;
48 import android.util.Log;
50 import java.io.IOException;
51 import java.util.HashSet;
52 import java.util.List;
55 * Database helper class for {@link SettingsProvider}.
56 * Mostly just has a bit {@link #onCreate} to initialize the database.
58 public class DatabaseHelper extends SQLiteOpenHelper {
59 private static final String TAG = "SettingsProvider";
60 private static final String DATABASE_NAME = "settings.db";
62 // Please, please please. If you update the database version, check to make sure the
63 // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
64 // is properly propagated through your change. Not doing so will result in a loss of user
66 private static final int DATABASE_VERSION = 64;
68 private Context mContext;
70 private static final HashSet<String> mValidTables = new HashSet<String>();
73 mValidTables.add("system");
74 mValidTables.add("secure");
75 mValidTables.add("bluetooth_devices");
76 mValidTables.add("bookmarks");
79 mValidTables.add("favorites");
80 mValidTables.add("gservices");
81 mValidTables.add("old_favorites");
84 public DatabaseHelper(Context context) {
85 super(context, DATABASE_NAME, null, DATABASE_VERSION);
89 public static boolean isValidTable(String name) {
90 return mValidTables.contains(name);
93 private void createSecureTable(SQLiteDatabase db) {
94 db.execSQL("CREATE TABLE secure (" +
95 "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
96 "name TEXT UNIQUE ON CONFLICT REPLACE," +
99 db.execSQL("CREATE INDEX secureIndex1 ON secure (name);");
103 public void onCreate(SQLiteDatabase db) {
104 db.execSQL("CREATE TABLE system (" +
105 "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
106 "name TEXT UNIQUE ON CONFLICT REPLACE," +
109 db.execSQL("CREATE INDEX systemIndex1 ON system (name);");
111 createSecureTable(db);
113 db.execSQL("CREATE TABLE bluetooth_devices (" +
114 "_id INTEGER PRIMARY KEY," +
121 db.execSQL("CREATE TABLE bookmarks (" +
122 "_id INTEGER PRIMARY KEY," +
126 "shortcut INTEGER," +
130 db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);");
131 db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);");
133 // Populate bookmarks table with initial bookmarks
136 // Load initial volume levels into DB
137 loadVolumeLevels(db);
139 // Load inital settings values
144 public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
145 Log.w(TAG, "Upgrading settings database from version " + oldVersion + " to "
148 int upgradeVersion = oldVersion;
150 // Pattern for upgrade blocks:
152 // if (upgradeVersion == [the DATABASE_VERSION you set] - 1) {
153 // .. your upgrade logic..
154 // upgradeVersion = [the DATABASE_VERSION you set]
157 if (upgradeVersion == 20) {
159 * Version 21 is part of the volume control refresh. There is no
160 * longer a UI-visible for setting notification vibrate on/off (in
161 * our design), but the functionality still exists. Force the
162 * notification vibrate to on.
164 loadVibrateSetting(db, true);
169 if (upgradeVersion < 22) {
171 // Upgrade the lock gesture storage location and format
172 upgradeLockPatternLocation(db);
175 if (upgradeVersion < 23) {
176 db.execSQL("UPDATE favorites SET iconResource=0 WHERE iconType=0");
180 if (upgradeVersion == 23) {
181 db.beginTransaction();
183 db.execSQL("ALTER TABLE favorites ADD spanX INTEGER");
184 db.execSQL("ALTER TABLE favorites ADD spanY INTEGER");
185 // Shortcuts, applications, folders
186 db.execSQL("UPDATE favorites SET spanX=1, spanY=1 WHERE itemType<=0");
187 // Photo frames, clocks
189 "UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
191 db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001");
192 db.setTransactionSuccessful();
199 if (upgradeVersion == 24) {
200 db.beginTransaction();
202 // The value of the constants for preferring wifi or preferring mobile have been
203 // swapped, so reload the default.
204 db.execSQL("DELETE FROM system WHERE name='network_preference'");
205 db.execSQL("INSERT INTO system ('name', 'value') values ('network_preference', '" +
206 ConnectivityManager.DEFAULT_NETWORK_PREFERENCE + "')");
207 db.setTransactionSuccessful();
214 if (upgradeVersion == 25) {
215 db.beginTransaction();
217 db.execSQL("ALTER TABLE favorites ADD uri TEXT");
218 db.execSQL("ALTER TABLE favorites ADD displayMode INTEGER");
219 db.setTransactionSuccessful();
226 if (upgradeVersion == 26) {
227 // This introduces the new secure settings table.
228 db.beginTransaction();
230 createSecureTable(db);
231 db.setTransactionSuccessful();
238 if (upgradeVersion == 27) {
239 String[] settingsToMove = {
240 Settings.Secure.ADB_ENABLED,
241 Settings.Secure.ANDROID_ID,
242 Settings.Secure.BLUETOOTH_ON,
243 Settings.Secure.DATA_ROAMING,
244 Settings.Secure.DEVICE_PROVISIONED,
245 Settings.Secure.HTTP_PROXY,
246 Settings.Secure.INSTALL_NON_MARKET_APPS,
247 Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
248 Settings.Secure.LOGGING_ID,
249 Settings.Secure.NETWORK_PREFERENCE,
250 Settings.Secure.PARENTAL_CONTROL_ENABLED,
251 Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
252 Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
253 Settings.Secure.SETTINGS_CLASSNAME,
254 Settings.Secure.USB_MASS_STORAGE_ENABLED,
255 Settings.Secure.USE_GOOGLE_MAIL,
256 Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
257 Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
258 Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT,
259 Settings.Secure.WIFI_ON,
260 Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE,
261 Settings.Secure.WIFI_WATCHDOG_AP_COUNT,
262 Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS,
263 Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED,
264 Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS,
265 Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT,
266 Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS,
267 Settings.Secure.WIFI_WATCHDOG_ON,
268 Settings.Secure.WIFI_WATCHDOG_PING_COUNT,
269 Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS,
270 Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS,
272 moveFromSystemToSecure(db, settingsToMove);
276 if (upgradeVersion == 28 || upgradeVersion == 29) {
277 // Note: The upgrade to 28 was flawed since it didn't delete the old
278 // setting first before inserting. Combining 28 and 29 with the
281 // This upgrade adds the STREAM_NOTIFICATION type to the list of
282 // types affected by ringer modes (silent, vibrate, etc.)
283 db.beginTransaction();
285 db.execSQL("DELETE FROM system WHERE name='"
286 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
287 int newValue = (1 << AudioManager.STREAM_RING)
288 | (1 << AudioManager.STREAM_NOTIFICATION)
289 | (1 << AudioManager.STREAM_SYSTEM);
290 db.execSQL("INSERT INTO system ('name', 'value') values ('"
291 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
292 + String.valueOf(newValue) + "')");
293 db.setTransactionSuccessful();
301 if (upgradeVersion == 30) {
303 * Upgrade 31 clears the title for all quick launch shortcuts so the
304 * activities' titles will be resolved at display time. Also, the
305 * folder is changed to '@quicklaunch'.
307 db.beginTransaction();
309 db.execSQL("UPDATE bookmarks SET folder = '@quicklaunch'");
310 db.execSQL("UPDATE bookmarks SET title = ''");
311 db.setTransactionSuccessful();
318 if (upgradeVersion == 31) {
320 * Animations are now managed in preferences, and may be
321 * enabled or disabled based on product resources.
323 db.beginTransaction();
324 SQLiteStatement stmt = null;
326 db.execSQL("DELETE FROM system WHERE name='"
327 + Settings.System.WINDOW_ANIMATION_SCALE + "'");
328 db.execSQL("DELETE FROM system WHERE name='"
329 + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
330 stmt = db.compileStatement("INSERT INTO system(name,value)"
332 loadDefaultAnimationSettings(stmt);
333 db.setTransactionSuccessful();
336 if (stmt != null) stmt.close();
341 if (upgradeVersion == 32) {
342 // The Wi-Fi watchdog SSID list is now seeded with the value of
343 // the property ro.com.android.wifi-watchlist
344 String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
345 if (!TextUtils.isEmpty(wifiWatchList)) {
346 db.beginTransaction();
348 db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
349 Settings.Secure.WIFI_WATCHDOG_WATCH_LIST + "','" +
350 wifiWatchList + "');");
351 db.setTransactionSuccessful();
359 if (upgradeVersion == 33) {
360 // Set the default zoom controls to: tap-twice to bring up +/-
361 db.beginTransaction();
363 db.execSQL("INSERT INTO system(name,value) values('zoom','2');");
364 db.setTransactionSuccessful();
371 if (upgradeVersion == 34) {
372 db.beginTransaction();
373 SQLiteStatement stmt = null;
375 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
377 loadSecure35Settings(stmt);
378 db.setTransactionSuccessful();
381 if (stmt != null) stmt.close();
385 // due to a botched merge from donut to eclair, the initialization of ASSISTED_GPS_ENABLED
386 // was accidentally done out of order here.
387 // to fix this, ASSISTED_GPS_ENABLED is now initialized while upgrading from 38 to 39,
388 // and we intentionally do nothing from 35 to 36 now.
389 if (upgradeVersion == 35) {
393 if (upgradeVersion == 36) {
394 // This upgrade adds the STREAM_SYSTEM_ENFORCED type to the list of
395 // types affected by ringer modes (silent, vibrate, etc.)
396 db.beginTransaction();
398 db.execSQL("DELETE FROM system WHERE name='"
399 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
400 int newValue = (1 << AudioManager.STREAM_RING)
401 | (1 << AudioManager.STREAM_NOTIFICATION)
402 | (1 << AudioManager.STREAM_SYSTEM)
403 | (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
404 db.execSQL("INSERT INTO system ('name', 'value') values ('"
405 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
406 + String.valueOf(newValue) + "')");
407 db.setTransactionSuccessful();
414 if (upgradeVersion == 37) {
415 db.beginTransaction();
416 SQLiteStatement stmt = null;
418 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
420 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
421 R.string.airplane_mode_toggleable_radios);
422 db.setTransactionSuccessful();
425 if (stmt != null) stmt.close();
430 if (upgradeVersion == 38) {
431 db.beginTransaction();
434 mContext.getResources().getBoolean(R.bool.assisted_gps_enabled) ? "1" : "0";
435 db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
436 Settings.Secure.ASSISTED_GPS_ENABLED + "','" + value + "');");
437 db.setTransactionSuccessful();
445 if (upgradeVersion == 39) {
446 upgradeAutoBrightness(db);
450 if (upgradeVersion == 40) {
452 * All animations are now turned on by default!
454 db.beginTransaction();
455 SQLiteStatement stmt = null;
457 db.execSQL("DELETE FROM system WHERE name='"
458 + Settings.System.WINDOW_ANIMATION_SCALE + "'");
459 db.execSQL("DELETE FROM system WHERE name='"
460 + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
461 stmt = db.compileStatement("INSERT INTO system(name,value)"
463 loadDefaultAnimationSettings(stmt);
464 db.setTransactionSuccessful();
467 if (stmt != null) stmt.close();
472 if (upgradeVersion == 41) {
474 * Initialize newly public haptic feedback setting
476 db.beginTransaction();
477 SQLiteStatement stmt = null;
479 db.execSQL("DELETE FROM system WHERE name='"
480 + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'");
481 stmt = db.compileStatement("INSERT INTO system(name,value)"
483 loadDefaultHapticSettings(stmt);
484 db.setTransactionSuccessful();
487 if (stmt != null) stmt.close();
492 if (upgradeVersion == 42) {
494 * Initialize new notification pulse setting
496 db.beginTransaction();
497 SQLiteStatement stmt = null;
499 stmt = db.compileStatement("INSERT INTO system(name,value)"
501 loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
502 R.bool.def_notification_pulse);
503 db.setTransactionSuccessful();
506 if (stmt != null) stmt.close();
511 if (upgradeVersion == 43) {
513 * This upgrade stores bluetooth volume separately from voice volume
515 db.beginTransaction();
516 SQLiteStatement stmt = null;
518 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
520 loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO,
521 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
522 db.setTransactionSuccessful();
525 if (stmt != null) stmt.close();
530 if (upgradeVersion == 44) {
532 * Gservices was moved into vendor/google.
534 db.execSQL("DROP TABLE IF EXISTS gservices");
535 db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
539 if (upgradeVersion == 45) {
541 * New settings for MountService
543 db.beginTransaction();
545 db.execSQL("INSERT INTO secure(name,value) values('" +
546 Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND + "','1');");
547 db.execSQL("INSERT INTO secure(name,value) values('" +
548 Settings.Secure.MOUNT_UMS_AUTOSTART + "','0');");
549 db.execSQL("INSERT INTO secure(name,value) values('" +
550 Settings.Secure.MOUNT_UMS_PROMPT + "','1');");
551 db.execSQL("INSERT INTO secure(name,value) values('" +
552 Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED + "','1');");
553 db.setTransactionSuccessful();
560 if (upgradeVersion == 46) {
562 * The password mode constants have changed; reset back to no
565 db.beginTransaction();
567 db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
568 db.setTransactionSuccessful();
576 if (upgradeVersion == 47) {
578 * The password mode constants have changed again; reset back to no
581 db.beginTransaction();
583 db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
584 db.setTransactionSuccessful();
591 if (upgradeVersion == 48) {
593 * Default recognition service no longer initialized here,
594 * moved to RecognitionManagerService.
599 if (upgradeVersion == 49) {
601 * New settings for new user interface noises.
603 db.beginTransaction();
604 SQLiteStatement stmt = null;
606 stmt = db.compileStatement("INSERT INTO system(name,value)"
608 loadUISoundEffectsSettings(stmt);
609 db.setTransactionSuccessful();
612 if (stmt != null) stmt.close();
618 if (upgradeVersion == 50) {
620 * Install location no longer initiated here.
625 if (upgradeVersion == 51) {
626 /* Move the lockscreen related settings to Secure, including some private ones. */
627 String[] settingsToMove = {
628 Secure.LOCK_PATTERN_ENABLED,
629 Secure.LOCK_PATTERN_VISIBLE,
630 Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
631 "lockscreen.password_type",
632 "lockscreen.lockoutattemptdeadline",
633 "lockscreen.patterneverchosen",
634 "lock_pattern_autolock",
635 "lockscreen.lockedoutpermanently",
636 "lockscreen.password_salt"
638 moveFromSystemToSecure(db, settingsToMove);
642 if (upgradeVersion == 52) {
643 // new vibration/silent mode settings
644 db.beginTransaction();
645 SQLiteStatement stmt = null;
647 stmt = db.compileStatement("INSERT INTO system(name,value)"
649 loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
650 R.bool.def_vibrate_in_silent);
651 db.setTransactionSuccessful();
654 if (stmt != null) stmt.close();
660 if (upgradeVersion == 53) {
662 * New settings for set install location UI no longer initiated here.
667 if (upgradeVersion == 54) {
669 * Update the screen timeout value if set to never
671 db.beginTransaction();
673 upgradeScreenTimeoutFromNever(db);
674 db.setTransactionSuccessful();
682 if (upgradeVersion == 55) {
683 /* Move the install location settings. */
684 String[] settingsToMove = {
685 Secure.SET_INSTALL_LOCATION,
686 Secure.DEFAULT_INSTALL_LOCATION
688 moveFromSystemToSecure(db, settingsToMove);
689 db.beginTransaction();
690 SQLiteStatement stmt = null;
692 stmt = db.compileStatement("INSERT INTO system(name,value)"
694 loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 0);
695 loadSetting(stmt, Secure.DEFAULT_INSTALL_LOCATION,
696 PackageHelper.APP_INSTALL_AUTO);
697 db.setTransactionSuccessful();
700 if (stmt != null) stmt.close();
705 if (upgradeVersion == 56) {
707 * Add Bluetooth to list of toggleable radios in airplane mode
709 db.beginTransaction();
710 SQLiteStatement stmt = null;
712 db.execSQL("DELETE FROM system WHERE name='"
713 + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
714 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
716 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
717 R.string.airplane_mode_toggleable_radios);
718 db.setTransactionSuccessful();
721 if (stmt != null) stmt.close();
726 if (upgradeVersion == 57) {
729 * 1. Enable injection of accessibility scripts in WebViews.
730 * 2. Define the key bindings for traversing web content in WebViews.
732 db.beginTransaction();
733 SQLiteStatement stmt = null;
735 stmt = db.compileStatement("INSERT INTO secure(name,value)"
737 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
738 R.bool.def_accessibility_script_injection);
740 stmt = db.compileStatement("INSERT INTO secure(name,value)"
742 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
743 R.string.def_accessibility_web_content_key_bindings);
744 db.setTransactionSuccessful();
747 if (stmt != null) stmt.close();
752 if (upgradeVersion == 58) {
753 /* Add default for new Auto Time Zone */
754 db.beginTransaction();
755 SQLiteStatement stmt = null;
757 stmt = db.compileStatement("INSERT INTO secure(name,value)"
759 loadBooleanSetting(stmt, Settings.System.AUTO_TIME_ZONE,
760 R.bool.def_auto_time_zone); // Sync timezone to NITZ
761 db.setTransactionSuccessful();
764 if (stmt != null) stmt.close();
769 if (upgradeVersion == 59) {
770 // Persistence for the rotation lock feature.
771 db.beginTransaction();
772 SQLiteStatement stmt = null;
774 stmt = db.compileStatement("INSERT INTO system(name,value)"
776 loadBooleanSetting(stmt, Settings.System.USER_ROTATION,
777 R.integer.def_user_rotation); // should be zero degrees
778 db.setTransactionSuccessful();
781 if (stmt != null) stmt.close();
786 if (upgradeVersion == 60) {
787 upgradeScreenTimeout(db);
791 if (upgradeVersion == 61) {
792 upgradeScreenTimeout(db);
796 // Change the default for screen auto-brightness mode
797 if (upgradeVersion == 62) {
798 upgradeAutoBrightness(db);
802 if (upgradeVersion == 63) {
803 // This upgrade adds the STREAM_MUSIC type to the list of
804 // types affected by ringer modes (silent, vibrate, etc.)
805 db.beginTransaction();
807 db.execSQL("DELETE FROM system WHERE name='"
808 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
809 int newValue = (1 << AudioManager.STREAM_RING)
810 | (1 << AudioManager.STREAM_NOTIFICATION)
811 | (1 << AudioManager.STREAM_SYSTEM)
812 | (1 << AudioManager.STREAM_SYSTEM_ENFORCED)
813 | (1 << AudioManager.STREAM_MUSIC);
814 db.execSQL("INSERT INTO system ('name', 'value') values ('"
815 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
816 + String.valueOf(newValue) + "')");
817 db.setTransactionSuccessful();
824 if (upgradeVersion == 64) {
825 // New setting to configure the long press timeout.
826 db.beginTransaction();
827 SQLiteStatement stmt = null;
829 stmt = db.compileStatement("INSERT INTO secure(name,value)"
831 loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
832 R.integer.def_long_press_timeout_millis);
834 db.setTransactionSuccessful();
837 if (stmt != null) stmt.close();
842 // *** Remember to update DATABASE_VERSION above!
844 if (upgradeVersion != currentVersion) {
845 Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
846 + ", must wipe the settings provider");
847 db.execSQL("DROP TABLE IF EXISTS system");
848 db.execSQL("DROP INDEX IF EXISTS systemIndex1");
849 db.execSQL("DROP TABLE IF EXISTS secure");
850 db.execSQL("DROP INDEX IF EXISTS secureIndex1");
851 db.execSQL("DROP TABLE IF EXISTS gservices");
852 db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
853 db.execSQL("DROP TABLE IF EXISTS bluetooth_devices");
854 db.execSQL("DROP TABLE IF EXISTS bookmarks");
855 db.execSQL("DROP INDEX IF EXISTS bookmarksIndex1");
856 db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
857 db.execSQL("DROP TABLE IF EXISTS favorites");
860 // Added for diagnosing settings.db wipes after the fact
861 String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion;
862 db.execSQL("INSERT INTO secure(name,value) values('" +
863 "wiped_db_reason" + "','" + wipeReason + "');");
867 private void moveFromSystemToSecure(SQLiteDatabase db, String [] settingsToMove) {
868 // Copy settings values from 'system' to 'secure' and delete them from 'system'
869 SQLiteStatement insertStmt = null;
870 SQLiteStatement deleteStmt = null;
872 db.beginTransaction();
875 db.compileStatement("INSERT INTO secure (name,value) SELECT name,value FROM "
876 + "system WHERE name=?");
877 deleteStmt = db.compileStatement("DELETE FROM system WHERE name=?");
880 for (String setting : settingsToMove) {
881 insertStmt.bindString(1, setting);
882 insertStmt.execute();
884 deleteStmt.bindString(1, setting);
885 deleteStmt.execute();
887 db.setTransactionSuccessful();
890 if (insertStmt != null) {
893 if (deleteStmt != null) {
899 private void upgradeLockPatternLocation(SQLiteDatabase db) {
900 Cursor c = db.query("system", new String[] {"_id", "value"}, "name='lock_pattern'",
901 null, null, null, null);
902 if (c.getCount() > 0) {
904 String lockPattern = c.getString(1);
905 if (!TextUtils.isEmpty(lockPattern)) {
906 // Convert lock pattern
908 LockPatternUtils lpu = new LockPatternUtils(mContext);
909 List<LockPatternView.Cell> cellPattern =
910 LockPatternUtils.stringToPattern(lockPattern);
911 lpu.saveLockPattern(cellPattern);
912 } catch (IllegalArgumentException e) {
913 // Don't want corrupted lock pattern to hang the reboot process
917 db.delete("system", "name='lock_pattern'", null);
923 private void upgradeScreenTimeoutFromNever(SQLiteDatabase db) {
924 // See if the timeout is -1 (for "Never").
925 Cursor c = db.query("system", new String[] { "_id", "value" }, "name=? AND value=?",
926 new String[] { Settings.System.SCREEN_OFF_TIMEOUT, "-1" },
929 SQLiteStatement stmt = null;
930 if (c.getCount() > 0) {
933 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
936 // Set the timeout to 30 minutes in milliseconds
937 loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
938 Integer.toString(30 * 60 * 1000));
940 if (stmt != null) stmt.close();
947 private void upgradeScreenTimeout(SQLiteDatabase db) {
948 // Change screen timeout to current default
949 db.beginTransaction();
950 SQLiteStatement stmt = null;
952 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
954 loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
955 R.integer.def_screen_off_timeout);
956 db.setTransactionSuccessful();
964 private void upgradeAutoBrightness(SQLiteDatabase db) {
965 db.beginTransaction();
968 mContext.getResources().getBoolean(
969 R.bool.def_screen_brightness_automatic_mode) ? "1" : "0";
970 db.execSQL("INSERT OR REPLACE INTO system(name,value) values('" +
971 Settings.System.SCREEN_BRIGHTNESS_MODE + "','" + value + "');");
972 db.setTransactionSuccessful();
979 * Loads the default set of bookmarked shortcuts from an xml file.
981 * @param db The database to write the values into
982 * @param startingIndex The zero-based position at which bookmarks in this file should begin
984 private int loadBookmarks(SQLiteDatabase db, int startingIndex) {
985 Intent intent = new Intent(Intent.ACTION_MAIN, null);
986 intent.addCategory(Intent.CATEGORY_LAUNCHER);
987 ContentValues values = new ContentValues();
989 PackageManager packageManager = mContext.getPackageManager();
990 int i = startingIndex;
993 XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
994 XmlUtils.beginDocument(parser, "bookmarks");
996 final int depth = parser.getDepth();
999 while (((type = parser.next()) != XmlPullParser.END_TAG ||
1000 parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
1002 if (type != XmlPullParser.START_TAG) {
1006 String name = parser.getName();
1007 if (!"bookmark".equals(name)) {
1011 String pkg = parser.getAttributeValue(null, "package");
1012 String cls = parser.getAttributeValue(null, "class");
1013 String shortcutStr = parser.getAttributeValue(null, "shortcut");
1015 int shortcutValue = shortcutStr.charAt(0);
1016 if (TextUtils.isEmpty(shortcutStr)) {
1017 Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
1020 ActivityInfo info = null;
1021 ComponentName cn = new ComponentName(pkg, cls);
1023 info = packageManager.getActivityInfo(cn, 0);
1024 } catch (PackageManager.NameNotFoundException e) {
1025 String[] packages = packageManager.canonicalToCurrentPackageNames(
1026 new String[] { pkg });
1027 cn = new ComponentName(packages[0], cls);
1029 info = packageManager.getActivityInfo(cn, 0);
1030 } catch (PackageManager.NameNotFoundException e1) {
1031 Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
1036 intent.setComponent(cn);
1037 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1038 values.put(Settings.Bookmarks.INTENT, intent.toUri(0));
1039 values.put(Settings.Bookmarks.TITLE,
1040 info.loadLabel(packageManager).toString());
1041 values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
1042 db.insert("bookmarks", null, values);
1046 } catch (XmlPullParserException e) {
1047 Log.w(TAG, "Got execption parsing bookmarks.", e);
1048 } catch (IOException e) {
1049 Log.w(TAG, "Got execption parsing bookmarks.", e);
1056 * Loads the default set of bookmark packages.
1058 * @param db The database to write the values into
1060 private void loadBookmarks(SQLiteDatabase db) {
1061 loadBookmarks(db, 0);
1065 * Loads the default volume levels. It is actually inserting the index of
1066 * the volume array for each of the volume controls.
1068 * @param db the database to insert the volume levels into
1070 private void loadVolumeLevels(SQLiteDatabase db) {
1071 SQLiteStatement stmt = null;
1073 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
1076 loadSetting(stmt, Settings.System.VOLUME_MUSIC,
1077 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
1078 loadSetting(stmt, Settings.System.VOLUME_RING,
1079 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]);
1080 loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
1081 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
1084 Settings.System.VOLUME_VOICE,
1085 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
1086 loadSetting(stmt, Settings.System.VOLUME_ALARM,
1087 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]);
1090 Settings.System.VOLUME_NOTIFICATION,
1091 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]);
1094 Settings.System.VOLUME_BLUETOOTH_SCO,
1095 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
1097 loadSetting(stmt, Settings.System.MODE_RINGER,
1098 AudioManager.RINGER_MODE_NORMAL);
1100 loadVibrateSetting(db, false);
1102 // By default, only the ring/notification, system and music streams are affected
1103 loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
1104 (1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) |
1105 (1 << AudioManager.STREAM_SYSTEM) | (1 << AudioManager.STREAM_SYSTEM_ENFORCED) |
1106 (1 << AudioManager.STREAM_MUSIC));
1108 loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
1109 ((1 << AudioManager.STREAM_MUSIC) |
1110 (1 << AudioManager.STREAM_RING) |
1111 (1 << AudioManager.STREAM_NOTIFICATION) |
1112 (1 << AudioManager.STREAM_SYSTEM)));
1114 if (stmt != null) stmt.close();
1118 private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
1120 db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
1123 SQLiteStatement stmt = null;
1125 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
1128 // Vibrate off by default for ringer, on for notification
1130 vibrate = AudioService.getValueForVibrateSetting(vibrate,
1131 AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);
1132 vibrate |= AudioService.getValueForVibrateSetting(vibrate,
1133 AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
1134 loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
1136 if (stmt != null) stmt.close();
1140 private void loadSettings(SQLiteDatabase db) {
1141 loadSystemSettings(db);
1142 loadSecureSettings(db);
1145 private void loadSystemSettings(SQLiteDatabase db) {
1146 SQLiteStatement stmt = null;
1148 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
1151 loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
1152 R.bool.def_dim_screen);
1153 loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
1154 "1".equals(SystemProperties.get("ro.kernel.qemu")) ? 1 : 0);
1155 loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
1156 R.integer.def_screen_off_timeout);
1158 // Set default cdma emergency tone
1159 loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
1161 // Set default cdma call auto retry
1162 loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
1164 // Set default cdma DTMF type
1165 loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
1167 // Set default hearing aid
1168 loadSetting(stmt, Settings.System.HEARING_AID, 0);
1170 // Set default tty mode
1171 loadSetting(stmt, Settings.System.TTY_MODE, 0);
1173 loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
1174 R.bool.def_airplane_mode_on);
1176 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
1177 R.string.def_airplane_mode_radios);
1179 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
1180 R.string.airplane_mode_toggleable_radios);
1182 loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
1183 R.bool.def_auto_time); // Sync time to NITZ
1185 loadBooleanSetting(stmt, Settings.System.AUTO_TIME_ZONE,
1186 R.bool.def_auto_time_zone); // Sync timezone to NITZ
1188 loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
1189 R.integer.def_screen_brightness);
1191 loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
1192 R.bool.def_screen_brightness_automatic_mode);
1194 loadDefaultAnimationSettings(stmt);
1196 loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
1197 R.bool.def_accelerometer_rotation);
1199 loadDefaultHapticSettings(stmt);
1201 loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
1202 R.bool.def_notification_pulse);
1203 loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
1204 loadSetting(stmt, Settings.Secure.DEFAULT_INSTALL_LOCATION,
1205 PackageHelper.APP_INSTALL_AUTO);
1207 loadUISoundEffectsSettings(stmt);
1209 loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
1210 R.bool.def_vibrate_in_silent);
1212 loadBooleanSetting(stmt, Settings.System.USE_PTP_INTERFACE,
1213 R.bool.def_use_ptp_interface);
1215 // Set notification volume to follow ringer volume by default
1216 loadBooleanSetting(stmt, Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
1217 R.bool.def_notifications_use_ring_volume);
1219 loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
1220 R.integer.def_pointer_speed);
1223 if (stmt != null) stmt.close();
1227 private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
1228 loadIntegerSetting(stmt, Settings.System.POWER_SOUNDS_ENABLED,
1229 R.integer.def_power_sounds_enabled);
1230 loadStringSetting(stmt, Settings.System.LOW_BATTERY_SOUND,
1231 R.string.def_low_battery_sound);
1233 loadIntegerSetting(stmt, Settings.System.DOCK_SOUNDS_ENABLED,
1234 R.integer.def_dock_sounds_enabled);
1235 loadStringSetting(stmt, Settings.System.DESK_DOCK_SOUND,
1236 R.string.def_desk_dock_sound);
1237 loadStringSetting(stmt, Settings.System.DESK_UNDOCK_SOUND,
1238 R.string.def_desk_undock_sound);
1239 loadStringSetting(stmt, Settings.System.CAR_DOCK_SOUND,
1240 R.string.def_car_dock_sound);
1241 loadStringSetting(stmt, Settings.System.CAR_UNDOCK_SOUND,
1242 R.string.def_car_undock_sound);
1244 loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
1245 R.integer.def_lockscreen_sounds_enabled);
1246 loadStringSetting(stmt, Settings.System.LOCK_SOUND,
1247 R.string.def_lock_sound);
1248 loadStringSetting(stmt, Settings.System.UNLOCK_SOUND,
1249 R.string.def_unlock_sound);
1252 private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
1253 loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
1254 R.fraction.def_window_animation_scale, 1);
1255 loadFractionSetting(stmt, Settings.System.TRANSITION_ANIMATION_SCALE,
1256 R.fraction.def_window_transition_scale, 1);
1259 private void loadDefaultHapticSettings(SQLiteStatement stmt) {
1260 loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
1261 R.bool.def_haptic_feedback);
1264 private void loadSecureSettings(SQLiteDatabase db) {
1265 SQLiteStatement stmt = null;
1267 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1270 loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
1271 R.bool.def_bluetooth_on);
1273 // Data roaming default, based on build
1274 loadSetting(stmt, Settings.Secure.DATA_ROAMING,
1275 "true".equalsIgnoreCase(
1276 SystemProperties.get("ro.com.android.dataroaming",
1279 loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
1280 R.bool.def_install_non_market_apps);
1282 loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
1283 R.string.def_location_providers_allowed);
1285 loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
1286 R.bool.assisted_gps_enabled);
1288 loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
1289 R.integer.def_network_preference);
1291 loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
1292 R.bool.def_usb_mass_storage_enabled);
1294 loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
1295 R.bool.def_wifi_on);
1296 loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
1297 R.bool.def_networks_available_notification_on);
1299 String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
1300 if (!TextUtils.isEmpty(wifiWatchList)) {
1301 loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
1304 // Set the preferred network mode to 0 = Global, CDMA default
1306 if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
1307 type = Phone.NT_MODE_GLOBAL;
1309 type = SystemProperties.getInt("ro.telephony.default_network",
1310 RILConstants.PREFERRED_NETWORK_MODE);
1312 loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
1314 // Enable or disable Cell Broadcast SMS
1315 loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
1316 RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
1318 // Set the preferred cdma subscription to 0 = Subscription from RUIM, when available
1319 loadSetting(stmt, Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
1320 RILConstants.PREFERRED_CDMA_SUBSCRIPTION);
1322 // Don't do this. The SystemServer will initialize ADB_ENABLED from a
1323 // persistent system property instead.
1324 //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
1326 // Allow mock locations default, based on build
1327 loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
1328 "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
1330 loadSecure35Settings(stmt);
1332 loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
1333 R.bool.def_mount_play_notification_snd);
1335 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
1336 R.bool.def_mount_ums_autostart);
1338 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
1339 R.bool.def_mount_ums_prompt);
1341 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
1342 R.bool.def_mount_ums_notify_enabled);
1344 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
1345 R.bool.def_accessibility_script_injection);
1347 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
1348 R.string.def_accessibility_web_content_key_bindings);
1350 final int maxBytes = mContext.getResources().getInteger(
1351 R.integer.def_download_manager_max_bytes_over_mobile);
1353 loadSetting(stmt, Settings.Secure.DOWNLOAD_MAX_BYTES_OVER_MOBILE,
1354 Integer.toString(maxBytes));
1357 final int recommendedMaxBytes = mContext.getResources().getInteger(
1358 R.integer.def_download_manager_recommended_max_bytes_over_mobile);
1359 if (recommendedMaxBytes > 0) {
1360 loadSetting(stmt, Settings.Secure.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE,
1361 Integer.toString(recommendedMaxBytes));
1364 loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
1365 R.integer.def_long_press_timeout_millis);
1367 if (stmt != null) stmt.close();
1371 private void loadSecure35Settings(SQLiteStatement stmt) {
1372 loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED,
1373 R.bool.def_backup_enabled);
1375 loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
1376 R.string.def_backup_transport);
1379 private void loadSetting(SQLiteStatement stmt, String key, Object value) {
1380 stmt.bindString(1, key);
1381 stmt.bindString(2, value.toString());
1385 private void loadStringSetting(SQLiteStatement stmt, String key, int resid) {
1386 loadSetting(stmt, key, mContext.getResources().getString(resid));
1389 private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
1390 loadSetting(stmt, key,
1391 mContext.getResources().getBoolean(resid) ? "1" : "0");
1394 private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) {
1395 loadSetting(stmt, key,
1396 Integer.toString(mContext.getResources().getInteger(resid)));
1399 private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) {
1400 loadSetting(stmt, key,
1401 Float.toString(mContext.getResources().getFraction(resid, base, base)));