/*
 * 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.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER;
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.IUserRestrictionsListener;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.provider.settings.validators.SystemSettingsValidators;
import android.provider.settings.validators.Validator;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
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.SystemConfig;

import com.google.android.collect.Sets;

import libcore.util.HexEncoding;

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.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
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";

    // 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 RemoteCallback mConfigMonitorCallback;

    @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;

    // 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();

        synchronized (mLock) {
            mUserManager = UserManager.get(getContext());
            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;
    }

    @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);
                final boolean overrideableByRestore = getSettingOverrideableByRestore(args);
                insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false,
                        overrideableByRestore);
                break;
            }

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

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

            case Settings.CALL_METHOD_SET_ALL_CONFIG: {
                String prefix = getSettingPrefix(args);
                Map<String, String> flags = getSettingFlags(args);
                Bundle result = new Bundle();
                result.putBoolean(Settings.KEY_CONFIG_SET_RETURN,
                        setAllConfigSettings(prefix, flags));
                return result;
            }

            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 = packageValuesForCallResult(getAllConfigFlags(prefix),
                        isTrackingGeneration(args));
                reportDeviceConfigAccess(prefix);
                return result;
            }

            case Settings.CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG: {
                RemoteCallback callback = args.getParcelable(
                        Settings.CALL_METHOD_MONITOR_CALLBACK_KEY);
                setMonitorCallback(callback);
                break;
            }

            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,
                        /* overrideableByRestore */ false)) {
                    return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
                }
            } break;

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

            case TABLE_SYSTEM: {
                if (insertSystemSetting(name, value, UserHandle.getCallingUserId(),
                        /* overridableByRestore */ false)) {
                    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.
        IUserRestrictionsListener listener = new IUserRestrictionsListener.Stub() {
            @Override
            public void onUserRestrictionsChanged(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 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);
                    }
                }
            }
        };
        mUserManager.addUserRestrictionsListener(listener);
    }

    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 setAllConfigSettings(String prefix, Map<String, String> keyValues) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "setAllConfigSettings for prefix: " + prefix);
        }

        enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);

        synchronized (mLock) {
            final int key = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
            return mSettingsRegistry.setConfigSettingsLocked(key, prefix, keyValues,
                    resolveCallingPackage());
        }
    }

    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,
                            /* overrideableByRestore */ false);
                }

                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 HashMap<String, String> getAllConfigFlags(@Nullable String prefix) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix);
        }

        DeviceConfig.enforceReadPermission(getContext(),
                prefix != null ? prefix.split("/")[0] : null);

        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();
            HashMap<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,
            boolean overrideableByRestore) {
        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, overrideableByRestore);
    }

    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 isSettingRestrictedForUser(String name, int userId,
            String value, int callerUid) {
        final long oldId = Binder.clearCallingIdentity();
        try {
            return (name != null
                    && mUserManager.isSettingRestrictedForUser(name, userId, value, callerUid));
        } finally {
            Binder.restoreCallingIdentity(oldId);
        }
    }

    private boolean mutateGlobalSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
            int mode) {
        // overrideableByRestore = false as by default settings values shouldn't be overrideable by
        // restore.
        return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId, operation,
                forceNotify, mode, /* overrideableByRestore */ false);
    }

    private boolean mutateGlobalSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
            int mode, boolean overrideableByRestore) {
        // 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 (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, overrideableByRestore);
                }

                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, boolean overrideableByRestore) {
                    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,
            boolean overrideableByRestore) {
        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, overrideableByRestore);
    }

    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) {
        // overrideableByRestore = false as by default settings values shouldn't be overrideable by
        // restore.
        return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId, operation,
                forceNotify, mode, /* overrideableByRestore */ false);
    }

    private boolean mutateSecureSetting(String name, String value, String tag,
            boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
            int mode, boolean overrideableByRestore) {
        // 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 (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;
        }

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

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

                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,
            boolean overrideableByRestore) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", "
                    + requestingUserId + ")");
        }

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

    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) {
        // overrideableByRestore = false as by default settings values shouldn't be overrideable by
        // restore.
        return mutateSystemSetting(name, value, runAsUserId, operation,
                /* overrideableByRestore */ false);
    }

    private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation,
            boolean overrideableByRestore) {
        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 (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, overrideableByRestore);
                }

                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) {
        Validator validator = SystemSettingsValidators.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,
                /* overrideableByRestore */ false);
    }

    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 Bundle packageValuesForCallResult(HashMap<String, String> keyValues,
            boolean trackingGeneration) {
        Bundle result = new Bundle();
        result.putSerializable(Settings.NameValueTable.VALUE, keyValues);
        if (trackingGeneration) {
            synchronized (mLock) {
                mSettingsRegistry.mGenerationRegistry.addGenerationData(result,
                        mSettingsRegistry.getSettingsLocked(
                                SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM).mKey);
            }
        }

        return result;
    }

    private void setMonitorCallback(RemoteCallback callback) {
        if (callback == null) {
            return;
        }
        getContext().enforceCallingOrSelfPermission(
                Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS,
                "Permission denial: registering for config access requires: "
                        + Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS);
        synchronized (mLock) {
            mConfigMonitorCallback = callback;
        }
    }

    private void reportDeviceConfigAccess(@Nullable String prefix) {
        if (prefix == null) {
            return;
        }
        String callingPackage = getCallingPackage();
        String namespace = prefix.replace("/", "");
        if (DeviceConfig.getPublicNamespaces().contains(namespace)) {
            return;
        }
        synchronized (mLock) {
            if (mConfigMonitorCallback != null) {
                Bundle callbackResult = new Bundle();
                callbackResult.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE,
                        Settings.EXTRA_ACCESS_CALLBACK);
                callbackResult.putString(Settings.EXTRA_CALLING_PACKAGE, callingPackage);
                callbackResult.putString(Settings.EXTRA_NAMESPACE, namespace);
                mConfigMonitorCallback.sendResult(callbackResult);
            }
        }
    }

    private void reportDeviceConfigUpdate(@Nullable String prefix) {
        if (prefix == null) {
            return;
        }
        String namespace = prefix.replace("/", "");
        if (DeviceConfig.getPublicNamespaces().contains(namespace)) {
            return;
        }
        synchronized (mLock) {
            if (mConfigMonitorCallback != null) {
                Bundle callbackResult = new Bundle();
                callbackResult.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE,
                        Settings.EXTRA_NAMESPACE_UPDATED_CALLBACK);
                callbackResult.putString(Settings.EXTRA_NAMESPACE, namespace);
                mConfigMonitorCallback.sendResult(callbackResult);
            }
        }
    }

    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) {
        return (args != null) ? args.getString(Settings.CALL_METHOD_PREFIX_KEY) : null;
    }

    private static Map<String, String> getSettingFlags(Bundle args) {
        return (args != null) ? (HashMap) args.getSerializable(Settings.CALL_METHOD_FLAGS_KEY)
                : Collections.emptyMap();
    }

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

    private static boolean getSettingOverrideableByRestore(Bundle args) {
        return (args != null) && args.getBoolean(Settings.CALL_METHOD_OVERRIDEABLE_BY_RESTORE_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 = HexEncoding.encodeToString(keyBytes, true /* upperCase */);

            // 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();
            if (userKey == null || userKey.length() % 2 != 0) {
                throw new IllegalStateException("User key invalid");
            }

            // Convert the user's key back to a byte array.
            final byte[] keyBytes = HexEncoding.decode(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.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 = HexEncoding.encodeToString(m.doFinal(), false /* upperCase */)
                    .substring(0, 16);

            // 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<>();
            }
            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, boolean overrideableByRestore) {
            return insertSettingLocked(type, userId, name, value, tag, makeDefault, false,
                    packageName, forceNotify, criticalSettings, overrideableByRestore);
        }

        public boolean insertSettingLocked(int type, int userId, String name, String value,
                String tag, boolean makeDefault, boolean forceNonSystemPackage, String packageName,
                boolean forceNotify, Set<String> criticalSettings, boolean overrideableByRestore) {
            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, overrideableByRestore);
            }

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

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

        /**
         * Set Config Settings using consumed keyValues, returns true if the keyValues can be set,
         * false otherwise.
         */
        public boolean setConfigSettingsLocked(int key, String prefix,
                Map<String, String> keyValues, String packageName) {
            SettingsState settingsState = peekSettingsStateLocked(key);
            if (settingsState != null) {
                if (settingsState.isNewConfigBannedLocked(prefix, keyValues)) {
                    return false;
                }
                List<String> changedSettings =
                        settingsState.setSettingsLocked(prefix, keyValues, packageName);
                if (!changedSettings.isEmpty()) {
                    reportDeviceConfigUpdate(prefix);
                    notifyForConfigSettingsChangeLocked(key, prefix, changedSettings);
                }
            }
            // keyValues aren't banned and can be set
            return true;
        }

        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, /*prefix=*/
                    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;
            }

            banConfigurationIfNecessary(type, prefix, settingsState);
            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 notifyForConfigSettingsChangeLocked(int key, String prefix,
                List<String> changedSettings) {

            // Increment the generation first, so observers always see the new value
            mGenerationRegistry.incrementGeneration(key);

            StringBuilder stringBuilder = new StringBuilder(prefix);
            for (int i = 0; i < changedSettings.size(); ++i) {
                stringBuilder.append(changedSettings.get(i).split("/")[1]).append("/");
            }

            final long token = Binder.clearCallingIdentity();
            try {
                notifySettingChangeForRunningUsers(key, stringBuilder.toString());
            } finally {
                Binder.restoreCallingIdentity(token);
            }

            // 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 boolean shouldBan(int type) {
            if (SETTINGS_TYPE_CONFIG != type) {
                return false;
            }
            final int callingUid = Binder.getCallingUid();
            final int appId = UserHandle.getAppId(callingUid);

            // Only non-shell resets should result in namespace banning
            return appId != SHELL_UID;
        }

        private void banConfigurationIfNecessary(int type, @Nullable String prefix,
                SettingsState settingsState) {
            // Banning should be performed only for Settings.Config and for non-shell reset calls
            if (!shouldBan(type)) {
                return;
            }
            if (prefix != null) {
                settingsState.banConfigurationLocked(prefix, getAllConfigFlags(prefix));
            } else {
                Set<String> configPrefixes = settingsState.getAllConfigPrefixesLocked();
                for (String configPrefix : configPrefixes) {
                    settingsState.banConfigurationLocked(configPrefix,
                            getAllConfigFlags(configPrefix));
                }
            }
        }

        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) {
                            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 = 186;

            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.
             *
             * All settings modifications should be made through
             * {@link SettingsState#insertSettingOverrideableByRestoreLocked(String, String, String,
             * boolean, String)} so that restore can override those values if needed.
             *
             * 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.insertSettingOverrideableByRestoreLocked(
                            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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                            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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                Settings.Secure.DOZE_PICK_UP_GESTURE, "0", null, true,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                        secureSettings.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                            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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                    Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS, defaultValue,
                                    null, true, SettingsState.SYSTEM_PACKAGE_NAME);
                        }

                    }
                    currentVersion = 155;
                }

                if (currentVersion == 155) {
                    // Version 156: migrated to version 184
                    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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                Secure.ZEN_DURATION, globalZenDuration.getValue(), null, false,
                                SettingsState.SYSTEM_PACKAGE_NAME);

                        // set global zen duration setting to null since it's deprecated
                        globalSettings.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                    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.insertSettingOverrideableByRestoreLocked(
                                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
                    // Removed. Moved NOTIFICATION_BUBBLES to Global Settings.
                    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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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 (SecurityException | IllegalStateException | 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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                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 default.

                    // Removed. Moved NOTIFICATION_BUBBLES to Global Settings.
                    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.insertSettingOverrideableByRestoreLocked(
                                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.insertSettingOverrideableByRestoreLocked(
                                        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;
                }

                if (currentVersion == 182) {
                    // Remove secure bubble settings; it's in global now.
                    getSecureSettingsLocked(userId).deleteSettingLocked("notification_bubbles");

                    // Removed. Updated NOTIFICATION_BUBBLES to be true by default, see 184.
                    currentVersion = 183;
                }

                if (currentVersion == 183) {
                    // Version 183: Set default values for WIRELESS_CHARGING_STARTED_SOUND
                    // and CHARGING_STARTED_SOUND
                    final SettingsState globalSettings = getGlobalSettingsLocked();

                    final String oldValueWireless = globalSettings.getSettingLocked(
                            Global.WIRELESS_CHARGING_STARTED_SOUND).getValue();
                    final String oldValueWired = globalSettings.getSettingLocked(
                            Global.CHARGING_STARTED_SOUND).getValue();

                    final String defaultValueWireless = getContext().getResources().getString(
                            R.string.def_wireless_charging_started_sound);
                    final String defaultValueWired = getContext().getResources().getString(
                            R.string.def_charging_started_sound);

                    // wireless charging sound
                    if (oldValueWireless == null
                            || TextUtils.equals(oldValueWireless, defaultValueWired)) {
                        if (!TextUtils.isEmpty(defaultValueWireless)) {
                            globalSettings.insertSettingOverrideableByRestoreLocked(
                                    Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWireless,
                                    null /* tag */, true /* makeDefault */,
                                    SettingsState.SYSTEM_PACKAGE_NAME);
                        } else if (!TextUtils.isEmpty(defaultValueWired)) {
                            // if the wireless sound is empty, use the wired charging sound
                            globalSettings.insertSettingOverrideableByRestoreLocked(
                                    Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWired,
                                    null /* tag */, true /* makeDefault */,
                                    SettingsState.SYSTEM_PACKAGE_NAME);
                        }
                    }

                    // wired charging sound
                    if (oldValueWired == null && !TextUtils.isEmpty(defaultValueWired)) {
                        globalSettings.insertSettingOverrideableByRestoreLocked(
                                Global.CHARGING_STARTED_SOUND, defaultValueWired,
                                null /* tag */, true /* makeDefault */,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    currentVersion = 184;
                }

                if (currentVersion == 184) {
                    // Version 184: Reset the default for Global Settings: NOTIFICATION_BUBBLES
                    // This is originally set in version 182, however, the default value changed
                    // so this step is to ensure the value is updated to the correct default.
                    getGlobalSettingsLocked().insertSettingOverrideableByRestoreLocked(
                            Global.NOTIFICATION_BUBBLES, getContext().getResources().getBoolean(
                                    R.bool.def_notification_bubbles) ? "1" : "0", null /* tag */,
                            true /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME);

                    currentVersion = 185;
                }

                if (currentVersion == 185) {
                    // Deprecate ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, and migrate it
                    // to ACCESSIBILITY_BUTTON_TARGET_COMPONENT.
                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
                    final Setting magnifyNavbarEnabled = secureSettings.getSettingLocked(
                            Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
                    if ("1".equals(magnifyNavbarEnabled.getValue())) {
                        secureSettings.insertSettingLocked(
                                Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
                                ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER,
                                null /* tag */, false /* makeDefault */,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    } else {
                        // Clear a11y button targets list setting. A11yManagerService will end up
                        // adding all legacy enabled services that want the button to the list, so
                        // there's no need to keep tracking them.
                        secureSettings.insertSettingLocked(
                                Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
                                null, null /* tag */, false /* makeDefault */,
                                SettingsState.SYSTEM_PACKAGE_NAME);
                    }
                    secureSettings.deleteSettingLocked(
                            Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
                    currentVersion = 186;
                }

                // 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.insertSettingOverrideableByRestoreLocked(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);

                }
            }
        }
    }
}
