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