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