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