/*
 * 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 static android.os.Process.INVALID_UID;
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.backup.BackupManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.om.IOverlayManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.hardware.camera2.utils.ArrayUtils;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.provider.SettingsValidators;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ByteStringUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.providers.settings.SettingsState.Setting;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;

import com.google.android.collect.Sets;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;


/**
 * <p>
 * This class is a content provider that publishes the system settings.
 * It can be accessed via the content provider APIs or via custom call
 * commands. The latter is a bit faster and is the preferred way to access
 * the platform settings.
 * </p>
 * <p>
 * There are three settings types, global (with signature level protection
 * and shared across users), secure (with signature permission level
 * protection and per user), and system (with dangerous permission level
 * protection and per user). Global settings are stored under the device owner.
 * Each of these settings is represented by a {@link
 * com.android.providers.settings.SettingsState} object mapped to an integer
 * key derived from the setting type in the most significant bits and user
 * id in the least significant bits. Settings are synchronously loaded on
 * instantiation of a SettingsState and asynchronously persisted on mutation.
 * Settings are stored in the user specific system directory.
 * </p>
 * <p>
 * Apps targeting APIs Lollipop MR1 and lower can add custom settings entries
 * and get a warning. Targeting higher API version prohibits this as the
 * system settings are not a place for apps to save their state. When a package
 * is removed the settings it added are deleted. Apps cannot delete system
 * settings added by the platform. System settings values are validated to
 * ensure the clients do not put bad values. Global and secure settings are
 * changed only by trusted parties, therefore no validation is performed. Also
 * there is a limit on the amount of app specific settings that can be added
 * to prevent unlimited growth of the system process memory footprint.
 * </p>
 */
@SuppressWarnings("deprecation")
public class SettingsProvider extends ContentProvider {
    static final boolean DEBUG = false;

    private static final boolean DROP_DATABASE_ON_MIGRATION = true;

    private static final String LOG_TAG = "SettingsProvider";

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

    // Old tables no longer exist.
    private static final String TABLE_FAVORITES = "favorites";
    private static final String TABLE_OLD_FAVORITES = "old_favorites";
    private static final String TABLE_BLUETOOTH_DEVICES = "bluetooth_devices";
    private static final String TABLE_BOOKMARKS = "bookmarks";
    private static final String TABLE_ANDROID_METADATA = "android_metadata";

    // The set of removed legacy tables.
    private static final Set<String> REMOVED_LEGACY_TABLES = new ArraySet<>();
    static {
        REMOVED_LEGACY_TABLES.add(TABLE_FAVORITES);
        REMOVED_LEGACY_TABLES.add(TABLE_OLD_FAVORITES);
        REMOVED_LEGACY_TABLES.add(TABLE_BLUETOOTH_DEVICES);
        REMOVED_LEGACY_TABLES.add(TABLE_BOOKMARKS);
        REMOVED_LEGACY_TABLES.add(TABLE_ANDROID_METADATA);
    }

    private static final int MUTATION_OPERATION_INSERT = 1;
    private static final int MUTATION_OPERATION_DELETE = 2;
    private static final int MUTATION_OPERATION_UPDATE = 3;
    private static final int MUTATION_OPERATION_RESET = 4;

    private static final String[] ALL_COLUMNS = new String[] {
            Settings.NameValueTable._ID,
            Settings.NameValueTable.NAME,
            Settings.NameValueTable.VALUE
    };

    public static final int SETTINGS_TYPE_GLOBAL = SettingsState.SETTINGS_TYPE_GLOBAL;
    public static final int SETTINGS_TYPE_SYSTEM = SettingsState.SETTINGS_TYPE_SYSTEM;
    public static final int SETTINGS_TYPE_SECURE = SettingsState.SETTINGS_TYPE_SECURE;
    public static final int SETTINGS_TYPE_SSAID = SettingsState.SETTINGS_TYPE_SSAID;
    public static final int SETTINGS_TYPE_CONFIG = SettingsState.SETTINGS_TYPE_CONFIG;

    private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair(
            Settings.NameValueTable.VALUE, null);

    public static final String RESULT_ROWS_DELETED = "result_rows_deleted";
    public static final String RESULT_SETTINGS_LIST = "result_settings_list";

    // Overlay specified settings whitelisted for Instant Apps
    private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>();
    private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
    private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>();

    static {
        for (String name : Resources.getSystem().getStringArray(
                com.android.internal.R.array.config_allowedGlobalInstantAppSettings)) {
            OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS.add(name);
        }
        for (String name : Resources.getSystem().getStringArray(
                com.android.internal.R.array.config_allowedSystemInstantAppSettings)) {
            OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS.add(name);
        }
        for (String name : Resources.getSystem().getStringArray(
                com.android.internal.R.array.config_allowedSecureInstantAppSettings)) {
            OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS.add(name);
        }
    }

    // Changes to these global settings are synchronously persisted
    private static final Set<String> CRITICAL_GLOBAL_SETTINGS = new ArraySet<>();
    static {
        CRITICAL_GLOBAL_SETTINGS.add(Settings.Global.DEVICE_PROVISIONED);
    }

    // Changes to these secure settings are synchronously persisted
    private static final Set<String> CRITICAL_SECURE_SETTINGS = new ArraySet<>();
    static {
        CRITICAL_SECURE_SETTINGS.add(Settings.Secure.USER_SETUP_COMPLETE);
    }

    // Per user secure settings that moved to the for all users global settings.
    static final Set<String> sSecureMovedToGlobalSettings = new ArraySet<>();
    static {
        Settings.Secure.getMovedToGlobalSettings(sSecureMovedToGlobalSettings);
    }

    // Per user system settings that moved to the for all users global settings.
    static final Set<String> sSystemMovedToGlobalSettings = new ArraySet<>();
    static {
        Settings.System.getMovedToGlobalSettings(sSystemMovedToGlobalSettings);
    }

    // Per user system settings that moved to the per user secure settings.
    static final Set<String> sSystemMovedToSecureSettings = new ArraySet<>();
    static {
        Settings.System.getMovedToSecureSettings(sSystemMovedToSecureSettings);
    }

    // Per all users global settings that moved to the per user secure settings.
    static final Set<String> sGlobalMovedToSecureSettings = new ArraySet<>();
    static {
        Settings.Global.getMovedToSecureSettings(sGlobalMovedToSecureSettings);
    }

    // Per user secure settings that are cloned for the managed profiles of the user.
    private static final Set<String> sSecureCloneToManagedSettings = new ArraySet<>();
    static {
        Settings.Secure.getCloneToManagedProfileSettings(sSecureCloneToManagedSettings);
    }

    // Per user system settings that are cloned for the managed profiles of the user.
    private static final Set<String> sSystemCloneToManagedSettings = new ArraySet<>();
    static {
        Settings.System.getCloneToManagedProfileSettings(sSystemCloneToManagedSettings);
    }

    // Per user system settings that are cloned from the profile's parent when a dependency
    // in {@link Settings.Secure} is set to "1".
    public static final Map<String, String> sSystemCloneFromParentOnDependency = new ArrayMap<>();
    static {
        Settings.System.getCloneFromParentOnValueSettings(sSystemCloneFromParentOnDependency);
    }

    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private SettingsRegistry mSettingsRegistry;

    @GuardedBy("mLock")
    private HandlerThread mHandlerThread;

    @GuardedBy("mLock")
    private Handler mHandler;

    // We have to call in the user manager with no lock held,
    private volatile UserManager mUserManager;

    private UserManagerInternal mUserManagerInternal;

    // We have to call in the package manager with no lock held,
    private volatile IPackageManager mPackageManager;

    public static int makeKey(int type, int userId) {
        return SettingsState.makeKey(type, userId);
    }

    public static int getTypeFromKey(int key) {
        return SettingsState.getTypeFromKey(key);
    }

    public static int getUserIdFromKey(int key) {
        return SettingsState.getUserIdFromKey(key);
    }

    public static String settingTypeToString(int type) {
        return SettingsState.settingTypeToString(type);
    }

    public static String keyToString(int key) {
        return SettingsState.keyToString(key);
    }

    @Override
    public boolean onCreate() {
        Settings.setInSystemServer();

        // fail to boot if there're any backed up settings that don't have a non-null validator
        ensureAllBackedUpSystemSettingsHaveValidators();
        ensureAllBackedUpGlobalSettingsHaveValidators();
        ensureAllBackedUpSecureSettingsHaveValidators();

        synchronized (mLock) {
            mUserManager = UserManager.get(getContext());
            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
            mPackageManager = AppGlobals.getPackageManager();
            mHandlerThread = new HandlerThread(LOG_TAG,
                    Process.THREAD_PRIORITY_BACKGROUND);
            mHandlerThread.start();
            mHandler = new Handler(mHandlerThread.getLooper());
            mSettingsRegistry = new SettingsRegistry();
        }
        mHandler.post(() -> {
            registerBroadcastReceivers();
            startWatchingUserRestrictionChanges();
        });
        ServiceManager.addService("settings", new SettingsService(this));
        ServiceManager.addService("device_config", new DeviceConfigService(this));
        return true;
    }

    private void ensureAllBackedUpSystemSettingsHaveValidators() {
        String offenders = getOffenders(concat(Settings.System.SETTINGS_TO_BACKUP,
                Settings.System.LEGACY_RESTORE_SETTINGS), Settings.System.VALIDATORS);

        failToBootIfOffendersPresent(offenders, "Settings.System");
    }

    private void ensureAllBackedUpGlobalSettingsHaveValidators() {
        String offenders = getOffenders(concat(Settings.Global.SETTINGS_TO_BACKUP,
                Settings.Global.LEGACY_RESTORE_SETTINGS), Settings.Global.VALIDATORS);

        failToBootIfOffendersPresent(offenders, "Settings.Global");
    }

    private void ensureAllBackedUpSecureSettingsHaveValidators() {
        String offenders = getOffenders(concat(Settings.Secure.SETTINGS_TO_BACKUP,
                Settings.Secure.LEGACY_RESTORE_SETTINGS), Settings.Secure.VALIDATORS);

        failToBootIfOffendersPresent(offenders, "Settings.Secure");
    }

    private void failToBootIfOffendersPresent(String offenders, String settingsType) {
        if (offenders.length() > 0) {
            throw new RuntimeException("All " + settingsType + " settings that are backed up"
                    + " have to have a non-null validator, but those don't: " + offenders);
        }
    }

    private String getOffenders(String[] settingsToBackup, Map<String,
            SettingsValidators.Validator> validators) {
        StringBuilder offenders = new StringBuilder();
        for (String setting : settingsToBackup) {
            if (validators.get(setting) == null) {
                offenders.append(setting).append(" ");
            }
        }
        return offenders.toString();
    }

    private final String[] concat(String[] first, String[] second) {
        if (second == null || second.length == 0) {
            return first;
        }
        final int firstLen = first.length;
        final int secondLen = second.length;
        String[] both = new String[firstLen + secondLen];
        System.arraycopy(first, 0, both, 0, firstLen);
        System.arraycopy(second, 0, both, firstLen, secondLen);
        return both;
    }

    @Override
    public Bundle call(String method, String name, Bundle args) {
        final int requestingUserId = getRequestingUserId(args);
        switch (method) {
            case Settings.CALL_METHOD_GET_CONFIG: {
                Setting setting = getConfigSetting(name);
                return packageValueForCallResult(setting, isTrackingGeneration(args));
            }

            case Settings.CALL_METHOD_GET_GLOBAL: {
                Setting setting = getGlobalSetting(name);
                return packageValueForCallResult(setting, isTrackingGeneration(args));
            }

            case Settings.CALL_METHOD_GET_SECURE: {
                Setting setting = getSecureSetting(name, requestingUserId,
                        /*enableOverride=*/ true);
                return packageValueForCallResult(setting, isTrackingGeneration(args));
            }

            case Settings.CALL_METHOD_GET_SYSTEM: {
                Setting setting = getSystemSetting(name, requestingUserId);
                return packageValueForCallResult(setting, isTrackingGeneration(args));
            }

            case Settings.CALL_METHOD_PUT_CONFIG: {
                String value = getSettingValue(args);
                final boolean makeDefault = getSettingMakeDefault(args);
                insertConfigSetting(name, value, makeDefault);
                break;
            }

            case Settings.CALL_METHOD_PUT_GLOBAL: {
                String value = getSettingValue(args);
                String tag = getSettingTag(args);
                final boolean makeDefault = getSettingMakeDefault(args);
                insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false);
                break;
            }

            case Settings.CALL_METHOD_PUT_SECURE: {
                String value = getSettingValue(args);
                String tag = getSettingTag(args);
                final boolean makeDefault = getSettingMakeDefault(args);
                insertSecureSetting(name, value, tag, makeDefault, requestingUserId, false);
                break;
            }

            case Settings.CALL_METHOD_PUT_SYSTEM: {
                String value = getSettingValue(args);
                insertSystemSetting(name, value, requestingUserId);
                break;
            }

            case Settings.CALL_METHOD_RESET_CONFIG: {
                final int mode = getResetModeEnforcingPermission(args);
                String prefix = getSettingPrefix(args);
                resetConfigSetting(mode, prefix);
                break;
            }

            case Settings.CALL_METHOD_RESET_GLOBAL: {
                final int mode = getResetModeEnforcingPermission(args);
                String tag = getSettingTag(args);
                resetGlobalSetting(requestingUserId, mode, tag);
                break;
            }

            case Settings.CALL_METHOD_RESET_SECURE: {
                final int mode = getResetModeEnforcingPermission(args);
                String tag = getSettingTag(args);
                resetSecureSetting(requestingUserId, mode, tag);
                break;
            }

            case Settings.CALL_METHOD_DELETE_CONFIG: {
                int rows  = deleteConfigSetting(name) ? 1 : 0;
                Bundle result = new Bundle();
                result.putInt(RESULT_ROWS_DELETED, rows);
                return result;
            }

            case Settings.CALL_METHOD_DELETE_GLOBAL: {
                int rows = deleteGlobalSetting(name, requestingUserId, false) ? 1 : 0;
                Bundle result = new Bundle();
                result.putInt(RESULT_ROWS_DELETED, rows);
                return result;
            }

            case Settings.CALL_METHOD_DELETE_SECURE: {
                int rows = deleteSecureSetting(name, requestingUserId, false) ? 1 : 0;
                Bundle result = new Bundle();
                result.putInt(RESULT_ROWS_DELETED, rows);
                return result;
            }

            case Settings.CALL_METHOD_DELETE_SYSTEM: {
                int rows = deleteSystemSetting(name, requestingUserId) ? 1 : 0;
                Bundle result = new Bundle();
                result.putInt(RESULT_ROWS_DELETED, rows);
                return result;
            }

            case Settings.CALL_METHOD_LIST_CONFIG: {
                String prefix = getSettingPrefix(args);
                Bundle result = new Bundle();
                result.putSerializable(
                        Settings.NameValueTable.VALUE, (HashMap) getAllConfigFlags(prefix));
                return result;
            }

            case Settings.CALL_METHOD_LIST_GLOBAL: {
                Bundle result = new Bundle();
                result.putStringArrayList(RESULT_SETTINGS_LIST,
                        buildSettingsList(getAllGlobalSettings(null)));
                return result;
            }

            case Settings.CALL_METHOD_LIST_SECURE: {
                Bundle result = new Bundle();
                result.putStringArrayList(RESULT_SETTINGS_LIST,
                        buildSettingsList(getAllSecureSettings(requestingUserId, null)));
                return result;
            }

            case Settings.CALL_METHOD_LIST_SYSTEM: {
                Bundle result = new Bundle();
                result.putStringArrayList(RESULT_SETTINGS_LIST,
                        buildSettingsList(getAllSystemSettings(requestingUserId, null)));
                return result;
            }

            default: {
                Slog.w(LOG_TAG, "call() with invalid method: " + method);
            } break;
        }

