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.IPackageManager; 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.Environment; 35import android.os.RemoteException; 36import android.os.ServiceManager; 37import android.os.SystemProperties; 38import android.os.UserHandle; 39import android.provider.Settings; 40import android.provider.Settings.Global; 41import android.provider.Settings.Secure; 42import android.telephony.TelephonyManager; 43import android.text.TextUtils; 44import android.util.Log; 45 46import com.android.internal.content.PackageHelper; 47import com.android.internal.telephony.Phone; 48import com.android.internal.telephony.PhoneConstants; 49import com.android.internal.telephony.RILConstants; 50import com.android.internal.util.XmlUtils; 51import com.android.internal.widget.LockPatternUtils; 52import com.android.internal.widget.LockPatternView; 53 54import org.xmlpull.v1.XmlPullParser; 55import org.xmlpull.v1.XmlPullParserException; 56 57import java.io.File; 58import java.io.IOException; 59import java.util.HashSet; 60import java.util.List; 61 62/** 63 * Database helper class for {@link SettingsProvider}. 64 * Mostly just has a bit {@link #onCreate} to initialize the database. 65 */ 66public class DatabaseHelper extends SQLiteOpenHelper { 67 private static final String TAG = "SettingsProvider"; 68 private static final String DATABASE_NAME = "settings.db"; 69 70 // Please, please please. If you update the database version, check to make sure the 71 // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' 72 // is properly propagated through your change. Not doing so will result in a loss of user 73 // settings. 74 private static final int DATABASE_VERSION = 95; 75 76 private Context mContext; 77 private int mUserHandle; 78 79 private static final HashSet<String> mValidTables = new HashSet<String>(); 80 81 private static final String TABLE_SYSTEM = "system"; 82 private static final String TABLE_SECURE = "secure"; 83 private static final String TABLE_GLOBAL = "global"; 84 85 static { 86 mValidTables.add(TABLE_SYSTEM); 87 mValidTables.add(TABLE_SECURE); 88 mValidTables.add(TABLE_GLOBAL); 89 mValidTables.add("bluetooth_devices"); 90 mValidTables.add("bookmarks"); 91 92 // These are old. 93 mValidTables.add("favorites"); 94 mValidTables.add("gservices"); 95 mValidTables.add("old_favorites"); 96 } 97 98 static String dbNameForUser(final int userHandle) { 99 // The owner gets the unadorned db name; 100 if (userHandle == UserHandle.USER_OWNER) { 101 return DATABASE_NAME; 102 } else { 103 // Place the database in the user-specific data tree so that it's 104 // cleaned up automatically when the user is deleted. 105 File databaseFile = new File( 106 Environment.getUserSystemDirectory(userHandle), DATABASE_NAME); 107 return databaseFile.getPath(); 108 } 109 } 110 111 public DatabaseHelper(Context context, int userHandle) { 112 super(context, dbNameForUser(userHandle), null, DATABASE_VERSION); 113 mContext = context; 114 mUserHandle = userHandle; 115 setWriteAheadLoggingEnabled(true); 116 } 117 118 public static boolean isValidTable(String name) { 119 return mValidTables.contains(name); 120 } 121 122 private void createSecureTable(SQLiteDatabase db) { 123 db.execSQL("CREATE TABLE secure (" + 124 "_id INTEGER PRIMARY KEY AUTOINCREMENT," + 125 "name TEXT UNIQUE ON CONFLICT REPLACE," + 126 "value TEXT" + 127 ");"); 128 db.execSQL("CREATE INDEX secureIndex1 ON secure (name);"); 129 } 130 131 private void createGlobalTable(SQLiteDatabase db) { 132 db.execSQL("CREATE TABLE global (" + 133 "_id INTEGER PRIMARY KEY AUTOINCREMENT," + 134 "name TEXT UNIQUE ON CONFLICT REPLACE," + 135 "value TEXT" + 136 ");"); 137 db.execSQL("CREATE INDEX globalIndex1 ON global (name);"); 138 } 139 140 @Override 141 public void onCreate(SQLiteDatabase db) { 142 db.execSQL("CREATE TABLE system (" + 143 "_id INTEGER PRIMARY KEY AUTOINCREMENT," + 144 "name TEXT UNIQUE ON CONFLICT REPLACE," + 145 "value TEXT" + 146 ");"); 147 db.execSQL("CREATE INDEX systemIndex1 ON system (name);"); 148 149 createSecureTable(db); 150 151 // Only create the global table for the singleton 'owner' user 152 if (mUserHandle == UserHandle.USER_OWNER) { 153 createGlobalTable(db); 154 } 155 156 db.execSQL("CREATE TABLE bluetooth_devices (" + 157 "_id INTEGER PRIMARY KEY," + 158 "name TEXT," + 159 "addr TEXT," + 160 "channel INTEGER," + 161 "type INTEGER" + 162 ");"); 163 164 db.execSQL("CREATE TABLE bookmarks (" + 165 "_id INTEGER PRIMARY KEY," + 166 "title TEXT," + 167 "folder TEXT," + 168 "intent TEXT," + 169 "shortcut INTEGER," + 170 "ordering INTEGER" + 171 ");"); 172 173 db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);"); 174 db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);"); 175 176 // Populate bookmarks table with initial bookmarks 177 boolean onlyCore = false; 178 try { 179 onlyCore = IPackageManager.Stub.asInterface(ServiceManager.getService( 180 "package")).isOnlyCoreApps(); 181 } catch (RemoteException e) { 182 } 183 if (!onlyCore) { 184 loadBookmarks(db); 185 } 186 187 // Load initial volume levels into DB 188 loadVolumeLevels(db); 189 190 // Load inital settings values 191 loadSettings(db); 192 } 193 194 @Override 195 public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { 196 Log.w(TAG, "Upgrading settings database from version " + oldVersion + " to " 197 + currentVersion); 198 199 int upgradeVersion = oldVersion; 200 201 // Pattern for upgrade blocks: 202 // 203 // if (upgradeVersion == [the DATABASE_VERSION you set] - 1) { 204 // .. your upgrade logic.. 205 // upgradeVersion = [the DATABASE_VERSION you set] 206 // } 207 208 if (upgradeVersion == 20) { 209 /* 210 * Version 21 is part of the volume control refresh. There is no 211 * longer a UI-visible for setting notification vibrate on/off (in 212 * our design), but the functionality still exists. Force the 213 * notification vibrate to on. 214 */ 215 loadVibrateSetting(db, true); 216 217 upgradeVersion = 21; 218 } 219 220 if (upgradeVersion < 22) { 221 upgradeVersion = 22; 222 // Upgrade the lock gesture storage location and format 223 upgradeLockPatternLocation(db); 224 } 225 226 if (upgradeVersion < 23) { 227 db.execSQL("UPDATE favorites SET iconResource=0 WHERE iconType=0"); 228 upgradeVersion = 23; 229 } 230 231 if (upgradeVersion == 23) { 232 db.beginTransaction(); 233 try { 234 db.execSQL("ALTER TABLE favorites ADD spanX INTEGER"); 235 db.execSQL("ALTER TABLE favorites ADD spanY INTEGER"); 236 // Shortcuts, applications, folders 237 db.execSQL("UPDATE favorites SET spanX=1, spanY=1 WHERE itemType<=0"); 238 // Photo frames, clocks 239 db.execSQL( 240 "UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002"); 241 // Search boxes 242 db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001"); 243 db.setTransactionSuccessful(); 244 } finally { 245 db.endTransaction(); 246 } 247 upgradeVersion = 24; 248 } 249 250 if (upgradeVersion == 24) { 251 db.beginTransaction(); 252 try { 253 // The value of the constants for preferring wifi or preferring mobile have been 254 // swapped, so reload the default. 255 db.execSQL("DELETE FROM system WHERE name='network_preference'"); 256 db.execSQL("INSERT INTO system ('name', 'value') values ('network_preference', '" + 257 ConnectivityManager.DEFAULT_NETWORK_PREFERENCE + "')"); 258 db.setTransactionSuccessful(); 259 } finally { 260 db.endTransaction(); 261 } 262 upgradeVersion = 25; 263 } 264 265 if (upgradeVersion == 25) { 266 db.beginTransaction(); 267 try { 268 db.execSQL("ALTER TABLE favorites ADD uri TEXT"); 269 db.execSQL("ALTER TABLE favorites ADD displayMode INTEGER"); 270 db.setTransactionSuccessful(); 271 } finally { 272 db.endTransaction(); 273 } 274 upgradeVersion = 26; 275 } 276 277 if (upgradeVersion == 26) { 278 // This introduces the new secure settings table. 279 db.beginTransaction(); 280 try { 281 createSecureTable(db); 282 db.setTransactionSuccessful(); 283 } finally { 284 db.endTransaction(); 285 } 286 upgradeVersion = 27; 287 } 288 289 if (upgradeVersion == 27) { 290 String[] settingsToMove = { 291 Settings.Secure.ADB_ENABLED, 292 Settings.Secure.ANDROID_ID, 293 Settings.Secure.BLUETOOTH_ON, 294 Settings.Secure.DATA_ROAMING, 295 Settings.Secure.DEVICE_PROVISIONED, 296 Settings.Secure.HTTP_PROXY, 297 Settings.Secure.INSTALL_NON_MARKET_APPS, 298 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 299 Settings.Secure.LOGGING_ID, 300 Settings.Secure.NETWORK_PREFERENCE, 301 Settings.Secure.PARENTAL_CONTROL_ENABLED, 302 Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE, 303 Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL, 304 Settings.Secure.SETTINGS_CLASSNAME, 305 Settings.Secure.USB_MASS_STORAGE_ENABLED, 306 Settings.Secure.USE_GOOGLE_MAIL, 307 Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 308 Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 309 Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, 310 Settings.Secure.WIFI_ON, 311 Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE, 312 Settings.Secure.WIFI_WATCHDOG_AP_COUNT, 313 Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS, 314 Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED, 315 Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS, 316 Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT, 317 Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS, 318 Settings.Secure.WIFI_WATCHDOG_ON, 319 Settings.Secure.WIFI_WATCHDOG_PING_COUNT, 320 Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS, 321 Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS, 322 }; 323 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false); 324 upgradeVersion = 28; 325 } 326 327 if (upgradeVersion == 28 || upgradeVersion == 29) { 328 // Note: The upgrade to 28 was flawed since it didn't delete the old 329 // setting first before inserting. Combining 28 and 29 with the 330 // fixed version. 331 332 // This upgrade adds the STREAM_NOTIFICATION type to the list of 333 // types affected by ringer modes (silent, vibrate, etc.) 334 db.beginTransaction(); 335 try { 336 db.execSQL("DELETE FROM system WHERE name='" 337 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'"); 338 int newValue = (1 << AudioManager.STREAM_RING) 339 | (1 << AudioManager.STREAM_NOTIFICATION) 340 | (1 << AudioManager.STREAM_SYSTEM); 341 db.execSQL("INSERT INTO system ('name', 'value') values ('" 342 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '" 343 + String.valueOf(newValue) + "')"); 344 db.setTransactionSuccessful(); 345 } finally { 346 db.endTransaction(); 347 } 348 349 upgradeVersion = 30; 350 } 351 352 if (upgradeVersion == 30) { 353 /* 354 * Upgrade 31 clears the title for all quick launch shortcuts so the 355 * activities' titles will be resolved at display time. Also, the 356 * folder is changed to '@quicklaunch'. 357 */ 358 db.beginTransaction(); 359 try { 360 db.execSQL("UPDATE bookmarks SET folder = '@quicklaunch'"); 361 db.execSQL("UPDATE bookmarks SET title = ''"); 362 db.setTransactionSuccessful(); 363 } finally { 364 db.endTransaction(); 365 } 366 upgradeVersion = 31; 367 } 368 369 if (upgradeVersion == 31) { 370 /* 371 * Animations are now managed in preferences, and may be 372 * enabled or disabled based on product resources. 373 */ 374 db.beginTransaction(); 375 SQLiteStatement stmt = null; 376 try { 377 db.execSQL("DELETE FROM system WHERE name='" 378 + Settings.System.WINDOW_ANIMATION_SCALE + "'"); 379 db.execSQL("DELETE FROM system WHERE name='" 380 + Settings.System.TRANSITION_ANIMATION_SCALE + "'"); 381 stmt = db.compileStatement("INSERT INTO system(name,value)" 382 + " VALUES(?,?);"); 383 loadDefaultAnimationSettings(stmt); 384 db.setTransactionSuccessful(); 385 } finally { 386 db.endTransaction(); 387 if (stmt != null) stmt.close(); 388 } 389 upgradeVersion = 32; 390 } 391 392 if (upgradeVersion == 32) { 393 // The Wi-Fi watchdog SSID list is now seeded with the value of 394 // the property ro.com.android.wifi-watchlist 395 String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist"); 396 if (!TextUtils.isEmpty(wifiWatchList)) { 397 db.beginTransaction(); 398 try { 399 db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" + 400 Settings.Secure.WIFI_WATCHDOG_WATCH_LIST + "','" + 401 wifiWatchList + "');"); 402 db.setTransactionSuccessful(); 403 } finally { 404 db.endTransaction(); 405 } 406 } 407 upgradeVersion = 33; 408 } 409 410 if (upgradeVersion == 33) { 411 // Set the default zoom controls to: tap-twice to bring up +/- 412 db.beginTransaction(); 413 try { 414 db.execSQL("INSERT INTO system(name,value) values('zoom','2');"); 415 db.setTransactionSuccessful(); 416 } finally { 417 db.endTransaction(); 418 } 419 upgradeVersion = 34; 420 } 421 422 if (upgradeVersion == 34) { 423 db.beginTransaction(); 424 SQLiteStatement stmt = null; 425 try { 426 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" 427 + " VALUES(?,?);"); 428 loadSecure35Settings(stmt); 429 db.setTransactionSuccessful(); 430 } finally { 431 db.endTransaction(); 432 if (stmt != null) stmt.close(); 433 } 434 upgradeVersion = 35; 435 } 436 // due to a botched merge from donut to eclair, the initialization of ASSISTED_GPS_ENABLED 437 // was accidentally done out of order here. 438 // to fix this, ASSISTED_GPS_ENABLED is now initialized while upgrading from 38 to 39, 439 // and we intentionally do nothing from 35 to 36 now. 440 if (upgradeVersion == 35) { 441 upgradeVersion = 36; 442 } 443 444 if (upgradeVersion == 36) { 445 // This upgrade adds the STREAM_SYSTEM_ENFORCED type to the list of 446 // types affected by ringer modes (silent, vibrate, etc.) 447 db.beginTransaction(); 448 try { 449 db.execSQL("DELETE FROM system WHERE name='" 450 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'"); 451 int newValue = (1 << AudioManager.STREAM_RING) 452 | (1 << AudioManager.STREAM_NOTIFICATION) 453 | (1 << AudioManager.STREAM_SYSTEM) 454 | (1 << AudioManager.STREAM_SYSTEM_ENFORCED); 455 db.execSQL("INSERT INTO system ('name', 'value') values ('" 456 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '" 457 + String.valueOf(newValue) + "')"); 458 db.setTransactionSuccessful(); 459 } finally { 460 db.endTransaction(); 461 } 462 upgradeVersion = 37; 463 } 464 465 if (upgradeVersion == 37) { 466 db.beginTransaction(); 467 SQLiteStatement stmt = null; 468 try { 469 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" 470 + " VALUES(?,?);"); 471 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS, 472 R.string.airplane_mode_toggleable_radios); 473 db.setTransactionSuccessful(); 474 } finally { 475 db.endTransaction(); 476 if (stmt != null) stmt.close(); 477 } 478 upgradeVersion = 38; 479 } 480 481 if (upgradeVersion == 38) { 482 db.beginTransaction(); 483 try { 484 String value = 485 mContext.getResources().getBoolean(R.bool.assisted_gps_enabled) ? "1" : "0"; 486 db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" + 487 Settings.Global.ASSISTED_GPS_ENABLED + "','" + value + "');"); 488 db.setTransactionSuccessful(); 489 } finally { 490 db.endTransaction(); 491 } 492 493 upgradeVersion = 39; 494 } 495 496 if (upgradeVersion == 39) { 497 upgradeAutoBrightness(db); 498 upgradeVersion = 40; 499 } 500 501 if (upgradeVersion == 40) { 502 /* 503 * All animations are now turned on by default! 504 */ 505 db.beginTransaction(); 506 SQLiteStatement stmt = null; 507 try { 508 db.execSQL("DELETE FROM system WHERE name='" 509 + Settings.System.WINDOW_ANIMATION_SCALE + "'"); 510 db.execSQL("DELETE FROM system WHERE name='" 511 + Settings.System.TRANSITION_ANIMATION_SCALE + "'"); 512 stmt = db.compileStatement("INSERT INTO system(name,value)" 513 + " VALUES(?,?);"); 514 loadDefaultAnimationSettings(stmt); 515 db.setTransactionSuccessful(); 516 } finally { 517 db.endTransaction(); 518 if (stmt != null) stmt.close(); 519 } 520 upgradeVersion = 41; 521 } 522 523 if (upgradeVersion == 41) { 524 /* 525 * Initialize newly public haptic feedback setting 526 */ 527 db.beginTransaction(); 528 SQLiteStatement stmt = null; 529 try { 530 db.execSQL("DELETE FROM system WHERE name='" 531 + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'"); 532 stmt = db.compileStatement("INSERT INTO system(name,value)" 533 + " VALUES(?,?);"); 534 loadDefaultHapticSettings(stmt); 535 db.setTransactionSuccessful(); 536 } finally { 537 db.endTransaction(); 538 if (stmt != null) stmt.close(); 539 } 540 upgradeVersion = 42; 541 } 542 543 if (upgradeVersion == 42) { 544 /* 545 * Initialize new notification pulse setting 546 */ 547 db.beginTransaction(); 548 SQLiteStatement stmt = null; 549 try { 550 stmt = db.compileStatement("INSERT INTO system(name,value)" 551 + " VALUES(?,?);"); 552 loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE, 553 R.bool.def_notification_pulse); 554 db.setTransactionSuccessful(); 555 } finally { 556 db.endTransaction(); 557 if (stmt != null) stmt.close(); 558 } 559 upgradeVersion = 43; 560 } 561 562 if (upgradeVersion == 43) { 563 /* 564 * This upgrade stores bluetooth volume separately from voice volume 565 */ 566 db.beginTransaction(); 567 SQLiteStatement stmt = null; 568 try { 569 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" 570 + " VALUES(?,?);"); 571 loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO, 572 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]); 573 db.setTransactionSuccessful(); 574 } finally { 575 db.endTransaction(); 576 if (stmt != null) stmt.close(); 577 } 578 upgradeVersion = 44; 579 } 580 581 if (upgradeVersion == 44) { 582 /* 583 * Gservices was moved into vendor/google. 584 */ 585 db.execSQL("DROP TABLE IF EXISTS gservices"); 586 db.execSQL("DROP INDEX IF EXISTS gservicesIndex1"); 587 upgradeVersion = 45; 588 } 589 590 if (upgradeVersion == 45) { 591 /* 592 * New settings for MountService 593 */ 594 db.beginTransaction(); 595 try { 596 db.execSQL("INSERT INTO secure(name,value) values('" + 597 Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND + "','1');"); 598 db.execSQL("INSERT INTO secure(name,value) values('" + 599 Settings.Secure.MOUNT_UMS_AUTOSTART + "','0');"); 600 db.execSQL("INSERT INTO secure(name,value) values('" + 601 Settings.Secure.MOUNT_UMS_PROMPT + "','1');"); 602 db.execSQL("INSERT INTO secure(name,value) values('" + 603 Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED + "','1');"); 604 db.setTransactionSuccessful(); 605 } finally { 606 db.endTransaction(); 607 } 608 upgradeVersion = 46; 609 } 610 611 if (upgradeVersion == 46) { 612 /* 613 * The password mode constants have changed; reset back to no 614 * password. 615 */ 616 db.beginTransaction(); 617 try { 618 db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';"); 619 db.setTransactionSuccessful(); 620 } finally { 621 db.endTransaction(); 622 } 623 upgradeVersion = 47; 624 } 625 626 627 if (upgradeVersion == 47) { 628 /* 629 * The password mode constants have changed again; reset back to no 630 * password. 631 */ 632 db.beginTransaction(); 633 try { 634 db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';"); 635 db.setTransactionSuccessful(); 636 } finally { 637 db.endTransaction(); 638 } 639 upgradeVersion = 48; 640 } 641 642 if (upgradeVersion == 48) { 643 /* 644 * Default recognition service no longer initialized here, 645 * moved to RecognitionManagerService. 646 */ 647 upgradeVersion = 49; 648 } 649 650 if (upgradeVersion == 49) { 651 /* 652 * New settings for new user interface noises. 653 */ 654 db.beginTransaction(); 655 SQLiteStatement stmt = null; 656 try { 657 stmt = db.compileStatement("INSERT INTO system(name,value)" 658 + " VALUES(?,?);"); 659 loadUISoundEffectsSettings(stmt); 660 db.setTransactionSuccessful(); 661 } finally { 662 db.endTransaction(); 663 if (stmt != null) stmt.close(); 664 } 665 666 upgradeVersion = 50; 667 } 668 669 if (upgradeVersion == 50) { 670 /* 671 * Install location no longer initiated here. 672 */ 673 upgradeVersion = 51; 674 } 675 676 if (upgradeVersion == 51) { 677 /* Move the lockscreen related settings to Secure, including some private ones. */ 678 String[] settingsToMove = { 679 Secure.LOCK_PATTERN_ENABLED, 680 Secure.LOCK_PATTERN_VISIBLE, 681 Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 682 "lockscreen.password_type", 683 "lockscreen.lockoutattemptdeadline", 684 "lockscreen.patterneverchosen", 685 "lock_pattern_autolock", 686 "lockscreen.lockedoutpermanently", 687 "lockscreen.password_salt" 688 }; 689 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false); 690 upgradeVersion = 52; 691 } 692 693 if (upgradeVersion == 52) { 694 // new vibration/silent mode settings 695 db.beginTransaction(); 696 SQLiteStatement stmt = null; 697 try { 698 stmt = db.compileStatement("INSERT INTO system(name,value)" 699 + " VALUES(?,?);"); 700 loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT, 701 R.bool.def_vibrate_in_silent); 702 db.setTransactionSuccessful(); 703 } finally { 704 db.endTransaction(); 705 if (stmt != null) stmt.close(); 706 } 707 708 upgradeVersion = 53; 709 } 710 711 if (upgradeVersion == 53) { 712 /* 713 * New settings for set install location UI no longer initiated here. 714 */ 715 upgradeVersion = 54; 716 } 717 718 if (upgradeVersion == 54) { 719 /* 720 * Update the screen timeout value if set to never 721 */ 722 db.beginTransaction(); 723 try { 724 upgradeScreenTimeoutFromNever(db); 725 db.setTransactionSuccessful(); 726 } finally { 727 db.endTransaction(); 728 } 729 730 upgradeVersion = 55; 731 } 732 733 if (upgradeVersion == 55) { 734 /* Move the install location settings. */ 735 String[] settingsToMove = { 736 Global.SET_INSTALL_LOCATION, 737 Global.DEFAULT_INSTALL_LOCATION 738 }; 739 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false); 740 db.beginTransaction(); 741 SQLiteStatement stmt = null; 742 try { 743 stmt = db.compileStatement("INSERT INTO system(name,value)" 744 + " VALUES(?,?);"); 745 loadSetting(stmt, Global.SET_INSTALL_LOCATION, 0); 746 loadSetting(stmt, Global.DEFAULT_INSTALL_LOCATION, 747 PackageHelper.APP_INSTALL_AUTO); 748 db.setTransactionSuccessful(); 749 } finally { 750 db.endTransaction(); 751 if (stmt != null) stmt.close(); 752 } 753 upgradeVersion = 56; 754 } 755 756 if (upgradeVersion == 56) { 757 /* 758 * Add Bluetooth to list of toggleable radios in airplane mode 759 */ 760 db.beginTransaction(); 761 SQLiteStatement stmt = null; 762 try { 763 db.execSQL("DELETE FROM system WHERE name='" 764 + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'"); 765 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" 766 + " VALUES(?,?);"); 767 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS, 768 R.string.airplane_mode_toggleable_radios); 769 db.setTransactionSuccessful(); 770 } finally { 771 db.endTransaction(); 772 if (stmt != null) stmt.close(); 773 } 774 upgradeVersion = 57; 775 } 776 777 /************* The following are Honeycomb changes ************/ 778 779 if (upgradeVersion == 57) { 780 /* 781 * New settings to: 782 * 1. Enable injection of accessibility scripts in WebViews. 783 * 2. Define the key bindings for traversing web content in WebViews. 784 */ 785 db.beginTransaction(); 786 SQLiteStatement stmt = null; 787 try { 788 stmt = db.compileStatement("INSERT INTO secure(name,value)" 789 + " VALUES(?,?);"); 790 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 791 R.bool.def_accessibility_script_injection); 792 stmt.close(); 793 stmt = db.compileStatement("INSERT INTO secure(name,value)" 794 + " VALUES(?,?);"); 795 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS, 796 R.string.def_accessibility_web_content_key_bindings); 797 db.setTransactionSuccessful(); 798 } finally { 799 db.endTransaction(); 800 if (stmt != null) stmt.close(); 801 } 802 upgradeVersion = 58; 803 } 804 805 if (upgradeVersion == 58) { 806 /* Add default for new Auto Time Zone */ 807 int autoTimeValue = getIntValueFromSystem(db, Settings.System.AUTO_TIME, 0); 808 db.beginTransaction(); 809 SQLiteStatement stmt = null; 810 try { 811 stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);"); 812 loadSetting(stmt, Settings.System.AUTO_TIME_ZONE, 813 autoTimeValue); // Sync timezone to NITZ if auto_time was enabled 814 db.setTransactionSuccessful(); 815 } finally { 816 db.endTransaction(); 817 if (stmt != null) stmt.close(); 818 } 819 upgradeVersion = 59; 820 } 821 822 if (upgradeVersion == 59) { 823 // Persistence for the rotation lock feature. 824 db.beginTransaction(); 825 SQLiteStatement stmt = null; 826 try { 827 stmt = db.compileStatement("INSERT INTO system(name,value)" 828 + " VALUES(?,?);"); 829 loadBooleanSetting(stmt, Settings.System.USER_ROTATION, 830 R.integer.def_user_rotation); // should be zero degrees 831 db.setTransactionSuccessful(); 832 } finally { 833 db.endTransaction(); 834 if (stmt != null) stmt.close(); 835 } 836 upgradeVersion = 60; 837 } 838 839 if (upgradeVersion == 60) { 840 // Don't do this for upgrades from Gingerbread 841 // Were only required for intra-Honeycomb upgrades for testing 842 // upgradeScreenTimeout(db); 843 upgradeVersion = 61; 844 } 845 846 if (upgradeVersion == 61) { 847 // Don't do this for upgrades from Gingerbread 848 // Were only required for intra-Honeycomb upgrades for testing 849 // upgradeScreenTimeout(db); 850 upgradeVersion = 62; 851 } 852 853 // Change the default for screen auto-brightness mode 854 if (upgradeVersion == 62) { 855 // Don't do this for upgrades from Gingerbread 856 // Were only required for intra-Honeycomb upgrades for testing 857 // upgradeAutoBrightness(db); 858 upgradeVersion = 63; 859 } 860 861 if (upgradeVersion == 63) { 862 // This upgrade adds the STREAM_MUSIC type to the list of 863 // types affected by ringer modes (silent, vibrate, etc.) 864 db.beginTransaction(); 865 try { 866 db.execSQL("DELETE FROM system WHERE name='" 867 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'"); 868 int newValue = (1 << AudioManager.STREAM_RING) 869 | (1 << AudioManager.STREAM_NOTIFICATION) 870 | (1 << AudioManager.STREAM_SYSTEM) 871 | (1 << AudioManager.STREAM_SYSTEM_ENFORCED) 872 | (1 << AudioManager.STREAM_MUSIC); 873 db.execSQL("INSERT INTO system ('name', 'value') values ('" 874 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '" 875 + String.valueOf(newValue) + "')"); 876 db.setTransactionSuccessful(); 877 } finally { 878 db.endTransaction(); 879 } 880 upgradeVersion = 64; 881 } 882 883 if (upgradeVersion == 64) { 884 // New setting to configure the long press timeout. 885 db.beginTransaction(); 886 SQLiteStatement stmt = null; 887 try { 888 stmt = db.compileStatement("INSERT INTO secure(name,value)" 889 + " VALUES(?,?);"); 890 loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT, 891 R.integer.def_long_press_timeout_millis); 892 stmt.close(); 893 db.setTransactionSuccessful(); 894 } finally { 895 db.endTransaction(); 896 if (stmt != null) stmt.close(); 897 } 898 upgradeVersion = 65; 899 } 900 901 /************* The following are Ice Cream Sandwich changes ************/ 902 903 if (upgradeVersion == 65) { 904 /* 905 * Animations are removed from Settings. Turned on by default 906 */ 907 db.beginTransaction(); 908 SQLiteStatement stmt = null; 909 try { 910 db.execSQL("DELETE FROM system WHERE name='" 911 + Settings.System.WINDOW_ANIMATION_SCALE + "'"); 912 db.execSQL("DELETE FROM system WHERE name='" 913 + Settings.System.TRANSITION_ANIMATION_SCALE + "'"); 914 stmt = db.compileStatement("INSERT INTO system(name,value)" 915 + " VALUES(?,?);"); 916 loadDefaultAnimationSettings(stmt); 917 db.setTransactionSuccessful(); 918 } finally { 919 db.endTransaction(); 920 if (stmt != null) stmt.close(); 921 } 922 upgradeVersion = 66; 923 } 924 925 if (upgradeVersion == 66) { 926 // This upgrade makes sure that MODE_RINGER_STREAMS_AFFECTED is set 927 // according to device voice capability 928 db.beginTransaction(); 929 try { 930 int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) | 931 (1 << AudioManager.STREAM_NOTIFICATION) | 932 (1 << AudioManager.STREAM_SYSTEM) | 933 (1 << AudioManager.STREAM_SYSTEM_ENFORCED); 934 if (!mContext.getResources().getBoolean( 935 com.android.internal.R.bool.config_voice_capable)) { 936 ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC); 937 } 938 db.execSQL("DELETE FROM system WHERE name='" 939 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'"); 940 db.execSQL("INSERT INTO system ('name', 'value') values ('" 941 + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '" 942 + String.valueOf(ringerModeAffectedStreams) + "')"); 943 db.setTransactionSuccessful(); 944 } finally { 945 db.endTransaction(); 946 } 947 upgradeVersion = 67; 948 } 949 950 if (upgradeVersion == 67) { 951 // New setting to enable touch exploration. 952 db.beginTransaction(); 953 SQLiteStatement stmt = null; 954 try { 955 stmt = db.compileStatement("INSERT INTO secure(name,value)" 956 + " VALUES(?,?);"); 957 loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED, 958 R.bool.def_touch_exploration_enabled); 959 stmt.close(); 960 db.setTransactionSuccessful(); 961 } finally { 962 db.endTransaction(); 963 if (stmt != null) stmt.close(); 964 } 965 upgradeVersion = 68; 966 } 967 968 if (upgradeVersion == 68) { 969 // Enable all system sounds by default 970 db.beginTransaction(); 971 try { 972 db.execSQL("DELETE FROM system WHERE name='" 973 + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "'"); 974 db.setTransactionSuccessful(); 975 } finally { 976 db.endTransaction(); 977 } 978 upgradeVersion = 69; 979 } 980 981 if (upgradeVersion == 69) { 982 // Add RADIO_NFC to AIRPLANE_MODE_RADIO and AIRPLANE_MODE_TOGGLEABLE_RADIOS 983 String airplaneRadios = mContext.getResources().getString( 984 R.string.def_airplane_mode_radios); 985 String toggleableRadios = mContext.getResources().getString( 986 R.string.airplane_mode_toggleable_radios); 987 db.beginTransaction(); 988 try { 989 db.execSQL("UPDATE system SET value='" + airplaneRadios + "' " + 990 "WHERE name='" + Settings.System.AIRPLANE_MODE_RADIOS + "'"); 991 db.execSQL("UPDATE system SET value='" + toggleableRadios + "' " + 992 "WHERE name='" + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'"); 993 db.setTransactionSuccessful(); 994 } finally { 995 db.endTransaction(); 996 } 997 upgradeVersion = 70; 998 } 999 1000 if (upgradeVersion == 70) { 1001 // Update all built-in bookmarks. Some of the package names have changed. 1002 loadBookmarks(db); 1003 upgradeVersion = 71; 1004 } 1005 1006 if (upgradeVersion == 71) { 1007 // New setting to specify whether to speak passwords in accessibility mode. 1008 db.beginTransaction(); 1009 SQLiteStatement stmt = null; 1010 try { 1011 stmt = db.compileStatement("INSERT INTO secure(name,value)" 1012 + " VALUES(?,?);"); 1013 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 1014 R.bool.def_accessibility_speak_password); 1015 db.setTransactionSuccessful(); 1016 } finally { 1017 db.endTransaction(); 1018 if (stmt != null) stmt.close(); 1019 } 1020 upgradeVersion = 72; 1021 } 1022 1023 if (upgradeVersion == 72) { 1024 // update vibration settings 1025 db.beginTransaction(); 1026 SQLiteStatement stmt = null; 1027 try { 1028 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)" 1029 + " VALUES(?,?);"); 1030 loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT, 1031 R.bool.def_vibrate_in_silent); 1032 db.setTransactionSuccessful(); 1033 } finally { 1034 db.endTransaction(); 1035 if (stmt != null) stmt.close(); 1036 } 1037 upgradeVersion = 73; 1038 } 1039 1040 if (upgradeVersion == 73) { 1041 upgradeVibrateSettingFromNone(db); 1042 upgradeVersion = 74; 1043 } 1044 1045 if (upgradeVersion == 74) { 1046 // URL from which WebView loads a JavaScript based screen-reader. 1047 db.beginTransaction(); 1048 SQLiteStatement stmt = null; 1049 try { 1050 stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);"); 1051 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL, 1052 R.string.def_accessibility_screen_reader_url); 1053 db.setTransactionSuccessful(); 1054 } finally { 1055 db.endTransaction(); 1056 if (stmt != null) stmt.close(); 1057 } 1058 upgradeVersion = 75; 1059 } 1060 if (upgradeVersion == 75) { 1061 db.beginTransaction(); 1062 SQLiteStatement stmt = null; 1063 Cursor c = null; 1064 try { 1065 c = db.query(TABLE_SECURE, new String[] {"_id", "value"}, 1066 "name='lockscreen.disabled'", 1067 null, null, null, null); 1068 // only set default if it has not yet been set 1069 if (c == null || c.getCount() == 0) { 1070 stmt = db.compileStatement("INSERT INTO system(name,value)" 1071 + " VALUES(?,?);"); 1072 loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, 1073 R.bool.def_lockscreen_disabled); 1074 } 1075 db.setTransactionSuccessful(); 1076 } finally { 1077 db.endTransaction(); 1078 if (c != null) c.close(); 1079 if (stmt != null) stmt.close(); 1080 } 1081 upgradeVersion = 76; 1082 } 1083 1084 /************* The following are Jelly Bean changes ************/ 1085 1086 if (upgradeVersion == 76) { 1087 // Removed VIBRATE_IN_SILENT setting 1088 db.beginTransaction(); 1089 try { 1090 db.execSQL("DELETE FROM system WHERE name='" 1091 + Settings.System.VIBRATE_IN_SILENT + "'"); 1092 db.setTransactionSuccessful(); 1093 } finally { 1094 db.endTransaction(); 1095 } 1096 1097 upgradeVersion = 77; 1098 } 1099 1100 if (upgradeVersion == 77) { 1101 // Introduce "vibrate when ringing" setting 1102 loadVibrateWhenRingingSetting(db); 1103 1104 upgradeVersion = 78; 1105 } 1106 1107 if (upgradeVersion == 78) { 1108 // The JavaScript based screen-reader URL changes in JellyBean. 1109 db.beginTransaction(); 1110 SQLiteStatement stmt = null; 1111 try { 1112 stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)" 1113 + " VALUES(?,?);"); 1114 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL, 1115 R.string.def_accessibility_screen_reader_url); 1116 db.setTransactionSuccessful(); 1117 } finally { 1118 db.endTransaction(); 1119 if (stmt != null) stmt.close(); 1120 } 1121 upgradeVersion = 79; 1122 } 1123 1124 if (upgradeVersion == 79) { 1125 // Before touch exploration was a global setting controlled by the user 1126 // via the UI. However, if the enabled accessibility services do not 1127 // handle touch exploration mode, enabling it makes no sense. Therefore, 1128 // now the services request touch exploration mode and the user is 1129 // presented with a dialog to allow that and if she does we store that 1130 // in the database. As a result of this change a user that has enabled 1131 // accessibility, touch exploration, and some accessibility services 1132 // may lose touch exploration state, thus rendering the device useless 1133 // unless sighted help is provided, since the enabled service(s) are 1134 // not in the list of services to which the user granted a permission 1135 // to put the device in touch explore mode. Here we are allowing all 1136 // enabled accessibility services to toggle touch exploration provided 1137 // accessibility and touch exploration are enabled and no services can 1138 // toggle touch exploration. Note that the user has already manually 1139 // enabled the services and touch exploration which means the she has 1140 // given consent to have these services work in touch exploration mode. 1141 final boolean accessibilityEnabled = getIntValueFromTable(db, TABLE_SECURE, 1142 Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; 1143 final boolean touchExplorationEnabled = getIntValueFromTable(db, TABLE_SECURE, 1144 Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1; 1145 if (accessibilityEnabled && touchExplorationEnabled) { 1146 String enabledServices = getStringValueFromTable(db, TABLE_SECURE, 1147 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ""); 1148 String touchExplorationGrantedServices = getStringValueFromTable(db, TABLE_SECURE, 1149 Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, ""); 1150 if (TextUtils.isEmpty(touchExplorationGrantedServices) 1151 && !TextUtils.isEmpty(enabledServices)) { 1152 SQLiteStatement stmt = null; 1153 try { 1154 db.beginTransaction(); 1155 stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)" 1156 + " VALUES(?,?);"); 1157 loadSetting(stmt, 1158 Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, 1159 enabledServices); 1160 db.setTransactionSuccessful(); 1161 } finally { 1162 db.endTransaction(); 1163 if (stmt != null) stmt.close(); 1164 } 1165 } 1166 } 1167 upgradeVersion = 80; 1168 } 1169 1170 // vvv Jelly Bean MR1 changes begin here vvv 1171 1172 if (upgradeVersion == 80) { 1173 // update screensaver settings 1174 db.beginTransaction(); 1175 SQLiteStatement stmt = null; 1176 try { 1177 stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)" 1178 + " VALUES(?,?);"); 1179 loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED, 1180 com.android.internal.R.bool.config_dreamsEnabledByDefault); 1181 loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 1182 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); 1183 loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1184 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault); 1185 loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS, 1186 com.android.internal.R.string.config_dreamsDefaultComponent); 1187 loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, 1188 com.android.internal.R.string.config_dreamsDefaultComponent); 1189 1190 db.setTransactionSuccessful(); 1191 } finally { 1192 db.endTransaction(); 1193 if (stmt != null) stmt.close(); 1194 } 1195 upgradeVersion = 81; 1196 } 1197 1198 if (upgradeVersion == 81) { 1199 // Add package verification setting 1200 db.beginTransaction(); 1201 SQLiteStatement stmt = null; 1202 try { 1203 stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)" 1204 + " VALUES(?,?);"); 1205 loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1206 R.bool.def_package_verifier_enable); 1207 db.setTransactionSuccessful(); 1208 } finally { 1209 db.endTransaction(); 1210 if (stmt != null) stmt.close(); 1211 } 1212 upgradeVersion = 82; 1213 } 1214 1215 if (upgradeVersion == 82) { 1216 // Move to per-user settings dbs 1217 if (mUserHandle == UserHandle.USER_OWNER) { 1218 1219 db.beginTransaction(); 1220 SQLiteStatement stmt = null; 1221 try { 1222 // Migrate now-global settings. Note that this happens before 1223 // new users can be created. 1224 createGlobalTable(db); 1225 String[] settingsToMove = hashsetToStringArray(SettingsProvider.sSystemGlobalKeys); 1226 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, false); 1227 settingsToMove = hashsetToStringArray(SettingsProvider.sSecureGlobalKeys); 1228 moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, false); 1229 1230 db.setTransactionSuccessful(); 1231 } finally { 1232 db.endTransaction(); 1233 if (stmt != null) stmt.close(); 1234 } 1235 } 1236 upgradeVersion = 83; 1237 } 1238 1239 if (upgradeVersion == 83) { 1240 // 1. Setting whether screen magnification is enabled. 1241 // 2. Setting for screen magnification scale. 1242 // 3. Setting for screen magnification auto update. 1243 db.beginTransaction(); 1244 SQLiteStatement stmt = null; 1245 try { 1246 stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);"); 1247 loadBooleanSetting(stmt, 1248 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 1249 R.bool.def_accessibility_display_magnification_enabled); 1250 stmt.close(); 1251 stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);"); 1252 loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 1253 R.fraction.def_accessibility_display_magnification_scale, 1); 1254 stmt.close(); 1255 stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);"); 1256 loadBooleanSetting(stmt, 1257 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE, 1258 R.bool.def_accessibility_display_magnification_auto_update); 1259 1260 db.setTransactionSuccessful(); 1261 } finally { 1262 db.endTransaction(); 1263 if (stmt != null) stmt.close(); 1264 } 1265 upgradeVersion = 84; 1266 } 1267 1268 if (upgradeVersion == 84) { 1269 if (mUserHandle == UserHandle.USER_OWNER) { 1270 db.beginTransaction(); 1271 SQLiteStatement stmt = null; 1272 try { 1273 // Patch up the slightly-wrong key migration from 82 -> 83 for those 1274 // devices that missed it, ignoring if the move is redundant 1275 String[] settingsToMove = { 1276 Settings.Secure.ADB_ENABLED, 1277 Settings.Secure.BLUETOOTH_ON, 1278 Settings.Secure.DATA_ROAMING, 1279 Settings.Secure.DEVICE_PROVISIONED, 1280 Settings.Secure.INSTALL_NON_MARKET_APPS, 1281 Settings.Secure.USB_MASS_STORAGE_ENABLED 1282 }; 1283 moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true); 1284 db.setTransactionSuccessful(); 1285 } finally { 1286 db.endTransaction(); 1287 if (stmt != null) stmt.close(); 1288 } 1289 } 1290 upgradeVersion = 85; 1291 } 1292 1293 if (upgradeVersion == 85) { 1294 if (mUserHandle == UserHandle.USER_OWNER) { 1295 db.beginTransaction(); 1296 try { 1297 // Fix up the migration, ignoring already-migrated elements, to snap up to 1298 // date with new changes to the set of global versus system/secure settings 1299 String[] settingsToMove = { Settings.System.STAY_ON_WHILE_PLUGGED_IN }; 1300 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true); 1301 1302 db.setTransactionSuccessful(); 1303 } finally { 1304 db.endTransaction(); 1305 } 1306 } 1307 upgradeVersion = 86; 1308 } 1309 1310 if (upgradeVersion == 86) { 1311 if (mUserHandle == UserHandle.USER_OWNER) { 1312 db.beginTransaction(); 1313 try { 1314 String[] settingsToMove = { 1315 Settings.Global.PACKAGE_VERIFIER_ENABLE, 1316 Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 1317 Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE 1318 }; 1319 moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true); 1320 1321 db.setTransactionSuccessful(); 1322 } finally { 1323 db.endTransaction(); 1324 } 1325 } 1326 upgradeVersion = 87; 1327 } 1328 1329 if (upgradeVersion == 87) { 1330 if (mUserHandle == UserHandle.USER_OWNER) { 1331 db.beginTransaction(); 1332 try { 1333 String[] settingsToMove = { 1334 Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS, 1335 Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS, 1336 Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS 1337 }; 1338 moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true); 1339 1340 db.setTransactionSuccessful(); 1341 } finally { 1342 db.endTransaction(); 1343 } 1344 } 1345 upgradeVersion = 88; 1346 } 1347 1348 if (upgradeVersion == 88) { 1349 if (mUserHandle == UserHandle.USER_OWNER) { 1350 db.beginTransaction(); 1351 try { 1352 String[] settingsToMove = { 1353 Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD, 1354 Settings.Global.BATTERY_DISCHARGE_THRESHOLD, 1355 Settings.Global.SEND_ACTION_APP_ERROR, 1356 Settings.Global.DROPBOX_AGE_SECONDS, 1357 Settings.Global.DROPBOX_MAX_FILES, 1358 Settings.Global.DROPBOX_QUOTA_KB, 1359 Settings.Global.DROPBOX_QUOTA_PERCENT, 1360 Settings.Global.DROPBOX_RESERVE_PERCENT, 1361 Settings.Global.DROPBOX_TAG_PREFIX, 1362 Settings.Global.ERROR_LOGCAT_PREFIX, 1363 Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL, 1364 Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD, 1365 Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE, 1366 Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES, 1367 Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES, 1368 Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS, 1369 Settings.Global.CONNECTIVITY_CHANGE_DELAY, 1370 Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 1371 Settings.Global.CAPTIVE_PORTAL_SERVER, 1372 Settings.Global.NSD_ON, 1373 Settings.Global.SET_INSTALL_LOCATION, 1374 Settings.Global.DEFAULT_INSTALL_LOCATION, 1375 Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY, 1376 Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 1377 Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, 1378 Settings.Global.HTTP_PROXY, 1379 Settings.Global.GLOBAL_HTTP_PROXY_HOST, 1380 Settings.Global.GLOBAL_HTTP_PROXY_PORT, 1381 Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, 1382 Settings.Global.SET_GLOBAL_HTTP_PROXY, 1383 Settings.Global.DEFAULT_DNS_SERVER, 1384 }; 1385 moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true); 1386 db.setTransactionSuccessful(); 1387 } finally { 1388 db.endTransaction(); 1389 } 1390 } 1391 upgradeVersion = 89; 1392 } 1393 1394 if (upgradeVersion == 89) { 1395 if (mUserHandle == UserHandle.USER_OWNER) { 1396 db.beginTransaction(); 1397 try { 1398 String[] prefixesToMove = { 1399 Settings.Global.BLUETOOTH_HEADSET_PRIORITY_PREFIX, 1400 Settings.Global.BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX, 1401 Settings.Global.BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX, 1402 }; 1403 1404 movePrefixedSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, prefixesToMove); 1405 1406 db.setTransactionSuccessful(); 1407 } finally { 1408 db.endTransaction(); 1409 } 1410 } 1411 upgradeVersion = 90; 1412 } 1413 1414 if (upgradeVersion == 90) { 1415 if (mUserHandle == UserHandle.USER_OWNER) { 1416 db.beginTransaction(); 1417 try { 1418 String[] systemToGlobal = { 1419 Settings.Global.WINDOW_ANIMATION_SCALE, 1420 Settings.Global.TRANSITION_ANIMATION_SCALE, 1421 Settings.Global.ANIMATOR_DURATION_SCALE, 1422 Settings.Global.FANCY_IME_ANIMATIONS, 1423 Settings.Global.COMPATIBILITY_MODE, 1424 Settings.Global.EMERGENCY_TONE, 1425 Settings.Global.CALL_AUTO_RETRY, 1426 Settings.Global.DEBUG_APP, 1427 Settings.Global.WAIT_FOR_DEBUGGER, 1428 Settings.Global.SHOW_PROCESSES, 1429 Settings.Global.ALWAYS_FINISH_ACTIVITIES, 1430 }; 1431 String[] secureToGlobal = { 1432 Settings.Global.PREFERRED_NETWORK_MODE, 1433 Settings.Global.PREFERRED_CDMA_SUBSCRIPTION, 1434 }; 1435 1436 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, systemToGlobal, true); 1437 moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, secureToGlobal, true); 1438 1439 db.setTransactionSuccessful(); 1440 } finally { 1441 db.endTransaction(); 1442 } 1443 } 1444 upgradeVersion = 91; 1445 } 1446 1447 if (upgradeVersion == 91) { 1448 if (mUserHandle == UserHandle.USER_OWNER) { 1449 db.beginTransaction(); 1450 try { 1451 // Move ringer mode from system to global settings 1452 String[] settingsToMove = { Settings.Global.MODE_RINGER }; 1453 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true); 1454 1455 db.setTransactionSuccessful(); 1456 } finally { 1457 db.endTransaction(); 1458 } 1459 } 1460 upgradeVersion = 92; 1461 } 1462 1463 if (upgradeVersion == 92) { 1464 SQLiteStatement stmt = null; 1465 try { 1466 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" 1467 + " VALUES(?,?);"); 1468 if (mUserHandle == UserHandle.USER_OWNER) { 1469 // consider existing primary users to have made it through user setup 1470 // if the globally-scoped device-provisioned bit is set 1471 // (indicating they already made it through setup as primary) 1472 int deviceProvisioned = getIntValueFromTable(db, TABLE_GLOBAL, 1473 Settings.Global.DEVICE_PROVISIONED, 0); 1474 loadSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE, 1475 deviceProvisioned); 1476 } else { 1477 // otherwise use the default 1478 loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE, 1479 R.bool.def_user_setup_complete); 1480 } 1481 } finally { 1482 if (stmt != null) stmt.close(); 1483 } 1484 upgradeVersion = 93; 1485 } 1486 1487 if (upgradeVersion == 93) { 1488 // Redo this step, since somehow it didn't work the first time for some users 1489 if (mUserHandle == UserHandle.USER_OWNER) { 1490 db.beginTransaction(); 1491 SQLiteStatement stmt = null; 1492 try { 1493 // Migrate now-global settings 1494 String[] settingsToMove = hashsetToStringArray(SettingsProvider.sSystemGlobalKeys); 1495 moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true); 1496 settingsToMove = hashsetToStringArray(SettingsProvider.sSecureGlobalKeys); 1497 moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true); 1498 1499 db.setTransactionSuccessful(); 1500 } finally { 1501 db.endTransaction(); 1502 if (stmt != null) stmt.close(); 1503 } 1504 } 1505 upgradeVersion = 94; 1506 } 1507 1508 if (upgradeVersion == 94) { 1509 // Add wireless charging started sound setting 1510 if (mUserHandle == UserHandle.USER_OWNER) { 1511 db.beginTransaction(); 1512 SQLiteStatement stmt = null; 1513 try { 1514 stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)" 1515 + " VALUES(?,?);"); 1516 loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND, 1517 R.string.def_wireless_charging_started_sound); 1518 db.setTransactionSuccessful(); 1519 } finally { 1520 db.endTransaction(); 1521 if (stmt != null) stmt.close(); 1522 } 1523 } 1524 upgradeVersion = 95; 1525 } 1526 1527 // *** Remember to update DATABASE_VERSION above! 1528 1529 if (upgradeVersion != currentVersion) { 1530 Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion 1531 + ", must wipe the settings provider"); 1532 db.execSQL("DROP TABLE IF EXISTS global"); 1533 db.execSQL("DROP TABLE IF EXISTS globalIndex1"); 1534 db.execSQL("DROP TABLE IF EXISTS system"); 1535 db.execSQL("DROP INDEX IF EXISTS systemIndex1"); 1536 db.execSQL("DROP TABLE IF EXISTS secure"); 1537 db.execSQL("DROP INDEX IF EXISTS secureIndex1"); 1538 db.execSQL("DROP TABLE IF EXISTS gservices"); 1539 db.execSQL("DROP INDEX IF EXISTS gservicesIndex1"); 1540 db.execSQL("DROP TABLE IF EXISTS bluetooth_devices"); 1541 db.execSQL("DROP TABLE IF EXISTS bookmarks"); 1542 db.execSQL("DROP INDEX IF EXISTS bookmarksIndex1"); 1543 db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2"); 1544 db.execSQL("DROP TABLE IF EXISTS favorites"); 1545 onCreate(db); 1546 1547 // Added for diagnosing settings.db wipes after the fact 1548 String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion; 1549 db.execSQL("INSERT INTO secure(name,value) values('" + 1550 "wiped_db_reason" + "','" + wipeReason + "');"); 1551 } 1552 } 1553 1554 private String[] hashsetToStringArray(HashSet<String> set) { 1555 String[] array = new String[set.size()]; 1556 return set.toArray(array); 1557 } 1558 1559 private void moveSettingsToNewTable(SQLiteDatabase db, 1560 String sourceTable, String destTable, 1561 String[] settingsToMove, boolean doIgnore) { 1562 // Copy settings values from the source table to the dest, and remove from the source 1563 SQLiteStatement insertStmt = null; 1564 SQLiteStatement deleteStmt = null; 1565 1566 db.beginTransaction(); 1567 try { 1568 insertStmt = db.compileStatement("INSERT " 1569 + (doIgnore ? " OR IGNORE " : "") 1570 + " INTO " + destTable + " (name,value) SELECT name,value FROM " 1571 + sourceTable + " WHERE name=?"); 1572 deleteStmt = db.compileStatement("DELETE FROM " + sourceTable + " WHERE name=?"); 1573 1574 for (String setting : settingsToMove) { 1575 insertStmt.bindString(1, setting); 1576 insertStmt.execute(); 1577 1578 deleteStmt.bindString(1, setting); 1579 deleteStmt.execute(); 1580 } 1581 db.setTransactionSuccessful(); 1582 } finally { 1583 db.endTransaction(); 1584 if (insertStmt != null) { 1585 insertStmt.close(); 1586 } 1587 if (deleteStmt != null) { 1588 deleteStmt.close(); 1589 } 1590 } 1591 } 1592 1593 /** 1594 * Move any settings with the given prefixes from the source table to the 1595 * destination table. 1596 */ 1597 private void movePrefixedSettingsToNewTable( 1598 SQLiteDatabase db, String sourceTable, String destTable, String[] prefixesToMove) { 1599 SQLiteStatement insertStmt = null; 1600 SQLiteStatement deleteStmt = null; 1601 1602 db.beginTransaction(); 1603 try { 1604 insertStmt = db.compileStatement("INSERT INTO " + destTable 1605 + " (name,value) SELECT name,value FROM " + sourceTable 1606 + " WHERE substr(name,0,?)=?"); 1607 deleteStmt = db.compileStatement( 1608 "DELETE FROM " + sourceTable + " WHERE substr(name,0,?)=?"); 1609 1610 for (String prefix : prefixesToMove) { 1611 insertStmt.bindLong(1, prefix.length() + 1); 1612 insertStmt.bindString(2, prefix); 1613 insertStmt.execute(); 1614 1615 deleteStmt.bindLong(1, prefix.length() + 1); 1616 deleteStmt.bindString(2, prefix); 1617 deleteStmt.execute(); 1618 } 1619 db.setTransactionSuccessful(); 1620 } finally { 1621 db.endTransaction(); 1622 if (insertStmt != null) { 1623 insertStmt.close(); 1624 } 1625 if (deleteStmt != null) { 1626 deleteStmt.close(); 1627 } 1628 } 1629 } 1630 1631 private void upgradeLockPatternLocation(SQLiteDatabase db) { 1632 Cursor c = db.query(TABLE_SYSTEM, new String[] {"_id", "value"}, "name='lock_pattern'", 1633 null, null, null, null); 1634 if (c.getCount() > 0) { 1635 c.moveToFirst(); 1636 String lockPattern = c.getString(1); 1637 if (!TextUtils.isEmpty(lockPattern)) { 1638 // Convert lock pattern 1639 try { 1640 LockPatternUtils lpu = new LockPatternUtils(mContext); 1641 List<LockPatternView.Cell> cellPattern = 1642 LockPatternUtils.stringToPattern(lockPattern); 1643 lpu.saveLockPattern(cellPattern); 1644 } catch (IllegalArgumentException e) { 1645 // Don't want corrupted lock pattern to hang the reboot process 1646 } 1647 } 1648 c.close(); 1649 db.delete(TABLE_SYSTEM, "name='lock_pattern'", null); 1650 } else { 1651 c.close(); 1652 } 1653 } 1654 1655 private void upgradeScreenTimeoutFromNever(SQLiteDatabase db) { 1656 // See if the timeout is -1 (for "Never"). 1657 Cursor c = db.query(TABLE_SYSTEM, new String[] { "_id", "value" }, "name=? AND value=?", 1658 new String[] { Settings.System.SCREEN_OFF_TIMEOUT, "-1" }, 1659 null, null, null); 1660 1661 SQLiteStatement stmt = null; 1662 if (c.getCount() > 0) { 1663 c.close(); 1664 try { 1665 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)" 1666 + " VALUES(?,?);"); 1667 1668 // Set the timeout to 30 minutes in milliseconds 1669 loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, 1670 Integer.toString(30 * 60 * 1000)); 1671 } finally { 1672 if (stmt != null) stmt.close(); 1673 } 1674 } else { 1675 c.close(); 1676 } 1677 } 1678 1679 private void upgradeVibrateSettingFromNone(SQLiteDatabase db) { 1680 int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON, 0); 1681 // If the ringer vibrate value is invalid, set it to the default 1682 if ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_OFF) { 1683 vibrateSetting = AudioService.getValueForVibrateSetting(0, 1684 AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT); 1685 } 1686 // Apply the same setting to the notification vibrate value 1687 vibrateSetting = AudioService.getValueForVibrateSetting(vibrateSetting, 1688 AudioManager.VIBRATE_TYPE_NOTIFICATION, vibrateSetting); 1689 1690 SQLiteStatement stmt = null; 1691 try { 1692 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)" 1693 + " VALUES(?,?);"); 1694 loadSetting(stmt, Settings.System.VIBRATE_ON, vibrateSetting); 1695 } finally { 1696 if (stmt != null) 1697 stmt.close(); 1698 } 1699 } 1700 1701 private void upgradeScreenTimeout(SQLiteDatabase db) { 1702 // Change screen timeout to current default 1703 db.beginTransaction(); 1704 SQLiteStatement stmt = null; 1705 try { 1706 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)" 1707 + " VALUES(?,?);"); 1708 loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, 1709 R.integer.def_screen_off_timeout); 1710 db.setTransactionSuccessful(); 1711 } finally { 1712 db.endTransaction(); 1713 if (stmt != null) 1714 stmt.close(); 1715 } 1716 } 1717 1718 private void upgradeAutoBrightness(SQLiteDatabase db) { 1719 db.beginTransaction(); 1720 try { 1721 String value = 1722 mContext.getResources().getBoolean( 1723 R.bool.def_screen_brightness_automatic_mode) ? "1" : "0"; 1724 db.execSQL("INSERT OR REPLACE INTO system(name,value) values('" + 1725 Settings.System.SCREEN_BRIGHTNESS_MODE + "','" + value + "');"); 1726 db.setTransactionSuccessful(); 1727 } finally { 1728 db.endTransaction(); 1729 } 1730 } 1731 1732 /** 1733 * Loads the default set of bookmarked shortcuts from an xml file. 1734 * 1735 * @param db The database to write the values into 1736 */ 1737 private void loadBookmarks(SQLiteDatabase db) { 1738 ContentValues values = new ContentValues(); 1739 1740 PackageManager packageManager = mContext.getPackageManager(); 1741 try { 1742 XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks); 1743 XmlUtils.beginDocument(parser, "bookmarks"); 1744 1745 final int depth = parser.getDepth(); 1746 int type; 1747 1748 while (((type = parser.next()) != XmlPullParser.END_TAG || 1749 parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { 1750 1751 if (type != XmlPullParser.START_TAG) { 1752 continue; 1753 } 1754 1755 String name = parser.getName(); 1756 if (!"bookmark".equals(name)) { 1757 break; 1758 } 1759 1760 String pkg = parser.getAttributeValue(null, "package"); 1761 String cls = parser.getAttributeValue(null, "class"); 1762 String shortcutStr = parser.getAttributeValue(null, "shortcut"); 1763 String category = parser.getAttributeValue(null, "category"); 1764 1765 int shortcutValue = shortcutStr.charAt(0); 1766 if (TextUtils.isEmpty(shortcutStr)) { 1767 Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls); 1768 continue; 1769 } 1770 1771 final Intent intent; 1772 final String title; 1773 if (pkg != null && cls != null) { 1774 ActivityInfo info = null; 1775 ComponentName cn = new ComponentName(pkg, cls); 1776 try { 1777 info = packageManager.getActivityInfo(cn, 0); 1778 } catch (PackageManager.NameNotFoundException e) { 1779 String[] packages = packageManager.canonicalToCurrentPackageNames( 1780 new String[] { pkg }); 1781 cn = new ComponentName(packages[0], cls); 1782 try { 1783 info = packageManager.getActivityInfo(cn, 0); 1784 } catch (PackageManager.NameNotFoundException e1) { 1785 Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e); 1786 continue; 1787 } 1788 } 1789 1790 intent = new Intent(Intent.ACTION_MAIN, null); 1791 intent.addCategory(Intent.CATEGORY_LAUNCHER); 1792 intent.setComponent(cn); 1793 title = info.loadLabel(packageManager).toString(); 1794 } else if (category != null) { 1795 intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category); 1796 title = ""; 1797 } else { 1798 Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr 1799 + ": missing package/class or category attributes"); 1800 continue; 1801 } 1802 1803 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1804 values.put(Settings.Bookmarks.INTENT, intent.toUri(0)); 1805 values.put(Settings.Bookmarks.TITLE, title); 1806 values.put(Settings.Bookmarks.SHORTCUT, shortcutValue); 1807 db.delete("bookmarks", "shortcut = ?", 1808 new String[] { Integer.toString(shortcutValue) }); 1809 db.insert("bookmarks", null, values); 1810 } 1811 } catch (XmlPullParserException e) { 1812 Log.w(TAG, "Got execption parsing bookmarks.", e); 1813 } catch (IOException e) { 1814 Log.w(TAG, "Got execption parsing bookmarks.", e); 1815 } 1816 } 1817 1818 /** 1819 * Loads the default volume levels. It is actually inserting the index of 1820 * the volume array for each of the volume controls. 1821 * 1822 * @param db the database to insert the volume levels into 1823 */ 1824 private void loadVolumeLevels(SQLiteDatabase db) { 1825 SQLiteStatement stmt = null; 1826 try { 1827 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" 1828 + " VALUES(?,?);"); 1829 1830 loadSetting(stmt, Settings.System.VOLUME_MUSIC, 1831 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]); 1832 loadSetting(stmt, Settings.System.VOLUME_RING, 1833 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]); 1834 loadSetting(stmt, Settings.System.VOLUME_SYSTEM, 1835 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]); 1836 loadSetting( 1837 stmt, 1838 Settings.System.VOLUME_VOICE, 1839 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]); 1840 loadSetting(stmt, Settings.System.VOLUME_ALARM, 1841 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]); 1842 loadSetting( 1843 stmt, 1844 Settings.System.VOLUME_NOTIFICATION, 1845 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]); 1846 loadSetting( 1847 stmt, 1848 Settings.System.VOLUME_BLUETOOTH_SCO, 1849 AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]); 1850 1851 // By default: 1852 // - ringtones, notification, system and music streams are affected by ringer mode 1853 // on non voice capable devices (tablets) 1854 // - ringtones, notification and system streams are affected by ringer mode 1855 // on voice capable devices (phones) 1856 int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) | 1857 (1 << AudioManager.STREAM_NOTIFICATION) | 1858 (1 << AudioManager.STREAM_SYSTEM) | 1859 (1 << AudioManager.STREAM_SYSTEM_ENFORCED); 1860 if (!mContext.getResources().getBoolean( 1861 com.android.internal.R.bool.config_voice_capable)) { 1862 ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC); 1863 } 1864 loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED, 1865 ringerModeAffectedStreams); 1866 1867 loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED, 1868 ((1 << AudioManager.STREAM_MUSIC) | 1869 (1 << AudioManager.STREAM_RING) | 1870 (1 << AudioManager.STREAM_NOTIFICATION) | 1871 (1 << AudioManager.STREAM_SYSTEM))); 1872 } finally { 1873 if (stmt != null) stmt.close(); 1874 } 1875 1876 loadVibrateWhenRingingSetting(db); 1877 } 1878 1879 private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) { 1880 if (deleteOld) { 1881 db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'"); 1882 } 1883 1884 SQLiteStatement stmt = null; 1885 try { 1886 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" 1887 + " VALUES(?,?);"); 1888 1889 // Vibrate on by default for ringer, on for notification 1890 int vibrate = 0; 1891 vibrate = AudioService.getValueForVibrateSetting(vibrate, 1892 AudioManager.VIBRATE_TYPE_NOTIFICATION, 1893 AudioManager.VIBRATE_SETTING_ONLY_SILENT); 1894 vibrate |= AudioService.getValueForVibrateSetting(vibrate, 1895 AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT); 1896 loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate); 1897 } finally { 1898 if (stmt != null) stmt.close(); 1899 } 1900 } 1901 1902 private void loadVibrateWhenRingingSetting(SQLiteDatabase db) { 1903 // The default should be off. VIBRATE_SETTING_ONLY_SILENT should also be ignored here. 1904 // Phone app should separately check whether AudioManager#getRingerMode() returns 1905 // RINGER_MODE_VIBRATE, with which the device should vibrate anyway. 1906 int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON, 1907 AudioManager.VIBRATE_SETTING_OFF); 1908 boolean vibrateWhenRinging = ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_ON); 1909 1910 SQLiteStatement stmt = null; 1911 try { 1912 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" 1913 + " VALUES(?,?);"); 1914 loadSetting(stmt, Settings.System.VIBRATE_WHEN_RINGING, vibrateWhenRinging ? 1 : 0); 1915 } finally { 1916 if (stmt != null) stmt.close(); 1917 } 1918 } 1919 1920 private void loadSettings(SQLiteDatabase db) { 1921 loadSystemSettings(db); 1922 loadSecureSettings(db); 1923 // The global table only exists for the 'owner' user 1924 if (mUserHandle == UserHandle.USER_OWNER) { 1925 loadGlobalSettings(db); 1926 } 1927 } 1928 1929 private void loadSystemSettings(SQLiteDatabase db) { 1930 SQLiteStatement stmt = null; 1931 try { 1932 stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" 1933 + " VALUES(?,?);"); 1934 1935 loadBooleanSetting(stmt, Settings.System.DIM_SCREEN, 1936 R.bool.def_dim_screen); 1937 loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, 1938 R.integer.def_screen_off_timeout); 1939 1940 // Set default cdma DTMF type 1941 loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0); 1942 1943 // Set default hearing aid 1944 loadSetting(stmt, Settings.System.HEARING_AID, 0); 1945 1946 // Set default tty mode 1947 loadSetting(stmt, Settings.System.TTY_MODE, 0); 1948 1949 loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS, 1950 R.integer.def_screen_brightness); 1951 1952 loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE, 1953 R.bool.def_screen_brightness_automatic_mode); 1954 1955 loadDefaultAnimationSettings(stmt); 1956 1957 loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION, 1958 R.bool.def_accelerometer_rotation); 1959 1960 loadDefaultHapticSettings(stmt); 1961 1962 loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE, 1963 R.bool.def_notification_pulse); 1964 1965 loadUISoundEffectsSettings(stmt); 1966 1967 loadIntegerSetting(stmt, Settings.System.POINTER_SPEED, 1968 R.integer.def_pointer_speed); 1969 } finally { 1970 if (stmt != null) stmt.close(); 1971 } 1972 } 1973 1974 private void loadUISoundEffectsSettings(SQLiteStatement stmt) { 1975 loadBooleanSetting(stmt, Settings.System.DTMF_TONE_WHEN_DIALING, 1976 R.bool.def_dtmf_tones_enabled); 1977 loadBooleanSetting(stmt, Settings.System.SOUND_EFFECTS_ENABLED, 1978 R.bool.def_sound_effects_enabled); 1979 loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED, 1980 R.bool.def_haptic_feedback); 1981 1982 loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1983 R.integer.def_lockscreen_sounds_enabled); 1984 } 1985 1986 private void loadDefaultAnimationSettings(SQLiteStatement stmt) { 1987 loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE, 1988 R.fraction.def_window_animation_scale, 1); 1989 loadFractionSetting(stmt, Settings.System.TRANSITION_ANIMATION_SCALE, 1990 R.fraction.def_window_transition_scale, 1); 1991 } 1992 1993 private void loadDefaultHapticSettings(SQLiteStatement stmt) { 1994 loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED, 1995 R.bool.def_haptic_feedback); 1996 } 1997 1998 private void loadSecureSettings(SQLiteDatabase db) { 1999 SQLiteStatement stmt = null; 2000 try { 2001 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" 2002 + " VALUES(?,?);"); 2003 2004 loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 2005 R.string.def_location_providers_allowed); 2006 2007 String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist"); 2008 if (!TextUtils.isEmpty(wifiWatchList)) { 2009 loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList); 2010 } 2011 2012 // Don't do this. The SystemServer will initialize ADB_ENABLED from a 2013 // persistent system property instead. 2014 //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0); 2015 2016 // Allow mock locations default, based on build 2017 loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION, 2018 "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0); 2019 2020 loadSecure35Settings(stmt); 2021 2022 loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND, 2023 R.bool.def_mount_play_notification_snd); 2024 2025 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART, 2026 R.bool.def_mount_ums_autostart); 2027 2028 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT, 2029 R.bool.def_mount_ums_prompt); 2030 2031 loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED, 2032 R.bool.def_mount_ums_notify_enabled); 2033 2034 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 2035 R.bool.def_accessibility_script_injection); 2036 2037 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS, 2038 R.string.def_accessibility_web_content_key_bindings); 2039 2040 loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT, 2041 R.integer.def_long_press_timeout_millis); 2042 2043 loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED, 2044 R.bool.def_touch_exploration_enabled); 2045 2046 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 2047 R.bool.def_accessibility_speak_password); 2048 2049 loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL, 2050 R.string.def_accessibility_screen_reader_url); 2051 2052 if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) { 2053 loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1"); 2054 } else { 2055 loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, 2056 R.bool.def_lockscreen_disabled); 2057 } 2058 2059 loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED, 2060 com.android.internal.R.bool.config_dreamsEnabledByDefault); 2061 loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 2062 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); 2063 loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 2064 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault); 2065 loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS, 2066 com.android.internal.R.string.config_dreamsDefaultComponent); 2067 loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, 2068 com.android.internal.R.string.config_dreamsDefaultComponent); 2069 2070 loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 2071 R.bool.def_accessibility_display_magnification_enabled); 2072 2073 loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2074 R.fraction.def_accessibility_display_magnification_scale, 1); 2075 2076 loadBooleanSetting(stmt, 2077 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE, 2078 R.bool.def_accessibility_display_magnification_auto_update); 2079 2080 loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE, 2081 R.bool.def_user_setup_complete); 2082 } finally { 2083 if (stmt != null) stmt.close(); 2084 } 2085 } 2086 2087 private void loadSecure35Settings(SQLiteStatement stmt) { 2088 loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED, 2089 R.bool.def_backup_enabled); 2090 2091 loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT, 2092 R.string.def_backup_transport); 2093 } 2094 2095 private void loadGlobalSettings(SQLiteDatabase db) { 2096 SQLiteStatement stmt = null; 2097 try { 2098 stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)" 2099 + " VALUES(?,?);"); 2100 2101 // --- Previously in 'system' 2102 loadBooleanSetting(stmt, Settings.Global.AIRPLANE_MODE_ON, 2103 R.bool.def_airplane_mode_on); 2104 2105 loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_RADIOS, 2106 R.string.def_airplane_mode_radios); 2107 2108 loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS, 2109 R.string.airplane_mode_toggleable_radios); 2110 2111 loadBooleanSetting(stmt, Settings.Global.ASSISTED_GPS_ENABLED, 2112 R.bool.assisted_gps_enabled); 2113 2114 loadBooleanSetting(stmt, Settings.Global.AUTO_TIME, 2115 R.bool.def_auto_time); // Sync time to NITZ 2116 2117 loadBooleanSetting(stmt, Settings.Global.AUTO_TIME_ZONE, 2118 R.bool.def_auto_time_zone); // Sync timezone to NITZ 2119 2120 loadSetting(stmt, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 2121 ("1".equals(SystemProperties.get("ro.kernel.qemu")) || 2122 mContext.getResources().getBoolean(R.bool.def_stay_on_while_plugged_in)) 2123 ? 1 : 0); 2124 2125 loadIntegerSetting(stmt, Settings.Global.WIFI_SLEEP_POLICY, 2126 R.integer.def_wifi_sleep_policy); 2127 2128 loadSetting(stmt, Settings.Global.MODE_RINGER, 2129 AudioManager.RINGER_MODE_NORMAL); 2130 2131 // --- Previously in 'secure' 2132 loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE, 2133 R.bool.def_package_verifier_enable); 2134 2135 loadBooleanSetting(stmt, Settings.Global.WIFI_ON, 2136 R.bool.def_wifi_on); 2137 2138 loadBooleanSetting(stmt, Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 2139 R.bool.def_networks_available_notification_on); 2140 2141 loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_ON, 2142 R.bool.def_bluetooth_on); 2143 2144 // Enable or disable Cell Broadcast SMS 2145 loadSetting(stmt, Settings.Global.CDMA_CELL_BROADCAST_SMS, 2146 RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED); 2147 2148 // Data roaming default, based on build 2149 loadSetting(stmt, Settings.Global.DATA_ROAMING, 2150 "true".equalsIgnoreCase( 2151 SystemProperties.get("ro.com.android.dataroaming", 2152 "false")) ? 1 : 0); 2153 2154 loadBooleanSetting(stmt, Settings.Global.DEVICE_PROVISIONED, 2155 R.bool.def_device_provisioned); 2156 2157 final int maxBytes = mContext.getResources().getInteger( 2158 R.integer.def_download_manager_max_bytes_over_mobile); 2159 if (maxBytes > 0) { 2160 loadSetting(stmt, Settings.Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE, 2161 Integer.toString(maxBytes)); 2162 } 2163 2164 final int recommendedMaxBytes = mContext.getResources().getInteger( 2165 R.integer.def_download_manager_recommended_max_bytes_over_mobile); 2166 if (recommendedMaxBytes > 0) { 2167 loadSetting(stmt, Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE, 2168 Integer.toString(recommendedMaxBytes)); 2169 } 2170 2171 // Mobile Data default, based on build 2172 loadSetting(stmt, Settings.Global.MOBILE_DATA, 2173 "true".equalsIgnoreCase( 2174 SystemProperties.get("ro.com.android.mobiledata", 2175 "true")) ? 1 : 0); 2176 2177 loadBooleanSetting(stmt, Settings.Global.NETSTATS_ENABLED, 2178 R.bool.def_netstats_enabled); 2179 2180 loadBooleanSetting(stmt, Settings.Global.INSTALL_NON_MARKET_APPS, 2181 R.bool.def_install_non_market_apps); 2182 2183 loadIntegerSetting(stmt, Settings.Global.NETWORK_PREFERENCE, 2184 R.integer.def_network_preference); 2185 2186 loadBooleanSetting(stmt, Settings.Global.USB_MASS_STORAGE_ENABLED, 2187 R.bool.def_usb_mass_storage_enabled); 2188 2189 loadIntegerSetting(stmt, Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT, 2190 R.integer.def_max_dhcp_retries); 2191 2192 loadBooleanSetting(stmt, Settings.Global.WIFI_DISPLAY_ON, 2193 R.bool.def_wifi_display_on); 2194 2195 loadStringSetting(stmt, Settings.Global.LOCK_SOUND, 2196 R.string.def_lock_sound); 2197 loadStringSetting(stmt, Settings.Global.UNLOCK_SOUND, 2198 R.string.def_unlock_sound); 2199 loadIntegerSetting(stmt, Settings.Global.POWER_SOUNDS_ENABLED, 2200 R.integer.def_power_sounds_enabled); 2201 loadStringSetting(stmt, Settings.Global.LOW_BATTERY_SOUND, 2202 R.string.def_low_battery_sound); 2203 loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED, 2204 R.integer.def_dock_sounds_enabled); 2205 loadStringSetting(stmt, Settings.Global.DESK_DOCK_SOUND, 2206 R.string.def_desk_dock_sound); 2207 loadStringSetting(stmt, Settings.Global.DESK_UNDOCK_SOUND, 2208 R.string.def_desk_undock_sound); 2209 loadStringSetting(stmt, Settings.Global.CAR_DOCK_SOUND, 2210 R.string.def_car_dock_sound); 2211 loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND, 2212 R.string.def_car_undock_sound); 2213 loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND, 2214 R.string.def_wireless_charging_started_sound); 2215 2216 loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0); 2217 loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION, 2218 PackageHelper.APP_INSTALL_AUTO); 2219 2220 // Set default cdma emergency tone 2221 loadSetting(stmt, Settings.Global.EMERGENCY_TONE, 0); 2222 2223 // Set default cdma call auto retry 2224 loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0); 2225 2226 // Set the preferred network mode to 0 = Global, CDMA default 2227 int type; 2228 if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) { 2229 type = Phone.NT_MODE_GLOBAL; 2230 } else { 2231 type = SystemProperties.getInt("ro.telephony.default_network", 2232 RILConstants.PREFERRED_NETWORK_MODE); 2233 } 2234 loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type); 2235 2236 // --- New global settings start here 2237 } finally { 2238 if (stmt != null) stmt.close(); 2239 } 2240 } 2241 2242 private void loadSetting(SQLiteStatement stmt, String key, Object value) { 2243 stmt.bindString(1, key); 2244 stmt.bindString(2, value.toString()); 2245 stmt.execute(); 2246 } 2247 2248 private void loadStringSetting(SQLiteStatement stmt, String key, int resid) { 2249 loadSetting(stmt, key, mContext.getResources().getString(resid)); 2250 } 2251 2252 private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) { 2253 loadSetting(stmt, key, 2254 mContext.getResources().getBoolean(resid) ? "1" : "0"); 2255 } 2256 2257 private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) { 2258 loadSetting(stmt, key, 2259 Integer.toString(mContext.getResources().getInteger(resid))); 2260 } 2261 2262 private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) { 2263 loadSetting(stmt, key, 2264 Float.toString(mContext.getResources().getFraction(resid, base, base))); 2265 } 2266 2267 private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) { 2268 return getIntValueFromTable(db, TABLE_SYSTEM, name, defaultValue); 2269 } 2270 2271 private int getIntValueFromTable(SQLiteDatabase db, String table, String name, 2272 int defaultValue) { 2273 String value = getStringValueFromTable(db, table, name, null); 2274 return (value != null) ? Integer.parseInt(value) : defaultValue; 2275 } 2276 2277 private String getStringValueFromTable(SQLiteDatabase db, String table, String name, 2278 String defaultValue) { 2279 Cursor c = null; 2280 try { 2281 c = db.query(table, new String[] { Settings.System.VALUE }, "name='" + name + "'", 2282 null, null, null, null); 2283 if (c != null && c.moveToFirst()) { 2284 String val = c.getString(0); 2285 return val == null ? defaultValue : val; 2286 } 2287 } finally { 2288 if (c != null) c.close(); 2289 } 2290 return defaultValue; 2291 } 2292} 2293