/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.providers.settings;

import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.media.AudioSystem;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Environment;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.Log;

import com.android.ims.ImsConfig;
import com.android.internal.content.PackageHelper;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Legacy settings database helper class for {@link SettingsProvider}.
 *
 * IMPORTANT: Do not add any more upgrade steps here as the global,
 * secure, and system settings are no longer stored in a database
 * but are kept in memory and persisted to XML.
 *
 * See: SettingsProvider.UpgradeController#onUpgradeLocked
 *
 * @deprecated The implementation is frozen.  Do not add any new code to this class!
 */
@Deprecated
class DatabaseHelper extends SQLiteOpenHelper {
    private static final String TAG = "SettingsProvider";
    private static final String DATABASE_NAME = "settings.db";

    // Please, please please. If you update the database version, check to make sure the
    // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
    // is properly propagated through your change.  Not doing so will result in a loss of user
    // settings.
    private static final int DATABASE_VERSION = 118;

    private Context mContext;
    private int mUserHandle;

    private static final HashSet<String> mValidTables = new HashSet<String>();

    private static final String DATABASE_JOURNAL_SUFFIX = "-journal";
    private static final String DATABASE_BACKUP_SUFFIX = "-backup";

    private static final String TABLE_SYSTEM = "system";
    private static final String TABLE_SECURE = "secure";
    private static final String TABLE_GLOBAL = "global";

    static {
        mValidTables.add(TABLE_SYSTEM);
        mValidTables.add(TABLE_SECURE);
        mValidTables.add(TABLE_GLOBAL);

        // These are old.
        mValidTables.add("bluetooth_devices");
        mValidTables.add("bookmarks");
        mValidTables.add("favorites");
        mValidTables.add("old_favorites");
        mValidTables.add("android_metadata");
    }

    static String dbNameForUser(final int userHandle) {
        // The owner gets the unadorned db name;
        if (userHandle == UserHandle.USER_SYSTEM) {
            return DATABASE_NAME;
        } else {
            // Place the database in the user-specific data tree so that it's
            // cleaned up automatically when the user is deleted.
            File databaseFile = new File(
                    Environment.getUserSystemDirectory(userHandle), DATABASE_NAME);
            // If databaseFile doesn't exist, database can be kept in memory. It's safe because the
            // database will be migrated and disposed of immediately after onCreate finishes
            if (!databaseFile.exists()) {
                Log.i(TAG, "No previous database file exists - running in in-memory mode");
                return null;
            }
            return databaseFile.getPath();
        }
    }

    public DatabaseHelper(Context context, int userHandle) {
        super(context, dbNameForUser(userHandle), null, DATABASE_VERSION);
        mContext = context;
        mUserHandle = userHandle;
    }

    public static boolean isValidTable(String name) {
        return mValidTables.contains(name);
    }

    private boolean isInMemory() {
        return getDatabaseName() == null;
    }

    public void dropDatabase() {
        close();
        // No need to remove files if db is in memory
        if (isInMemory()) {
            return;
        }
        File databaseFile = mContext.getDatabasePath(getDatabaseName());
        if (databaseFile.exists()) {
            databaseFile.delete();
        }
        File databaseJournalFile = mContext.getDatabasePath(getDatabaseName()
                + DATABASE_JOURNAL_SUFFIX);
        if (databaseJournalFile.exists()) {
            databaseJournalFile.delete();
        }
    }

    public void backupDatabase() {
        close();
        // No need to backup files if db is in memory
        if (isInMemory()) {
            return;
        }
        File databaseFile = mContext.getDatabasePath(getDatabaseName());
        if (!databaseFile.exists()) {
            return;
        }
        File backupFile = mContext.getDatabasePath(getDatabaseName()
                + DATABASE_BACKUP_SUFFIX);
        if (backupFile.exists()) {
            return;
        }
        databaseFile.renameTo(backupFile);
    }

    private void createSecureTable(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE secure (" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                "name TEXT UNIQUE ON CONFLICT REPLACE," +
                "value TEXT" +
                ");");
        db.execSQL("CREATE INDEX secureIndex1 ON secure (name);");
    }