        return null;
    }

    @Override
    public String getType(Uri uri) {
        Arguments args = new Arguments(uri, null, null, true);
        if (TextUtils.isEmpty(args.name)) {
            return "vnd.android.cursor.dir/" + args.table;
        } else {
            return "vnd.android.cursor.item/" + args.table;
        }
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String where, String[] whereArgs,
            String order) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "query() for user: " + UserHandle.getCallingUserId());
        }

        Arguments args = new Arguments(uri, where, whereArgs, true);
        String[] normalizedProjection = normalizeProjection(projection);

        // If a legacy table that is gone, done.
        if (REMOVED_LEGACY_TABLES.contains(args.table)) {
            return new MatrixCursor(normalizedProjection, 0);
        }

        switch (args.table) {
            case TABLE_GLOBAL: {
                if (args.name != null) {
                    Setting setting = getGlobalSetting(args.name);
                    return packageSettingForQuery(setting, normalizedProjection);
                } else {
                    return getAllGlobalSettings(projection);
                }
            }

            case TABLE_SECURE: {
                final int userId = UserHandle.getCallingUserId();
                if (args.name != null) {
                    Setting setting = getSecureSetting(args.name, userId);
                    return packageSettingForQuery(setting, normalizedProjection);
                } else {
                    return getAllSecureSettings(userId, projection);
                }
            }

            case TABLE_SYSTEM: {
                final int userId = UserHandle.getCallingUserId();
                if (args.name != null) {
                    Setting setting = getSystemSetting(args.name, userId);
                    return packageSettingForQuery(setting, normalizedProjection);
                } else {
                    return getAllSystemSettings(userId, projection);
                }
            }

            default: {
                throw new IllegalArgumentException("Invalid Uri path:" + uri);
            }
        }
    }

    private ArrayList<String> buildSettingsList(Cursor cursor) {
        final ArrayList<String> lines = new ArrayList<String>();
        try {
            while (cursor != null && cursor.moveToNext()) {
                lines.add(cursor.getString(1) + "=" + cursor.getString(2));
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return lines;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "insert() for user: " + UserHandle.getCallingUserId());
        }

        String table = getValidTableOrThrow(uri);

        // If a legacy table that is gone, done.
        if (REMOVED_LEGACY_TABLES.contains(table)) {
            return null;
        }

        String name = values.getAsString(Settings.Secure.NAME);
        if (!isKeyValid(name)) {
            return null;
        }

        String value = values.getAsString(Settings.Secure.VALUE);

        switch (table) {
            case TABLE_GLOBAL: {
                if (insertGlobalSetting(name, value, null, false,
                        UserHandle.getCallingUserId(), false)) {
                    return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
                }
            } break;

            case TABLE_SECURE: {
                if (insertSecureSetting(name, value, null, false,
                        UserHandle.getCallingUserId(), false)) {
                    return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
                }
            } break;

            case TABLE_SYSTEM: {
                if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) {
                    return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
                }
            } break;

            default: {
                throw new IllegalArgumentException("Bad Uri path:" + uri);
            }
        }

        return null;
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] allValues) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "bulkInsert() for user: " + UserHandle.getCallingUserId());
        }

        int insertionCount = 0;
        final int valuesCount = allValues.length;
        for (int i = 0; i < valuesCount; i++) {
            ContentValues values = allValues[i];
            if (insert(uri, values) != null) {
                insertionCount++;
            }
        }

        return insertionCount;
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "delete() for user: " + UserHandle.getCallingUserId());
        }

        Arguments args = new Arguments(uri, where, whereArgs, false);

        // If a legacy table that is gone, done.
        if (REMOVED_LEGACY_TABLES.contains(args.table)) {
            return 0;
        }

        if (!isKeyValid(args.name)) {
            return 0;
        }

        switch (args.table) {
            case TABLE_GLOBAL: {
                final int userId = UserHandle.getCallingUserId();
                return deleteGlobalSetting(args.name, userId, false) ? 1 : 0;
            }

            case TABLE_SECURE: {
                final int userId = UserHandle.getCallingUserId();
                return deleteSecureSetting(args.name, userId, false) ? 1 : 0;
            }

            case TABLE_SYSTEM: {
                final int userId = UserHandle.getCallingUserId();
                return deleteSystemSetting(args.name, userId) ? 1 : 0;
            }

            default: {
                throw new IllegalArgumentException("Bad Uri path:" + uri);
            }
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "update() for user: " + UserHandle.getCallingUserId());
        }

        Arguments args = new Arguments(uri, where, whereArgs, false);

        // If a legacy table that is gone, done.
        if (REMOVED_LEGACY_TABLES.contains(args.table)) {
            return 0;
        }

        String name = values.getAsString(Settings.Secure.NAME);
        if (!isKeyValid(name)) {
            return 0;
        }
        String value = values.getAsString(Settings.Secure.VALUE);

        switch (args.table) {
            case TABLE_GLOBAL: {
                final int userId = UserHandle.getCallingUserId();
                return updateGlobalSetting(args.name, value, null, false,
                        userId, false) ? 1 : 0;
            }

            case TABLE_SECURE: {
                final int userId = UserHandle.getCallingUserId();
                return updateSecureSetting(args.name, value, null, false,
                        userId, false) ? 1 : 0;
            }

            case TABLE_SYSTEM: {
                final int userId = UserHandle.getCallingUserId();
                return updateSystemSetting(args.name, value, userId) ? 1 : 0;
            }

            default: {
                throw new IllegalArgumentException("Invalid Uri path:" + uri);
            }
        }
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        final int userId = getUserIdFromUri(uri, UserHandle.getCallingUserId());
        if (userId != UserHandle.getCallingUserId()) {
            getContext().enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS,
                    "Access files from the settings of another user");
        }
        uri = ContentProvider.getUriWithoutUserId(uri);

        final String cacheRingtoneSetting;
        final String cacheName;
        if (Settings.System.RINGTONE_CACHE_URI.equals(uri)) {
            cacheRingtoneSetting = Settings.System.RINGTONE;
            cacheName = Settings.System.RINGTONE_CACHE;
        } else if (Settings.System.NOTIFICATION_SOUND_CACHE_URI.equals(uri)) {
            cacheRingtoneSetting = Settings.System.NOTIFICATION_SOUND;
            cacheName = Settings.System.NOTIFICATION_SOUND_CACHE;
        } else if (Settings.System.ALARM_ALERT_CACHE_URI.equals(uri)) {
            cacheRingtoneSetting = Settings.System.ALARM_ALERT;
            cacheName = Settings.System.ALARM_ALERT_CACHE;
        } else {
            throw new FileNotFoundException("Direct file access no longer supported; "
                    + "ringtone playback is available through android.media.Ringtone");
        }

        int actualCacheOwner;
        // Redirect cache to parent if ringtone setting is owned by profile parent
        synchronized (mLock) {
            actualCacheOwner = resolveOwningUserIdForSystemSettingLocked(userId,
                    cacheRingtoneSetting);
        }
        final File cacheFile = new File(getRingtoneCacheDir(actualCacheOwner), cacheName);
        return ParcelFileDescriptor.open(cacheFile, ParcelFileDescriptor.parseMode(mode));
    }

    private File getRingtoneCacheDir(int userId) {
        final File cacheDir = new File(Environment.getDataSystemDeDirectory(userId), "ringtones");
        cacheDir.mkdir();
        SELinux.restorecon(cacheDir);
        return cacheDir;
    }

    /**
     * Dump all settings as a proto buf.
     *
     * @param fd The file to dump to
     */
    void dumpProto(@NonNull FileDescriptor fd) {
        ProtoOutputStream proto = new ProtoOutputStream(fd);

        synchronized (mLock) {
            SettingsProtoDumpUtil.dumpProtoLocked(mSettingsRegistry, proto);
        }

        proto.flush();
    }

    public void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) {
        synchronized (mLock) {
            final long identity = Binder.clearCallingIdentity();
            try {
                SparseBooleanArray users = mSettingsRegistry.getKnownUsersLocked();
                final int userCount = users.size();
                for (int i = 0; i < userCount; i++) {
                    dumpForUserLocked(users.keyAt(i), pw);
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }
    }

    @GuardedBy("mLock")
    private void dumpForUserLocked(int userId, PrintWriter pw) {
        if (userId == UserHandle.USER_SYSTEM) {
            pw.println("CONFIG SETTINGS (user " + userId + ")");
            SettingsState configSettings = mSettingsRegistry.getSettingsLocked(
                    SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
            if (configSettings != null) {
                dumpSettingsLocked(configSettings, pw);
                pw.println();
                configSettings.dumpHistoricalOperations(pw);
            }

            pw.println("GLOBAL SETTINGS (user " + userId + ")");
            SettingsState globalSettings = mSettingsRegistry.getSettingsLocked(
                    SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
            if (globalSettings != null) {
                dumpSettingsLocked(globalSettings, pw);
                pw.println();
                globalSettings.dumpHistoricalOperations(pw);
            }
        }

        pw.println("SECURE SETTINGS (user " + userId + ")");
        SettingsState secureSettings = mSettingsRegistry.getSettingsLocked(
                SETTINGS_TYPE_SECURE, userId);
        if (secureSettings != null) {
            dumpSettingsLocked(secureSettings, pw);
            pw.println();
            secureSettings.dumpHistoricalOperations(pw);
        }

        pw.println("SYSTEM SETTINGS (user " + userId + ")");
        SettingsState systemSettings = mSettingsRegistry.getSettingsLocked(
                SETTINGS_TYPE_SYSTEM, userId);
        if (systemSettings != null) {
            dumpSettingsLocked(systemSettings, pw);
            pw.println();
            systemSettings.dumpHistoricalOperations(pw);
        }
    }

    private void dumpSettingsLocked(SettingsState settingsState, PrintWriter pw) {
        List<String> names = settingsState.getSettingNamesLocked();

        final int nameCount = names.size();

        for (int i = 0; i < nameCount; i++) {
            String name = names.get(i);
            Setting setting = settingsState.getSettingLocked(name);
            pw.print("_id:"); pw.print(toDumpString(setting.getId()));
            pw.print(" name:"); pw.print(toDumpString(name));
            if (setting.getPackageName() != null) {
                pw.print(" pkg:"); pw.print(setting.getPackageName());
            }
            pw.print(" value:"); pw.print(toDumpString(setting.getValue()));
            if (setting.getDefaultValue() != null) {
                pw.print(" default:"); pw.print(setting.getDefaultValue());
                pw.print(" defaultSystemSet:"); pw.print(setting.isDefaultFromSystem());
            }
            if (setting.getTag() != null) {
                pw.print(" tag:"); pw.print(setting.getTag());
            }
            pw.println();
        }
    }

    private static String toDumpString(String s) {
        if (s != null) {
            return s;
        }
        return "{null}";
    }

    private void registerBroadcastReceivers() {
        IntentFilter userFilter = new IntentFilter();
        userFilter.addAction(Intent.ACTION_USER_REMOVED);
        userFilter.addAction(Intent.ACTION_USER_STOPPED);

        getContext().registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                        UserHandle.USER_SYSTEM);

                switch (intent.getAction()) {
                    case Intent.ACTION_USER_REMOVED: {
                        synchronized (mLock) {
                            mSettingsRegistry.removeUserStateLocked(userId, true);
                        }
                    } break;

                    case Intent.ACTION_USER_STOPPED: {
                        synchronized (mLock) {
                            mSettingsRegistry.removeUserStateLocked(userId, false);
                        }
                    } break;
                }
            }
        }, userFilter);

        PackageMonitor monitor = new PackageMonitor() {
            @Override
            public void onPackageRemoved(String packageName, int uid) {
                synchronized (mLock) {
                    mSettingsRegistry.removeSettingsForPackageLocked(packageName,
                            UserHandle.getUserId(uid));
                }
            }

            @Override
            public void onUidRemoved(int uid) {
                synchronized (mLock) {
                    mSettingsRegistry.onUidRemovedLocked(uid);
                }
            }

            @Override
            public void onPackageDataCleared(String packageName, int uid) {
                synchronized (mLock) {
                    mSettingsRegistry.removeSettingsForPackageLocked(packageName,
                            UserHandle.getUserId(uid));
                }
            }
        };

        // package changes
        monitor.register(getContext(), BackgroundThread.getHandler().getLooper(),
                UserHandle.ALL, true);
    }

    private void startWatchingUserRestrictionChanges() {
        // TODO: The current design of settings looking different based on user restrictions
        // should be reworked to keep them separate and system code should check the setting
        // first followed by checking the user restriction before performing an operation.
        UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
        userManager.addUserRestrictionsListener((int userId, Bundle newRestrictions,
                Bundle prevRestrictions) -> {
            Set<String> changedRestrictions = getRestrictionDiff(prevRestrictions, newRestrictions);
            // We are changing the settings affected by restrictions to their current
            // value with a forced update to ensure that all cross profile dependencies
            // are taken into account. Also make sure the settings update to.. the same
            // value passes the security checks, so clear binder calling id.
            if (changedRestrictions.contains(UserManager.DISALLOW_SHARE_LOCATION)) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    synchronized (mLock) {
                        Setting setting = getSecureSetting(
                                Settings.Secure.LOCATION_MODE, userId);
                        updateSecureSetting(Settings.Secure.LOCATION_MODE,
                                setting != null ? setting.getValue() : null, null,
                                true, userId, true);
                        setting = getSecureSetting(
                                Settings.Secure.LOCATION_PROVIDERS_ALLOWED, userId);
                        updateSecureSetting(Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                                setting != null ? setting.getValue() : null, null,
                                true, userId, true);
                    }
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
            if (changedRestrictions.contains(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
                    || changedRestrictions.contains(
                            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY)) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    synchronized (mLock) {
                        Setting setting = getGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS);
                        String value = setting != null ? setting.getValue() : null;
                        updateGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS,
                                value, null, true, userId, true);
                    }
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
            if (changedRestrictions.contains(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    synchronized (mLock) {
                        Setting setting = getGlobalSetting(Settings.Global.ADB_ENABLED);
                        String value = setting != null ? setting.getValue() : null;
                        updateGlobalSetting(Settings.Global.ADB_ENABLED,
                                value, null, true, userId, true);
                    }
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
            if (changedRestrictions.contains(UserManager.ENSURE_VERIFY_APPS)) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    synchronized (mLock) {
                        Setting enable = getGlobalSetting(
                                Settings.Global.PACKAGE_VERIFIER_ENABLE);
                        String enableValue = enable != null ? enable.getValue() : null;
                        updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_ENABLE,
                                enableValue, null, true, userId, true);
                        Setting include = getGlobalSetting(
                                Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB);
                        String includeValue = include != null ? include.getValue() : null;
                        updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB,
                                includeValue, null, true, userId, true);
                    }
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
            if (changedRestrictions.contains(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    synchronized (mLock) {
                        Setting setting = getGlobalSetting(
                                Settings.Global.PREFERRED_NETWORK_MODE);
                        String value = setting != null ? setting.getValue() : null;
                        updateGlobalSetting(Settings.Global.PREFERRED_NETWORK_MODE,
                                value, null, true, userId, true);
                    }
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
        });
    }

    private static Set<String> getRestrictionDiff(Bundle prevRestrictions, Bundle newRestrictions) {
        Set<String> restrictionNames = Sets.newArraySet();
        restrictionNames.addAll(prevRestrictions.keySet());
        restrictionNames.addAll(newRestrictions.keySet());
        Set<String> diff = Sets.newArraySet();
        for (String restrictionName : restrictionNames) {
            if (prevRestrictions.getBoolean(restrictionName) != newRestrictions.getBoolean(
                    restrictionName)) {
                diff.add(restrictionName);
            }
        }
        return diff;
    }

    private Setting getConfigSetting(String name) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getConfigSetting(" + name + ")");
        }

        DeviceConfig.enforceReadPermission(getContext(), /*namespace=*/name.split("/")[0]);

        // Get the value.
        synchronized (mLock) {
            return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_CONFIG,
                    UserHandle.USER_SYSTEM, name);
        }
    }

    private boolean insertConfigSetting(String name, String value, boolean makeDefault) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "insertConfigSetting(" + name + ", " + value  + ", "
                    + makeDefault + ")");
        }
        return mutateConfigSetting(name, value, null, makeDefault,
                MUTATION_OPERATION_INSERT, 0);
    }

    private boolean deleteConfigSetting(String name) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "deleteConfigSetting(" + name + ")");
        }
        return mutateConfigSetting(name, null, null, false,
                MUTATION_OPERATION_DELETE, 0);
    }

    private void resetConfigSetting(int mode, String prefix) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "resetConfigSetting(" + mode + ", " + prefix + ")");
        }
        mutateConfigSetting(null, null, prefix, false,
                MUTATION_OPERATION_RESET, mode);
    }

    private boolean mutateConfigSetting(String name, String value, String prefix,
            boolean makeDefault, int operation, int mode) {
        enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);

        // Perform the mutation.
        synchronized (mLock) {
            switch (operation) {
                case MUTATION_OPERATION_INSERT: {
                    return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
                            UserHandle.USER_SYSTEM, name, value, null, makeDefault, true,
                            resolveCallingPackage(), false, null);
                }

                case MUTATION_OPERATION_DELETE: {
                    return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_CONFIG,
                            UserHandle.USER_SYSTEM, name, false, null);
                }

                case MUTATION_OPERATION_RESET: {
                    mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG,
                            UserHandle.USER_SYSTEM, resolveCallingPackage(), mode, null, prefix);
                } return true;
            }
        }

        return false;
    }

    private Map<String, String> getAllConfigFlags(@Nullable String prefix) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix);
        }

        synchronized (mLock) {
            // Get the settings.
            SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
                    SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);

            List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_CONFIG,
                    UserHandle.USER_SYSTEM);

            final int nameCount = names.size();
            Map<String, String> flagsToValues = new HashMap<>(names.size());

            for (int i = 0; i < nameCount; i++) {
                String name = names.get(i);
                Setting setting = settingsState.getSettingLocked(name);
                if (prefix == null || setting.getName().startsWith(prefix)) {
                    flagsToValues.put(setting.getName(), setting.getValue());
                }
            }

            return flagsToValues;
        }
    }

    private Cursor getAllGlobalSettings(String[] projection) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getAllGlobalSettings()");
        }

        synchronized (mLock) {
            // Get the settings.
            SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
                    SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);

            List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_GLOBAL,
                    UserHandle.USER_SYSTEM);

            final int nameCount = names.size();

            String[] normalizedProjection = normalizeProjection(projection);
            MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);

            // Anyone can get the global settings, so no security checks.
            for (int i = 0; i < nameCount; i++) {
                String name = names.get(i);
                Setting setting = settingsState.getSettingLocked(name);
                appendSettingToCursor(result, setting);
            }

            return result;
        }
    }

    private Setting getGlobalSetting(String name) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")");
        }

        // Ensure the caller can access the setting.
        enforceSettingReadable(name, SETTINGS_TYPE_GLOBAL, UserHandle.getCallingUserId());

        // Get the value.
        synchronized (mLock) {
            return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_GLOBAL,
                    UserHandle.USER_SYSTEM, name);
        }
    }

    private boolean updateGlobalSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, boolean forceNotify) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ", "
                    + ", " + tag + ", " + makeDefault + ", " + requestingUserId
                    + ", " + forceNotify + ")");
        }
        return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
                MUTATION_OPERATION_UPDATE, forceNotify, 0);
    }

    private boolean insertGlobalSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, boolean forceNotify) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value  + ", "
                    + ", " + tag + ", " + makeDefault + ", " + requestingUserId
                    + ", " + forceNotify + ")");
        }
        return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
                MUTATION_OPERATION_INSERT, forceNotify, 0);
    }

    private boolean deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "deleteGlobalSetting(" + name + ", " + requestingUserId
                    + ", " + forceNotify + ")");
        }
        return mutateGlobalSetting(name, null, null, false, requestingUserId,
                MUTATION_OPERATION_DELETE, forceNotify, 0);
    }

    private void resetGlobalSetting(int requestingUserId, int mode, String tag) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "resetGlobalSetting(" + requestingUserId + ", "
                    + mode + ", " + tag + ")");
        }
        mutateGlobalSetting(null, null, tag, false, requestingUserId,
                MUTATION_OPERATION_RESET, false, mode);
    }

    private boolean mutateGlobalSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
            int mode) {
        // Make sure the caller can change the settings - treated as secure.
        enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);

        // Resolve the userId on whose behalf the call is made.
        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);

        // If this is a setting that is currently restricted for this user, do not allow
        // unrestricting changes.
        if (name != null && mUserManagerInternal.isSettingRestrictedForUser(
                name, callingUserId, value, Binder.getCallingUid())) {
            return false;
        }

        // Perform the mutation.
        synchronized (mLock) {
            switch (operation) {
                case MUTATION_OPERATION_INSERT: {
                    return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
                            UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
                            getCallingPackage(), forceNotify, CRITICAL_GLOBAL_SETTINGS);
                }

                case MUTATION_OPERATION_DELETE: {
                    return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_GLOBAL,
                            UserHandle.USER_SYSTEM, name, forceNotify, CRITICAL_GLOBAL_SETTINGS);
                }

                case MUTATION_OPERATION_UPDATE: {
                    return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_GLOBAL,
                            UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
                            getCallingPackage(), forceNotify, CRITICAL_GLOBAL_SETTINGS);
                }

                case MUTATION_OPERATION_RESET: {
                    mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_GLOBAL,
                            UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
                } return true;
            }
        }

        return false;
    }

    private PackageInfo getCallingPackageInfo(int userId) {
        try {
            return mPackageManager.getPackageInfo(getCallingPackage(),
                    PackageManager.GET_SIGNATURES, userId);
        } catch (RemoteException e) {
            throw new IllegalStateException("Package " + getCallingPackage() + " doesn't exist");
        }
    }

    private Cursor getAllSecureSettings(int userId, String[] projection) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")");
        }

        // Resolve the userId on whose behalf the call is made.
        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);

        // The relevant "calling package" userId will be the owning userId for some
        // profiles, and we can't do the lookup inside our [lock held] loop, so work out
        // up front who the effective "new SSAID" user ID for that settings name will be.
        final int ssaidUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
                Settings.Secure.ANDROID_ID);
        final PackageInfo ssaidCallingPkg = getCallingPackageInfo(ssaidUserId);

        synchronized (mLock) {
            List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SECURE, callingUserId);

            final int nameCount = names.size();

            String[] normalizedProjection = normalizeProjection(projection);
            MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);

            for (int i = 0; i < nameCount; i++) {
                String name = names.get(i);
                // Determine the owning user as some profile settings are cloned from the parent.
                final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
                        name);

                if (!isSecureSettingAccessible(name, callingUserId, owningUserId)) {
                    // This caller is not permitted to access this setting. Pretend the setting
                    // doesn't exist.
                    continue;
                }

                // As of Android O, the SSAID is read from an app-specific entry in table
                // SETTINGS_FILE_SSAID, unless accessed by a system process.
                final Setting setting;
                if (isNewSsaidSetting(name)) {
                    setting = getSsaidSettingLocked(ssaidCallingPkg, owningUserId);
                } else {
                    setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE, owningUserId,
                            name);
                }
                appendSettingToCursor(result, setting);
            }

            return result;
        }
    }

    private Setting getSecureSetting(String name, int requestingUserId) {
        return getSecureSetting(name, requestingUserId, /*enableOverride=*/ false);
    }

    private Setting getSecureSetting(String name, int requestingUserId, boolean enableOverride) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")");
        }

        // Resolve the userId on whose behalf the call is made.
        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);

        // Ensure the caller can access the setting.
        enforceSettingReadable(name, SETTINGS_TYPE_SECURE, UserHandle.getCallingUserId());

        // Determine the owning user as some profile settings are cloned from the parent.
        final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);

        if (!isSecureSettingAccessible(name, callingUserId, owningUserId)) {
            // This caller is not permitted to access this setting. Pretend the setting doesn't
            // exist.
            SettingsState settings = mSettingsRegistry.getSettingsLocked(SETTINGS_TYPE_SECURE,
                    owningUserId);
            return settings != null ? settings.getNullSetting() : null;
        }

        // As of Android O, the SSAID is read from an app-specific entry in table
        // SETTINGS_FILE_SSAID, unless accessed by a system process.
        if (isNewSsaidSetting(name)) {
            PackageInfo callingPkg = getCallingPackageInfo(owningUserId);
            synchronized (mLock) {
                return getSsaidSettingLocked(callingPkg, owningUserId);
            }
        }
        if (enableOverride) {
            if (Secure.LOCATION_MODE.equals(name)) {
                final Setting overridden = getLocationModeSetting(owningUserId);
                if (overridden != null) {
                    return overridden;
                }
            }
        }

        // Not the SSAID; do a straight lookup
        synchronized (mLock) {
            return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE,
                    owningUserId, name);
        }
    }

    private boolean isNewSsaidSetting(String name) {
        return Settings.Secure.ANDROID_ID.equals(name)
                && UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID;
    }

    @GuardedBy("mLock")
    private Setting getSsaidSettingLocked(PackageInfo callingPkg, int owningUserId) {
        // Get uid of caller (key) used to store ssaid value
        String name = Integer.toString(
                UserHandle.getUid(owningUserId, UserHandle.getAppId(Binder.getCallingUid())));

        if (DEBUG) {
            Slog.v(LOG_TAG, "getSsaidSettingLocked(" + name + "," + owningUserId + ")");
        }

        // Retrieve the ssaid from the table if present.
        final Setting ssaid = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId,
                name);
        // If the app is an Instant App use its stored SSAID instead of our own.
        final String instantSsaid;
        final long token = Binder.clearCallingIdentity();
        try {
            instantSsaid = mPackageManager.getInstantAppAndroidId(callingPkg.packageName,
                    owningUserId);
        } catch (RemoteException e) {
            Slog.e(LOG_TAG, "Failed to get Instant App Android ID", e);
            return null;
        } finally {
            Binder.restoreCallingIdentity(token);
        }

        final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked(
                SETTINGS_TYPE_SSAID, owningUserId);

        if (instantSsaid != null) {
            // Use the stored value if it is still valid.
            if (ssaid != null && instantSsaid.equals(ssaid.getValue())) {
                return mascaradeSsaidSetting(ssaidSettings, ssaid);
            }
            // The value has changed, update the stored value.
            final boolean success = ssaidSettings.insertSettingLocked(name, instantSsaid, null,
                    true, callingPkg.packageName);
            if (!success) {
                throw new IllegalStateException("Failed to update instant app android id");
            }
            Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID,
                    owningUserId, name);
            return mascaradeSsaidSetting(ssaidSettings, setting);
        }

        // Lazy initialize ssaid if not yet present in ssaid table.
        if (ssaid == null || ssaid.isNull() || ssaid.getValue() == null) {
            Setting setting = mSettingsRegistry.generateSsaidLocked(callingPkg, owningUserId);
            return mascaradeSsaidSetting(ssaidSettings, setting);
        }

        return mascaradeSsaidSetting(ssaidSettings, ssaid);
    }

    private Setting mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting) {
        // SSAID settings are located in a dedicated table for internal bookkeeping
        // but for the world they reside in the secure table, so adjust the key here.
        // We have a special name when looking it up but want the world to see it as
        // "android_id".
        if (ssaidSetting != null) {
            return settingsState.new Setting(ssaidSetting) {
                @Override
                public int getKey() {
                    final int userId = getUserIdFromKey(super.getKey());
                    return makeKey(SETTINGS_TYPE_SECURE, userId);
                }

                @Override
                public String getName() {
                    return Settings.Secure.ANDROID_ID;
                }
            };
        }
        return null;
    }

    private Setting getLocationModeSetting(int owningUserId) {
        synchronized (mLock) {
            final Setting setting = getGlobalSetting(
                    Global.LOCATION_GLOBAL_KILL_SWITCH);
            if (!"1".equals(setting.getValue())) {
                return null;
            }
            // Global kill-switch is enabled. Return an empty value.
            final SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
                    SETTINGS_TYPE_SECURE, owningUserId);
            return settingsState.new Setting(
                    Secure.LOCATION_MODE,
                    "", // value
                    "", // tag
                    "", // default value
                    "", // package name
                    false, // from system
                    "0" // id
            ) {
                @Override
                public boolean update(String value, boolean setDefault, String packageName,
                        String tag, boolean forceNonSystemPackage) {
                    Slog.wtf(LOG_TAG, "update shouldn't be called on this instance.");
                    return false;
                }
            };
        }
    }

    private boolean insertSecureSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, boolean forceNotify) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", "
                    + ", " + tag  + ", " + makeDefault + ", "  + requestingUserId
                    + ", " + forceNotify + ")");
        }
        return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
                MUTATION_OPERATION_INSERT, forceNotify, 0);
    }

    private boolean deleteSecureSetting(String name, int requestingUserId, boolean forceNotify) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId
                    + ", " + forceNotify + ")");
        }

        return mutateSecureSetting(name, null, null, false, requestingUserId,
                MUTATION_OPERATION_DELETE, forceNotify, 0);
    }

    private boolean updateSecureSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, boolean forceNotify) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", "
                    + ", " + tag  + ", " + makeDefault + ", "  + requestingUserId
                    + ", "  + forceNotify +")");
        }

        return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
                MUTATION_OPERATION_UPDATE, forceNotify, 0);
    }

    private void resetSecureSetting(int requestingUserId, int mode, String tag) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "resetSecureSetting(" + requestingUserId + ", "
                    + mode + ", " + tag + ")");
        }

        mutateSecureSetting(null, null, tag, false, requestingUserId,
                MUTATION_OPERATION_RESET, false, mode);
    }

    private boolean mutateSecureSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
            int mode) {
        // Make sure the caller can change the settings.
        enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);

        // Resolve the userId on whose behalf the call is made.
        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);

        // If this is a setting that is currently restricted for this user, do not allow
        // unrestricting changes.
        if (name != null && mUserManagerInternal.isSettingRestrictedForUser(
                name, callingUserId, value, Binder.getCallingUid())) {
            return false;
        }

        // Determine the owning user as some profile settings are cloned from the parent.
        final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);

        // Only the owning user can change the setting.
        if (owningUserId != callingUserId) {
            return false;
        }

        // Special cases for location providers (sigh).
        if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
            return updateLocationProvidersAllowedLocked(value, tag, owningUserId, makeDefault,
                    forceNotify);
        }

        // Mutate the value.
        synchronized (mLock) {
            switch (operation) {
                case MUTATION_OPERATION_INSERT: {
                    return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
                            owningUserId, name, value, tag, makeDefault,
                            getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
                }

                case MUTATION_OPERATION_DELETE: {
                    return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SECURE,
                            owningUserId, name, forceNotify, CRITICAL_SECURE_SETTINGS);
                }

                case MUTATION_OPERATION_UPDATE: {
                    return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SECURE,
                            owningUserId, name, value, tag, makeDefault,
                            getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
                }

                case MUTATION_OPERATION_RESET: {
                    mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_SECURE,
                            UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
                } return true;
            }
        }

        return false;
    }

    private Cursor getAllSystemSettings(int userId, String[] projection) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getAllSecureSystem(" + userId + ")");
        }

        // Resolve the userId on whose behalf the call is made.
        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);

        synchronized (mLock) {
            List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SYSTEM, callingUserId);

            final int nameCount = names.size();

            String[] normalizedProjection = normalizeProjection(projection);
            MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);

            for (int i = 0; i < nameCount; i++) {
                String name = names.get(i);

                // Determine the owning user as some profile settings are cloned from the parent.
                final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId,
                        name);

                Setting setting = mSettingsRegistry.getSettingLocked(
                        SETTINGS_TYPE_SYSTEM, owningUserId, name);
                appendSettingToCursor(result, setting);
            }

            return result;
        }
    }

    private Setting getSystemSetting(String name, int requestingUserId) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")");
        }

        // Resolve the userId on whose behalf the call is made.
        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);

        // Ensure the caller can access the setting.
        enforceSettingReadable(name, SETTINGS_TYPE_SYSTEM, UserHandle.getCallingUserId());

        // Determine the owning user as some profile settings are cloned from the parent.
        final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);

        // Get the value.
        synchronized (mLock) {
            return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SYSTEM, owningUserId, name);
        }
    }

    private boolean insertSystemSetting(String name, String value, int requestingUserId) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", "
                    + requestingUserId + ")");
        }

        return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
    }

    private boolean deleteSystemSetting(String name, int requestingUserId) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "deleteSystemSetting(" + name + ", " + requestingUserId + ")");
        }

        return mutateSystemSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
    }

    private boolean updateSystemSetting(String name, String value, int requestingUserId) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "updateSystemSetting(" + name + ", " + value + ", "
                    + requestingUserId + ")");
        }

        return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
    }

    private boolean mutateSystemSetting(String name, String value, int runAsUserId,
            int operation) {
        if (!hasWriteSecureSettingsPermission()) {
            // If the caller doesn't hold WRITE_SECURE_SETTINGS, we verify whether this
            // operation is allowed for the calling package through appops.
            if (!Settings.checkAndNoteWriteSettingsOperation(getContext(),
                    Binder.getCallingUid(), getCallingPackage(), true)) {
                return false;
            }
        }

        // Resolve the userId on whose behalf the call is made.
        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(runAsUserId);

        if (name != null && mUserManagerInternal.isSettingRestrictedForUser(
                name, callingUserId, value, Binder.getCallingUid())) {
            return false;
        }

        // Enforce what the calling package can mutate the system settings.
        enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name, callingUserId);

        // Determine the owning user as some profile settings are cloned from the parent.
        final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);

        // Only the owning user id can change the setting.
        if (owningUserId != callingUserId) {
            return false;
        }

        // Invalidate any relevant cache files
        String cacheName = null;
        if (Settings.System.RINGTONE.equals(name)) {
            cacheName = Settings.System.RINGTONE_CACHE;
        } else if (Settings.System.NOTIFICATION_SOUND.equals(name)) {
            cacheName = Settings.System.NOTIFICATION_SOUND_CACHE;
        } else if (Settings.System.ALARM_ALERT.equals(name)) {
            cacheName = Settings.System.ALARM_ALERT_CACHE;
        }
        if (cacheName != null) {
            final File cacheFile = new File(
                    getRingtoneCacheDir(owningUserId), cacheName);
            cacheFile.delete();
        }

        // Mutate the value.
        synchronized (mLock) {
            switch (operation) {
                case MUTATION_OPERATION_INSERT: {
                    validateSystemSettingValue(name, value);
                    return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SYSTEM,
                            owningUserId, name, value, null, false, getCallingPackage(),
                            false, null);
                }

                case MUTATION_OPERATION_DELETE: {
                    return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SYSTEM,
                            owningUserId, name, false, null);
                }

                case MUTATION_OPERATION_UPDATE: {
                    validateSystemSettingValue(name, value);
                    return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SYSTEM,
                            owningUserId, name, value, null, false, getCallingPackage(),
                            false, null);
                }
            }

            return false;
        }
    }

    private boolean hasWriteSecureSettingsPermission() {
        // Write secure settings is a more protected permission. If caller has it we are good.
        if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        }

        return false;
    }

    private void validateSystemSettingValue(String name, String value) {
        SettingsValidators.Validator validator = Settings.System.VALIDATORS.get(name);
        if (validator != null && !validator.validate(value)) {
            throw new IllegalArgumentException("Invalid value: " + value
                    + " for setting: " + name);
        }
    }

    /**
     * Returns {@code true} if the specified secure setting should be accessible to the caller.
     */
    private boolean isSecureSettingAccessible(String name, int callingUserId,
            int owningUserId) {
        // Special case for location (sigh).
        // This check is not inside the name-based checks below because this method performs checks
        // only if the calling user ID is not the same as the owning user ID.
        if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) {
            return false;
        }

        switch (name) {
            case "bluetooth_address":
                // BluetoothManagerService for some reason stores the Android's Bluetooth MAC
                // address in this secure setting. Secure settings can normally be read by any app,
                // which thus enables them to bypass the recently introduced restrictions on access
                // to device identifiers.
                // To mitigate this we make this setting available only to callers privileged to see
                // this device's MAC addresses, same as through public API
                // BluetoothAdapter.getAddress() (see BluetoothManagerService for details).
                return getContext().checkCallingOrSelfPermission(
                        Manifest.permission.LOCAL_MAC_ADDRESS) == PackageManager.PERMISSION_GRANTED;
            default:
                return true;
        }
    }

    private boolean isLocationProvidersAllowedRestricted(String name, int callingUserId,
            int owningUserId) {
        // Optimization - location providers are restricted only for managed profiles.
        if (callingUserId == owningUserId) {
            return false;
        }
        if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)
                && mUserManager.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION,
                new UserHandle(callingUserId))) {
            return true;
        }
        return false;
    }

    private int resolveOwningUserIdForSecureSettingLocked(int userId, String setting) {
        return resolveOwningUserIdLocked(userId, sSecureCloneToManagedSettings, setting);
    }

    private int resolveOwningUserIdForSystemSettingLocked(int userId, String setting) {
        final int parentId;
        // Resolves dependency if setting has a dependency and the calling user has a parent
        if (sSystemCloneFromParentOnDependency.containsKey(setting)
                && (parentId = getGroupParentLocked(userId)) != userId) {
            // The setting has a dependency and the profile has a parent
            String dependency = sSystemCloneFromParentOnDependency.get(setting);
            // Lookup the dependency setting as ourselves, some callers may not have access to it.
            final long token = Binder.clearCallingIdentity();
            try {
                Setting settingObj = getSecureSetting(dependency, userId);
                if (settingObj != null && settingObj.getValue().equals("1")) {
                    return parentId;
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }
        return resolveOwningUserIdLocked(userId, sSystemCloneToManagedSettings, setting);
    }

    private int resolveOwningUserIdLocked(int userId, Set<String> keys, String name) {
        final int parentId = getGroupParentLocked(userId);
        if (parentId != userId && keys.contains(name)) {
            return parentId;
        }
        return userId;
    }

    private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation,
            String name, int userId) {
        // System/root/shell can mutate whatever secure settings they want.
        final int callingUid = Binder.getCallingUid();
        final int appId = UserHandle.getAppId(callingUid);
        if (appId == android.os.Process.SYSTEM_UID
                || appId == Process.SHELL_UID
                || appId == Process.ROOT_UID) {
            return;
        }

        switch (operation) {
            case MUTATION_OPERATION_INSERT:
                // Insert updates.
            case MUTATION_OPERATION_UPDATE: {
                if (Settings.System.PUBLIC_SETTINGS.contains(name)) {
                    return;
                }

                // The calling package is already verified.
                PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);

                // Privileged apps can do whatever they want.
                if ((packageInfo.applicationInfo.privateFlags
                        & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
                    return;
                }

                warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
                        packageInfo.applicationInfo.targetSdkVersion, name);
            } break;

            case MUTATION_OPERATION_DELETE: {
                if (Settings.System.PUBLIC_SETTINGS.contains(name)
                        || Settings.System.PRIVATE_SETTINGS.contains(name)) {
                    throw new IllegalArgumentException("You cannot delete system defined"
                            + " secure settings.");
                }

                // The calling package is already verified.
                PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);

                // Privileged apps can do whatever they want.
                if ((packageInfo.applicationInfo.privateFlags &
                        ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
                    return;
                }

                warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
                        packageInfo.applicationInfo.targetSdkVersion, name);
            } break;
        }
    }

    private Set<String> getInstantAppAccessibleSettings(int settingsType) {
        switch (settingsType) {
            case SETTINGS_TYPE_GLOBAL:
                return Settings.Global.INSTANT_APP_SETTINGS;
            case SETTINGS_TYPE_SECURE:
                return Settings.Secure.INSTANT_APP_SETTINGS;
            case SETTINGS_TYPE_SYSTEM:
                return Settings.System.INSTANT_APP_SETTINGS;
            default:
                throw new IllegalArgumentException("Invalid settings type: " + settingsType);
        }
    }

    private Set<String> getOverlayInstantAppAccessibleSettings(int settingsType) {
        switch (settingsType) {
            case SETTINGS_TYPE_GLOBAL:
                return OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS;
            case SETTINGS_TYPE_SYSTEM:
                return OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS;
            case SETTINGS_TYPE_SECURE:
                return OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS;
            default:
                throw new IllegalArgumentException("Invalid settings type: " + settingsType);
        }
    }

    @GuardedBy("mLock")
    private List<String> getSettingsNamesLocked(int settingsType, int userId) {
        // Don't enforce the instant app whitelist for now -- its too prone to unintended breakage
        // in the current form.
        return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId);
    }

    private void enforceSettingReadable(String settingName, int settingsType, int userId) {
        if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
            return;
        }
        ApplicationInfo ai = getCallingApplicationInfoOrThrow();
        if (!ai.isInstantApp()) {
            return;
        }
        if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)
                && !getOverlayInstantAppAccessibleSettings(settingsType).contains(settingName)) {
            // Don't enforce the instant app whitelist for now -- its too prone to unintended
            // breakage in the current form.
            Slog.w(LOG_TAG, "Instant App " + ai.packageName
                    + " trying to access unexposed setting, this will be an error in the future.");
        }
    }

    private ApplicationInfo getCallingApplicationInfoOrThrow() {
        // We always use the callingUid for this lookup. This means that if hypothetically an
        // app was installed in user A with cross user and in user B as an Instant App
        // the app in A would be able to see all the settings in user B. However since cross
        // user is a system permission and the app must be uninstalled in B and then installed as
        // an Instant App that situation is not realistic or supported.
        ApplicationInfo ai = null;
        try {
            ai = mPackageManager.getApplicationInfo(getCallingPackage(), 0
                    , UserHandle.getCallingUserId());
        } catch (RemoteException ignored) {
        }
        if (ai == null) {
            throw new IllegalStateException("Failed to lookup info for package "
                    + getCallingPackage());
        }
        return ai;
    }

    private PackageInfo getCallingPackageInfoOrThrow(int userId) {
        try {
            PackageInfo packageInfo = mPackageManager.getPackageInfo(
                    getCallingPackage(), 0, userId);
            if (packageInfo != null) {
                return packageInfo;
            }
        } catch (RemoteException e) {
            /* ignore */
        }
        throw new IllegalStateException("Calling package doesn't exist");
    }

    private int getGroupParentLocked(int userId) {
        // Most frequent use case.
        if (userId == UserHandle.USER_SYSTEM) {
            return userId;
        }
        // We are in the same process with the user manager and the returned
        // user info is a cached instance, so just look up instead of cache.
        final long identity = Binder.clearCallingIdentity();
        try {
            // Just a lookup and not reentrant, so holding a lock is fine.
            UserInfo userInfo = mUserManager.getProfileParent(userId);
            return (userInfo != null) ? userInfo.id : userId;
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private void enforceWritePermission(String permission) {
        if (getContext().checkCallingOrSelfPermission(permission)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Permission denial: writing to settings requires:"
                    + permission);
        }
    }

    /*
     * Used to parse changes to the value of Settings.Secure.LOCATION_PROVIDERS_ALLOWED.
     * This setting contains a list of the currently enabled location providers.
     * But helper functions in android.providers.Settings can enable or disable
     * a single provider by using a "+" or "-" prefix before the provider name.
     *
     * <p>See also {@link com.android.server.pm.UserRestrictionsUtils#isSettingRestrictedForUser()}.
     * If DISALLOW_SHARE_LOCATION is set, the said method will only allow values with
     * the "-" prefix.
     *
     * @returns whether the enabled location providers changed.
     */
    @GuardedBy("mLock")
    private boolean updateLocationProvidersAllowedLocked(String value, String tag,
            int owningUserId, boolean makeDefault, boolean forceNotify) {
        if (TextUtils.isEmpty(value)) {
            return false;
        }
        Setting oldSetting = getSecureSetting(
                Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId);
        if (oldSetting == null) {
            return false;
        }
        String oldProviders = oldSetting.getValue();
        List<String> oldProvidersList = TextUtils.isEmpty(oldProviders)
                ? new ArrayList<>() : new ArrayList<>(Arrays.asList(oldProviders.split(",")));
        Set<String> newProvidersSet = new ArraySet<>();
        newProvidersSet.addAll(oldProvidersList);

        String[] providerUpdates = value.split(",");
        boolean inputError = false;
        for (String provider : providerUpdates) {
            // do not update location_providers_allowed when input is invalid
            if (TextUtils.isEmpty(provider)) {
                inputError = true;
                break;
            }
            final char prefix = provider.charAt(0);
            // do not update location_providers_allowed when input is invalid
            if (prefix != '+' && prefix != '-') {
                inputError = true;
                break;
            }
            // skip prefix
            provider = provider.substring(1);
            if (prefix == '+') {
                newProvidersSet.add(provider);
            } else if (prefix == '-') {
                newProvidersSet.remove(provider);
            }
        }
        String newProviders = TextUtils.join(",", newProvidersSet.toArray());
        if (inputError == true || newProviders.equals(oldProviders)) {
            // nothing changed, so no need to update the database
            if (forceNotify) {
                mSettingsRegistry.notifyForSettingsChange(
                        makeKey(SETTINGS_TYPE_SECURE, owningUserId),
                        Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
            }
            return false;
        }
        return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
                owningUserId, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, newProviders, tag,
                makeDefault, getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
    }

    private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
            int targetSdkVersion, String name) {
        // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash.
        if (targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
            if (Settings.System.PRIVATE_SETTINGS.contains(name)) {
                Slog.w(LOG_TAG, "You shouldn't not change private system settings."
                        + " This will soon become an error.");
            } else {
                Slog.w(LOG_TAG, "You shouldn't keep your settings in the secure settings."
                        + " This will soon become an error.");
            }
        } else {
            if (Settings.System.PRIVATE_SETTINGS.contains(name)) {
                throw new IllegalArgumentException("You cannot change private secure settings.");
            } else {
                throw new IllegalArgumentException("You cannot keep your settings in"
                        + " the secure settings.");
            }
        }
    }

    private static int resolveCallingUserIdEnforcingPermissionsLocked(int requestingUserId) {
        if (requestingUserId == UserHandle.getCallingUserId()) {
            return requestingUserId;
        }
        return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                Binder.getCallingUid(), requestingUserId, false, true,
                "get/set setting for user", null);
    }

    private Bundle packageValueForCallResult(Setting setting,
            boolean trackingGeneration) {
        if (!trackingGeneration) {
            if (setting == null || setting.isNull()) {
                return NULL_SETTING_BUNDLE;
            }
            return Bundle.forPair(Settings.NameValueTable.VALUE, setting.getValue());
        }
        Bundle result = new Bundle();
        result.putString(Settings.NameValueTable.VALUE,
                !setting.isNull() ? setting.getValue() : null);

        mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getKey());
        return result;
    }

    private static int getRequestingUserId(Bundle args) {
        final int callingUserId = UserHandle.getCallingUserId();
        return (args != null) ? args.getInt(Settings.CALL_METHOD_USER_KEY, callingUserId)
                : callingUserId;
    }

    private boolean isTrackingGeneration(Bundle args) {
        return args != null && args.containsKey(Settings.CALL_METHOD_TRACK_GENERATION_KEY);
    }

    private static String getSettingValue(Bundle args) {
        return (args != null) ? args.getString(Settings.NameValueTable.VALUE) : null;
    }

    private static String getSettingTag(Bundle args) {
        return (args != null) ? args.getString(Settings.CALL_METHOD_TAG_KEY) : null;
    }

    private static String getSettingPrefix(Bundle args) {
        String prefix = (args != null) ? args.getString(Settings.CALL_METHOD_PREFIX_KEY) : null;
        // Append '/' to ensure we only match properties with this exact prefix.
        // i.e. "foo" should match "foo/property" but not "foobar/property"
        return prefix != null ? prefix + "/" : null;
    }

    private static boolean getSettingMakeDefault(Bundle args) {
        return (args != null) && args.getBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY);
    }

    private static int getResetModeEnforcingPermission(Bundle args) {
        final int mode = (args != null) ? args.getInt(Settings.CALL_METHOD_RESET_MODE_KEY) : 0;
        switch (mode) {
            case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
                if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
                    throw new SecurityException("Only system, shell/root on a "
                            + "debuggable build can reset to untrusted defaults");
                }
                return mode;
            }
            case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
                if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
                    throw new SecurityException("Only system, shell/root on a "
                            + "debuggable build can reset untrusted changes");
                }
                return mode;
            }
            case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
                if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
                    throw new SecurityException("Only system, shell/root on a "
                            + "debuggable build can reset to trusted defaults");
                }
                return mode;
            }
            case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
                return mode;
            }
        }
        throw new IllegalArgumentException("Invalid reset mode: " + mode);
    }

    private static boolean isCallerSystemOrShellOrRootOnDebuggableBuild() {
        final int appId = UserHandle.getAppId(Binder.getCallingUid());
        return appId == SYSTEM_UID || (Build.IS_DEBUGGABLE
                && (appId == SHELL_UID || appId == ROOT_UID));
    }

    private static String getValidTableOrThrow(Uri uri) {
        if (uri.getPathSegments().size() > 0) {
            String table = uri.getPathSegments().get(0);
            if (DatabaseHelper.isValidTable(table)) {
                return table;
            }
            throw new IllegalArgumentException("Bad root path: " + table);
        }
        throw new IllegalArgumentException("Invalid URI:" + uri);
    }

    private static MatrixCursor packageSettingForQuery(Setting setting, String[] projection) {
        if (setting.isNull()) {
            return new MatrixCursor(projection, 0);
        }
        MatrixCursor cursor = new MatrixCursor(projection, 1);
        appendSettingToCursor(cursor, setting);
        return cursor;
    }

    private static String[] normalizeProjection(String[] projection) {
        if (projection == null) {
            return ALL_COLUMNS;
        }

        final int columnCount = projection.length;
        for (int i = 0; i < columnCount; i++) {
            String column = projection[i];
            if (!ArrayUtils.contains(ALL_COLUMNS, column)) {
                throw new IllegalArgumentException("Invalid column: " + column);
            }
        }

        return projection;
    }

    private static void appendSettingToCursor(MatrixCursor cursor, Setting setting) {
        if (setting == null || setting.isNull()) {
            return;
        }
        final int columnCount = cursor.getColumnCount();

        String[] values =  new String[columnCount];

        for (int i = 0; i < columnCount; i++) {
            String column = cursor.getColumnName(i);

            switch (column) {
                case Settings.NameValueTable._ID: {
                    values[i] = setting.getId();
                } break;

                case Settings.NameValueTable.NAME: {
                    values[i] = setting.getName();
                } break;

                case Settings.NameValueTable.VALUE: {
                    values[i] = setting.getValue();
                } break;
            }
        }

        cursor.addRow(values);
    }

    private static boolean isKeyValid(String key) {
        return !(TextUtils.isEmpty(key) || SettingsState.isBinary(key));
    }

    private String resolveCallingPackage() {
        switch (Binder.getCallingUid()) {
            case Process.ROOT_UID: {
                return "root";
            }

            case Process.SHELL_UID: {
                return "com.android.shell";
            }

            default: {
                return getCallingPackage();
            }
        }
    }

    private static final class Arguments {
        private static final Pattern WHERE_PATTERN_WITH_PARAM_NO_BRACKETS =
                Pattern.compile("[\\s]*name[\\s]*=[\\s]*\\?[\\s]*");

        private static final Pattern WHERE_PATTERN_WITH_PARAM_IN_BRACKETS =
                Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*\\?[\\s]*\\)[\\s]*");

        private static final Pattern WHERE_PATTERN_NO_PARAM_IN_BRACKETS =
                Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*\\)[\\s]*");

        private static final Pattern WHERE_PATTERN_NO_PARAM_NO_BRACKETS =
                Pattern.compile("[\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*");

        public final String table;
        public final String name;

        public Arguments(Uri uri, String where, String[] whereArgs, boolean supportAll) {
            final int segmentSize = uri.getPathSegments().size();
            switch (segmentSize) {
                case 1: {
                    if (where != null
                            && (WHERE_PATTERN_WITH_PARAM_NO_BRACKETS.matcher(where).matches()
                                || WHERE_PATTERN_WITH_PARAM_IN_BRACKETS.matcher(where).matches())
                            && whereArgs.length == 1) {
                        name = whereArgs[0];
                        table = computeTableForSetting(uri, name);
                        return;
                    } else if (where != null
                            && (WHERE_PATTERN_NO_PARAM_NO_BRACKETS.matcher(where).matches()
                                || WHERE_PATTERN_NO_PARAM_IN_BRACKETS.matcher(where).matches())) {
                        final int startIndex = Math.max(where.indexOf("'"),
                                where.indexOf("\"")) + 1;
                        final int endIndex = Math.max(where.lastIndexOf("'"),
                                where.lastIndexOf("\""));
                        name = where.substring(startIndex, endIndex);
                        table = computeTableForSetting(uri, name);
                        return;
                    } else if (supportAll && where == null && whereArgs == null) {
                        name = null;
                        table = computeTableForSetting(uri, null);
                        return;
                    }
                } break;

                case 2: {
                    if (where == null && whereArgs == null) {
                        name = uri.getPathSegments().get(1);
                        table = computeTableForSetting(uri, name);
                        return;
                    }
                } break;
            }

            EventLogTags.writeUnsupportedSettingsQuery(
                    uri.toSafeString(), where, Arrays.toString(whereArgs));
            String message = String.format( "Supported SQL:\n"
                    + "  uri content://some_table/some_property with null where and where args\n"
                    + "  uri content://some_table with query name=? and single name as arg\n"
                    + "  uri content://some_table with query name=some_name and null args\n"
                    + "  but got - uri:%1s, where:%2s whereArgs:%3s", uri, where,
                    Arrays.toString(whereArgs));
            throw new IllegalArgumentException(message);
        }

        private static String computeTableForSetting(Uri uri, String name) {
            String table = getValidTableOrThrow(uri);

            if (name != null) {
                if (sSystemMovedToSecureSettings.contains(name)) {
                    table = TABLE_SECURE;
                }

                if (sSystemMovedToGlobalSettings.contains(name)) {
                    table = TABLE_GLOBAL;
                }

                if (sSecureMovedToGlobalSettings.contains(name)) {
                    table = TABLE_GLOBAL;
                }

                if (sGlobalMovedToSecureSettings.contains(name)) {
                    table = TABLE_SECURE;
                }
            }

            return table;
        }
    }

    final class SettingsRegistry {
        private static final String DROPBOX_TAG_USERLOG = "restricted_profile_ssaid";

        private static final String SETTINGS_FILE_GLOBAL = "settings_global.xml";
        private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml";
        private static final String SETTINGS_FILE_SECURE = "settings_secure.xml";
        private static final String SETTINGS_FILE_SSAID = "settings_ssaid.xml";
        private static final String SETTINGS_FILE_CONFIG = "settings_config.xml";

        private static final String SSAID_USER_KEY = "userkey";

        private final SparseArray<SettingsState> mSettingsStates = new SparseArray<>();

        private GenerationRegistry mGenerationRegistry;

        private final Handler mHandler;

        private final BackupManager mBackupManager;

        private String mSettingsCreationBuildId;

        public SettingsRegistry() {
            mHandler = new MyHandler(getContext().getMainLooper());
            mGenerationRegistry = new GenerationRegistry(mLock);
            mBackupManager = new BackupManager(getContext());
            migrateAllLegacySettingsIfNeeded();
            syncSsaidTableOnStart();
        }

        private void generateUserKeyLocked(int userId) {
            // Generate a random key for each user used for creating a new ssaid.
            final byte[] keyBytes = new byte[32];
            final SecureRandom rand = new SecureRandom();
            rand.nextBytes(keyBytes);

            // Convert to string for storage in settings table.
            final String userKey = ByteStringUtils.toHexString(keyBytes);

            // Store the key in the ssaid table.
            final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
            final boolean success = ssaidSettings.insertSettingLocked(SSAID_USER_KEY, userKey, null,
                    true, SettingsState.SYSTEM_PACKAGE_NAME);

            if (!success) {
                throw new IllegalStateException("Ssaid settings not accessible");
            }
        }

        private byte[] getLengthPrefix(byte[] data) {
            return ByteBuffer.allocate(4).putInt(data.length).array();
        }

        public Setting generateSsaidLocked(PackageInfo callingPkg, int userId) {
            // Read the user's key from the ssaid table.
            Setting userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
            if (userKeySetting == null || userKeySetting.isNull()
                    || userKeySetting.getValue() == null) {
                // Lazy initialize and store the user key.
                generateUserKeyLocked(userId);
                userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
                if (userKeySetting == null || userKeySetting.isNull()
                        || userKeySetting.getValue() == null) {
                    throw new IllegalStateException("User key not accessible");
                }
            }
            final String userKey = userKeySetting.getValue();

            // Convert the user's key back to a byte array.
            final byte[] keyBytes = ByteStringUtils.fromHexToByteArray(userKey);

            // Validate that the key is of expected length.
            // Keys are currently 32 bytes, but were once 16 bytes during Android O development.
            if (keyBytes == null || (keyBytes.length != 16 && keyBytes.length != 32)) {
                throw new IllegalStateException("User key invalid");
            }

            final Mac m;
            try {
                m = Mac.getInstance("HmacSHA256");
                m.init(new SecretKeySpec(keyBytes, m.getAlgorithm()));
            } catch (NoSuchAlgorithmException e) {
                throw new IllegalStateException("HmacSHA256 is not available", e);
            } catch (InvalidKeyException e) {
                throw new IllegalStateException("Key is corrupted", e);
            }

            // Mac each of the developer signatures.
            for (int i = 0; i < callingPkg.signatures.length; i++) {
                byte[] sig = callingPkg.signatures[i].toByteArray();
                m.update(getLengthPrefix(sig), 0, 4);
                m.update(sig);
            }

            // Convert result to a string for storage in settings table. Only want first 64 bits.
            final String ssaid = ByteStringUtils.toHexString(m.doFinal()).substring(0, 16)
                    .toLowerCase(Locale.US);

            // Save the ssaid in the ssaid table.
            final String uid = Integer.toString(callingPkg.applicationInfo.uid);
            final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
            final boolean success = ssaidSettings.insertSettingLocked(uid, ssaid, null, true,
                callingPkg.packageName);

            if (!success) {
                throw new IllegalStateException("Ssaid settings not accessible");
            }

            return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
        }

        public void syncSsaidTableOnStart() {
            synchronized (mLock) {
                // Verify that each user's packages and ssaid's are in sync.
                for (UserInfo user : mUserManager.getUsers(true)) {
                    // Get all uids for the user's packages.
                    final List<PackageInfo> packages;
                    try {
                        packages = mPackageManager.getInstalledPackages(
                            PackageManager.MATCH_UNINSTALLED_PACKAGES,
                            user.id).getList();
                    } catch (RemoteException e) {
                        throw new IllegalStateException("Package manager not available");
                    }
                    final Set<String> appUids = new HashSet<>();
                    for (PackageInfo info : packages) {
                        appUids.add(Integer.toString(info.applicationInfo.uid));
                    }

                    // Get all uids currently stored in the user's ssaid table.
                    final Set<String> ssaidUids = new HashSet<>(
                            getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
                    ssaidUids.remove(SSAID_USER_KEY);

                    // Perform a set difference for the appUids and ssaidUids.
                    ssaidUids.removeAll(appUids);

                    // If there are ssaidUids left over they need to be removed from the table.
                    final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
                            user.id);
                    for (String uid : ssaidUids) {
                        ssaidSettings.deleteSettingLocked(uid);
                    }
                }
            }
        }

        public List<String> getSettingsNamesLocked(int type, int userId) {
            final int key = makeKey(type, userId);
            SettingsState settingsState = peekSettingsStateLocked(key);
            if (settingsState == null) {
                return new ArrayList<String>();
            }
            return settingsState.getSettingNamesLocked();
        }

        public SparseBooleanArray getKnownUsersLocked() {
            SparseBooleanArray users = new SparseBooleanArray();
            for (int i = mSettingsStates.size()-1; i >= 0; i--) {
                users.put(getUserIdFromKey(mSettingsStates.keyAt(i)), true);
            }
            return users;
        }

        @Nullable
        public SettingsState getSettingsLocked(int type, int userId) {
            final int key = makeKey(type, userId);
            return peekSettingsStateLocked(key);
        }

        public boolean ensureSettingsForUserLocked(int userId) {
            // First make sure this user actually exists.
            if (mUserManager.getUserInfo(userId) == null) {
                Slog.wtf(LOG_TAG, "Requested user " + userId + " does not exist");
                return false;
            }

            // Migrate the setting for this user if needed.
            migrateLegacySettingsForUserIfNeededLocked(userId);

            // Ensure config settings loaded if owner.
            if (userId == UserHandle.USER_SYSTEM) {
                final int configKey
                        = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
                ensureSettingsStateLocked(configKey);
            }

            // Ensure global settings loaded if owner.
            if (userId == UserHandle.USER_SYSTEM) {
                final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
                ensureSettingsStateLocked(globalKey);
            }

            // Ensure secure settings loaded.
            final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
            ensureSettingsStateLocked(secureKey);

            // Make sure the secure settings have an Android id set.
            SettingsState secureSettings = getSettingsLocked(SETTINGS_TYPE_SECURE, userId);
            ensureSecureSettingAndroidIdSetLocked(secureSettings);

            // Ensure system settings loaded.
            final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
            ensureSettingsStateLocked(systemKey);

            // Ensure secure settings loaded.
            final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
            ensureSettingsStateLocked(ssaidKey);

            // Upgrade the settings to the latest version.
            UpgradeController upgrader = new UpgradeController(userId);
            upgrader.upgradeIfNeededLocked();
            return true;
        }

        private void ensureSettingsStateLocked(int key) {
            if (mSettingsStates.get(key) == null) {
                final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key));
                SettingsState settingsState = new SettingsState(getContext(), mLock,
                        getSettingsFile(key), key, maxBytesPerPackage, mHandlerThread.getLooper());
                mSettingsStates.put(key, settingsState);
            }
        }

        public void removeUserStateLocked(int userId, boolean permanently) {
            // We always keep the global settings in memory.

            // Nuke system settings.
            final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
            final SettingsState systemSettingsState = mSettingsStates.get(systemKey);
            if (systemSettingsState != null) {
                if (permanently) {
                    mSettingsStates.remove(systemKey);
                    systemSettingsState.destroyLocked(null);
                } else {
                    systemSettingsState.destroyLocked(new Runnable() {
                        @Override
                        public void run() {
                            mSettingsStates.remove(systemKey);
                        }
                    });
                }
            }

            // Nuke secure settings.
            final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
            final SettingsState secureSettingsState = mSettingsStates.get(secureKey);
            if (secureSettingsState != null) {
                if (permanently) {
                    mSettingsStates.remove(secureKey);
                    secureSettingsState.destroyLocked(null);
                } else {
                    secureSettingsState.destroyLocked(new Runnable() {
                        @Override
                        public void run() {
                            mSettingsStates.remove(secureKey);
                        }
                    });
                }
            }

            // Nuke ssaid settings.
            final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
            final SettingsState ssaidSettingsState = mSettingsStates.get(ssaidKey);
            if (ssaidSettingsState != null) {
                if (permanently) {
                    mSettingsStates.remove(ssaidKey);
                    ssaidSettingsState.destroyLocked(null);
                } else {
                    ssaidSettingsState.destroyLocked(new Runnable() {
                        @Override
                        public void run() {
                            mSettingsStates.remove(ssaidKey);
                        }
                    });
                }
            }

            // Nuke generation tracking data
            mGenerationRegistry.onUserRemoved(userId);
        }

        public boolean insertSettingLocked(int type, int userId, String name, String value,
                String tag, boolean makeDefault, String packageName, boolean forceNotify,
                Set<String> criticalSettings) {
            return insertSettingLocked(type, userId, name, value, tag, makeDefault, false,
                    packageName, forceNotify, criticalSettings);
        }

        public boolean insertSettingLocked(int type, int userId, String name, String value,
                String tag, boolean makeDefault, boolean forceNonSystemPackage, String packageName,
                boolean forceNotify, Set<String> criticalSettings) {
            final int key = makeKey(type, userId);

            boolean success = false;
            SettingsState settingsState = peekSettingsStateLocked(key);
            if (settingsState != null) {
                success = settingsState.insertSettingLocked(name, value,
                        tag, makeDefault, forceNonSystemPackage, packageName);
            }

            if (success && criticalSettings != null && criticalSettings.contains(name)) {
                settingsState.persistSyncLocked();
            }

            if (forceNotify || success) {
                notifyForSettingsChange(key, name);
            }
            return success;
        }

        public boolean deleteSettingLocked(int type, int userId, String name, boolean forceNotify,
                Set<String> criticalSettings) {
            final int key = makeKey(type, userId);

            boolean success = false;
            SettingsState settingsState = peekSettingsStateLocked(key);
            if (settingsState != null) {
                success = settingsState.deleteSettingLocked(name);
            }

            if (success && criticalSettings != null && criticalSettings.contains(name)) {
                settingsState.persistSyncLocked();
            }

            if (forceNotify || success) {
                notifyForSettingsChange(key, name);
            }
            return success;
        }

        public boolean updateSettingLocked(int type, int userId, String name, String value,
                String tag, boolean makeDefault, String packageName, boolean forceNotify,
                Set<String> criticalSettings) {
            final int key = makeKey(type, userId);

            boolean success = false;
            SettingsState settingsState = peekSettingsStateLocked(key);
            if (settingsState != null) {
                success = settingsState.updateSettingLocked(name, value, tag,
                        makeDefault, packageName);
            }

            if (success && criticalSettings != null && criticalSettings.contains(name)) {
                settingsState.persistSyncLocked();
            }

            if (forceNotify || success) {
                notifyForSettingsChange(key, name);
            }

            return success;
        }

        public Setting getSettingLocked(int type, int userId, String name) {
            final int key = makeKey(type, userId);

            SettingsState settingsState = peekSettingsStateLocked(key);
            if (settingsState == null) {
                return null;
            }

            // getSettingLocked will return non-null result
            return settingsState.getSettingLocked(name);
        }

        public void resetSettingsLocked(int type, int userId, String packageName, int mode,
                String tag) {
            resetSettingsLocked(type, userId, packageName, mode, tag, null);
        }

        public void resetSettingsLocked(int type, int userId, String packageName, int mode,
                String tag, @Nullable String prefix) {
            final int key = makeKey(type, userId);
            SettingsState settingsState = peekSettingsStateLocked(key);
            if (settingsState == null) {
                return;
            }

            switch (mode) {
                case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
                    for (String name : settingsState.getSettingNamesLocked()) {
                        boolean someSettingChanged = false;
                        Setting setting = settingsState.getSettingLocked(name);
                        if (packageName.equals(setting.getPackageName())) {
                            if ((tag != null && !tag.equals(setting.getTag()))
                                    || (prefix != null && !setting.getName().startsWith(prefix))) {
                                continue;
                            }
                            if (settingsState.resetSettingLocked(name)) {
                                someSettingChanged = true;
                                notifyForSettingsChange(key, name);
                            }
                        }
                        if (someSettingChanged) {
                            settingsState.persistSyncLocked();
                        }
                    }
                } break;

                case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
                    for (String name : settingsState.getSettingNamesLocked()) {
                        boolean someSettingChanged = false;
                        Setting setting = settingsState.getSettingLocked(name);
                        if (!SettingsState.isSystemPackage(getContext(),
                                setting.getPackageName(), INVALID_UID, userId)) {
                            if (prefix != null && !setting.getName().startsWith(prefix)) {
                                continue;
                            }
                            if (settingsState.resetSettingLocked(name)) {
                                someSettingChanged = true;
                                notifyForSettingsChange(key, name);
                            }
                        }
                        if (someSettingChanged) {
                            settingsState.persistSyncLocked();
                        }
                    }
                } break;

                case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
                    for (String name : settingsState.getSettingNamesLocked()) {
                        boolean someSettingChanged = false;
                        Setting setting = settingsState.getSettingLocked(name);
                        if (!SettingsState.isSystemPackage(getContext(),
                                setting.getPackageName(), INVALID_UID, userId)) {
                            if (prefix != null && !setting.getName().startsWith(prefix)) {
                                continue;
                            }
                            if (setting.isDefaultFromSystem()) {
                                if (settingsState.resetSettingLocked(name)) {
                                    someSettingChanged = true;
                                    notifyForSettingsChange(key, name);
                                }
                            } else if (settingsState.deleteSettingLocked(name)) {
                                someSettingChanged = true;
                                notifyForSettingsChange(key, name);
                            }
                        }
                        if (someSettingChanged) {
                            settingsState.persistSyncLocked();
                        }
                    }
                } break;

                case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
                    for (String name : settingsState.getSettingNamesLocked()) {
                        Setting setting = settingsState.getSettingLocked(name);
                        boolean someSettingChanged = false;
                        if (prefix != null && !setting.getName().startsWith(prefix)) {
                            continue;
                        }
                        if (setting.isDefaultFromSystem()) {
                            if (settingsState.resetSettingLocked(name)) {
                                someSettingChanged = true;
                                notifyForSettingsChange(key, name);
                            }
                        } else if (settingsState.deleteSettingLocked(name)) {
                            someSettingChanged = true;
                            notifyForSettingsChange(key, name);
                        }
                        if (someSettingChanged) {
                            settingsState.persistSyncLocked();
                        }
                    }
                } break;
            }
        }

        public void removeSettingsForPackageLocked(String packageName, int userId) {
            // Global and secure settings are signature protected. Apps signed
            // by the platform certificate are generally not uninstalled  and
            // the main exception is tests. We trust components signed
            // by the platform certificate and do not do a clean up after them.

            final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
            SettingsState systemSettings = mSettingsStates.get(systemKey);
            if (systemSettings != null) {
                systemSettings.removeSettingsForPackageLocked(packageName);
            }
        }

        public void onUidRemovedLocked(int uid) {
            final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
                    UserHandle.getUserId(uid));
            if (ssaidSettings != null) {
                ssaidSettings.deleteSettingLocked(Integer.toString(uid));
            }
        }

        @Nullable
        private SettingsState peekSettingsStateLocked(int key) {
            SettingsState settingsState = mSettingsStates.get(key);
            if (settingsState != null) {
                return settingsState;
            }

            if (!ensureSettingsForUserLocked(getUserIdFromKey(key))) {
                return null;
            }
            return mSettingsStates.get(key);
        }

        private void migrateAllLegacySettingsIfNeeded() {
            synchronized (mLock) {
                final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
                File globalFile = getSettingsFile(key);
                if (SettingsState.stateFileExists(globalFile)) {
                    return;
                }

                mSettingsCreationBuildId = Build.ID;

                final long identity = Binder.clearCallingIdentity();
                try {
                    List<UserInfo> users = mUserManager.getUsers(true);

                    final int userCount = users.size();
                    for (int i = 0; i < userCount; i++) {
                        final int userId = users.get(i).id;

                        DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
                        SQLiteDatabase database = dbHelper.getWritableDatabase();
                        migrateLegacySettingsForUserLocked(dbHelper, database, userId);

                        // Upgrade to the latest version.
                        UpgradeController upgrader = new UpgradeController(userId);
                        upgrader.upgradeIfNeededLocked();

                        // Drop from memory if not a running user.
                        if (!mUserManager.isUserRunning(new UserHandle(userId))) {
                            removeUserStateLocked(userId, false);
                        }
                    }
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
        }

        private void migrateLegacySettingsForUserIfNeededLocked(int userId) {
            // Every user has secure settings and if no file we need to migrate.
            final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
            File secureFile = getSettingsFile(secureKey);
            if (SettingsState.stateFileExists(secureFile)) {
                return;
            }

            DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
            SQLiteDatabase database = dbHelper.getWritableDatabase();

            migrateLegacySettingsForUserLocked(dbHelper, database, userId);
        }

        private void migrateLegacySettingsForUserLocked(DatabaseHelper dbHelper,
                SQLiteDatabase database, int userId) {
            // Move over the system settings.
            final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
            ensureSettingsStateLocked(systemKey);
            SettingsState systemSettings = mSettingsStates.get(systemKey);
            migrateLegacySettingsLocked(systemSettings, database, TABLE_SYSTEM);
            systemSettings.persistSyncLocked();

            // Move over the secure settings.
            // Do this after System settings, since this is the first thing we check when deciding
            // to skip over migration from db to xml for a secondary user.
            final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
            ensureSettingsStateLocked(secureKey);
            SettingsState secureSettings = mSettingsStates.get(secureKey);
            migrateLegacySettingsLocked(secureSettings, database, TABLE_SECURE);
            ensureSecureSettingAndroidIdSetLocked(secureSettings);
            secureSettings.persistSyncLocked();

            // Move over the global settings if owner.
            // Do this last, since this is the first thing we check when deciding
            // to skip over migration from db to xml for owner user.
            if (userId == UserHandle.USER_SYSTEM) {
                final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, userId);
                ensureSettingsStateLocked(globalKey);
                SettingsState globalSettings = mSettingsStates.get(globalKey);
                migrateLegacySettingsLocked(globalSettings, database, TABLE_GLOBAL);
                // If this was just created
                if (mSettingsCreationBuildId != null) {
                    globalSettings.insertSettingLocked(Settings.Global.DATABASE_CREATION_BUILDID,
                            mSettingsCreationBuildId, null, true,
                            SettingsState.SYSTEM_PACKAGE_NAME);
                }
                globalSettings.persistSyncLocked();
            }

            // Drop the database as now all is moved and persisted.
            if (DROP_DATABASE_ON_MIGRATION) {
                dbHelper.dropDatabase();
            } else {
                dbHelper.backupDatabase();
            }
        }

        private void migrateLegacySettingsLocked(SettingsState settingsState,
                SQLiteDatabase database, String table) {
            SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
            queryBuilder.setTables(table);

            Cursor cursor = queryBuilder.query(database, ALL_COLUMNS,
                    null, null, null, null, null);

            if (cursor == null) {
                return;
            }

            try {
                if (!cursor.moveToFirst()) {
                    return;
                }

                final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME);
                final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE);

                settingsState.setVersionLocked(database.getVersion());

                while (!cursor.isAfterLast()) {
                    String name = cursor.getString(nameColumnIdx);
                    String value = cursor.getString(valueColumnIdx);
                    settingsState.insertSettingLocked(name, value, null, true,
                            SettingsState.SYSTEM_PACKAGE_NAME);
                    cursor.moveToNext();
                }
            } finally {
                cursor.close();
            }
        }

        @GuardedBy("secureSettings.mLock")
        private void ensureSecureSettingAndroidIdSetLocked(SettingsState secureSettings) {
            Setting value = secureSettings.getSettingLocked(Settings.Secure.ANDROID_ID);

            if (!value.isNull()) {
                return;
            }

            final int userId = getUserIdFromKey(secureSettings.mKey);

            final UserInfo user;
            final long identity = Binder.clearCallingIdentity();
            try {
                user = mUserManager.getUserInfo(userId);
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
            if (user == null) {
                // Can happen due to races when deleting users - treat as benign.
                return;
            }

            String androidId = Long.toHexString(new SecureRandom().nextLong());
            secureSettings.insertSettingLocked(Settings.Secure.ANDROID_ID, androidId,
                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);

            Slog.d(LOG_TAG, "Generated and saved new ANDROID_ID [" + androidId
                    + "] for user " + userId);

            // Write a drop box entry if it's a restricted profile
            if (user.isRestricted()) {
                DropBoxManager dbm = (DropBoxManager) getContext().getSystemService(
                        Context.DROPBOX_SERVICE);
                if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
                    dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis()
                            + "," + DROPBOX_TAG_USERLOG + "," + androidId + "\n");
                }
            }
        }

        private void notifyForSettingsChange(int key, String name) {
            // Increment the generation first, so observers always see the new value
            mGenerationRegistry.incrementGeneration(key);

            if (isGlobalSettingsKey(key) || isConfigSettingsKey(key)) {
                final long token = Binder.clearCallingIdentity();
                try {
                    if (Global.LOCATION_GLOBAL_KILL_SWITCH.equals(name)
                            && isGlobalSettingsKey(key)) {
                        // When the global kill switch is updated, send the
                        // change notification for the location setting.
                        notifyLocationChangeForRunningUsers();
                    }
                    notifySettingChangeForRunningUsers(key, name);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            } else {
                final int userId = getUserIdFromKey(key);
                final Uri uri = getNotificationUriFor(key, name);
                mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
                        userId, 0, uri).sendToTarget();
                if (isSecureSettingsKey(key)) {
                    maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
                            sSecureCloneToManagedSettings);
                    maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name,
                            sSystemCloneFromParentOnDependency.values());
                } else if (isSystemSettingsKey(key)) {
                    maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
                            sSystemCloneToManagedSettings);
                }
            }

            // Always notify that our data changed
            mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget();
        }

        private void maybeNotifyProfiles(int type, int userId, Uri uri, String name,
                Collection<String> keysCloned) {
            if (keysCloned.contains(name)) {
                for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
                    // the notification for userId has already been sent.
                    if (profileId != userId) {
                        final int key = makeKey(type, profileId);
                        // Increment the generation first, so observers always see the new value
                        mGenerationRegistry.incrementGeneration(key);
                        mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
                                profileId, 0, uri).sendToTarget();
                    }
                }
            }
        }

        private void notifySettingChangeForRunningUsers(int key, String name) {
            // Important: No need to update generation for each user as there
            // is a singleton generation entry for the global settings which
            // is already incremented be the caller.
            final Uri uri = getNotificationUriFor(key, name);
            final List<UserInfo> users = mUserManager.getUsers(/*excludeDying*/ true);
            for (int i = 0; i < users.size(); i++) {
                final int userId = users.get(i).id;
                if (mUserManager.isUserRunning(UserHandle.of(userId))) {
                    mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
                            userId, 0, uri).sendToTarget();
                }
            }
        }

        private void notifyLocationChangeForRunningUsers() {
            final List<UserInfo> users = mUserManager.getUsers(/*excludeDying=*/ true);

            for (int i = 0; i < users.size(); i++) {
                final int userId = users.get(i).id;

                if (!mUserManager.isUserRunning(UserHandle.of(userId))) {
                    continue;
                }

                // Increment the generation first, so observers always see the new value
                final int key = makeKey(SETTINGS_TYPE_SECURE, userId);
                mGenerationRegistry.incrementGeneration(key);

                final Uri uri = getNotificationUriFor(key, Secure.LOCATION_MODE);
                mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
                        userId, 0, uri).sendToTarget();
            }
        }

        private boolean isConfigSettingsKey(int key) {
            return getTypeFromKey(key) == SETTINGS_TYPE_CONFIG;
        }

        private boolean isGlobalSettingsKey(int key) {
            return getTypeFromKey(key) == SETTINGS_TYPE_GLOBAL;
        }

        private boolean isSystemSettingsKey(int key) {
            return getTypeFromKey(key) == SETTINGS_TYPE_SYSTEM;
        }

        private boolean isSecureSettingsKey(int key) {
            return getTypeFromKey(key) == SETTINGS_TYPE_SECURE;
        }

        private boolean isSsaidSettingsKey(int key) {
            return getTypeFromKey(key) == SETTINGS_TYPE_SSAID;
        }

        private File getSettingsFile(int key) {
            if (isConfigSettingsKey(key)) {
                final int userId = getUserIdFromKey(key);
                return new File(Environment.getUserSystemDirectory(userId),
                        SETTINGS_FILE_CONFIG);
            } else if (isGlobalSettingsKey(key)) {
                final int userId = getUserIdFromKey(key);
                return new File(Environment.getUserSystemDirectory(userId),
                        SETTINGS_FILE_GLOBAL);
            } else if (isSystemSettingsKey(key)) {
                final int userId = getUserIdFromKey(key);
                return new File(Environment.getUserSystemDirectory(userId),
                        SETTINGS_FILE_SYSTEM);
            } else if (isSecureSettingsKey(key)) {
                final int userId = getUserIdFromKey(key);
                return new File(Environment.getUserSystemDirectory(userId),
                        SETTINGS_FILE_SECURE);
            } else if (isSsaidSettingsKey(key)) {
                final int userId = getUserIdFromKey(key);
                return new File(Environment.getUserSystemDirectory(userId),
                        SETTINGS_FILE_SSAID);
            } else {
                throw new IllegalArgumentException("Invalid settings key:" + key);
            }
        }

        private Uri getNotificationUriFor(int key, String name) {
            if (isConfigSettingsKey(key)) {
                return (name != null) ? Uri.withAppendedPath(DeviceConfig.CONTENT_URI, name)
                        : DeviceConfig.CONTENT_URI;
            } else if (isGlobalSettingsKey(key)) {
                return (name != null) ? Uri.withAppendedPath(Settings.Global.CONTENT_URI, name)
                        : Settings.Global.CONTENT_URI;
            } else if (isSecureSettingsKey(key)) {
                return (name != null) ? Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name)
                        : Settings.Secure.CONTENT_URI;
            } else if (isSystemSettingsKey(key)) {
                return (name != null) ? Uri.withAppendedPath(Settings.System.CONTENT_URI, name)
                        : Settings.System.CONTENT_URI;
            } else {
                throw new IllegalArgumentException("Invalid settings key:" + key);
            }
        }

        private int getMaxBytesPerPackageForType(int type) {
            switch (type) {
                case SETTINGS_TYPE_CONFIG:
                case SETTINGS_TYPE_GLOBAL:
                case SETTINGS_TYPE_SECURE:
                case SETTINGS_TYPE_SSAID: {
                    return SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED;
                }

                default: {
                    return SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED;
                }
            }
        }

        private final class MyHandler extends Handler {
            private static final int MSG_NOTIFY_URI_CHANGED = 1;
            private static final int MSG_NOTIFY_DATA_CHANGED = 2;

            public MyHandler(Looper looper) {
                super(looper);
            }

            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_NOTIFY_URI_CHANGED: {
                        final int userId = msg.arg1;
                        Uri uri = (Uri) msg.obj;
                        try {
                            getContext().getContentResolver().notifyChange(uri, null, true, userId);
                        } catch (SecurityException e) {
                            Slog.w(LOG_TAG, "Failed to notify for " + userId + ": " + uri, e);
                        }
                        if (DEBUG || true) {
                            Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri);
                        }
                    } break;

                    case MSG_NOTIFY_DATA_CHANGED: {
                        mBackupManager.dataChanged();
                    } break;
                }
            }
        }

        private final class UpgradeController {
            private static final int SETTINGS_VERSION = 182;

            private final int mUserId;

            public UpgradeController(int userId) {
                mUserId = userId;
            }

            public void upgradeIfNeededLocked() {
                // The version of all settings for a user is the same (all users have secure).
                SettingsState secureSettings = getSettingsLocked(
                        SETTINGS_TYPE_SECURE, mUserId);

                // Try an update from the current state.
                final int oldVersion = secureSettings.getVersionLocked();
                final int newVersion = SETTINGS_VERSION;

                // If up do date - done.
                if (oldVersion == newVersion) {
                    return;
                }

                // Try to upgrade.
                final int curVersion = onUpgradeLocked(mUserId, oldVersion, newVersion);

                // If upgrade failed start from scratch and upgrade.
                if (curVersion != newVersion) {
                    // Drop state we have for this user.
                    removeUserStateLocked(mUserId, true);

                    // Recreate the database.
                    DatabaseHelper dbHelper = new DatabaseHelper(getContext(), mUserId);
                    SQLiteDatabase database = dbHelper.getWritableDatabase();
                    dbHelper.recreateDatabase(database, newVersion, curVersion, oldVersion);

                    // Migrate the settings for this user.
                    migrateLegacySettingsForUserLocked(dbHelper, database, mUserId);

                    // Now upgrade should work fine.
                    onUpgradeLocked(mUserId, oldVersion, newVersion);

                    // Make a note what happened, so we don't wonder why data was lost
                    String reason = "Settings rebuilt! Current version: "
                            + curVersion + " while expected: " + newVersion;
                    getGlobalSettingsLocked().insertSettingLocked(
                            Settings.Global.DATABASE_DOWNGRADE_REASON,
                            reason, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                }

                // Set the global settings version if owner.
                if (mUserId == UserHandle.USER_SYSTEM) {
                    SettingsState globalSettings = getSettingsLocked(
                            SETTINGS_TYPE_GLOBAL, mUserId);
                    globalSettings.setVersionLocked(newVersion);
                }

                // Set the secure settings version.
                secureSettings.setVersionLocked(newVersion);

                // Set the system settings version.
                SettingsState systemSettings = getSettingsLocked(
                        SETTINGS_TYPE_SYSTEM, mUserId);
                systemSettings.setVersionLocked(newVersion);
            }

            private SettingsState getGlobalSettingsLocked() {
                return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
            }

            private SettingsState getSecureSettingsLocked(int userId) {
                return getSettingsLocked(SETTINGS_TYPE_SECURE, userId);
            }

            private SettingsState getSsaidSettingsLocked(int userId) {
                return getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
            }

            private SettingsState getSystemSettingsLocked(int userId) {
                return getSettingsLocked(SETTINGS_TYPE_SYSTEM, userId);
            }

            /**
             * You must perform all necessary mutations to bring the settings
             * for this user from the old to the new version. When you add a new
             * upgrade step you *must* update SETTINGS_VERSION.
             *
             * This is an example of moving a setting from secure to global.
             *
             * // v119: Example settings changes.
             * if (currentVersion == 118) {
             *     if (userId == UserHandle.USER_OWNER) {
             *         // Remove from the secure settings.
             *         SettingsState secureSettings = getSecureSettingsLocked(userId);
             *         String name = "example_setting_to_move";
             *         String value = secureSettings.getSetting(name);
             *         secureSettings.deleteSetting(name);
             *
             *         // Add to the global settings.
             *         SettingsState globalSettings = getGlobalSettingsLocked();
             *         globalSettings.insertSetting(name, value, SettingsState.SYSTEM_PACKAGE_NAME);
             *     }
             *
             *     // Update the current version.
             *     currentVersion = 119;
             * }
             */
            private int onUpgradeLocked(int userId, int oldVersion, int newVersion) {
                if (DEBUG) {
                    Slog.w(LOG_TAG, "Upgrading settings for user: " + userId + " from version: "
                            + oldVersion + " to version: " + newVersion);
                }

                int currentVersion = oldVersion;

                // v119: Reset zen + ringer mode.
                if (currentVersion == 118) {
                    if (userId == UserHandle.USER_SYSTEM) {
                        final SettingsState globalSettings = getGlobalSettingsLocked();
                        globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE,
                                Integer.toString(Settings.Global.ZEN_MODE_OFF), null,
                                true, SettingsState.SYSTEM_PACKAGE_NAME);
                        globalSettings.updateSettingLocked(Settings.Global.MODE_RINGER,
                                Integer.toString(AudioManager.RINGER_MODE_NORMAL), null,
                                true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 119;
                }

                // v120: Add double tap to wake setting.
                if (currentVersion == 119) {
                    SettingsState secureSettings = getSecureSettingsLocked(userId);
                    secureSettings.insertSettingLocked(Settings.Secure.DOUBLE_TAP_TO_WAKE,
                            getContext().getResources().getBoolean(
                                    R.bool.def_double_tap_to_wake) ? "1" : "0", null, true,
                            SettingsState.SYSTEM_PACKAGE_NAME);

                    currentVersion = 120;
                }

                if (currentVersion == 120) {
                    // Before 121, we used a different string encoding logic.  We just bump the
                    // version here; SettingsState knows how to handle pre-version 120 files.
                    currentVersion = 121;
                }

                if (currentVersion == 121) {
                    // Version 122: allow OEMs to set a default payment component in resources.
                    // Note that we only write the default if no default has been set;
                    // if there is, we just leave the default at whatever it currently is.
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    String defaultComponent = (getContext().getResources().getString(
                            R.string.def_nfc_payment_component));
                    Setting currentSetting = secureSettings.getSettingLocked(
                            Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
                    if (defaultComponent != null && !defaultComponent.isEmpty() &&
                        currentSetting.isNull()) {
                        secureSettings.insertSettingLocked(
                                Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
                                defaultComponent, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 122;
                }

                if (currentVersion == 122) {
                    // Version 123: Adding a default value for the ability to add a user from
                    // the lock screen.
                    if (userId == UserHandle.USER_SYSTEM) {
                        final SettingsState globalSettings = getGlobalSettingsLocked();
                        Setting currentSetting = globalSettings.getSettingLocked(
                                Settings.Global.ADD_USERS_WHEN_LOCKED);
                        if (currentSetting.isNull()) {
                            globalSettings.insertSettingLocked(
                                    Settings.Global.ADD_USERS_WHEN_LOCKED,
                                    getContext().getResources().getBoolean(
                                            R.bool.def_add_users_from_lockscreen) ? "1" : "0",
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }
                    currentVersion = 123;
                }

                if (currentVersion == 123) {
                    final SettingsState globalSettings = getGlobalSettingsLocked();
                    String defaultDisabledProfiles = (getContext().getResources().getString(
                            R.string.def_bluetooth_disabled_profiles));
                    globalSettings.insertSettingLocked(Settings.Global.BLUETOOTH_DISABLED_PROFILES,
                            defaultDisabledProfiles, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    currentVersion = 124;
                }

                if (currentVersion == 124) {
                    // Version 124: allow OEMs to set a default value for whether IME should be
                    // shown when a physical keyboard is connected.
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    Setting currentSetting = secureSettings.getSettingLocked(
                            Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
                    if (currentSetting.isNull()) {
                        secureSettings.insertSettingLocked(
                                Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
                                getContext().getResources().getBoolean(
                                        R.bool.def_show_ime_with_hard_keyboard) ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 125;
                }

                if (currentVersion == 125) {
                    // Version 125: Allow OEMs to set the default VR service.
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    Setting currentSetting = secureSettings.getSettingLocked(
                            Settings.Secure.ENABLED_VR_LISTENERS);
                    if (currentSetting.isNull()) {
                        ArraySet<ComponentName> l =
                                SystemConfig.getInstance().getDefaultVrComponents();

                        if (l != null && !l.isEmpty()) {
                            StringBuilder b = new StringBuilder();
                            boolean start = true;
                            for (ComponentName c : l) {
                                if (!start) {
                                    b.append(':');
                                }
                                b.append(c.flattenToString());
                                start = false;
                            }
                            secureSettings.insertSettingLocked(
                                    Settings.Secure.ENABLED_VR_LISTENERS, b.toString(),
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }

                    }
                    currentVersion = 126;
                }

                if (currentVersion == 126) {
                    // Version 126: copy the primary values of LOCK_SCREEN_SHOW_NOTIFICATIONS and
                    // LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS into managed profile.
                    if (mUserManager.isManagedProfile(userId)) {
                        final SettingsState systemSecureSettings =
                                getSecureSettingsLocked(UserHandle.USER_SYSTEM);

                        final Setting showNotifications = systemSecureSettings.getSettingLocked(
                                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
                        if (!showNotifications.isNull()) {
                            final SettingsState secureSettings = getSecureSettingsLocked(userId);
                            secureSettings.insertSettingLocked(
                                    Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
                                    showNotifications.getValue(), null, true,
                                    SettingsState.SYSTEM_PACKAGE_NAME);
                        }

                        final Setting allowPrivate = systemSecureSettings.getSettingLocked(
                                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
                        if (!allowPrivate.isNull()) {
                            final SettingsState secureSettings = getSecureSettingsLocked(userId);
                            secureSettings.insertSettingLocked(
                                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
                                    allowPrivate.getValue(), null, true,
                                    SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }
                    currentVersion = 127;
                }

                if (currentVersion == 127) {
                    // version 127 is no longer used.
                    currentVersion = 128;
                }

                if (currentVersion == 128) {
                    // Version 128: Removed
                    currentVersion = 129;
                }

                if (currentVersion == 129) {
                    // default longpress timeout changed from 500 to 400. If unchanged from the old
                    // default, update to the new default.
                    final SettingsState systemSecureSettings =
                            getSecureSettingsLocked(userId);
                    final String oldValue = systemSecureSettings.getSettingLocked(
                            Settings.Secure.LONG_PRESS_TIMEOUT).getValue();
                    if (TextUtils.equals("500", oldValue)) {
                        systemSecureSettings.insertSettingLocked(
                                Settings.Secure.LONG_PRESS_TIMEOUT,
                                String.valueOf(getContext().getResources().getInteger(
                                        R.integer.def_long_press_timeout_millis)),
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 130;
                }

                if (currentVersion == 130) {
                    // Split Ambient settings
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    boolean dozeExplicitlyDisabled = "0".equals(secureSettings.
                            getSettingLocked(Settings.Secure.DOZE_ENABLED).getValue());

                    if (dozeExplicitlyDisabled) {
                        secureSettings.insertSettingLocked(Settings.Secure.DOZE_PICK_UP_GESTURE,
                                "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        secureSettings.insertSettingLocked(Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
                                "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 131;
                }

                if (currentVersion == 131) {
                    // Initialize new multi-press timeout to default value
                    final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
                    final String oldValue = systemSecureSettings.getSettingLocked(
                            Settings.Secure.MULTI_PRESS_TIMEOUT).getValue();
                    if (TextUtils.equals(null, oldValue)) {
                        systemSecureSettings.insertSettingLocked(
                                Settings.Secure.MULTI_PRESS_TIMEOUT,
                                String.valueOf(getContext().getResources().getInteger(
                                        R.integer.def_multi_press_timeout_millis)),
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 132;
                }

                if (currentVersion == 132) {
                    // Version 132: Allow managed profile to optionally use the parent's ringtones
                    final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
                    String defaultSyncParentSounds = (getContext().getResources()
                            .getBoolean(R.bool.def_sync_parent_sounds) ? "1" : "0");
                    systemSecureSettings.insertSettingLocked(
                            Settings.Secure.SYNC_PARENT_SOUNDS, defaultSyncParentSounds,
                            null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    currentVersion = 133;
                }

                if (currentVersion == 133) {
                    // Version 133: Add default end button behavior
                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
                    if (systemSettings.getSettingLocked(Settings.System.END_BUTTON_BEHAVIOR)
                            .isNull()) {
                        String defaultEndButtonBehavior = Integer.toString(getContext()
                                .getResources().getInteger(R.integer.def_end_button_behavior));
                        systemSettings.insertSettingLocked(Settings.System.END_BUTTON_BEHAVIOR,
                                defaultEndButtonBehavior, null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 134;
                }

                if (currentVersion == 134) {
                    // Remove setting that specifies if magnification values should be preserved.
                    // This setting defaulted to true and never has a UI.
                    getSecureSettingsLocked(userId).deleteSettingLocked(
                            Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE);
                    currentVersion = 135;
                }

                if (currentVersion == 135) {
                    // Version 135 no longer used.
                    currentVersion = 136;
                }

                if (currentVersion == 136) {
                    // Version 136: Store legacy SSAID for all apps currently installed on the
                    // device as first step in migrating SSAID to be unique per application.

                    final boolean isUpgrade;
                    try {
                        isUpgrade = mPackageManager.isDeviceUpgrading();
                    } catch (RemoteException e) {
                        throw new IllegalStateException("Package manager not available");
                    }
                    // Only retain legacy ssaid if the device is performing an OTA. After wiping
                    // user data or first boot on a new device should use new ssaid generation.
                    if (isUpgrade) {
                        // Retrieve the legacy ssaid from the secure settings table.
                        final Setting legacySsaidSetting = getSettingLocked(SETTINGS_TYPE_SECURE,
                                userId, Settings.Secure.ANDROID_ID);
                        if (legacySsaidSetting == null || legacySsaidSetting.isNull()
                                || legacySsaidSetting.getValue() == null) {
                            throw new IllegalStateException("Legacy ssaid not accessible");
                        }
                        final String legacySsaid = legacySsaidSetting.getValue();

                        // Fill each uid with the legacy ssaid to be backwards compatible.
                        final List<PackageInfo> packages;
                        try {
                            packages = mPackageManager.getInstalledPackages(
                                PackageManager.MATCH_UNINSTALLED_PACKAGES,
                                userId).getList();
                        } catch (RemoteException e) {
                            throw new IllegalStateException("Package manager not available");
                        }

                        final SettingsState ssaidSettings = getSsaidSettingsLocked(userId);
                        for (PackageInfo info : packages) {
                            // Check if the UID already has an entry in the table.
                            final String uid = Integer.toString(info.applicationInfo.uid);
                            final Setting ssaid = ssaidSettings.getSettingLocked(uid);

                            if (ssaid.isNull() || ssaid.getValue() == null) {
                                // Android Id doesn't exist for this package so create it.
                                ssaidSettings.insertSettingLocked(uid, legacySsaid, null, true,
                                        info.packageName);
                                if (DEBUG) {
                                    Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid);
                                }
                            }
                        }
                    }

                    currentVersion = 137;
                }
                if (currentVersion == 137) {
                    // Version 138: Settings.Secure#INSTALL_NON_MARKET_APPS is deprecated and its
                    // default value set to 1. The user can no longer change the value of this
                    // setting through the UI.
                    final SettingsState secureSetting = getSecureSettingsLocked(userId);
                    if (!mUserManager.hasUserRestriction(
                            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, UserHandle.of(userId))
                            && secureSetting.getSettingLocked(
                            Settings.Secure.INSTALL_NON_MARKET_APPS).getValue().equals("0")) {

                        secureSetting.insertSettingLocked(Settings.Secure.INSTALL_NON_MARKET_APPS,
                                "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        // For managed profiles with profile owners, DevicePolicyManagerService
                        // may want to set the user restriction in this case
                        secureSetting.insertSettingLocked(
                                Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, "1", null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 138;
                }

                if (currentVersion == 138) {
                    // Version 139: Removed.
                    currentVersion = 139;
                }

                if (currentVersion == 139) {
                    // Version 140: Settings.Secure#ACCESSIBILITY_SPEAK_PASSWORD is deprecated and
                    // the user can no longer change the value of this setting through the UI.
                    // Force to true.
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    secureSettings.updateSettingLocked(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
                            "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    currentVersion = 140;
                }

                if (currentVersion == 140) {
                    // Version 141: Removed
                    currentVersion = 141;
                }

                if (currentVersion == 141) {
                    // This implementation was incorrectly setting the current value of
                    // settings changed by non-system packages as the default which default
                    // is set by the system. We add a new upgrade step at the end to properly
                    // handle this case which would also fix incorrect changes made by the
                    // old implementation of this step.
                    currentVersion = 142;
                }

                if (currentVersion == 142) {
                    // Version 143: Set a default value for Wi-Fi wakeup feature.
                    if (userId == UserHandle.USER_SYSTEM) {
                        final SettingsState globalSettings = getGlobalSettingsLocked();
                        Setting currentSetting = globalSettings.getSettingLocked(
                                Settings.Global.WIFI_WAKEUP_ENABLED);
                        if (currentSetting.isNull()) {
                            globalSettings.insertSettingLocked(
                                    Settings.Global.WIFI_WAKEUP_ENABLED,
                                    getContext().getResources().getBoolean(
                                            R.bool.def_wifi_wakeup_enabled) ? "1" : "0",
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }

                    currentVersion = 143;
                }

                if (currentVersion == 143) {
                    // Version 144: Set a default value for Autofill service.
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    final Setting currentSetting = secureSettings
                            .getSettingLocked(Settings.Secure.AUTOFILL_SERVICE);
                    if (currentSetting.isNull()) {
                        final String defaultValue = getContext().getResources().getString(
                                com.android.internal.R.string.config_defaultAutofillService);
                        if (defaultValue != null) {
                            Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as Autofill Service "
                                    + "for user " + userId);
                            secureSettings.insertSettingLocked(Settings.Secure.AUTOFILL_SERVICE,
                                    defaultValue, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }

                    currentVersion = 144;
                }

                if (currentVersion == 144) {
                    // Version 145: Removed
                    currentVersion = 145;
                }

                if (currentVersion == 145) {
                    // Version 146: In step 142 we had a bug where incorrectly
                    // some settings were considered system set and as a result
                    // made the default and marked as the default being set by
                    // the system. Here reevaluate the default and default system
                    // set flags. This would both fix corruption by the old impl
                    // of step 142 and also properly handle devices which never
                    // run 142.
                    if (userId == UserHandle.USER_SYSTEM) {
                        SettingsState globalSettings = getGlobalSettingsLocked();
                        ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings, userId);
                        globalSettings.persistSyncLocked();
                    }

                    SettingsState secureSettings = getSecureSettingsLocked(mUserId);
                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings, userId);
                    secureSettings.persistSyncLocked();

                    SettingsState systemSettings = getSystemSettingsLocked(mUserId);
                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings, userId);
                    systemSettings.persistSyncLocked();

                    currentVersion = 146;
                }

                if (currentVersion == 146) {
                    // Version 147: Removed. (This version previously allowed showing the
                    // "wifi_wakeup_available" setting).
                    // The setting that was added here is deleted in 153.
                    currentVersion = 147;
                }

                if (currentVersion == 147) {
                    // Version 148: Set the default value for DEFAULT_RESTRICT_BACKGROUND_DATA.
                    if (userId == UserHandle.USER_SYSTEM) {
                        final SettingsState globalSettings = getGlobalSettingsLocked();
                        final Setting currentSetting = globalSettings.getSettingLocked(
                                Global.DEFAULT_RESTRICT_BACKGROUND_DATA);
                        if (currentSetting.isNull()) {
                            globalSettings.insertSettingLocked(
                                    Global.DEFAULT_RESTRICT_BACKGROUND_DATA,
                                    getContext().getResources().getBoolean(
                                            R.bool.def_restrict_background_data) ? "1" : "0",
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }
                    currentVersion = 148;
                }

                if (currentVersion == 148) {
                    // Version 149: Set the default value for BACKUP_MANAGER_CONSTANTS.
                    final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
                    final String oldValue = systemSecureSettings.getSettingLocked(
                            Settings.Secure.BACKUP_MANAGER_CONSTANTS).getValue();
                    if (TextUtils.equals(null, oldValue)) {
                        final String defaultValue = getContext().getResources().getString(
                                R.string.def_backup_manager_constants);
                        if (!TextUtils.isEmpty(defaultValue)) {
                            systemSecureSettings.insertSettingLocked(
                                    Settings.Secure.BACKUP_MANAGER_CONSTANTS, defaultValue, null,
                                    true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }
                    currentVersion = 149;
                }

                if (currentVersion == 149) {
                    // Version 150: Set a default value for mobile data always on
                    final SettingsState globalSettings = getGlobalSettingsLocked();
                    final Setting currentSetting = globalSettings.getSettingLocked(
                            Settings.Global.MOBILE_DATA_ALWAYS_ON);
                    if (currentSetting.isNull()) {
                        globalSettings.insertSettingLocked(
                                Settings.Global.MOBILE_DATA_ALWAYS_ON,
                                getContext().getResources().getBoolean(
                                        R.bool.def_mobile_data_always_on) ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 150;
                }

                if (currentVersion == 150) {
                    // Version 151: Removed.
                    currentVersion = 151;
                }

                if (currentVersion == 151) {
                    // Version 152: Removed. (This version made the setting for wifi_wakeup enabled
                    // by default but it is now no longer configurable).
                    // The setting updated here is deleted in 153.
                    currentVersion = 152;
                }

                if (currentVersion == 152) {
                    getGlobalSettingsLocked().deleteSettingLocked("wifi_wakeup_available");
                    currentVersion = 153;
                }

                if (currentVersion == 153) {
                    // Version 154: Read notification badge configuration from config.
                    // If user has already set the value, don't do anything.
                    final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
                    final Setting showNotificationBadges = systemSecureSettings.getSettingLocked(
                            Settings.Secure.NOTIFICATION_BADGING);
                    if (showNotificationBadges.isNull()) {
                        final boolean defaultValue = getContext().getResources().getBoolean(
                                com.android.internal.R.bool.config_notificationBadging);
                        systemSecureSettings.insertSettingLocked(
                                Secure.NOTIFICATION_BADGING,
                                defaultValue ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 154;
                }

                if (currentVersion == 154) {
                    // Version 155: Set the default value for BACKUP_LOCAL_TRANSPORT_PARAMETERS.
                    final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
                    final String oldValue = systemSecureSettings.getSettingLocked(
                            Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS).getValue();
                    if (TextUtils.equals(null, oldValue)) {
                        final String defaultValue = getContext().getResources().getString(
                                R.string.def_backup_local_transport_parameters);
                        if (!TextUtils.isEmpty(defaultValue)) {
                            systemSecureSettings.insertSettingLocked(
                                    Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS, defaultValue,
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }

                    }
                    currentVersion = 155;
                }

                if (currentVersion == 155) {
                    // Version 156: Set the default value for CHARGING_STARTED_SOUND.
                    final SettingsState globalSettings = getGlobalSettingsLocked();
                    final String oldValue = globalSettings.getSettingLocked(
                            Global.CHARGING_STARTED_SOUND).getValue();
                    final String oldDefault = getContext().getResources().getString(
                            R.string.def_wireless_charging_started_sound);
                    if (TextUtils.equals(null, oldValue)
                            || TextUtils.equals(oldValue, oldDefault)) {
                        final String defaultValue = getContext().getResources().getString(
                                R.string.def_charging_started_sound);
                        if (!TextUtils.isEmpty(defaultValue)) {
                            globalSettings.insertSettingLocked(
                                    Settings.Global.CHARGING_STARTED_SOUND, defaultValue,
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }

                    }
                    currentVersion = 156;
                }

                if (currentVersion == 156) {
                    // Version 157: Set a default value for zen duration,
                    // in version 169, zen duration is moved to secure settings
                    final SettingsState globalSettings = getGlobalSettingsLocked();
                    final Setting currentSetting = globalSettings.getSettingLocked(
                            Global.ZEN_DURATION);
                    if (currentSetting.isNull()) {
                        String defaultZenDuration = Integer.toString(getContext()
                                .getResources().getInteger(R.integer.def_zen_duration));
                        globalSettings.insertSettingLocked(
                                Global.ZEN_DURATION, defaultZenDuration,
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 157;
                }

                if (currentVersion == 157) {
                    // Version 158: Set default value for BACKUP_AGENT_TIMEOUT_PARAMETERS.
                    final SettingsState globalSettings = getGlobalSettingsLocked();
                    final String oldValue = globalSettings.getSettingLocked(
                            Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS).getValue();
                    if (TextUtils.equals(null, oldValue)) {
                        final String defaultValue = getContext().getResources().getString(
                                R.string.def_backup_agent_timeout_parameters);
                        if (!TextUtils.isEmpty(defaultValue)) {
                            globalSettings.insertSettingLocked(
                                    Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS, defaultValue,
                                    null, true,
                                    SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }
                    currentVersion = 158;
                }

                if (currentVersion == 158) {
                    // Remove setting that specifies wifi bgscan throttling params
                    getGlobalSettingsLocked().deleteSettingLocked(
                        "wifi_scan_background_throttle_interval_ms");
                    getGlobalSettingsLocked().deleteSettingLocked(
                        "wifi_scan_background_throttle_package_whitelist");
                    currentVersion = 159;
                }

                if (currentVersion == 159) {
                    // Version 160: Hiding notifications from the lockscreen is only available as
                    // primary user option, profiles can only make them redacted. If a profile was
                    // configured to not show lockscreen notifications, ensure that at the very
                    // least these will be come hidden.
                    if (mUserManager.isManagedProfile(userId)) {
                        final SettingsState secureSettings = getSecureSettingsLocked(userId);
                        Setting showNotifications = secureSettings.getSettingLocked(
                            Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
                        // The default value is "1", check if user has turned it off.
                        if ("0".equals(showNotifications.getValue())) {
                            secureSettings.insertSettingLocked(
                                Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, "0",
                                null /* tag */, false /* makeDefault */,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                        // The setting is no longer valid for managed profiles, it should be
                        // treated as if it was set to "1".
                        secureSettings.deleteSettingLocked(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
                    }
                    currentVersion = 160;
                }

                if (currentVersion == 160) {
                    // Version 161: Set the default value for
                    // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY and
                    // SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT
                    final SettingsState globalSettings = getGlobalSettingsLocked();

                    String oldValue = globalSettings.getSettingLocked(
                            Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY).getValue();
                    if (TextUtils.equals(null, oldValue)) {
                        globalSettings.insertSettingLocked(
                                Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
                                Integer.toString(getContext().getResources().getInteger(
                                        R.integer.def_max_sound_trigger_detection_service_ops_per_day)),
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    oldValue = globalSettings.getSettingLocked(
                            Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT).getValue();
                    if (TextUtils.equals(null, oldValue)) {
                        globalSettings.insertSettingLocked(
                                Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT,
                                Integer.toString(getContext().getResources().getInteger(
                                        R.integer.def_sound_trigger_detection_service_op_timeout)),
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 161;
                }

                if (currentVersion == 161) {
                    // Version 161: Add a gesture for silencing phones
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    final Setting currentSetting = secureSettings.getSettingLocked(
                            Secure.VOLUME_HUSH_GESTURE);
                    if (currentSetting.isNull()) {
                        secureSettings.insertSettingLocked(
                                Secure.VOLUME_HUSH_GESTURE,
                                Integer.toString(Secure.VOLUME_HUSH_VIBRATE),
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 162;
                }

                if (currentVersion == 162) {
                    // Version 162: REMOVED: Add a gesture for silencing phones
                    currentVersion = 163;
                }

                if (currentVersion == 163) {
                    // Version 163: Update default value of
                    // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY from old to new default
                    final SettingsState settings = getGlobalSettingsLocked();
                    final Setting currentSetting = settings.getSettingLocked(
                            Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY);
                    if (currentSetting.isDefaultFromSystem()) {
                        settings.insertSettingLocked(
                                Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
                                Integer.toString(getContext().getResources().getInteger(
                                        R.integer
                                        .def_max_sound_trigger_detection_service_ops_per_day)),
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 164;
                }

                if (currentVersion == 164) {
                    // Version 164: REMOVED: show zen upgrade notification
                    currentVersion = 165;
                }

                if (currentVersion == 165) {
                    // Version 165: MOVED: Show zen settings suggestion and zen updated settings
                    // moved to secure settings and are set in version 169
                    currentVersion = 166;
                }

                if (currentVersion == 166) {
                    // Version 166: add default values for hush gesture used and manual ringer
                    // toggle
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    Setting currentHushUsedSetting = secureSettings.getSettingLocked(
                            Secure.HUSH_GESTURE_USED);
                    if (currentHushUsedSetting.isNull()) {
                        secureSettings.insertSettingLocked(
                                Settings.Secure.HUSH_GESTURE_USED, "0", null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    Setting currentRingerToggleCountSetting = secureSettings.getSettingLocked(
                            Secure.MANUAL_RINGER_TOGGLE_COUNT);
                    if (currentRingerToggleCountSetting.isNull()) {
                        secureSettings.insertSettingLocked(
                                Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, "0", null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 167;
                }

                if (currentVersion == 167) {
                    // Version 167: MOVED - Settings.Global.CHARGING_VIBRATION_ENABLED moved to
                    // Settings.Secure.CHARGING_VIBRATION_ENABLED, set in version 170
                    currentVersion = 168;
                }

                if (currentVersion == 168) {
                    // Version 168: by default, vibrate for phone calls
                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
                    final Setting currentSetting = systemSettings.getSettingLocked(
                            Settings.System.VIBRATE_WHEN_RINGING);
                    if (currentSetting.isNull()) {
                        systemSettings.insertSettingLocked(
                                Settings.System.VIBRATE_WHEN_RINGING,
                                getContext().getResources().getBoolean(
                                        R.bool.def_vibrate_when_ringing) ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 169;
                }

                if (currentVersion == 169) {
                    // Version 169: Set the default value for Secure Settings ZEN_DURATION,
                    // SHOW_ZEN_SETTINGS_SUGGESTION, ZEN_SETTINGS_UPDATE and
                    // ZEN_SETTINGS_SUGGESTION_VIEWED

                    final SettingsState globalSettings = getGlobalSettingsLocked();
                    final Setting globalZenDuration = globalSettings.getSettingLocked(
                            Global.ZEN_DURATION);

                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    final Setting secureZenDuration = secureSettings.getSettingLocked(
                            Secure.ZEN_DURATION);

                    // ZEN_DURATION
                    if (!globalZenDuration.isNull()) {
                        secureSettings.insertSettingLocked(
                                Secure.ZEN_DURATION, globalZenDuration.getValue(), null, false,
                                SettingsState.SYSTEM_PACKAGE_NAME);

                        // set global zen duration setting to null since it's deprecated
                        globalSettings.insertSettingLocked(
                                Global.ZEN_DURATION, null, null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    } else if (secureZenDuration.isNull()) {
                        String defaultZenDuration = Integer.toString(getContext()
                                .getResources().getInteger(R.integer.def_zen_duration));
                        secureSettings.insertSettingLocked(
                                Secure.ZEN_DURATION, defaultZenDuration, null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    // SHOW_ZEN_SETTINGS_SUGGESTION
                    final Setting currentShowZenSettingSuggestion = secureSettings.getSettingLocked(
                            Secure.SHOW_ZEN_SETTINGS_SUGGESTION);
                    if (currentShowZenSettingSuggestion.isNull()) {
                        secureSettings.insertSettingLocked(
                                Secure.SHOW_ZEN_SETTINGS_SUGGESTION, "1",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    // ZEN_SETTINGS_UPDATED
                    final Setting currentUpdatedSetting = secureSettings.getSettingLocked(
                            Secure.ZEN_SETTINGS_UPDATED);
                    if (currentUpdatedSetting.isNull()) {
                        secureSettings.insertSettingLocked(
                                Secure.ZEN_SETTINGS_UPDATED, "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    // ZEN_SETTINGS_SUGGESTION_VIEWED
                    final Setting currentSettingSuggestionViewed = secureSettings.getSettingLocked(
                            Secure.ZEN_SETTINGS_SUGGESTION_VIEWED);
                    if (currentSettingSuggestionViewed.isNull()) {
                        secureSettings.insertSettingLocked(
                                Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 170;
                }

                if (currentVersion == 170) {
                    // Version 170: Set the default value for Secure Settings:
                    // CHARGING_SOUNDS_ENABLED and CHARGING_VIBRATION_ENABLED

                    final SettingsState globalSettings = getGlobalSettingsLocked();
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    // CHARGING_SOUNDS_ENABLED
                    final Setting globalChargingSoundEnabled = globalSettings.getSettingLocked(
                            Global.CHARGING_SOUNDS_ENABLED);
                    final Setting secureChargingSoundsEnabled = secureSettings.getSettingLocked(
                            Secure.CHARGING_SOUNDS_ENABLED);

                    if (!globalChargingSoundEnabled.isNull()) {
                        if (secureChargingSoundsEnabled.isNull()) {
                            secureSettings.insertSettingLocked(
                                    Secure.CHARGING_SOUNDS_ENABLED,
                                    globalChargingSoundEnabled.getValue(), null, false,
                                    SettingsState.SYSTEM_PACKAGE_NAME);
                        }

                        // set global charging_sounds_enabled setting to null since it's deprecated
                        globalSettings.insertSettingLocked(
                                Global.CHARGING_SOUNDS_ENABLED, null, null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    } else if (secureChargingSoundsEnabled.isNull()) {
                        String defChargingSoundsEnabled = getContext().getResources()
                                .getBoolean(R.bool.def_charging_sounds_enabled) ? "1" : "0";
                        secureSettings.insertSettingLocked(
                                Secure.CHARGING_SOUNDS_ENABLED, defChargingSoundsEnabled, null,
                                true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    // CHARGING_VIBRATION_ENABLED
                    final Setting secureChargingVibrationEnabled = secureSettings.getSettingLocked(
                            Secure.CHARGING_VIBRATION_ENABLED);

                    if (secureChargingVibrationEnabled.isNull()) {
                        String defChargingVibrationEnabled = getContext().getResources()
                                .getBoolean(R.bool.def_charging_vibration_enabled) ? "1" : "0";
                        secureSettings.insertSettingLocked(
                                Secure.CHARGING_VIBRATION_ENABLED, defChargingVibrationEnabled,
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 171;
                }

                if (currentVersion == 171) {
                    // Version 171: by default, add STREAM_VOICE_CALL to list of streams that can
                    // be muted.
                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
                    final Setting currentSetting = systemSettings.getSettingLocked(
                              Settings.System.MUTE_STREAMS_AFFECTED);
                    if (!currentSetting.isNull()) {
                        try {
                            int currentSettingIntegerValue = Integer.parseInt(
                                    currentSetting.getValue());
                            if ((currentSettingIntegerValue
                                 & (1 << AudioManager.STREAM_VOICE_CALL)) == 0) {
                                systemSettings.insertSettingLocked(
                                    Settings.System.MUTE_STREAMS_AFFECTED,
                                    Integer.toString(
                                        currentSettingIntegerValue
                                        | (1 << AudioManager.STREAM_VOICE_CALL)),
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                            }
                        } catch (NumberFormatException e) {
                            // remove the setting in case it is not a valid integer
                            Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED"
                                   + "setting, removing setting", e);
                            systemSettings.deleteSettingLocked(
                                Settings.System.MUTE_STREAMS_AFFECTED);
                        }

                    }
                    currentVersion = 172;
                }

                if (currentVersion == 172) {
                    // Version 172: Set the default value for Secure Settings: LOCATION_MODE

                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    final Setting locationMode = secureSettings.getSettingLocked(
                            Secure.LOCATION_MODE);

                    if (locationMode.isNull()) {
                        final Setting locationProvidersAllowed = secureSettings.getSettingLocked(
                                Secure.LOCATION_PROVIDERS_ALLOWED);

                        final int defLocationMode;
                        if (locationProvidersAllowed.isNull()) {
                            defLocationMode = getContext().getResources().getInteger(
                                    R.integer.def_location_mode);
                        } else {
                            defLocationMode =
                                    !TextUtils.isEmpty(locationProvidersAllowed.getValue())
                                            ? Secure.LOCATION_MODE_ON
                                            : Secure.LOCATION_MODE_OFF;
                        }
                        secureSettings.insertSettingLocked(
                                Secure.LOCATION_MODE, Integer.toString(defLocationMode),
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 173;
                }

                if (currentVersion == 173) {
                    // Version 173: Set the default value for Secure Settings: NOTIFICATION_BUBBLES

                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    final Setting bubblesSetting = secureSettings.getSettingLocked(
                            Secure.NOTIFICATION_BUBBLES);

                    if (bubblesSetting.isNull()) {
                        secureSettings.insertSettingLocked(Secure.NOTIFICATION_BUBBLES,
                                getContext().getResources().getBoolean(
                                        R.bool.def_notification_bubbles) ? "1" : "0", null,
                                true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 174;
                }

                if (currentVersion == 174) {
                    // Version 174: Set the default value for Global Settings: APPLY_RAMPING_RINGER

                    final SettingsState globalSettings = getGlobalSettingsLocked();

                    Setting currentRampingRingerSetting = globalSettings.getSettingLocked(
                            Settings.Global.APPLY_RAMPING_RINGER);
                    if (currentRampingRingerSetting.isNull()) {
                        globalSettings.insertSettingLocked(
                                Settings.Global.APPLY_RAMPING_RINGER,
                                getContext().getResources().getBoolean(
                                        R.bool.def_apply_ramping_ringer) ? "1" : "0", null,
                                true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 175;
                }

                if (currentVersion == 175) {
                    // Version 175: Set the default value for System Settings:
                    // RING_VIBRATION_INTENSITY. If the notification vibration intensity has been
                    // set and ring vibration intensity hasn't, the ring vibration intensity should
                    // followed notification vibration intensity.

                    final SettingsState systemSettings = getSystemSettingsLocked(userId);

                    Setting notificationVibrationIntensity = systemSettings.getSettingLocked(
                            Settings.System.NOTIFICATION_VIBRATION_INTENSITY);

                    Setting ringVibrationIntensity = systemSettings.getSettingLocked(
                            Settings.System.RING_VIBRATION_INTENSITY);

                    if (!notificationVibrationIntensity.isNull()
                            && ringVibrationIntensity.isNull()) {
                        systemSettings.insertSettingLocked(
                                Settings.System.RING_VIBRATION_INTENSITY,
                                notificationVibrationIntensity.getValue(),
                                null , true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 176;
                }

                if (currentVersion == 176) {
                    // Version 176: Migrate the existing swipe up setting into the resource overlay
                    //              for the navigation bar interaction mode.  We do so only if the
                    //              setting is set.

                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    final Setting swipeUpSetting = secureSettings.getSettingLocked(
                            "swipe_up_to_switch_apps_enabled");
                    if (swipeUpSetting != null && !swipeUpSetting.isNull()
                            && swipeUpSetting.getValue().equals("1")) {
                        final IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
                                ServiceManager.getService(Context.OVERLAY_SERVICE));
                        try {
                            overlayManager.setEnabledExclusiveInCategory(
                                    NAV_BAR_MODE_2BUTTON_OVERLAY, UserHandle.USER_CURRENT);
                        } catch (RemoteException e) {
                            throw new IllegalStateException(
                                    "Failed to set nav bar interaction mode overlay");
                        }
                    }

                    currentVersion = 177;
                }

                if (currentVersion == 177) {
                    // Version 177: Set the default value for Secure Settings: AWARE_ENABLED

                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    final Setting awareEnabled = secureSettings.getSettingLocked(
                            Secure.AWARE_ENABLED);

                    if (awareEnabled.isNull()) {
                        final boolean defAwareEnabled = getContext().getResources().getBoolean(
                                R.bool.def_aware_enabled);
                        secureSettings.insertSettingLocked(
                                Secure.AWARE_ENABLED, defAwareEnabled ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 178;
                }

                if (currentVersion == 178) {
                    // Version 178: Set the default value for Secure Settings:
                    // SKIP_GESTURE & SILENCE_GESTURE

                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    final Setting skipGesture = secureSettings.getSettingLocked(
                            Secure.SKIP_GESTURE);

                    if (skipGesture.isNull()) {
                        final boolean defSkipGesture = getContext().getResources().getBoolean(
                                R.bool.def_skip_gesture);
                        secureSettings.insertSettingLocked(
                                Secure.SKIP_GESTURE, defSkipGesture ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    final Setting silenceGesture = secureSettings.getSettingLocked(
                            Secure.SILENCE_GESTURE);

                    if (silenceGesture.isNull()) {
                        final boolean defSilenceGesture = getContext().getResources().getBoolean(
                                R.bool.def_silence_gesture);
                        secureSettings.insertSettingLocked(
                                Secure.SILENCE_GESTURE, defSilenceGesture ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 179;
                }

                if (currentVersion == 179) {
                    // Version 178: Reset the default for Secure Settings: NOTIFICATION_BUBBLES
                    // This is originally set in version 173, however, the default value changed
                    // so this step is to ensure the value is updated to the correct defaulte
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    secureSettings.insertSettingLocked(Secure.NOTIFICATION_BUBBLES,
                            getContext().getResources().getBoolean(
                                    R.bool.def_notification_bubbles) ? "1" : "0", null,
                                    true, SettingsState.SYSTEM_PACKAGE_NAME);

                    currentVersion = 180;
                }

                if (currentVersion == 180) {
                    // Version 180: Set the default value for Secure Settings: AWARE_LOCK_ENABLED

                    final SettingsState secureSettings = getSecureSettingsLocked(userId);

                    final Setting awareLockEnabled = secureSettings.getSettingLocked(
                            Secure.AWARE_LOCK_ENABLED);

                    if (awareLockEnabled.isNull()) {
                        final boolean defAwareLockEnabled = getContext().getResources().getBoolean(
                                R.bool.def_aware_lock_enabled);
                        secureSettings.insertSettingLocked(
                                Secure.AWARE_LOCK_ENABLED, defAwareLockEnabled ? "1" : "0",
                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                    }

                    currentVersion = 181;
                }

                if (currentVersion == 181) {
                    // Version cd : by default, add STREAM_BLUETOOTH_SCO to list of streams that can
                    // be muted.
                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
                    final Setting currentSetting = systemSettings.getSettingLocked(
                              Settings.System.MUTE_STREAMS_AFFECTED);
                    if (!currentSetting.isNull()) {
                        try {
                            int currentSettingIntegerValue = Integer.parseInt(
                                    currentSetting.getValue());
                            if ((currentSettingIntegerValue
                                    & (1 << AudioManager.STREAM_BLUETOOTH_SCO)) == 0) {
                                systemSettings.insertSettingLocked(
                                        Settings.System.MUTE_STREAMS_AFFECTED,
                                        Integer.toString(
                                        currentSettingIntegerValue
                                        | (1 << AudioManager.STREAM_BLUETOOTH_SCO)),
                                        null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                            }
                        } catch (NumberFormatException e) {
                            // remove the setting in case it is not a valid integer
                            Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED"
                                    + "setting, removing setting", e);
                            systemSettings.deleteSettingLocked(
                                    Settings.System.MUTE_STREAMS_AFFECTED);
                        }

                    }
                    currentVersion = 182;
                }

                // vXXX: Add new settings above this point.

                if (currentVersion != newVersion) {
                    Slog.wtf("SettingsProvider", "warning: upgrading settings database to version "
                            + newVersion + " left it at "
                            + currentVersion +
                            " instead; this is probably a bug. Did you update SETTINGS_VERSION?",
                            new Throwable());
                    if (DEBUG) {
                        throw new RuntimeException("db upgrade error");
                    }
                }

                // Return the current version.
                return currentVersion;
            }
        }

        private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings,
                int userId) {
            List<String> names = settings.getSettingNamesLocked();
            final int nameCount = names.size();
            for (int i = 0; i < nameCount; i++) {
                String name = names.get(i);
                Setting setting = settings.getSettingLocked(name);

                // In the upgrade case we pretend the call is made from the app
                // that made the last change to the setting to properly determine
                // whether the call has been made by a system component.
                int callingUid = -1;
                try {
                    callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId);
                } catch (RemoteException e) {
                    /* ignore - handled below */
                }
                if (callingUid < 0) {
                    Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName());
                    continue;
                }
                try {
                    final boolean systemSet = SettingsState.isSystemPackage(getContext(),
                            setting.getPackageName(), callingUid, userId);
                    if (systemSet) {
                        settings.insertSettingLocked(name, setting.getValue(),
                                setting.getTag(), true, setting.getPackageName());
                    } else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) {
                        // We had a bug where changes by non-system packages were marked
                        // as system made and as a result set as the default. Therefore, if
                        // the package changed the setting last is not a system one but the
                        // setting is marked as its default coming from the system we clear
                        // the default and clear the system set flag.
                        settings.resetSettingDefaultValueLocked(name);
                    }
                } catch (IllegalStateException e) {
                    // If the package goes over its quota during the upgrade, don't
                    // crash but just log the error as the system does the upgrade.
                    Slog.e(LOG_TAG, "Error upgrading setting: " + setting.getName(), e);

                }
            }
        }
    }
}
