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