    private void createGlobalTable(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE global (" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                "name TEXT UNIQUE ON CONFLICT REPLACE," +
                "value TEXT" +
                ");");
        db.execSQL("CREATE INDEX globalIndex1 ON global (name);");
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE system (" +
                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                    "name TEXT UNIQUE ON CONFLICT REPLACE," +
                    "value TEXT" +
                    ");");
        db.execSQL("CREATE INDEX systemIndex1 ON system (name);");

        createSecureTable(db);

        // Only create the global table for the singleton 'owner/system' user
        if (mUserHandle == UserHandle.USER_SYSTEM) {
            createGlobalTable(db);
        }

        db.execSQL("CREATE TABLE bluetooth_devices (" +
                    "_id INTEGER PRIMARY KEY," +
                    "name TEXT," +
                    "addr TEXT," +
                    "channel INTEGER," +
                    "type INTEGER" +
                    ");");

        db.execSQL("CREATE TABLE bookmarks (" +
                    "_id INTEGER PRIMARY KEY," +
                    "title TEXT," +
                    "folder TEXT," +
                    "intent TEXT," +
                    "shortcut INTEGER," +
                    "ordering INTEGER" +
                    ");");

        db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);");
        db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);");

        // Populate bookmarks table with initial bookmarks
        boolean onlyCore = false;
        try {
            onlyCore = IPackageManager.Stub.asInterface(ServiceManager.getService(
                    "package")).isOnlyCoreApps();
        } catch (RemoteException e) {
        }
        if (!onlyCore) {
            loadBookmarks(db);
        }

        // Load initial volume levels into DB
        loadVolumeLevels(db);

        // Load inital settings values
        loadSettings(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
        Log.w(TAG, "Upgrading settings database from version " + oldVersion + " to "
                + currentVersion);

        int upgradeVersion = oldVersion;

        // Pattern for upgrade blocks:
        //
        //    if (upgradeVersion == [the DATABASE_VERSION you set] - 1) {
        //        .. your upgrade logic..
        //        upgradeVersion = [the DATABASE_VERSION you set]
        //    }

        if (upgradeVersion == 20) {
            /*
             * Version 21 is part of the volume control refresh. There is no
             * longer a UI-visible for setting notification vibrate on/off (in
             * our design), but the functionality still exists. Force the
             * notification vibrate to on.
             */
            loadVibrateSetting(db, true);

            upgradeVersion = 21;
        }

        if (upgradeVersion < 22) {
            upgradeVersion = 22;
            // Upgrade the lock gesture storage location and format
            upgradeLockPatternLocation(db);
        }

        if (upgradeVersion < 23) {
            db.execSQL("UPDATE favorites SET iconResource=0 WHERE iconType=0");
            upgradeVersion = 23;
        }

        if (upgradeVersion == 23) {
            db.beginTransaction();
            try {
                db.execSQL("ALTER TABLE favorites ADD spanX INTEGER");
                db.execSQL("ALTER TABLE favorites ADD spanY INTEGER");
                // Shortcuts, applications, folders
                db.execSQL("UPDATE favorites SET spanX=1, spanY=1 WHERE itemType<=0");
                // Photo frames, clocks
                db.execSQL(
                    "UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
                // Search boxes
                db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 24;
        }

        if (upgradeVersion == 24) {
            db.beginTransaction();
            try {
                // The value of the constants for preferring wifi or preferring mobile have been
                // swapped, so reload the default.
                db.execSQL("DELETE FROM system WHERE name='network_preference'");
                db.execSQL("INSERT INTO system ('name', 'value') values ('network_preference', '" +
                        ConnectivityManager.DEFAULT_NETWORK_PREFERENCE + "')");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 25;
        }

        if (upgradeVersion == 25) {
            db.beginTransaction();
            try {
                db.execSQL("ALTER TABLE favorites ADD uri TEXT");
                db.execSQL("ALTER TABLE favorites ADD displayMode INTEGER");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 26;
        }

        if (upgradeVersion == 26) {
            // This introduces the new secure settings table.
            db.beginTransaction();
            try {
                createSecureTable(db);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 27;
        }

        if (upgradeVersion == 27) {
            String[] settingsToMove = {
                    Settings.Secure.ADB_ENABLED,
                    Settings.Secure.ANDROID_ID,
                    Settings.Secure.BLUETOOTH_ON,
                    Settings.Secure.DATA_ROAMING,
                    Settings.Secure.DEVICE_PROVISIONED,
                    Settings.Secure.HTTP_PROXY,
                    Settings.Secure.INSTALL_NON_MARKET_APPS,
                    Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                    Settings.Secure.LOGGING_ID,
                    Settings.Secure.NETWORK_PREFERENCE,
                    Settings.Secure.PARENTAL_CONTROL_ENABLED,
                    Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
                    Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
                    Settings.Secure.SETTINGS_CLASSNAME,
                    Settings.Secure.USB_MASS_STORAGE_ENABLED,
                    Settings.Secure.USE_GOOGLE_MAIL,
                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
                    Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT,
                    Settings.Secure.WIFI_ON,
                    Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE,
                    Settings.Secure.WIFI_WATCHDOG_AP_COUNT,
                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS,
                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED,
                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS,
                    Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT,
                    Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS,
                    Settings.Secure.WIFI_WATCHDOG_ON,
                    Settings.Secure.WIFI_WATCHDOG_PING_COUNT,
                    Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS,
                    Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS,
                };
            moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false);
            upgradeVersion = 28;
        }

        if (upgradeVersion == 28 || upgradeVersion == 29) {
            // Note: The upgrade to 28 was flawed since it didn't delete the old
            // setting first before inserting. Combining 28 and 29 with the
            // fixed version.

            // This upgrade adds the STREAM_NOTIFICATION type to the list of
            // types affected by ringer modes (silent, vibrate, etc.)
            db.beginTransaction();
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
                int newValue = (1 << AudioManager.STREAM_RING)
                        | (1 << AudioManager.STREAM_NOTIFICATION)
                        | (1 << AudioManager.STREAM_SYSTEM);
                db.execSQL("INSERT INTO system ('name', 'value') values ('"
                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
                        + String.valueOf(newValue) + "')");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }

            upgradeVersion = 30;
        }

        if (upgradeVersion == 30) {
            /*
             * Upgrade 31 clears the title for all quick launch shortcuts so the
             * activities' titles will be resolved at display time. Also, the
             * folder is changed to '@quicklaunch'.
             */
            db.beginTransaction();
            try {
                db.execSQL("UPDATE bookmarks SET folder = '@quicklaunch'");
                db.execSQL("UPDATE bookmarks SET title = ''");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 31;
        }

        if (upgradeVersion == 31) {
            /*
             * Animations are now managed in preferences, and may be
             * enabled or disabled based on product resources.
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadDefaultAnimationSettings(stmt);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 32;
        }

        if (upgradeVersion == 32) {
            // The Wi-Fi watchdog SSID list is now seeded with the value of
            // the property ro.com.android.wifi-watchlist
            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
            if (!TextUtils.isEmpty(wifiWatchList)) {
                db.beginTransaction();
                try {
                    db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
                            Settings.Secure.WIFI_WATCHDOG_WATCH_LIST + "','" +
                            wifiWatchList + "');");
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 33;
        }

        if (upgradeVersion == 33) {
            // Set the default zoom controls to: tap-twice to bring up +/-
            db.beginTransaction();
            try {
                db.execSQL("INSERT INTO system(name,value) values('zoom','2');");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 34;
        }

        if (upgradeVersion == 34) {
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadSecure35Settings(stmt);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 35;
        }
            // due to a botched merge from donut to eclair, the initialization of ASSISTED_GPS_ENABLED
            // was accidentally done out of order here.
            // to fix this, ASSISTED_GPS_ENABLED is now initialized while upgrading from 38 to 39,
            // and we intentionally do nothing from 35 to 36 now.
        if (upgradeVersion == 35) {
            upgradeVersion = 36;
        }

        if (upgradeVersion == 36) {
           // This upgrade adds the STREAM_SYSTEM_ENFORCED type to the list of
            // types affected by ringer modes (silent, vibrate, etc.)
            db.beginTransaction();
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
                int newValue = (1 << AudioManager.STREAM_RING)
                        | (1 << AudioManager.STREAM_NOTIFICATION)
                        | (1 << AudioManager.STREAM_SYSTEM)
                        | (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
                db.execSQL("INSERT INTO system ('name', 'value') values ('"
                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
                        + String.valueOf(newValue) + "')");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 37;
        }

        if (upgradeVersion == 37) {
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                        + " VALUES(?,?);");
                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
                        R.string.airplane_mode_toggleable_radios);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 38;
        }

        if (upgradeVersion == 38) {
            db.beginTransaction();
            try {
                String value =
                        mContext.getResources().getBoolean(R.bool.assisted_gps_enabled) ? "1" : "0";
                db.execSQL("INSERT OR IGNORE INTO secure(name,value) values('" +
                        Settings.Global.ASSISTED_GPS_ENABLED + "','" + value + "');");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }

            upgradeVersion = 39;
        }

        if (upgradeVersion == 39) {
            upgradeAutoBrightness(db);
            upgradeVersion = 40;
        }

        if (upgradeVersion == 40) {
            /*
             * All animations are now turned on by default!
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadDefaultAnimationSettings(stmt);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 41;
        }

        if (upgradeVersion == 41) {
            /*
             * Initialize newly public haptic feedback setting
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'");
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadDefaultHapticSettings(stmt);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 42;
        }

        if (upgradeVersion == 42) {
            /*
             * Initialize new notification pulse setting
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                        R.bool.def_notification_pulse);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 43;
        }

        if (upgradeVersion == 43) {
            /*
             * This upgrade stores bluetooth volume separately from voice volume
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                        + " VALUES(?,?);");
                loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO,
                        AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO));
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 44;
        }

        if (upgradeVersion == 44) {
            /*
             * Gservices was moved into vendor/google.
             */
            db.execSQL("DROP TABLE IF EXISTS gservices");
            db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
            upgradeVersion = 45;
        }

        if (upgradeVersion == 45) {
             /*
              * New settings for MountService
              */
            db.beginTransaction();
            try {
                db.execSQL("INSERT INTO secure(name,value) values('" +
                        Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND + "','1');");
                db.execSQL("INSERT INTO secure(name,value) values('" +
                        Settings.Secure.MOUNT_UMS_AUTOSTART + "','0');");
                db.execSQL("INSERT INTO secure(name,value) values('" +
                        Settings.Secure.MOUNT_UMS_PROMPT + "','1');");
                db.execSQL("INSERT INTO secure(name,value) values('" +
                        Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED + "','1');");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 46;
        }

        if (upgradeVersion == 46) {
            /*
             * The password mode constants have changed; reset back to no
             * password.
             */
            db.beginTransaction();
            try {
                db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
           upgradeVersion = 47;
       }


        if (upgradeVersion == 47) {
            /*
             * The password mode constants have changed again; reset back to no
             * password.
             */
            db.beginTransaction();
            try {
                db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
           upgradeVersion = 48;
       }

       if (upgradeVersion == 48) {
           /*
            * Default recognition service no longer initialized here,
            * moved to RecognitionManagerService.
            */
           upgradeVersion = 49;
       }

       if (upgradeVersion == 49) {
           /*
            * New settings for new user interface noises.
            */
           db.beginTransaction();
           SQLiteStatement stmt = null;
           try {
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadUISoundEffectsSettings(stmt);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }

           upgradeVersion = 50;
       }

       if (upgradeVersion == 50) {
           /*
            * Install location no longer initiated here.
            */
           upgradeVersion = 51;
       }

       if (upgradeVersion == 51) {
           /* Move the lockscreen related settings to Secure, including some private ones. */
           String[] settingsToMove = {
                   Secure.LOCK_PATTERN_ENABLED,
                   Secure.LOCK_PATTERN_VISIBLE,
                   Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
                   "lockscreen.password_type",
                   "lockscreen.lockoutattemptdeadline",
                   "lockscreen.patterneverchosen",
                   "lock_pattern_autolock",
                   "lockscreen.lockedoutpermanently",
                   "lockscreen.password_salt"
           };
           moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false);
           upgradeVersion = 52;
       }

        if (upgradeVersion == 52) {
            // new vibration/silent mode settings
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
                        R.bool.def_vibrate_in_silent);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }

            upgradeVersion = 53;
        }

        if (upgradeVersion == 53) {
            /*
             * New settings for set install location UI no longer initiated here.
             */
            upgradeVersion = 54;
        }

        if (upgradeVersion == 54) {
            /*
             * Update the screen timeout value if set to never
             */
            db.beginTransaction();
            try {
                upgradeScreenTimeoutFromNever(db);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }

            upgradeVersion = 55;
        }

        if (upgradeVersion == 55) {
            /* Move the install location settings. */
            String[] settingsToMove = {
                    Global.SET_INSTALL_LOCATION,
                    Global.DEFAULT_INSTALL_LOCATION
            };
            moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, settingsToMove, false);
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadSetting(stmt, Global.SET_INSTALL_LOCATION, 0);
                loadSetting(stmt, Global.DEFAULT_INSTALL_LOCATION,
                        PackageHelper.APP_INSTALL_AUTO);
                db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
                 if (stmt != null) stmt.close();
             }
            upgradeVersion = 56;
        }

        if (upgradeVersion == 56) {
            /*
             * Add Bluetooth to list of toggleable radios in airplane mode
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                        + " VALUES(?,?);");
                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
                        R.string.airplane_mode_toggleable_radios);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 57;
        }

        /************* The following are Honeycomb changes ************/

        if (upgradeVersion == 57) {
            /*
             * New settings to:
             *  1. Enable injection of accessibility scripts in WebViews.
             *  2. Define the key bindings for traversing web content in WebViews.
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
                        R.bool.def_accessibility_script_injection);
                stmt.close();
                stmt = db.compileStatement("INSERT INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
                        R.string.def_accessibility_web_content_key_bindings);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 58;
        }

        if (upgradeVersion == 58) {
            /* Add default for new Auto Time Zone */
            int autoTimeValue = getIntValueFromSystem(db, Settings.System.AUTO_TIME, 0);
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);");
                loadSetting(stmt, Settings.System.AUTO_TIME_ZONE,
                        autoTimeValue); // Sync timezone to NITZ if auto_time was enabled
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 59;
        }

        if (upgradeVersion == 59) {
            // Persistence for the rotation lock feature.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.System.USER_ROTATION,
                        R.integer.def_user_rotation); // should be zero degrees
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 60;
        }

        if (upgradeVersion == 60) {
            // Don't do this for upgrades from Gingerbread
            // Were only required for intra-Honeycomb upgrades for testing
            // upgradeScreenTimeout(db);
            upgradeVersion = 61;
        }

        if (upgradeVersion == 61) {
            // Don't do this for upgrades from Gingerbread
            // Were only required for intra-Honeycomb upgrades for testing
            // upgradeScreenTimeout(db);
            upgradeVersion = 62;
        }

        // Change the default for screen auto-brightness mode
        if (upgradeVersion == 62) {
            // Don't do this for upgrades from Gingerbread
            // Were only required for intra-Honeycomb upgrades for testing
            // upgradeAutoBrightness(db);
            upgradeVersion = 63;
        }

        if (upgradeVersion == 63) {
            // This upgrade adds the STREAM_MUSIC type to the list of
             // types affected by ringer modes (silent, vibrate, etc.)
             db.beginTransaction();
             try {
                 db.execSQL("DELETE FROM system WHERE name='"
                         + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
                 int newValue = (1 << AudioManager.STREAM_RING)
                         | (1 << AudioManager.STREAM_NOTIFICATION)
                         | (1 << AudioManager.STREAM_SYSTEM)
                         | (1 << AudioManager.STREAM_SYSTEM_ENFORCED)
                         | (1 << AudioManager.STREAM_MUSIC);
                 db.execSQL("INSERT INTO system ('name', 'value') values ('"
                         + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
                         + String.valueOf(newValue) + "')");
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
             }
             upgradeVersion = 64;
         }

        if (upgradeVersion == 64) {
            // New setting to configure the long press timeout.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
                        R.integer.def_long_press_timeout_millis);
                stmt.close();
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 65;
        }

        /************* The following are Ice Cream Sandwich changes ************/

        if (upgradeVersion == 65) {
            /*
             * Animations are removed from Settings. Turned on by default
             */
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
                stmt = db.compileStatement("INSERT INTO system(name,value)"
                        + " VALUES(?,?);");
                loadDefaultAnimationSettings(stmt);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 66;
        }

        if (upgradeVersion == 66) {
            // This upgrade makes sure that MODE_RINGER_STREAMS_AFFECTED is set
            // according to device voice capability
            db.beginTransaction();
            try {
                int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
                                                (1 << AudioManager.STREAM_NOTIFICATION) |
                                                (1 << AudioManager.STREAM_SYSTEM) |
                                                (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
                if (!mContext.getResources().getBoolean(
                        com.android.internal.R.bool.config_voice_capable)) {
                    ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
                }
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
                db.execSQL("INSERT INTO system ('name', 'value') values ('"
                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
                        + String.valueOf(ringerModeAffectedStreams) + "')");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 67;
        }

        if (upgradeVersion == 67) {
            // New setting to enable touch exploration.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
                        R.bool.def_touch_exploration_enabled);
                stmt.close();
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 68;
        }

        if (upgradeVersion == 68) {
            // Enable all system sounds by default
            db.beginTransaction();
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                        + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "'");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 69;
        }

        if (upgradeVersion == 69) {
            // Add RADIO_NFC to AIRPLANE_MODE_RADIO and AIRPLANE_MODE_TOGGLEABLE_RADIOS
            String airplaneRadios = mContext.getResources().getString(
                    R.string.def_airplane_mode_radios);
            String toggleableRadios = mContext.getResources().getString(
                    R.string.airplane_mode_toggleable_radios);
            db.beginTransaction();
            try {
                db.execSQL("UPDATE system SET value='" + airplaneRadios + "' " +
                        "WHERE name='" + Settings.System.AIRPLANE_MODE_RADIOS + "'");
                db.execSQL("UPDATE system SET value='" + toggleableRadios + "' " +
                        "WHERE name='" + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 70;
        }

        if (upgradeVersion == 70) {
            // Update all built-in bookmarks.  Some of the package names have changed.
            loadBookmarks(db);
            upgradeVersion = 71;
        }

        if (upgradeVersion == 71) {
             // New setting to specify whether to speak passwords in accessibility mode.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
                        R.bool.def_accessibility_speak_password);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 72;
        }

        if (upgradeVersion == 72) {
            // update vibration settings
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
                        R.bool.def_vibrate_in_silent);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 73;
        }

        if (upgradeVersion == 73) {
            upgradeVibrateSettingFromNone(db);
            upgradeVersion = 74;
        }

        if (upgradeVersion == 74) {
            // URL from which WebView loads a JavaScript based screen-reader.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
                        R.string.def_accessibility_screen_reader_url);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 75;
        }
        if (upgradeVersion == 75) {
            db.beginTransaction();
            SQLiteStatement stmt = null;
            Cursor c = null;
            try {
                c = db.query(TABLE_SECURE, new String[] {"_id", "value"},
                        "name='lockscreen.disabled'",
                        null, null, null, null);
                // only set default if it has not yet been set
                if (c == null || c.getCount() == 0) {
                    stmt = db.compileStatement("INSERT INTO system(name,value)"
                            + " VALUES(?,?);");
                    loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
                            R.bool.def_lockscreen_disabled);
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (c != null) c.close();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 76;
        }

        /************* The following are Jelly Bean changes ************/

        if (upgradeVersion == 76) {
            // Removed VIBRATE_IN_SILENT setting
            db.beginTransaction();
            try {
                db.execSQL("DELETE FROM system WHERE name='"
                                + Settings.System.VIBRATE_IN_SILENT + "'");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }

            upgradeVersion = 77;
        }

        if (upgradeVersion == 77) {
            // Introduce "vibrate when ringing" setting
            loadVibrateWhenRingingSetting(db);

            upgradeVersion = 78;
        }

        if (upgradeVersion == 78) {
            // The JavaScript based screen-reader URL changes in JellyBean.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
                        R.string.def_accessibility_screen_reader_url);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 79;
        }

        if (upgradeVersion == 79) {
            // Before touch exploration was a global setting controlled by the user
            // via the UI. However, if the enabled accessibility services do not
            // handle touch exploration mode, enabling it makes no sense. Therefore,
            // now the services request touch exploration mode and the user is
            // presented with a dialog to allow that and if she does we store that
            // in the database. As a result of this change a user that has enabled
            // accessibility, touch exploration, and some accessibility services
            // may lose touch exploration state, thus rendering the device useless
            // unless sighted help is provided, since the enabled service(s) are
            // not in the list of services to which the user granted a permission
            // to put the device in touch explore mode. Here we are allowing all
            // enabled accessibility services to toggle touch exploration provided
            // accessibility and touch exploration are enabled and no services can
            // toggle touch exploration. Note that the user has already manually
            // enabled the services and touch exploration which means the she has
            // given consent to have these services work in touch exploration mode.
            final boolean accessibilityEnabled = getIntValueFromTable(db, TABLE_SECURE,
                    Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
            final boolean touchExplorationEnabled = getIntValueFromTable(db, TABLE_SECURE,
                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
            if (accessibilityEnabled && touchExplorationEnabled) {
                String enabledServices = getStringValueFromTable(db, TABLE_SECURE,
                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
                String touchExplorationGrantedServices = getStringValueFromTable(db, TABLE_SECURE,
                        Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, "");
                if (TextUtils.isEmpty(touchExplorationGrantedServices)
                        && !TextUtils.isEmpty(enabledServices)) {
                    SQLiteStatement stmt = null;
                    try {
                        db.beginTransaction();
                        stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
                                + " VALUES(?,?);");
                        loadSetting(stmt,
                                Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
                                enabledServices);
                        db.setTransactionSuccessful();
                    } finally {
                        db.endTransaction();
                        if (stmt != null) stmt.close();
                    }
                }
            }
            upgradeVersion = 80;
        }

        // vvv Jelly Bean MR1 changes begin here vvv

        if (upgradeVersion == 80) {
            // update screensaver settings
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED,
                        com.android.internal.R.bool.config_dreamsEnabledByDefault);
                loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
                        com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
                loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
                        com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
                loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS,
                        com.android.internal.R.string.config_dreamsDefaultComponent);
                loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
                        com.android.internal.R.string.config_dreamsDefaultComponent);

                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 81;
        }

        if (upgradeVersion == 81) {
            // Add package verification setting
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE,
                        R.bool.def_package_verifier_enable);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 82;
        }

        if (upgradeVersion == 82) {
            // Move to per-user settings dbs
            if (mUserHandle == UserHandle.USER_SYSTEM) {

                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    // Migrate now-global settings. Note that this happens before
                    // new users can be created.
                    createGlobalTable(db);
                    String[] settingsToMove = setToStringArray(
                            SettingsProvider.sSystemMovedToGlobalSettings);
                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, false);
                    settingsToMove = setToStringArray(
                            SettingsProvider.sSecureMovedToGlobalSettings);
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, false);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 83;
        }

        if (upgradeVersion == 83) {
            // 1. Setting whether screen magnification is enabled.
            // 2. Setting for screen magnification scale.
            // 3. Setting for screen magnification auto update.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
                loadBooleanSetting(stmt,
                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
                        R.bool.def_accessibility_display_magnification_enabled);
                stmt.close();
                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
                loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
                        R.fraction.def_accessibility_display_magnification_scale, 1);
                stmt.close();
                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
                loadBooleanSetting(stmt,
                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
                        R.bool.def_accessibility_display_magnification_auto_update);

                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 84;
        }

        if (upgradeVersion == 84) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    // Patch up the slightly-wrong key migration from 82 -> 83 for those
                    // devices that missed it, ignoring if the move is redundant
                    String[] settingsToMove = {
                            Settings.Secure.ADB_ENABLED,
                            Settings.Secure.BLUETOOTH_ON,
                            Settings.Secure.DATA_ROAMING,
                            Settings.Secure.DEVICE_PROVISIONED,
                            Settings.Secure.INSTALL_NON_MARKET_APPS,
                            Settings.Secure.USB_MASS_STORAGE_ENABLED
                    };
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 85;
        }

        if (upgradeVersion == 85) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    // Fix up the migration, ignoring already-migrated elements, to snap up to
                    // date with new changes to the set of global versus system/secure settings
                    String[] settingsToMove = { Settings.System.STAY_ON_WHILE_PLUGGED_IN };
                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 86;
        }

        if (upgradeVersion == 86) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    String[] settingsToMove = {
                            Settings.Global.PACKAGE_VERIFIER_ENABLE,
                            Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
                            Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE
                    };
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 87;
        }

        if (upgradeVersion == 87) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    String[] settingsToMove = {
                            Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
                            Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
                            Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS
                    };
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 88;
        }

        if (upgradeVersion == 88) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    String[] settingsToMove = {
                            Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD,
                            Settings.Global.BATTERY_DISCHARGE_THRESHOLD,
                            Settings.Global.SEND_ACTION_APP_ERROR,
                            Settings.Global.DROPBOX_AGE_SECONDS,
                            Settings.Global.DROPBOX_MAX_FILES,
                            Settings.Global.DROPBOX_QUOTA_KB,
                            Settings.Global.DROPBOX_QUOTA_PERCENT,
                            Settings.Global.DROPBOX_RESERVE_PERCENT,
                            Settings.Global.DROPBOX_TAG_PREFIX,
                            Settings.Global.ERROR_LOGCAT_PREFIX,
                            Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL,
                            Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD,
                            Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE,
                            Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES,
                            Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES,
                            Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS,
                            Settings.Global.CONNECTIVITY_CHANGE_DELAY,
                            Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED,
                            Settings.Global.CAPTIVE_PORTAL_SERVER,
                            Settings.Global.NSD_ON,
                            Settings.Global.SET_INSTALL_LOCATION,
                            Settings.Global.DEFAULT_INSTALL_LOCATION,
                            Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY,
                            Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY,
                            Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
                            Settings.Global.HTTP_PROXY,
                            Settings.Global.GLOBAL_HTTP_PROXY_HOST,
                            Settings.Global.GLOBAL_HTTP_PROXY_PORT,
                            Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
                            Settings.Global.SET_GLOBAL_HTTP_PROXY,
                            Settings.Global.DEFAULT_DNS_SERVER,
                    };
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 89;
        }

        if (upgradeVersion == 89) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    String[] prefixesToMove = {
                            Settings.Global.BLUETOOTH_HEADSET_PRIORITY_PREFIX,
                            Settings.Global.BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX,
                            Settings.Global.BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX,
                    };

                    movePrefixedSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, prefixesToMove);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 90;
        }

        if (upgradeVersion == 90) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    String[] systemToGlobal = {
                            Settings.Global.WINDOW_ANIMATION_SCALE,
                            Settings.Global.TRANSITION_ANIMATION_SCALE,
                            Settings.Global.ANIMATOR_DURATION_SCALE,
                            Settings.Global.FANCY_IME_ANIMATIONS,
                            Settings.Global.COMPATIBILITY_MODE,
                            Settings.Global.EMERGENCY_TONE,
                            Settings.Global.CALL_AUTO_RETRY,
                            Settings.Global.DEBUG_APP,
                            Settings.Global.WAIT_FOR_DEBUGGER,
                            Settings.Global.ALWAYS_FINISH_ACTIVITIES,
                    };
                    String[] secureToGlobal = {
                            Settings.Global.PREFERRED_NETWORK_MODE,
                            Settings.Global.CDMA_SUBSCRIPTION_MODE,
                    };

                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, systemToGlobal, true);
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, secureToGlobal, true);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 91;
        }

        if (upgradeVersion == 91) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    // Move ringer mode from system to global settings
                    String[] settingsToMove = { Settings.Global.MODE_RINGER };
                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 92;
        }

        if (upgradeVersion == 92) {
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                        + " VALUES(?,?);");
                if (mUserHandle == UserHandle.USER_SYSTEM) {
                    // consider existing primary users to have made it through user setup
                    // if the globally-scoped device-provisioned bit is set
                    // (indicating they already made it through setup as primary)
                    int deviceProvisioned = getIntValueFromTable(db, TABLE_GLOBAL,
                            Settings.Global.DEVICE_PROVISIONED, 0);
                    loadSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
                            deviceProvisioned);
                } else {
                    // otherwise use the default
                    loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
                            R.bool.def_user_setup_complete);
                }
            } finally {
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 93;
        }

        if (upgradeVersion == 93) {
            // Redo this step, since somehow it didn't work the first time for some users
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    // Migrate now-global settings
                    String[] settingsToMove = setToStringArray(
                            SettingsProvider.sSystemMovedToGlobalSettings);
                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);
                    settingsToMove = setToStringArray(
                            SettingsProvider.sSecureMovedToGlobalSettings);
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);

                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 94;
        }

        if (upgradeVersion == 94) {
            // Add wireless charging started sound setting
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
                            R.string.def_wireless_charging_started_sound);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 95;
        }

        if (upgradeVersion == 95) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                try {
                    String[] settingsToMove = { Settings.Global.BUGREPORT_IN_POWER_MENU };
                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }
            upgradeVersion = 96;
        }

        if (upgradeVersion == 96) {
            // NOP bump due to a reverted change that some people got on upgrade.
            upgradeVersion = 97;
        }

        if (upgradeVersion == 97) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
                            R.integer.def_low_battery_sound_timeout);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 98;
        }

        if (upgradeVersion == 98) {
            // no-op; LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
            upgradeVersion = 99;
        }

        if (upgradeVersion == 99) {
            // no-op; HEADS_UP_NOTIFICATIONS_ENABLED now handled in version 100
            upgradeVersion = 100;
        }

        if (upgradeVersion == 100) {
            // note: LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
                            R.integer.def_heads_up_enabled);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 101;
        }

        if (upgradeVersion == 101) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 102;
        }

        if (upgradeVersion == 102) {
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                // The INSTALL_NON_MARKET_APPS setting is becoming per-user rather
                // than device-global.
                if (mUserHandle == UserHandle.USER_SYSTEM) {
                    // In the owner user, the global table exists so we can migrate the
                    // entry from there to the secure table, preserving its value.
                    String[] globalToSecure = {
                            Settings.Secure.INSTALL_NON_MARKET_APPS
                    };
                    moveSettingsToNewTable(db, TABLE_GLOBAL, TABLE_SECURE, globalToSecure, true);
                } else {
                    // Secondary users' dbs don't have the global table, so institute the
                    // default.
                    stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                            + " VALUES(?,?);");
                    loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
                            R.bool.def_install_non_market_apps);
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 103;
        }

        if (upgradeVersion == 103) {
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
                        R.bool.def_wake_gesture_enabled);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 104;
        }

        if (upgradeVersion < 105) {
            // No-op: GUEST_USER_ENABLED setting was removed
            upgradeVersion = 105;
        }

        if (upgradeVersion < 106) {
            // LOCK_SCREEN_SHOW_NOTIFICATIONS is now per-user.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadIntegerSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
                        R.integer.def_lock_screen_show_notifications);
                if (mUserHandle == UserHandle.USER_SYSTEM) {
                    final int oldShow = getIntValueFromTable(db,
                            TABLE_GLOBAL, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, -1);
                    if (oldShow >= 0) {
                        // overwrite the default with whatever you had
                        loadSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, oldShow);
                        final SQLiteStatement deleteStmt
                                = db.compileStatement("DELETE FROM global WHERE name=?");
                        deleteStmt.bindString(1, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
                        deleteStmt.execute();
                    }
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 106;
        }

        if (upgradeVersion < 107) {
            // Add trusted sound setting
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadStringSetting(stmt, Settings.Global.TRUSTED_SOUND,
                            R.string.def_trusted_sound);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 107;
        }

        if (upgradeVersion < 108) {
            // Reset the auto-brightness setting to default since the behavior
            // of the feature is now quite different and is being presented to
            // the user in a new way as "adaptive brightness".
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
                        R.bool.def_screen_brightness_automatic_mode);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 108;
        }

        if (upgradeVersion < 109) {
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
                        R.bool.def_lock_screen_allow_private_notifications);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 109;
        }

        if (upgradeVersion < 110) {
            // The SIP_CALL_OPTIONS value SIP_ASK_EACH_TIME is being deprecated.
            // If the SIP_CALL_OPTIONS setting is set to SIP_ASK_EACH_TIME, default to
            // SIP_ADDRESS_ONLY.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("UPDATE system SET value = ? " +
                        "WHERE name = ? AND value = ?;");
                stmt.bindString(1, Settings.System.SIP_ADDRESS_ONLY);
                stmt.bindString(2, Settings.System.SIP_CALL_OPTIONS);
                stmt.bindString(3, Settings.System.SIP_ASK_ME_EACH_TIME);
                stmt.execute();
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 110;
        }

        if (upgradeVersion < 111) {
            // reset ringer mode, so it doesn't force zen mode to follow
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadSetting(stmt, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 111;
        }

        if (upgradeVersion < 112) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                // When device name was added, we went with Manufacturer + Model, device name should
                // actually be Model only.
                // Update device name to Model if it wasn't modified by user.
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("UPDATE global SET value = ? "
                        + " WHERE name = ? AND value = ?");
                    stmt.bindString(1, getDefaultDeviceName()); // new default device name
                    stmt.bindString(2, Settings.Global.DEVICE_NAME);
                    stmt.bindString(3, getOldDefaultDeviceName()); // old default device name
                    stmt.execute();
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 112;
        }

        if (upgradeVersion < 113) {
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                        + " VALUES(?,?);");
                loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
                        R.integer.def_sleep_timeout);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 113;
        }

        // We skipped 114 to handle a merge conflict with the introduction of theater mode.

        if (upgradeVersion < 115) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadBooleanSetting(stmt, Global.THEATER_MODE_ON,
                            R.bool.def_theater_mode_on);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 115;
        }

        if (upgradeVersion < 116) {
            if (mUserHandle == UserHandle.USER_SYSTEM) {
                db.beginTransaction();
                SQLiteStatement stmt = null;
                try {
                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
                            + " VALUES(?,?);");
                    loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
                            ImsConfig.FeatureValueConstants.ON);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                    if (stmt != null) stmt.close();
                }
            }
            upgradeVersion = 116;
        }

        if (upgradeVersion < 117) {
            db.beginTransaction();
            try {
                String[] systemToSecure = {
                        Settings.Secure.LOCK_TO_APP_EXIT_LOCKED
                };
                moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, systemToSecure, true);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            upgradeVersion = 117;
        }

        if (upgradeVersion < 118) {
            // Reset rotation-lock-for-accessibility on upgrade, since it now hides the display
            // setting.
            db.beginTransaction();
            SQLiteStatement stmt = null;
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                        + " VALUES(?,?);");
                loadSetting(stmt, Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                if (stmt != null) stmt.close();
            }
            upgradeVersion = 118;
        }

        /*
         * IMPORTANT: Do not add any more upgrade steps here as the global,
         * secure, and system settings are no longer stored in a database
         * but are kept in memory and persisted to XML.
         *
         * See: SettingsProvider.UpgradeController#onUpgradeLocked
         */

        if (upgradeVersion != currentVersion) {
            recreateDatabase(db, oldVersion, upgradeVersion, currentVersion);
        }
    }

    public void recreateDatabase(SQLiteDatabase db, int oldVersion,
            int upgradeVersion, int currentVersion) {
        db.execSQL("DROP TABLE IF EXISTS global");
        db.execSQL("DROP TABLE IF EXISTS globalIndex1");
        db.execSQL("DROP TABLE IF EXISTS system");
        db.execSQL("DROP INDEX IF EXISTS systemIndex1");
        db.execSQL("DROP TABLE IF EXISTS secure");
        db.execSQL("DROP INDEX IF EXISTS secureIndex1");
        db.execSQL("DROP TABLE IF EXISTS gservices");
        db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
        db.execSQL("DROP TABLE IF EXISTS bluetooth_devices");
        db.execSQL("DROP TABLE IF EXISTS bookmarks");
        db.execSQL("DROP INDEX IF EXISTS bookmarksIndex1");
        db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
        db.execSQL("DROP TABLE IF EXISTS favorites");

        onCreate(db);

        // Added for diagnosing settings.db wipes after the fact
        String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion;
        db.execSQL("INSERT INTO secure(name,value) values('" +
                "wiped_db_reason" + "','" + wipeReason + "');");
    }

    private String[] setToStringArray(Set<String> set) {
        String[] array = new String[set.size()];
        return set.toArray(array);
    }

    private void moveSettingsToNewTable(SQLiteDatabase db,
            String sourceTable, String destTable,
            String[] settingsToMove, boolean doIgnore) {
        // Copy settings values from the source table to the dest, and remove from the source
        SQLiteStatement insertStmt = null;
        SQLiteStatement deleteStmt = null;

        db.beginTransaction();
        try {
            insertStmt = db.compileStatement("INSERT "
                    + (doIgnore ? " OR IGNORE " : "")
                    + " INTO " + destTable + " (name,value) SELECT name,value FROM "
                    + sourceTable + " WHERE name=?");
            deleteStmt = db.compileStatement("DELETE FROM " + sourceTable + " WHERE name=?");

            for (String setting : settingsToMove) {
                insertStmt.bindString(1, setting);
                insertStmt.execute();

                deleteStmt.bindString(1, setting);
                deleteStmt.execute();
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
            if (insertStmt != null) {
                insertStmt.close();
            }
            if (deleteStmt != null) {
                deleteStmt.close();
            }
        }
    }

    /**
     * Move any settings with the given prefixes from the source table to the
     * destination table.
     */
    private void movePrefixedSettingsToNewTable(
            SQLiteDatabase db, String sourceTable, String destTable, String[] prefixesToMove) {
        SQLiteStatement insertStmt = null;
        SQLiteStatement deleteStmt = null;

        db.beginTransaction();
        try {
            insertStmt = db.compileStatement("INSERT INTO " + destTable
                    + " (name,value) SELECT name,value FROM " + sourceTable
                    + " WHERE substr(name,0,?)=?");
            deleteStmt = db.compileStatement(
                    "DELETE FROM " + sourceTable + " WHERE substr(name,0,?)=?");

            for (String prefix : prefixesToMove) {
                insertStmt.bindLong(1, prefix.length() + 1);
                insertStmt.bindString(2, prefix);
                insertStmt.execute();

                deleteStmt.bindLong(1, prefix.length() + 1);
                deleteStmt.bindString(2, prefix);
                deleteStmt.execute();
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
            if (insertStmt != null) {
                insertStmt.close();
            }
            if (deleteStmt != null) {
                deleteStmt.close();
            }
        }
    }

    private void upgradeLockPatternLocation(SQLiteDatabase db) {
        Cursor c = db.query(TABLE_SYSTEM, new String[] {"_id", "value"}, "name='lock_pattern'",
                null, null, null, null);
        if (c.getCount() > 0) {
            c.moveToFirst();
            String lockPattern = c.getString(1);
            if (!TextUtils.isEmpty(lockPattern)) {
                // Convert lock pattern
                try {
                    LockPatternUtils lpu = new LockPatternUtils(mContext);
                    List<LockPatternView.Cell> cellPattern =
                            LockPatternUtils.stringToPattern(lockPattern);
                    lpu.saveLockPattern(cellPattern, null, UserHandle.USER_SYSTEM);
                } catch (IllegalArgumentException e) {
                    // Don't want corrupted lock pattern to hang the reboot process
                }
            }
            c.close();
            db.delete(TABLE_SYSTEM, "name='lock_pattern'", null);
        } else {
            c.close();
        }
    }

    private void upgradeScreenTimeoutFromNever(SQLiteDatabase db) {
        // See if the timeout is -1 (for "Never").
        Cursor c = db.query(TABLE_SYSTEM, new String[] { "_id", "value" }, "name=? AND value=?",
                new String[] { Settings.System.SCREEN_OFF_TIMEOUT, "-1" },
                null, null, null);

        SQLiteStatement stmt = null;
        if (c.getCount() > 0) {
            c.close();
            try {
                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                        + " VALUES(?,?);");

                // Set the timeout to 30 minutes in milliseconds
                loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                        Integer.toString(30 * 60 * 1000));
            } finally {
                if (stmt != null) stmt.close();
            }
        } else {
            c.close();
        }
    }

    private void upgradeVibrateSettingFromNone(SQLiteDatabase db) {
        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON, 0);
        // If the ringer vibrate value is invalid, set it to the default
        if ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_OFF) {
            vibrateSetting = AudioSystem.getValueForVibrateSetting(0,
                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
        }
        // Apply the same setting to the notification vibrate value
        vibrateSetting = AudioSystem.getValueForVibrateSetting(vibrateSetting,
                AudioManager.VIBRATE_TYPE_NOTIFICATION, vibrateSetting);

        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                    + " VALUES(?,?);");
            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrateSetting);
        } finally {
            if (stmt != null)
                stmt.close();
        }
    }

    private void upgradeScreenTimeout(SQLiteDatabase db) {
        // Change screen timeout to current default
        db.beginTransaction();
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                    + " VALUES(?,?);");
            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                    R.integer.def_screen_off_timeout);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
            if (stmt != null)
                stmt.close();
        }
    }

    private void upgradeAutoBrightness(SQLiteDatabase db) {
        db.beginTransaction();
        try {
            String value =
                    mContext.getResources().getBoolean(
                    R.bool.def_screen_brightness_automatic_mode) ? "1" : "0";
            db.execSQL("INSERT OR REPLACE INTO system(name,value) values('" +
                    Settings.System.SCREEN_BRIGHTNESS_MODE + "','" + value + "');");
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
    }

    /**
     * Loads the default set of bookmarked shortcuts from an xml file.
     *
     * @param db The database to write the values into
     */
    private void loadBookmarks(SQLiteDatabase db) {
        ContentValues values = new ContentValues();

        PackageManager packageManager = mContext.getPackageManager();
        try {
            XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
            XmlUtils.beginDocument(parser, "bookmarks");

            final int depth = parser.getDepth();
            int type;

            while (((type = parser.next()) != XmlPullParser.END_TAG ||
                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {

                if (type != XmlPullParser.START_TAG) {
                    continue;
                }

                String name = parser.getName();
                if (!"bookmark".equals(name)) {
                    break;
                }

                String pkg = parser.getAttributeValue(null, "package");
                String cls = parser.getAttributeValue(null, "class");
                String shortcutStr = parser.getAttributeValue(null, "shortcut");
                String category = parser.getAttributeValue(null, "category");

                int shortcutValue = shortcutStr.charAt(0);
                if (TextUtils.isEmpty(shortcutStr)) {
                    Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
                    continue;
                }

                final Intent intent;
                final String title;
                if (pkg != null && cls != null) {
                    ActivityInfo info = null;
                    ComponentName cn = new ComponentName(pkg, cls);
                    try {
                        info = packageManager.getActivityInfo(cn, 0);
                    } catch (PackageManager.NameNotFoundException e) {
                        String[] packages = packageManager.canonicalToCurrentPackageNames(
                                new String[] { pkg });
                        cn = new ComponentName(packages[0], cls);
                        try {
                            info = packageManager.getActivityInfo(cn, 0);
                        } catch (PackageManager.NameNotFoundException e1) {
                            Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
                            continue;
                        }
                    }

                    intent = new Intent(Intent.ACTION_MAIN, null);
                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                    intent.setComponent(cn);
                    title = info.loadLabel(packageManager).toString();
                } else if (category != null) {
                    intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
                    title = "";
                } else {
                    Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr
                            + ": missing package/class or category attributes");
                    continue;
                }

                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                values.put(Settings.Bookmarks.INTENT, intent.toUri(0));
                values.put(Settings.Bookmarks.TITLE, title);
                values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
                db.delete("bookmarks", "shortcut = ?",
                        new String[] { Integer.toString(shortcutValue) });
                db.insert("bookmarks", null, values);
            }
        } catch (XmlPullParserException e) {
            Log.w(TAG, "Got execption parsing bookmarks.", e);
        } catch (IOException e) {
            Log.w(TAG, "Got execption parsing bookmarks.", e);
        }
    }

    /**
     * Loads the default volume levels. It is actually inserting the index of
     * the volume array for each of the volume controls.
     *
     * @param db the database to insert the volume levels into
     */
    private void loadVolumeLevels(SQLiteDatabase db) {
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                    + " VALUES(?,?);");

            loadSetting(stmt, Settings.System.VOLUME_MUSIC,
                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_MUSIC));
            loadSetting(stmt, Settings.System.VOLUME_RING,
                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_RING));
            loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_SYSTEM));
            loadSetting(
                    stmt,
                    Settings.System.VOLUME_VOICE,
                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_VOICE_CALL));
            loadSetting(stmt, Settings.System.VOLUME_ALARM,
                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_ALARM));
            loadSetting(
                    stmt,
                    Settings.System.VOLUME_NOTIFICATION,
                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_NOTIFICATION));
            loadSetting(
                    stmt,
                    Settings.System.VOLUME_BLUETOOTH_SCO,
                    AudioSystem.getDefaultStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO));

            // By default:
            // - ringtones, notification, system and music streams are affected by ringer mode
            // on non voice capable devices (tablets)
            // - ringtones, notification and system streams are affected by ringer mode
            // on voice capable devices (phones)
            int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
                                            (1 << AudioManager.STREAM_NOTIFICATION) |
                                            (1 << AudioManager.STREAM_SYSTEM) |
                                            (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
            if (!mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_voice_capable)) {
                ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
            }
            loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                    ringerModeAffectedStreams);

            loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
                    AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED);
        } finally {
            if (stmt != null) stmt.close();
        }

        loadVibrateWhenRingingSetting(db);
    }

    private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
        if (deleteOld) {
            db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
        }

        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                    + " VALUES(?,?);");

            // Vibrate on by default for ringer, on for notification
            int vibrate = 0;
            vibrate = AudioSystem.getValueForVibrateSetting(vibrate,
                    AudioManager.VIBRATE_TYPE_NOTIFICATION,
                    AudioManager.VIBRATE_SETTING_ONLY_SILENT);
            vibrate |= AudioSystem.getValueForVibrateSetting(vibrate,
                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
        } finally {
            if (stmt != null) stmt.close();
        }
    }

    private void loadVibrateWhenRingingSetting(SQLiteDatabase db) {
        // The default should be off. VIBRATE_SETTING_ONLY_SILENT should also be ignored here.
        // Phone app should separately check whether AudioManager#getRingerMode() returns
        // RINGER_MODE_VIBRATE, with which the device should vibrate anyway.
        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON,
                AudioManager.VIBRATE_SETTING_OFF);
        boolean vibrateWhenRinging = ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_ON);

        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                    + " VALUES(?,?);");
            loadSetting(stmt, Settings.System.VIBRATE_WHEN_RINGING, vibrateWhenRinging ? 1 : 0);
        } finally {
            if (stmt != null) stmt.close();
        }
    }

    private void loadSettings(SQLiteDatabase db) {
        loadSystemSettings(db);
        loadSecureSettings(db);
        // The global table only exists for the 'owner/system' user
        if (mUserHandle == UserHandle.USER_SYSTEM) {
            loadGlobalSettings(db);
        }
    }

    private void loadSystemSettings(SQLiteDatabase db) {
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                    + " VALUES(?,?);");

            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
                    R.bool.def_dim_screen);
            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                    R.integer.def_screen_off_timeout);

            // Set default cdma DTMF type
            loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);

            // Set default hearing aid
            loadSetting(stmt, Settings.System.HEARING_AID, 0);

            // Set default tty mode
            loadSetting(stmt, Settings.System.TTY_MODE, 0);

            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
                    R.integer.def_screen_brightness);

            loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
                    R.bool.def_screen_brightness_automatic_mode);

            loadDefaultAnimationSettings(stmt);

            loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
                    R.bool.def_accelerometer_rotation);

            loadDefaultHapticSettings(stmt);

            loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                    R.bool.def_notification_pulse);

            loadUISoundEffectsSettings(stmt);

            loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
                    R.integer.def_pointer_speed);

            /*
             * IMPORTANT: Do not add any more upgrade steps here as the global,
             * secure, and system settings are no longer stored in a database
             * but are kept in memory and persisted to XML.
             *
             * See: SettingsProvider.UpgradeController#onUpgradeLocked
             */
        } finally {
            if (stmt != null) stmt.close();
        }
    }

    private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
        loadBooleanSetting(stmt, Settings.System.DTMF_TONE_WHEN_DIALING,
                R.bool.def_dtmf_tones_enabled);
        loadBooleanSetting(stmt, Settings.System.SOUND_EFFECTS_ENABLED,
                R.bool.def_sound_effects_enabled);
        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
                R.bool.def_haptic_feedback);

        loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
            R.integer.def_lockscreen_sounds_enabled);
    }

    private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
        loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
                R.fraction.def_window_animation_scale, 1);
        loadFractionSetting(stmt, Settings.System.TRANSITION_ANIMATION_SCALE,
                R.fraction.def_window_transition_scale, 1);
    }

    private void loadDefaultHapticSettings(SQLiteStatement stmt) {
        loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
                R.bool.def_haptic_feedback);
    }

    private void loadSecureSettings(SQLiteDatabase db) {
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                    + " VALUES(?,?);");

            loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                    R.string.def_location_providers_allowed);

            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
            if (!TextUtils.isEmpty(wifiWatchList)) {
                loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
            }

            // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
            // persistent system property instead.
            //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);

            // Allow mock locations default, based on build
            loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
                    "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);

            loadSecure35Settings(stmt);

            loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
                    R.bool.def_mount_play_notification_snd);

            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
                    R.bool.def_mount_ums_autostart);

            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
                    R.bool.def_mount_ums_prompt);

            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
                    R.bool.def_mount_ums_notify_enabled);

            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
                    R.bool.def_accessibility_script_injection);

            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
                    R.string.def_accessibility_web_content_key_bindings);

            loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
                    R.integer.def_long_press_timeout_millis);

            loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
                    R.bool.def_touch_exploration_enabled);

            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
                    R.bool.def_accessibility_speak_password);

            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
                    R.string.def_accessibility_screen_reader_url);

            if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) {
                loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1");
            } else {
                loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
                        R.bool.def_lockscreen_disabled);
            }

            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED,
                    com.android.internal.R.bool.config_dreamsEnabledByDefault);
            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
                    com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
                    com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS,
                    com.android.internal.R.string.config_dreamsDefaultComponent);
            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
                    com.android.internal.R.string.config_dreamsDefaultComponent);

            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
                    R.bool.def_accessibility_display_magnification_enabled);

            loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
                    R.fraction.def_accessibility_display_magnification_scale, 1);

            loadBooleanSetting(stmt,
                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
                    R.bool.def_accessibility_display_magnification_auto_update);

            loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
                    R.bool.def_user_setup_complete);

            loadStringSetting(stmt, Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
                        R.string.def_immersive_mode_confirmations);

            loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
                    R.bool.def_install_non_market_apps);

            loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
                    R.bool.def_wake_gesture_enabled);

            loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
                    R.integer.def_lock_screen_show_notifications);

            loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
                    R.bool.def_lock_screen_allow_private_notifications);

            loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
                    R.integer.def_sleep_timeout);

            /*
             * IMPORTANT: Do not add any more upgrade steps here as the global,
             * secure, and system settings are no longer stored in a database
             * but are kept in memory and persisted to XML.
             *
             * See: SettingsProvider.UpgradeController#onUpgradeLocked
             */
        } finally {
            if (stmt != null) stmt.close();
        }
    }

    private void loadSecure35Settings(SQLiteStatement stmt) {
        loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED,
                R.bool.def_backup_enabled);

        loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
                R.string.def_backup_transport);
    }

    private void loadGlobalSettings(SQLiteDatabase db) {
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
                    + " VALUES(?,?);");

            // --- Previously in 'system'
            loadBooleanSetting(stmt, Settings.Global.AIRPLANE_MODE_ON,
                    R.bool.def_airplane_mode_on);

            loadBooleanSetting(stmt, Settings.Global.THEATER_MODE_ON,
                    R.bool.def_theater_mode_on);

            loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_RADIOS,
                    R.string.def_airplane_mode_radios);

            loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
                    R.string.airplane_mode_toggleable_radios);

            loadBooleanSetting(stmt, Settings.Global.ASSISTED_GPS_ENABLED,
                    R.bool.assisted_gps_enabled);

            loadBooleanSetting(stmt, Settings.Global.AUTO_TIME,
                    R.bool.def_auto_time); // Sync time to NITZ

            loadBooleanSetting(stmt, Settings.Global.AUTO_TIME_ZONE,
                    R.bool.def_auto_time_zone); // Sync timezone to NITZ

            loadSetting(stmt, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                    ("1".equals(SystemProperties.get("ro.kernel.qemu")) ||
                        mContext.getResources().getBoolean(R.bool.def_stay_on_while_plugged_in))
                     ? 1 : 0);

            loadIntegerSetting(stmt, Settings.Global.WIFI_SLEEP_POLICY,
                    R.integer.def_wifi_sleep_policy);

            loadSetting(stmt, Settings.Global.MODE_RINGER,
                    AudioManager.RINGER_MODE_NORMAL);

            // --- Previously in 'secure'
            loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE,
                    R.bool.def_package_verifier_enable);

            loadBooleanSetting(stmt, Settings.Global.WIFI_ON,
                    R.bool.def_wifi_on);

            loadBooleanSetting(stmt, Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
                    R.bool.def_networks_available_notification_on);

            loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_ON,
                    R.bool.def_bluetooth_on);

            // Enable or disable Cell Broadcast SMS
            loadSetting(stmt, Settings.Global.CDMA_CELL_BROADCAST_SMS,
                    RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);

            // Data roaming default, based on build
            loadSetting(stmt, Settings.Global.DATA_ROAMING,
                    "true".equalsIgnoreCase(
                            SystemProperties.get("ro.com.android.dataroaming",
                                    "false")) ? 1 : 0);

            loadBooleanSetting(stmt, Settings.Global.DEVICE_PROVISIONED,
                    R.bool.def_device_provisioned);

            final int maxBytes = mContext.getResources().getInteger(
                    R.integer.def_download_manager_max_bytes_over_mobile);
            if (maxBytes > 0) {
                loadSetting(stmt, Settings.Global.DOWNLOAD_MAX_BYTES_OVER_MOBILE,
                        Integer.toString(maxBytes));
            }

            final int recommendedMaxBytes = mContext.getResources().getInteger(
                    R.integer.def_download_manager_recommended_max_bytes_over_mobile);
            if (recommendedMaxBytes > 0) {
                loadSetting(stmt, Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE,
                        Integer.toString(recommendedMaxBytes));
            }

            // Mobile Data default, based on build
            loadSetting(stmt, Settings.Global.MOBILE_DATA,
                    "true".equalsIgnoreCase(
                            SystemProperties.get("ro.com.android.mobiledata",
                                    "true")) ? 1 : 0);

            loadBooleanSetting(stmt, Settings.Global.NETSTATS_ENABLED,
                    R.bool.def_netstats_enabled);

            loadBooleanSetting(stmt, Settings.Global.USB_MASS_STORAGE_ENABLED,
                    R.bool.def_usb_mass_storage_enabled);

            loadIntegerSetting(stmt, Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
                    R.integer.def_max_dhcp_retries);

            loadBooleanSetting(stmt, Settings.Global.WIFI_DISPLAY_ON,
                    R.bool.def_wifi_display_on);

            loadStringSetting(stmt, Settings.Global.LOCK_SOUND,
                    R.string.def_lock_sound);
            loadStringSetting(stmt, Settings.Global.UNLOCK_SOUND,
                    R.string.def_unlock_sound);
            loadStringSetting(stmt, Settings.Global.TRUSTED_SOUND,
                    R.string.def_trusted_sound);
            loadIntegerSetting(stmt, Settings.Global.POWER_SOUNDS_ENABLED,
                    R.integer.def_power_sounds_enabled);
            loadStringSetting(stmt, Settings.Global.LOW_BATTERY_SOUND,
                    R.string.def_low_battery_sound);
            loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED,
                    R.integer.def_dock_sounds_enabled);
            loadStringSetting(stmt, Settings.Global.DESK_DOCK_SOUND,
                    R.string.def_desk_dock_sound);
            loadStringSetting(stmt, Settings.Global.DESK_UNDOCK_SOUND,
                    R.string.def_desk_undock_sound);
            loadStringSetting(stmt, Settings.Global.CAR_DOCK_SOUND,
                    R.string.def_car_dock_sound);
            loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND,
                    R.string.def_car_undock_sound);
            loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
                    R.string.def_wireless_charging_started_sound);

            loadIntegerSetting(stmt, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED,
                    R.integer.def_dock_audio_media_enabled);

            loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
            loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
                    PackageHelper.APP_INSTALL_AUTO);

            // Set default cdma emergency tone
            loadSetting(stmt, Settings.Global.EMERGENCY_TONE, 0);

            // Set default cdma call auto retry
            loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);

            // Set the preferred network mode to target desired value or Default
            // value defined in RILConstants
            int type;
            type = RILConstants.PREFERRED_NETWORK_MODE;
            loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);

            // Set the preferred cdma subscription source to target desired value or default
            // value defined in CdmaSubscriptionSourceManager
            type = SystemProperties.getInt("ro.telephony.default_cdma_sub",
                        CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION);
            loadSetting(stmt, Settings.Global.CDMA_SUBSCRIPTION_MODE, type);

            loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
                    R.integer.def_low_battery_sound_timeout);

            loadIntegerSetting(stmt, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
                    R.integer.def_wifi_scan_always_available);

            loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
                    R.integer.def_heads_up_enabled);

            loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());

            loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
                    ImsConfig.FeatureValueConstants.ON);

            /*
             * IMPORTANT: Do not add any more upgrade steps here as the global,
             * secure, and system settings are no longer stored in a database
             * but are kept in memory and persisted to XML.
             *
             * See: SettingsProvider.UpgradeController#onUpgradeLocked
             */
        } finally {
            if (stmt != null) stmt.close();
        }
    }

    private void loadSetting(SQLiteStatement stmt, String key, Object value) {
        stmt.bindString(1, key);
        stmt.bindString(2, value.toString());
        stmt.execute();
    }

    private void loadStringSetting(SQLiteStatement stmt, String key, int resid) {
        loadSetting(stmt, key, mContext.getResources().getString(resid));
    }

    private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
        loadSetting(stmt, key,
                mContext.getResources().getBoolean(resid) ? "1" : "0");
    }

    private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) {
        loadSetting(stmt, key,
                Integer.toString(mContext.getResources().getInteger(resid)));
    }

    private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) {
        loadSetting(stmt, key,
                Float.toString(mContext.getResources().getFraction(resid, base, base)));
    }

    private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) {
        return getIntValueFromTable(db, TABLE_SYSTEM, name, defaultValue);
    }

    private int getIntValueFromTable(SQLiteDatabase db, String table, String name,
            int defaultValue) {
        String value = getStringValueFromTable(db, table, name, null);
        return (value != null) ? Integer.parseInt(value) : defaultValue;
    }

    private String getStringValueFromTable(SQLiteDatabase db, String table, String name,
            String defaultValue) {
        Cursor c = null;
        try {
            c = db.query(table, new String[] { Settings.System.VALUE }, "name='" + name + "'",
                    null, null, null, null);
            if (c != null && c.moveToFirst()) {
                String val = c.getString(0);
                return val == null ? defaultValue : val;
            }
        } finally {
            if (c != null) c.close();
        }
        return defaultValue;
    }

    private String getOldDefaultDeviceName() {
        return mContext.getResources().getString(R.string.def_device_name,
                Build.MANUFACTURER, Build.MODEL);
    }

    private String getDefaultDeviceName() {
        return mContext.getResources().getString(R.string.def_device_name_simple, Build.MODEL);
    }
}
