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