Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.providers.settings;
     18 
     19 import static android.os.Process.ROOT_UID;
     20 import static android.os.Process.SHELL_UID;
     21 import static android.os.Process.SYSTEM_UID;
     22 
     23 import android.Manifest;
     24 import android.annotation.NonNull;
     25 import android.annotation.Nullable;
     26 import android.app.ActivityManager;
     27 import android.app.AppGlobals;
     28 import android.app.backup.BackupManager;
     29 import android.content.BroadcastReceiver;
     30 import android.content.ComponentName;
     31 import android.content.ContentProvider;
     32 import android.content.ContentValues;
     33 import android.content.Context;
     34 import android.content.Intent;
     35 import android.content.IntentFilter;
     36 import android.content.pm.ApplicationInfo;
     37 import android.content.pm.IPackageManager;
     38 import android.content.pm.PackageInfo;
     39 import android.content.pm.PackageManager;
     40 import android.content.pm.UserInfo;
     41 import android.content.res.Resources;
     42 import android.database.Cursor;
     43 import android.database.MatrixCursor;
     44 import android.database.sqlite.SQLiteDatabase;
     45 import android.database.sqlite.SQLiteQueryBuilder;
     46 import android.hardware.camera2.utils.ArrayUtils;
     47 import android.media.AudioManager;
     48 import android.net.Uri;
     49 import android.os.Binder;
     50 import android.os.Build;
     51 import android.os.Bundle;
     52 import android.os.DropBoxManager;
     53 import android.os.Environment;
     54 import android.os.Handler;
     55 import android.os.HandlerThread;
     56 import android.os.Looper;
     57 import android.os.Message;
     58 import android.os.ParcelFileDescriptor;
     59 import android.os.Process;
     60 import android.os.RemoteException;
     61 import android.os.SELinux;
     62 import android.os.ServiceManager;
     63 import android.os.UserHandle;
     64 import android.os.UserManager;
     65 import android.os.UserManagerInternal;
     66 import android.provider.Settings;
     67 import android.provider.Settings.Global;
     68 import android.provider.Settings.Secure;
     69 import android.provider.SettingsValidators;
     70 import android.text.TextUtils;
     71 import android.util.ArrayMap;
     72 import android.util.ArraySet;
     73 import android.util.ByteStringUtils;
     74 import android.util.Slog;
     75 import android.util.SparseArray;
     76 import android.util.SparseBooleanArray;
     77 import android.util.proto.ProtoOutputStream;
     78 
     79 import com.android.internal.annotations.GuardedBy;
     80 import com.android.internal.content.PackageMonitor;
     81 import com.android.internal.os.BackgroundThread;
     82 import com.android.providers.settings.SettingsState.Setting;
     83 import com.android.server.LocalServices;
     84 import com.android.server.SystemConfig;
     85 
     86 import java.io.File;
     87 import java.io.FileDescriptor;
     88 import java.io.FileNotFoundException;
     89 import java.io.PrintWriter;
     90 import java.nio.ByteBuffer;
     91 import java.security.InvalidKeyException;
     92 import java.security.NoSuchAlgorithmException;
     93 import java.security.SecureRandom;
     94 import java.util.ArrayList;
     95 import java.util.Arrays;
     96 import java.util.Collection;
     97 import java.util.HashSet;
     98 import java.util.List;
     99 import java.util.Locale;
    100 import java.util.Map;
    101 import java.util.Set;
    102 import java.util.regex.Pattern;
    103 
    104 import javax.crypto.Mac;
    105 import javax.crypto.spec.SecretKeySpec;
    106 
    107 
    108 /**
    109  * <p>
    110  * This class is a content provider that publishes the system settings.
    111  * It can be accessed via the content provider APIs or via custom call
    112  * commands. The latter is a bit faster and is the preferred way to access
    113  * the platform settings.
    114  * </p>
    115  * <p>
    116  * There are three settings types, global (with signature level protection
    117  * and shared across users), secure (with signature permission level
    118  * protection and per user), and system (with dangerous permission level
    119  * protection and per user). Global settings are stored under the device owner.
    120  * Each of these settings is represented by a {@link
    121  * com.android.providers.settings.SettingsState} object mapped to an integer
    122  * key derived from the setting type in the most significant bits and user
    123  * id in the least significant bits. Settings are synchronously loaded on
    124  * instantiation of a SettingsState and asynchronously persisted on mutation.
    125  * Settings are stored in the user specific system directory.
    126  * </p>
    127  * <p>
    128  * Apps targeting APIs Lollipop MR1 and lower can add custom settings entries
    129  * and get a warning. Targeting higher API version prohibits this as the
    130  * system settings are not a place for apps to save their state. When a package
    131  * is removed the settings it added are deleted. Apps cannot delete system
    132  * settings added by the platform. System settings values are validated to
    133  * ensure the clients do not put bad values. Global and secure settings are
    134  * changed only by trusted parties, therefore no validation is performed. Also
    135  * there is a limit on the amount of app specific settings that can be added
    136  * to prevent unlimited growth of the system process memory footprint.
    137  * </p>
    138  */
    139 @SuppressWarnings("deprecation")
    140 public class SettingsProvider extends ContentProvider {
    141     static final boolean DEBUG = false;
    142 
    143     private static final boolean DROP_DATABASE_ON_MIGRATION = true;
    144 
    145     private static final String LOG_TAG = "SettingsProvider";
    146 
    147     private static final String TABLE_SYSTEM = "system";
    148     private static final String TABLE_SECURE = "secure";
    149     private static final String TABLE_GLOBAL = "global";
    150 
    151     // Old tables no longer exist.
    152     private static final String TABLE_FAVORITES = "favorites";
    153     private static final String TABLE_OLD_FAVORITES = "old_favorites";
    154     private static final String TABLE_BLUETOOTH_DEVICES = "bluetooth_devices";
    155     private static final String TABLE_BOOKMARKS = "bookmarks";
    156     private static final String TABLE_ANDROID_METADATA = "android_metadata";
    157 
    158     // The set of removed legacy tables.
    159     private static final Set<String> REMOVED_LEGACY_TABLES = new ArraySet<>();
    160     static {
    161         REMOVED_LEGACY_TABLES.add(TABLE_FAVORITES);
    162         REMOVED_LEGACY_TABLES.add(TABLE_OLD_FAVORITES);
    163         REMOVED_LEGACY_TABLES.add(TABLE_BLUETOOTH_DEVICES);
    164         REMOVED_LEGACY_TABLES.add(TABLE_BOOKMARKS);
    165         REMOVED_LEGACY_TABLES.add(TABLE_ANDROID_METADATA);
    166     }
    167 
    168     private static final int MUTATION_OPERATION_INSERT = 1;
    169     private static final int MUTATION_OPERATION_DELETE = 2;
    170     private static final int MUTATION_OPERATION_UPDATE = 3;
    171     private static final int MUTATION_OPERATION_RESET = 4;
    172 
    173     private static final String[] ALL_COLUMNS = new String[] {
    174             Settings.NameValueTable._ID,
    175             Settings.NameValueTable.NAME,
    176             Settings.NameValueTable.VALUE
    177     };
    178 
    179     public static final int SETTINGS_TYPE_GLOBAL = SettingsState.SETTINGS_TYPE_GLOBAL;
    180     public static final int SETTINGS_TYPE_SYSTEM = SettingsState.SETTINGS_TYPE_SYSTEM;
    181     public static final int SETTINGS_TYPE_SECURE = SettingsState.SETTINGS_TYPE_SECURE;
    182     public static final int SETTINGS_TYPE_SSAID = SettingsState.SETTINGS_TYPE_SSAID;
    183 
    184     private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair(
    185             Settings.NameValueTable.VALUE, null);
    186 
    187     // Overlay specified settings whitelisted for Instant Apps
    188     private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>();
    189     private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
    190     private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>();
    191 
    192     static {
    193         for (String name : Resources.getSystem().getStringArray(
    194                 com.android.internal.R.array.config_allowedGlobalInstantAppSettings)) {
    195             OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS.add(name);
    196         }
    197         for (String name : Resources.getSystem().getStringArray(
    198                 com.android.internal.R.array.config_allowedSystemInstantAppSettings)) {
    199             OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS.add(name);
    200         }
    201         for (String name : Resources.getSystem().getStringArray(
    202                 com.android.internal.R.array.config_allowedSecureInstantAppSettings)) {
    203             OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS.add(name);
    204         }
    205     }
    206 
    207     // Changes to these global settings are synchronously persisted
    208     private static final Set<String> CRITICAL_GLOBAL_SETTINGS = new ArraySet<>();
    209     static {
    210         CRITICAL_GLOBAL_SETTINGS.add(Settings.Global.DEVICE_PROVISIONED);
    211     }
    212 
    213     // Changes to these secure settings are synchronously persisted
    214     private static final Set<String> CRITICAL_SECURE_SETTINGS = new ArraySet<>();
    215     static {
    216         CRITICAL_SECURE_SETTINGS.add(Settings.Secure.USER_SETUP_COMPLETE);
    217     }
    218 
    219     // Per user secure settings that moved to the for all users global settings.
    220     static final Set<String> sSecureMovedToGlobalSettings = new ArraySet<>();
    221     static {
    222         Settings.Secure.getMovedToGlobalSettings(sSecureMovedToGlobalSettings);
    223     }
    224 
    225     // Per user system settings that moved to the for all users global settings.
    226     static final Set<String> sSystemMovedToGlobalSettings = new ArraySet<>();
    227     static {
    228         Settings.System.getMovedToGlobalSettings(sSystemMovedToGlobalSettings);
    229     }
    230 
    231     // Per user system settings that moved to the per user secure settings.
    232     static final Set<String> sSystemMovedToSecureSettings = new ArraySet<>();
    233     static {
    234         Settings.System.getMovedToSecureSettings(sSystemMovedToSecureSettings);
    235     }
    236 
    237     // Per all users global settings that moved to the per user secure settings.
    238     static final Set<String> sGlobalMovedToSecureSettings = new ArraySet<>();
    239     static {
    240         Settings.Global.getMovedToSecureSettings(sGlobalMovedToSecureSettings);
    241     }
    242 
    243     // Per user secure settings that are cloned for the managed profiles of the user.
    244     private static final Set<String> sSecureCloneToManagedSettings = new ArraySet<>();
    245     static {
    246         Settings.Secure.getCloneToManagedProfileSettings(sSecureCloneToManagedSettings);
    247     }
    248 
    249     // Per user system settings that are cloned for the managed profiles of the user.
    250     private static final Set<String> sSystemCloneToManagedSettings = new ArraySet<>();
    251     static {
    252         Settings.System.getCloneToManagedProfileSettings(sSystemCloneToManagedSettings);
    253     }
    254 
    255     // Per user system settings that are cloned from the profile's parent when a dependency
    256     // in {@link Settings.Secure} is set to "1".
    257     public static final Map<String, String> sSystemCloneFromParentOnDependency = new ArrayMap<>();
    258     static {
    259         Settings.System.getCloneFromParentOnValueSettings(sSystemCloneFromParentOnDependency);
    260     }
    261 
    262     private final Object mLock = new Object();
    263 
    264     @GuardedBy("mLock")
    265     private SettingsRegistry mSettingsRegistry;
    266 
    267     @GuardedBy("mLock")
    268     private HandlerThread mHandlerThread;
    269 
    270     @GuardedBy("mLock")
    271     private Handler mHandler;
    272 
    273     // We have to call in the user manager with no lock held,
    274     private volatile UserManager mUserManager;
    275 
    276     private UserManagerInternal mUserManagerInternal;
    277 
    278     // We have to call in the package manager with no lock held,
    279     private volatile IPackageManager mPackageManager;
    280 
    281     public static int makeKey(int type, int userId) {
    282         return SettingsState.makeKey(type, userId);
    283     }
    284 
    285     public static int getTypeFromKey(int key) {
    286         return SettingsState.getTypeFromKey(key);
    287     }
    288 
    289     public static int getUserIdFromKey(int key) {
    290         return SettingsState.getUserIdFromKey(key);
    291     }
    292 
    293     public static String settingTypeToString(int type) {
    294         return SettingsState.settingTypeToString(type);
    295     }
    296 
    297     public static String keyToString(int key) {
    298         return SettingsState.keyToString(key);
    299     }
    300 
    301     @Override
    302     public boolean onCreate() {
    303         Settings.setInSystemServer();
    304 
    305         // fail to boot if there're any backed up settings that don't have a non-null validator
    306         ensureAllBackedUpSystemSettingsHaveValidators();
    307         ensureAllBackedUpGlobalSettingsHaveValidators();
    308         ensureAllBackedUpSecureSettingsHaveValidators();
    309 
    310         synchronized (mLock) {
    311             mUserManager = UserManager.get(getContext());
    312             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
    313             mPackageManager = AppGlobals.getPackageManager();
    314             mHandlerThread = new HandlerThread(LOG_TAG,
    315                     Process.THREAD_PRIORITY_BACKGROUND);
    316             mHandlerThread.start();
    317             mHandler = new Handler(mHandlerThread.getLooper());
    318             mSettingsRegistry = new SettingsRegistry();
    319         }
    320         mHandler.post(() -> {
    321             registerBroadcastReceivers();
    322             startWatchingUserRestrictionChanges();
    323         });
    324         ServiceManager.addService("settings", new SettingsService(this));
    325         return true;
    326     }
    327 
    328     private void ensureAllBackedUpSystemSettingsHaveValidators() {
    329         String offenders = getOffenders(concat(Settings.System.SETTINGS_TO_BACKUP,
    330                 Settings.System.LEGACY_RESTORE_SETTINGS), Settings.System.VALIDATORS);
    331 
    332         failToBootIfOffendersPresent(offenders, "Settings.System");
    333     }
    334 
    335     private void ensureAllBackedUpGlobalSettingsHaveValidators() {
    336         String offenders = getOffenders(concat(Settings.Global.SETTINGS_TO_BACKUP,
    337                 Settings.Global.LEGACY_RESTORE_SETTINGS), Settings.Global.VALIDATORS);
    338 
    339         failToBootIfOffendersPresent(offenders, "Settings.Global");
    340     }
    341 
    342     private void ensureAllBackedUpSecureSettingsHaveValidators() {
    343         String offenders = getOffenders(concat(Settings.Secure.SETTINGS_TO_BACKUP,
    344                 Settings.Secure.LEGACY_RESTORE_SETTINGS), Settings.Secure.VALIDATORS);
    345 
    346         failToBootIfOffendersPresent(offenders, "Settings.Secure");
    347     }
    348 
    349     private void failToBootIfOffendersPresent(String offenders, String settingsType) {
    350         if (offenders.length() > 0) {
    351             throw new RuntimeException("All " + settingsType + " settings that are backed up"
    352                     + " have to have a non-null validator, but those don't: " + offenders);
    353         }
    354     }
    355 
    356     private String getOffenders(String[] settingsToBackup, Map<String,
    357             SettingsValidators.Validator> validators) {
    358         StringBuilder offenders = new StringBuilder();
    359         for (String setting : settingsToBackup) {
    360             if (validators.get(setting) == null) {
    361                 offenders.append(setting).append(" ");
    362             }
    363         }
    364         return offenders.toString();
    365     }
    366 
    367     private final String[] concat(String[] first, String[] second) {
    368         if (second == null || second.length == 0) {
    369             return first;
    370         }
    371         final int firstLen = first.length;
    372         final int secondLen = second.length;
    373         String[] both = new String[firstLen + secondLen];
    374         System.arraycopy(first, 0, both, 0, firstLen);
    375         System.arraycopy(second, 0, both, firstLen, secondLen);
    376         return both;
    377     }
    378 
    379     @Override
    380     public Bundle call(String method, String name, Bundle args) {
    381         final int requestingUserId = getRequestingUserId(args);
    382         switch (method) {
    383             case Settings.CALL_METHOD_GET_GLOBAL: {
    384                 Setting setting = getGlobalSetting(name);
    385                 return packageValueForCallResult(setting, isTrackingGeneration(args));
    386             }
    387 
    388             case Settings.CALL_METHOD_GET_SECURE: {
    389                 Setting setting = getSecureSetting(name, requestingUserId,
    390                         /*enableOverride=*/ true);
    391                 return packageValueForCallResult(setting, isTrackingGeneration(args));
    392             }
    393 
    394             case Settings.CALL_METHOD_GET_SYSTEM: {
    395                 Setting setting = getSystemSetting(name, requestingUserId);
    396                 return packageValueForCallResult(setting, isTrackingGeneration(args));
    397             }
    398 
    399             case Settings.CALL_METHOD_PUT_GLOBAL: {
    400                 String value = getSettingValue(args);
    401                 String tag = getSettingTag(args);
    402                 final boolean makeDefault = getSettingMakeDefault(args);
    403                 insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false);
    404                 break;
    405             }
    406 
    407             case Settings.CALL_METHOD_PUT_SECURE: {
    408                 String value = getSettingValue(args);
    409                 String tag = getSettingTag(args);
    410                 final boolean makeDefault = getSettingMakeDefault(args);
    411                 insertSecureSetting(name, value, tag, makeDefault, requestingUserId, false);
    412                 break;
    413             }
    414 
    415             case Settings.CALL_METHOD_PUT_SYSTEM: {
    416                 String value = getSettingValue(args);
    417                 insertSystemSetting(name, value, requestingUserId);
    418                 break;
    419             }
    420 
    421             case Settings.CALL_METHOD_RESET_GLOBAL: {
    422                 final int mode = getResetModeEnforcingPermission(args);
    423                 String tag = getSettingTag(args);
    424                 resetGlobalSetting(requestingUserId, mode, tag);
    425                 break;
    426             }
    427 
    428             case Settings.CALL_METHOD_RESET_SECURE: {
    429                 final int mode = getResetModeEnforcingPermission(args);
    430                 String tag = getSettingTag(args);
    431                 resetSecureSetting(requestingUserId, mode, tag);
    432                 break;
    433             }
    434 
    435             default: {
    436                 Slog.w(LOG_TAG, "call() with invalid method: " + method);
    437             } break;
    438         }
    439 
    440         return null;
    441     }
    442 
    443     @Override
    444     public String getType(Uri uri) {
    445         Arguments args = new Arguments(uri, null, null, true);
    446         if (TextUtils.isEmpty(args.name)) {
    447             return "vnd.android.cursor.dir/" + args.table;
    448         } else {
    449             return "vnd.android.cursor.item/" + args.table;
    450         }
    451     }
    452 
    453     @Override
    454     public Cursor query(Uri uri, String[] projection, String where, String[] whereArgs,
    455             String order) {
    456         if (DEBUG) {
    457             Slog.v(LOG_TAG, "query() for user: " + UserHandle.getCallingUserId());
    458         }
    459 
    460         Arguments args = new Arguments(uri, where, whereArgs, true);
    461         String[] normalizedProjection = normalizeProjection(projection);
    462 
    463         // If a legacy table that is gone, done.
    464         if (REMOVED_LEGACY_TABLES.contains(args.table)) {
    465             return new MatrixCursor(normalizedProjection, 0);
    466         }
    467 
    468         switch (args.table) {
    469             case TABLE_GLOBAL: {
    470                 if (args.name != null) {
    471                     Setting setting = getGlobalSetting(args.name);
    472                     return packageSettingForQuery(setting, normalizedProjection);
    473                 } else {
    474                     return getAllGlobalSettings(projection);
    475                 }
    476             }
    477 
    478             case TABLE_SECURE: {
    479                 final int userId = UserHandle.getCallingUserId();
    480                 if (args.name != null) {
    481                     Setting setting = getSecureSetting(args.name, userId);
    482                     return packageSettingForQuery(setting, normalizedProjection);
    483                 } else {
    484                     return getAllSecureSettings(userId, projection);
    485                 }
    486             }
    487 
    488             case TABLE_SYSTEM: {
    489                 final int userId = UserHandle.getCallingUserId();
    490                 if (args.name != null) {
    491                     Setting setting = getSystemSetting(args.name, userId);
    492                     return packageSettingForQuery(setting, normalizedProjection);
    493                 } else {
    494                     return getAllSystemSettings(userId, projection);
    495                 }
    496             }
    497 
    498             default: {
    499                 throw new IllegalArgumentException("Invalid Uri path:" + uri);
    500             }
    501         }
    502     }
    503 
    504     @Override
    505     public Uri insert(Uri uri, ContentValues values) {
    506         if (DEBUG) {
    507             Slog.v(LOG_TAG, "insert() for user: " + UserHandle.getCallingUserId());
    508         }
    509 
    510         String table = getValidTableOrThrow(uri);
    511 
    512         // If a legacy table that is gone, done.
    513         if (REMOVED_LEGACY_TABLES.contains(table)) {
    514             return null;
    515         }
    516 
    517         String name = values.getAsString(Settings.Secure.NAME);
    518         if (!isKeyValid(name)) {
    519             return null;
    520         }
    521 
    522         String value = values.getAsString(Settings.Secure.VALUE);
    523 
    524         switch (table) {
    525             case TABLE_GLOBAL: {
    526                 if (insertGlobalSetting(name, value, null, false,
    527                         UserHandle.getCallingUserId(), false)) {
    528                     return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
    529                 }
    530             } break;
    531 
    532             case TABLE_SECURE: {
    533                 if (insertSecureSetting(name, value, null, false,
    534                         UserHandle.getCallingUserId(), false)) {
    535                     return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
    536                 }
    537             } break;
    538 
    539             case TABLE_SYSTEM: {
    540                 if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) {
    541                     return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
    542                 }
    543             } break;
    544 
    545             default: {
    546                 throw new IllegalArgumentException("Bad Uri path:" + uri);
    547             }
    548         }
    549 
    550         return null;
    551     }
    552 
    553     @Override
    554     public int bulkInsert(Uri uri, ContentValues[] allValues) {
    555         if (DEBUG) {
    556             Slog.v(LOG_TAG, "bulkInsert() for user: " + UserHandle.getCallingUserId());
    557         }
    558 
    559         int insertionCount = 0;
    560         final int valuesCount = allValues.length;
    561         for (int i = 0; i < valuesCount; i++) {
    562             ContentValues values = allValues[i];
    563             if (insert(uri, values) != null) {
    564                 insertionCount++;
    565             }
    566         }
    567 
    568         return insertionCount;
    569     }
    570 
    571     @Override
    572     public int delete(Uri uri, String where, String[] whereArgs) {
    573         if (DEBUG) {
    574             Slog.v(LOG_TAG, "delete() for user: " + UserHandle.getCallingUserId());
    575         }
    576 
    577         Arguments args = new Arguments(uri, where, whereArgs, false);
    578 
    579         // If a legacy table that is gone, done.
    580         if (REMOVED_LEGACY_TABLES.contains(args.table)) {
    581             return 0;
    582         }
    583 
    584         if (!isKeyValid(args.name)) {
    585             return 0;
    586         }
    587 
    588         switch (args.table) {
    589             case TABLE_GLOBAL: {
    590                 final int userId = UserHandle.getCallingUserId();
    591                 return deleteGlobalSetting(args.name, userId, false) ? 1 : 0;
    592             }
    593 
    594             case TABLE_SECURE: {
    595                 final int userId = UserHandle.getCallingUserId();
    596                 return deleteSecureSetting(args.name, userId, false) ? 1 : 0;
    597             }
    598 
    599             case TABLE_SYSTEM: {
    600                 final int userId = UserHandle.getCallingUserId();
    601                 return deleteSystemSetting(args.name, userId) ? 1 : 0;
    602             }
    603 
    604             default: {
    605                 throw new IllegalArgumentException("Bad Uri path:" + uri);
    606             }
    607         }
    608     }
    609 
    610     @Override
    611     public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
    612         if (DEBUG) {
    613             Slog.v(LOG_TAG, "update() for user: " + UserHandle.getCallingUserId());
    614         }
    615 
    616         Arguments args = new Arguments(uri, where, whereArgs, false);
    617 
    618         // If a legacy table that is gone, done.
    619         if (REMOVED_LEGACY_TABLES.contains(args.table)) {
    620             return 0;
    621         }
    622 
    623         String name = values.getAsString(Settings.Secure.NAME);
    624         if (!isKeyValid(name)) {
    625             return 0;
    626         }
    627         String value = values.getAsString(Settings.Secure.VALUE);
    628 
    629         switch (args.table) {
    630             case TABLE_GLOBAL: {
    631                 final int userId = UserHandle.getCallingUserId();
    632                 return updateGlobalSetting(args.name, value, null, false,
    633                         userId, false) ? 1 : 0;
    634             }
    635 
    636             case TABLE_SECURE: {
    637                 final int userId = UserHandle.getCallingUserId();
    638                 return updateSecureSetting(args.name, value, null, false,
    639                         userId, false) ? 1 : 0;
    640             }
    641 
    642             case TABLE_SYSTEM: {
    643                 final int userId = UserHandle.getCallingUserId();
    644                 return updateSystemSetting(args.name, value, userId) ? 1 : 0;
    645             }
    646 
    647             default: {
    648                 throw new IllegalArgumentException("Invalid Uri path:" + uri);
    649             }
    650         }
    651     }
    652 
    653     @Override
    654     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    655         final int userId = getUserIdFromUri(uri, UserHandle.getCallingUserId());
    656         if (userId != UserHandle.getCallingUserId()) {
    657             getContext().enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS,
    658                     "Access files from the settings of another user");
    659         }
    660         uri = ContentProvider.getUriWithoutUserId(uri);
    661 
    662         final String cacheRingtoneSetting;
    663         final String cacheName;
    664         if (Settings.System.RINGTONE_CACHE_URI.equals(uri)) {
    665             cacheRingtoneSetting = Settings.System.RINGTONE;
    666             cacheName = Settings.System.RINGTONE_CACHE;
    667         } else if (Settings.System.NOTIFICATION_SOUND_CACHE_URI.equals(uri)) {
    668             cacheRingtoneSetting = Settings.System.NOTIFICATION_SOUND;
    669             cacheName = Settings.System.NOTIFICATION_SOUND_CACHE;
    670         } else if (Settings.System.ALARM_ALERT_CACHE_URI.equals(uri)) {
    671             cacheRingtoneSetting = Settings.System.ALARM_ALERT;
    672             cacheName = Settings.System.ALARM_ALERT_CACHE;
    673         } else {
    674             throw new FileNotFoundException("Direct file access no longer supported; "
    675                     + "ringtone playback is available through android.media.Ringtone");
    676         }
    677 
    678         int actualCacheOwner;
    679         // Redirect cache to parent if ringtone setting is owned by profile parent
    680         synchronized (mLock) {
    681             actualCacheOwner = resolveOwningUserIdForSystemSettingLocked(userId,
    682                     cacheRingtoneSetting);
    683         }
    684         final File cacheFile = new File(getRingtoneCacheDir(actualCacheOwner), cacheName);
    685         return ParcelFileDescriptor.open(cacheFile, ParcelFileDescriptor.parseMode(mode));
    686     }
    687 
    688     private File getRingtoneCacheDir(int userId) {
    689         final File cacheDir = new File(Environment.getDataSystemDeDirectory(userId), "ringtones");
    690         cacheDir.mkdir();
    691         SELinux.restorecon(cacheDir);
    692         return cacheDir;
    693     }
    694 
    695     /**
    696      * Dump all settings as a proto buf.
    697      *
    698      * @param fd The file to dump to
    699      */
    700     void dumpProto(@NonNull FileDescriptor fd) {
    701         ProtoOutputStream proto = new ProtoOutputStream(fd);
    702 
    703         synchronized (mLock) {
    704             SettingsProtoDumpUtil.dumpProtoLocked(mSettingsRegistry, proto);
    705         }
    706 
    707         proto.flush();
    708     }
    709 
    710     public void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) {
    711         synchronized (mLock) {
    712             final long identity = Binder.clearCallingIdentity();
    713             try {
    714                 SparseBooleanArray users = mSettingsRegistry.getKnownUsersLocked();
    715                 final int userCount = users.size();
    716                 for (int i = 0; i < userCount; i++) {
    717                     dumpForUserLocked(users.keyAt(i), pw);
    718                 }
    719             } finally {
    720                 Binder.restoreCallingIdentity(identity);
    721             }
    722         }
    723     }
    724 
    725     private void dumpForUserLocked(int userId, PrintWriter pw) {
    726         if (userId == UserHandle.USER_SYSTEM) {
    727             pw.println("GLOBAL SETTINGS (user " + userId + ")");
    728             SettingsState globalSettings = mSettingsRegistry.getSettingsLocked(
    729                     SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
    730             if (globalSettings != null) {
    731                 dumpSettingsLocked(globalSettings, pw);
    732                 pw.println();
    733                 globalSettings.dumpHistoricalOperations(pw);
    734             }
    735         }
    736 
    737         pw.println("SECURE SETTINGS (user " + userId + ")");
    738         SettingsState secureSettings = mSettingsRegistry.getSettingsLocked(
    739                 SETTINGS_TYPE_SECURE, userId);
    740         if (secureSettings != null) {
    741             dumpSettingsLocked(secureSettings, pw);
    742             pw.println();
    743             secureSettings.dumpHistoricalOperations(pw);
    744         }
    745 
    746         pw.println("SYSTEM SETTINGS (user " + userId + ")");
    747         SettingsState systemSettings = mSettingsRegistry.getSettingsLocked(
    748                 SETTINGS_TYPE_SYSTEM, userId);
    749         if (systemSettings != null) {
    750             dumpSettingsLocked(systemSettings, pw);
    751             pw.println();
    752             systemSettings.dumpHistoricalOperations(pw);
    753         }
    754     }
    755 
    756     private void dumpSettingsLocked(SettingsState settingsState, PrintWriter pw) {
    757         List<String> names = settingsState.getSettingNamesLocked();
    758 
    759         final int nameCount = names.size();
    760 
    761         for (int i = 0; i < nameCount; i++) {
    762             String name = names.get(i);
    763             Setting setting = settingsState.getSettingLocked(name);
    764             pw.print("_id:"); pw.print(toDumpString(setting.getId()));
    765             pw.print(" name:"); pw.print(toDumpString(name));
    766             if (setting.getPackageName() != null) {
    767                 pw.print(" pkg:"); pw.print(setting.getPackageName());
    768             }
    769             pw.print(" value:"); pw.print(toDumpString(setting.getValue()));
    770             if (setting.getDefaultValue() != null) {
    771                 pw.print(" default:"); pw.print(setting.getDefaultValue());
    772                 pw.print(" defaultSystemSet:"); pw.print(setting.isDefaultFromSystem());
    773             }
    774             if (setting.getTag() != null) {
    775                 pw.print(" tag:"); pw.print(setting.getTag());
    776             }
    777             pw.println();
    778         }
    779     }
    780 
    781     private static String toDumpString(String s) {
    782         if (s != null) {
    783             return s;
    784         }
    785         return "{null}";
    786     }
    787 
    788     private void registerBroadcastReceivers() {
    789         IntentFilter userFilter = new IntentFilter();
    790         userFilter.addAction(Intent.ACTION_USER_REMOVED);
    791         userFilter.addAction(Intent.ACTION_USER_STOPPED);
    792 
    793         getContext().registerReceiver(new BroadcastReceiver() {
    794             @Override
    795             public void onReceive(Context context, Intent intent) {
    796                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
    797                         UserHandle.USER_SYSTEM);
    798 
    799                 switch (intent.getAction()) {
    800                     case Intent.ACTION_USER_REMOVED: {
    801                         synchronized (mLock) {
    802                             mSettingsRegistry.removeUserStateLocked(userId, true);
    803                         }
    804                     } break;
    805 
    806                     case Intent.ACTION_USER_STOPPED: {
    807                         synchronized (mLock) {
    808                             mSettingsRegistry.removeUserStateLocked(userId, false);
    809                         }
    810                     } break;
    811                 }
    812             }
    813         }, userFilter);
    814 
    815         PackageMonitor monitor = new PackageMonitor() {
    816             @Override
    817             public void onPackageRemoved(String packageName, int uid) {
    818                 synchronized (mLock) {
    819                     mSettingsRegistry.onPackageRemovedLocked(packageName,
    820                             UserHandle.getUserId(uid));
    821                 }
    822             }
    823 
    824             @Override
    825             public void onUidRemoved(int uid) {
    826                 synchronized (mLock) {
    827                     mSettingsRegistry.onUidRemovedLocked(uid);
    828                 }
    829             }
    830         };
    831 
    832         // package changes
    833         monitor.register(getContext(), BackgroundThread.getHandler().getLooper(),
    834                 UserHandle.ALL, true);
    835     }
    836 
    837     private void startWatchingUserRestrictionChanges() {
    838         // TODO: The current design of settings looking different based on user restrictions
    839         // should be reworked to keep them separate and system code should check the setting
    840         // first followed by checking the user restriction before performing an operation.
    841         UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
    842         userManager.addUserRestrictionsListener((int userId, Bundle newRestrictions,
    843                 Bundle prevRestrictions) -> {
    844             // We are changing the settings affected by restrictions to their current
    845             // value with a forced update to ensure that all cross profile dependencies
    846             // are taken into account. Also make sure the settings update to.. the same
    847             // value passes the security checks, so clear binder calling id.
    848             if (newRestrictions.getBoolean(UserManager.DISALLOW_SHARE_LOCATION)
    849                     != prevRestrictions.getBoolean(UserManager.DISALLOW_SHARE_LOCATION)) {
    850                 final long identity = Binder.clearCallingIdentity();
    851                 try {
    852                     synchronized (mLock) {
    853                         Setting setting = getSecureSetting(
    854                                 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, userId);
    855                         updateSecureSetting(Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
    856                                 setting != null ? setting.getValue() : null, null,
    857                                 true, userId, true);
    858                     }
    859                 } finally {
    860                     Binder.restoreCallingIdentity(identity);
    861                 }
    862             }
    863             if (newRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
    864                     != prevRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)) {
    865                 final long identity = Binder.clearCallingIdentity();
    866                 try {
    867                     synchronized (mLock) {
    868                         Setting setting = getGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS);
    869                         String value = setting != null ? setting.getValue() : null;
    870                         updateGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS,
    871                                 value, null, true, userId, true);
    872                     }
    873                 } finally {
    874                     Binder.restoreCallingIdentity(identity);
    875                 }
    876             }
    877             if (newRestrictions.getBoolean(UserManager.DISALLOW_DEBUGGING_FEATURES)
    878                     != prevRestrictions.getBoolean(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
    879                 final long identity = Binder.clearCallingIdentity();
    880                 try {
    881                     synchronized (mLock) {
    882                         Setting setting = getGlobalSetting(Settings.Global.ADB_ENABLED);
    883                         String value = setting != null ? setting.getValue() : null;
    884                         updateGlobalSetting(Settings.Global.ADB_ENABLED,
    885                                 value, null, true, userId, true);
    886                     }
    887                 } finally {
    888                     Binder.restoreCallingIdentity(identity);
    889                 }
    890             }
    891             if (newRestrictions.getBoolean(UserManager.ENSURE_VERIFY_APPS)
    892                     != prevRestrictions.getBoolean(UserManager.ENSURE_VERIFY_APPS)) {
    893                 final long identity = Binder.clearCallingIdentity();
    894                 try {
    895                     synchronized (mLock) {
    896                         Setting enable = getGlobalSetting(
    897                                 Settings.Global.PACKAGE_VERIFIER_ENABLE);
    898                         String enableValue = enable != null ? enable.getValue() : null;
    899                         updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_ENABLE,
    900                                 enableValue, null, true, userId, true);
    901                         Setting include = getGlobalSetting(
    902                                 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB);
    903                         String includeValue = include != null ? include.getValue() : null;
    904                         updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB,
    905                                 includeValue, null, true, userId, true);
    906                     }
    907                 } finally {
    908                     Binder.restoreCallingIdentity(identity);
    909                 }
    910             }
    911             if (newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)
    912                     != prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
    913                 final long identity = Binder.clearCallingIdentity();
    914                 try {
    915                     synchronized (mLock) {
    916                         Setting setting = getGlobalSetting(
    917                                 Settings.Global.PREFERRED_NETWORK_MODE);
    918                         String value = setting != null ? setting.getValue() : null;
    919                         updateGlobalSetting(Settings.Global.PREFERRED_NETWORK_MODE,
    920                                 value, null, true, userId, true);
    921                     }
    922                 } finally {
    923                     Binder.restoreCallingIdentity(identity);
    924                 }
    925             }
    926         });
    927     }
    928 
    929     private Cursor getAllGlobalSettings(String[] projection) {
    930         if (DEBUG) {
    931             Slog.v(LOG_TAG, "getAllGlobalSettings()");
    932         }
    933 
    934         synchronized (mLock) {
    935             // Get the settings.
    936             SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
    937                     SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
    938 
    939             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_GLOBAL,
    940                     UserHandle.USER_SYSTEM);
    941 
    942             final int nameCount = names.size();
    943 
    944             String[] normalizedProjection = normalizeProjection(projection);
    945             MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
    946 
    947             // Anyone can get the global settings, so no security checks.
    948             for (int i = 0; i < nameCount; i++) {
    949                 String name = names.get(i);
    950                 Setting setting = settingsState.getSettingLocked(name);
    951                 appendSettingToCursor(result, setting);
    952             }
    953 
    954             return result;
    955         }
    956     }
    957 
    958     private Setting getGlobalSetting(String name) {
    959         if (DEBUG) {
    960             Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")");
    961         }
    962 
    963         // Ensure the caller can access the setting.
    964         enforceSettingReadable(name, SETTINGS_TYPE_GLOBAL, UserHandle.getCallingUserId());
    965 
    966         // Get the value.
    967         synchronized (mLock) {
    968             return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_GLOBAL,
    969                     UserHandle.USER_SYSTEM, name);
    970         }
    971     }
    972 
    973     private boolean updateGlobalSetting(String name, String value, String tag,
    974             boolean makeDefault, int requestingUserId, boolean forceNotify) {
    975         if (DEBUG) {
    976             Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ", "
    977                     + ", " + tag + ", " + makeDefault + ", " + requestingUserId
    978                     + ", " + forceNotify + ")");
    979         }
    980         return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
    981                 MUTATION_OPERATION_UPDATE, forceNotify, 0);
    982     }
    983 
    984     private boolean insertGlobalSetting(String name, String value, String tag,
    985             boolean makeDefault, int requestingUserId, boolean forceNotify) {
    986         if (DEBUG) {
    987             Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value  + ", "
    988                     + ", " + tag + ", " + makeDefault + ", " + requestingUserId
    989                     + ", " + forceNotify + ")");
    990         }
    991         return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
    992                 MUTATION_OPERATION_INSERT, forceNotify, 0);
    993     }
    994 
    995     private boolean deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify) {
    996         if (DEBUG) {
    997             Slog.v(LOG_TAG, "deleteGlobalSetting(" + name + ", " + requestingUserId
    998                     + ", " + forceNotify + ")");
    999         }
   1000         return mutateGlobalSetting(name, null, null, false, requestingUserId,
   1001                 MUTATION_OPERATION_DELETE, forceNotify, 0);
   1002     }
   1003 
   1004     private void resetGlobalSetting(int requestingUserId, int mode, String tag) {
   1005         if (DEBUG) {
   1006             Slog.v(LOG_TAG, "resetGlobalSetting(" + requestingUserId + ", "
   1007                     + mode + ", " + tag + ")");
   1008         }
   1009         mutateGlobalSetting(null, null, tag, false, requestingUserId,
   1010                 MUTATION_OPERATION_RESET, false, mode);
   1011     }
   1012 
   1013     private boolean mutateGlobalSetting(String name, String value, String tag,
   1014             boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
   1015             int mode) {
   1016         // Make sure the caller can change the settings - treated as secure.
   1017         enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
   1018 
   1019         // Resolve the userId on whose behalf the call is made.
   1020         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
   1021 
   1022         // If this is a setting that is currently restricted for this user, do not allow
   1023         // unrestricting changes.
   1024         if (name != null && mUserManagerInternal.isSettingRestrictedForUser(
   1025                 name, callingUserId, value, Binder.getCallingUid())) {
   1026             return false;
   1027         }
   1028 
   1029         // Perform the mutation.
   1030         synchronized (mLock) {
   1031             switch (operation) {
   1032                 case MUTATION_OPERATION_INSERT: {
   1033                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
   1034                             UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
   1035                             getCallingPackage(), forceNotify, CRITICAL_GLOBAL_SETTINGS);
   1036                 }
   1037 
   1038                 case MUTATION_OPERATION_DELETE: {
   1039                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_GLOBAL,
   1040                             UserHandle.USER_SYSTEM, name, forceNotify, CRITICAL_GLOBAL_SETTINGS);
   1041                 }
   1042 
   1043                 case MUTATION_OPERATION_UPDATE: {
   1044                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_GLOBAL,
   1045                             UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
   1046                             getCallingPackage(), forceNotify, CRITICAL_GLOBAL_SETTINGS);
   1047                 }
   1048 
   1049                 case MUTATION_OPERATION_RESET: {
   1050                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_GLOBAL,
   1051                             UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
   1052                 } return true;
   1053             }
   1054         }
   1055 
   1056         return false;
   1057     }
   1058 
   1059     private PackageInfo getCallingPackageInfo(int userId) {
   1060         try {
   1061             return mPackageManager.getPackageInfo(getCallingPackage(),
   1062                     PackageManager.GET_SIGNATURES, userId);
   1063         } catch (RemoteException e) {
   1064             throw new IllegalStateException("Package " + getCallingPackage() + " doesn't exist");
   1065         }
   1066     }
   1067 
   1068     private Cursor getAllSecureSettings(int userId, String[] projection) {
   1069         if (DEBUG) {
   1070             Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")");
   1071         }
   1072 
   1073         // Resolve the userId on whose behalf the call is made.
   1074         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
   1075 
   1076         // The relevant "calling package" userId will be the owning userId for some
   1077         // profiles, and we can't do the lookup inside our [lock held] loop, so work out
   1078         // up front who the effective "new SSAID" user ID for that settings name will be.
   1079         final int ssaidUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
   1080                 Settings.Secure.ANDROID_ID);
   1081         final PackageInfo ssaidCallingPkg = getCallingPackageInfo(ssaidUserId);
   1082 
   1083         synchronized (mLock) {
   1084             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SECURE, callingUserId);
   1085 
   1086             final int nameCount = names.size();
   1087 
   1088             String[] normalizedProjection = normalizeProjection(projection);
   1089             MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
   1090 
   1091             for (int i = 0; i < nameCount; i++) {
   1092                 String name = names.get(i);
   1093                 // Determine the owning user as some profile settings are cloned from the parent.
   1094                 final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
   1095                         name);
   1096 
   1097                 if (!isSecureSettingAccessible(name, callingUserId, owningUserId)) {
   1098                     // This caller is not permitted to access this setting. Pretend the setting
   1099                     // doesn't exist.
   1100                     continue;
   1101                 }
   1102 
   1103                 // As of Android O, the SSAID is read from an app-specific entry in table
   1104                 // SETTINGS_FILE_SSAID, unless accessed by a system process.
   1105                 final Setting setting;
   1106                 if (isNewSsaidSetting(name)) {
   1107                     setting = getSsaidSettingLocked(ssaidCallingPkg, owningUserId);
   1108                 } else {
   1109                     setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE, owningUserId,
   1110                             name);
   1111                 }
   1112                 appendSettingToCursor(result, setting);
   1113             }
   1114 
   1115             return result;
   1116         }
   1117     }
   1118 
   1119     private Setting getSecureSetting(String name, int requestingUserId) {
   1120         return getSecureSetting(name, requestingUserId, /*enableOverride=*/ false);
   1121     }
   1122 
   1123     private Setting getSecureSetting(String name, int requestingUserId, boolean enableOverride) {
   1124         if (DEBUG) {
   1125             Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")");
   1126         }
   1127 
   1128         // Resolve the userId on whose behalf the call is made.
   1129         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
   1130 
   1131         // Ensure the caller can access the setting.
   1132         enforceSettingReadable(name, SETTINGS_TYPE_SECURE, UserHandle.getCallingUserId());
   1133 
   1134         // Determine the owning user as some profile settings are cloned from the parent.
   1135         final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);
   1136 
   1137         if (!isSecureSettingAccessible(name, callingUserId, owningUserId)) {
   1138             // This caller is not permitted to access this setting. Pretend the setting doesn't
   1139             // exist.
   1140             SettingsState settings = mSettingsRegistry.getSettingsLocked(SETTINGS_TYPE_SECURE,
   1141                     owningUserId);
   1142             return settings != null ? settings.getNullSetting() : null;
   1143         }
   1144 
   1145         // As of Android O, the SSAID is read from an app-specific entry in table
   1146         // SETTINGS_FILE_SSAID, unless accessed by a system process.
   1147         if (isNewSsaidSetting(name)) {
   1148             PackageInfo callingPkg = getCallingPackageInfo(owningUserId);
   1149             synchronized (mLock) {
   1150                 return getSsaidSettingLocked(callingPkg, owningUserId);
   1151             }
   1152         }
   1153         if (enableOverride) {
   1154             if (Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
   1155                 final Setting overridden = getLocationProvidersAllowedSetting(owningUserId);
   1156                 if (overridden != null) {
   1157                     return overridden;
   1158                 }
   1159             }
   1160         }
   1161 
   1162         // Not the SSAID; do a straight lookup
   1163         synchronized (mLock) {
   1164             return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE,
   1165                     owningUserId, name);
   1166         }
   1167     }
   1168 
   1169     private boolean isNewSsaidSetting(String name) {
   1170         return Settings.Secure.ANDROID_ID.equals(name)
   1171                 && UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID;
   1172     }
   1173 
   1174     private Setting getSsaidSettingLocked(PackageInfo callingPkg, int owningUserId) {
   1175         // Get uid of caller (key) used to store ssaid value
   1176         String name = Integer.toString(
   1177                 UserHandle.getUid(owningUserId, UserHandle.getAppId(Binder.getCallingUid())));
   1178 
   1179         if (DEBUG) {
   1180             Slog.v(LOG_TAG, "getSsaidSettingLocked(" + name + "," + owningUserId + ")");
   1181         }
   1182 
   1183         // Retrieve the ssaid from the table if present.
   1184         final Setting ssaid = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId,
   1185                 name);
   1186         // If the app is an Instant App use its stored SSAID instead of our own.
   1187         final String instantSsaid;
   1188         final long token = Binder.clearCallingIdentity();
   1189         try {
   1190             instantSsaid = mPackageManager.getInstantAppAndroidId(callingPkg.packageName,
   1191                     owningUserId);
   1192         } catch (RemoteException e) {
   1193             Slog.e(LOG_TAG, "Failed to get Instant App Android ID", e);
   1194             return null;
   1195         } finally {
   1196             Binder.restoreCallingIdentity(token);
   1197         }
   1198 
   1199         final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked(
   1200                 SETTINGS_TYPE_SSAID, owningUserId);
   1201 
   1202         if (instantSsaid != null) {
   1203             // Use the stored value if it is still valid.
   1204             if (ssaid != null && instantSsaid.equals(ssaid.getValue())) {
   1205                 return mascaradeSsaidSetting(ssaidSettings, ssaid);
   1206             }
   1207             // The value has changed, update the stored value.
   1208             final boolean success = ssaidSettings.insertSettingLocked(name, instantSsaid, null,
   1209                     true, callingPkg.packageName);
   1210             if (!success) {
   1211                 throw new IllegalStateException("Failed to update instant app android id");
   1212             }
   1213             Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID,
   1214                     owningUserId, name);
   1215             return mascaradeSsaidSetting(ssaidSettings, setting);
   1216         }
   1217 
   1218         // Lazy initialize ssaid if not yet present in ssaid table.
   1219         if (ssaid == null || ssaid.isNull() || ssaid.getValue() == null) {
   1220             Setting setting = mSettingsRegistry.generateSsaidLocked(callingPkg, owningUserId);
   1221             return mascaradeSsaidSetting(ssaidSettings, setting);
   1222         }
   1223 
   1224         return mascaradeSsaidSetting(ssaidSettings, ssaid);
   1225     }
   1226 
   1227     private Setting mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting) {
   1228         // SSAID settings are located in a dedicated table for internal bookkeeping
   1229         // but for the world they reside in the secure table, so adjust the key here.
   1230         // We have a special name when looking it up but want the world to see it as
   1231         // "android_id".
   1232         if (ssaidSetting != null) {
   1233             return settingsState.new Setting(ssaidSetting) {
   1234                 @Override
   1235                 public int getKey() {
   1236                     final int userId = getUserIdFromKey(super.getKey());
   1237                     return makeKey(SETTINGS_TYPE_SECURE, userId);
   1238                 }
   1239 
   1240                 @Override
   1241                 public String getName() {
   1242                     return Settings.Secure.ANDROID_ID;
   1243                 }
   1244             };
   1245         }
   1246         return null;
   1247     }
   1248 
   1249     private Setting getLocationProvidersAllowedSetting(int owningUserId) {
   1250         synchronized (mLock) {
   1251             final Setting setting = getGlobalSetting(
   1252                     Global.LOCATION_GLOBAL_KILL_SWITCH);
   1253             if (!"1".equals(setting.getValue())) {
   1254                 return null;
   1255             }
   1256             // Global kill-switch is enabled. Return an empty value.
   1257             final SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
   1258                     SETTINGS_TYPE_SECURE, owningUserId);
   1259             return settingsState.new Setting(
   1260                     Secure.LOCATION_PROVIDERS_ALLOWED,
   1261                     "", // value
   1262                     "", // tag
   1263                     "", // default value
   1264                     "", // package name
   1265                     false, // from system
   1266                     "0" // id
   1267             ) {
   1268                 @Override
   1269                 public boolean update(String value, boolean setDefault, String packageName,
   1270                         String tag, boolean forceNonSystemPackage) {
   1271                     Slog.wtf(LOG_TAG, "update shoudln't be called on this instance.");
   1272                     return false;
   1273                 }
   1274             };
   1275         }
   1276     }
   1277 
   1278     private boolean insertSecureSetting(String name, String value, String tag,
   1279             boolean makeDefault, int requestingUserId, boolean forceNotify) {
   1280         if (DEBUG) {
   1281             Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", "
   1282                     + ", " + tag  + ", " + makeDefault + ", "  + requestingUserId
   1283                     + ", " + forceNotify + ")");
   1284         }
   1285         return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
   1286                 MUTATION_OPERATION_INSERT, forceNotify, 0);
   1287     }
   1288 
   1289     private boolean deleteSecureSetting(String name, int requestingUserId, boolean forceNotify) {
   1290         if (DEBUG) {
   1291             Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId
   1292                     + ", " + forceNotify + ")");
   1293         }
   1294 
   1295         return mutateSecureSetting(name, null, null, false, requestingUserId,
   1296                 MUTATION_OPERATION_DELETE, forceNotify, 0);
   1297     }
   1298 
   1299     private boolean updateSecureSetting(String name, String value, String tag,
   1300             boolean makeDefault, int requestingUserId, boolean forceNotify) {
   1301         if (DEBUG) {
   1302             Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", "
   1303                     + ", " + tag  + ", " + makeDefault + ", "  + requestingUserId
   1304                     + ", "  + forceNotify +")");
   1305         }
   1306 
   1307         return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
   1308                 MUTATION_OPERATION_UPDATE, forceNotify, 0);
   1309     }
   1310 
   1311     private void resetSecureSetting(int requestingUserId, int mode, String tag) {
   1312         if (DEBUG) {
   1313             Slog.v(LOG_TAG, "resetSecureSetting(" + requestingUserId + ", "
   1314                     + mode + ", " + tag + ")");
   1315         }
   1316 
   1317         mutateSecureSetting(null, null, tag, false, requestingUserId,
   1318                 MUTATION_OPERATION_RESET, false, mode);
   1319     }
   1320 
   1321     private boolean mutateSecureSetting(String name, String value, String tag,
   1322             boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
   1323             int mode) {
   1324         // Make sure the caller can change the settings.
   1325         enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
   1326 
   1327         // Resolve the userId on whose behalf the call is made.
   1328         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
   1329 
   1330         // If this is a setting that is currently restricted for this user, do not allow
   1331         // unrestricting changes.
   1332         if (name != null && mUserManagerInternal.isSettingRestrictedForUser(
   1333                 name, callingUserId, value, Binder.getCallingUid())) {
   1334             return false;
   1335         }
   1336 
   1337         // Determine the owning user as some profile settings are cloned from the parent.
   1338         final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);
   1339 
   1340         // Only the owning user can change the setting.
   1341         if (owningUserId != callingUserId) {
   1342             return false;
   1343         }
   1344 
   1345         // Special cases for location providers (sigh).
   1346         if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
   1347             return updateLocationProvidersAllowedLocked(value, tag, owningUserId, makeDefault,
   1348                     forceNotify);
   1349         }
   1350 
   1351         // Mutate the value.
   1352         synchronized (mLock) {
   1353             switch (operation) {
   1354                 case MUTATION_OPERATION_INSERT: {
   1355                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
   1356                             owningUserId, name, value, tag, makeDefault,
   1357                             getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
   1358                 }
   1359 
   1360                 case MUTATION_OPERATION_DELETE: {
   1361                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SECURE,
   1362                             owningUserId, name, forceNotify, CRITICAL_SECURE_SETTINGS);
   1363                 }
   1364 
   1365                 case MUTATION_OPERATION_UPDATE: {
   1366                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SECURE,
   1367                             owningUserId, name, value, tag, makeDefault,
   1368                             getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
   1369                 }
   1370 
   1371                 case MUTATION_OPERATION_RESET: {
   1372                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_SECURE,
   1373                             UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
   1374                 } return true;
   1375             }
   1376         }
   1377 
   1378         return false;
   1379     }
   1380 
   1381     private Cursor getAllSystemSettings(int userId, String[] projection) {
   1382         if (DEBUG) {
   1383             Slog.v(LOG_TAG, "getAllSecureSystem(" + userId + ")");
   1384         }
   1385 
   1386         // Resolve the userId on whose behalf the call is made.
   1387         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
   1388 
   1389         synchronized (mLock) {
   1390             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SYSTEM, callingUserId);
   1391 
   1392             final int nameCount = names.size();
   1393 
   1394             String[] normalizedProjection = normalizeProjection(projection);
   1395             MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
   1396 
   1397             for (int i = 0; i < nameCount; i++) {
   1398                 String name = names.get(i);
   1399 
   1400                 // Determine the owning user as some profile settings are cloned from the parent.
   1401                 final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId,
   1402                         name);
   1403 
   1404                 Setting setting = mSettingsRegistry.getSettingLocked(
   1405                         SETTINGS_TYPE_SYSTEM, owningUserId, name);
   1406                 appendSettingToCursor(result, setting);
   1407             }
   1408 
   1409             return result;
   1410         }
   1411     }
   1412 
   1413     private Setting getSystemSetting(String name, int requestingUserId) {
   1414         if (DEBUG) {
   1415             Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")");
   1416         }
   1417 
   1418         // Resolve the userId on whose behalf the call is made.
   1419         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
   1420 
   1421         // Ensure the caller can access the setting.
   1422         enforceSettingReadable(name, SETTINGS_TYPE_SYSTEM, UserHandle.getCallingUserId());
   1423 
   1424         // Determine the owning user as some profile settings are cloned from the parent.
   1425         final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
   1426 
   1427         // Get the value.
   1428         synchronized (mLock) {
   1429             return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SYSTEM, owningUserId, name);
   1430         }
   1431     }
   1432 
   1433     private boolean insertSystemSetting(String name, String value, int requestingUserId) {
   1434         if (DEBUG) {
   1435             Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", "
   1436                     + requestingUserId + ")");
   1437         }
   1438 
   1439         return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
   1440     }
   1441 
   1442     private boolean deleteSystemSetting(String name, int requestingUserId) {
   1443         if (DEBUG) {
   1444             Slog.v(LOG_TAG, "deleteSystemSetting(" + name + ", " + requestingUserId + ")");
   1445         }
   1446 
   1447         return mutateSystemSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
   1448     }
   1449 
   1450     private boolean updateSystemSetting(String name, String value, int requestingUserId) {
   1451         if (DEBUG) {
   1452             Slog.v(LOG_TAG, "updateSystemSetting(" + name + ", " + value + ", "
   1453                     + requestingUserId + ")");
   1454         }
   1455 
   1456         return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
   1457     }
   1458 
   1459     private boolean mutateSystemSetting(String name, String value, int runAsUserId,
   1460             int operation) {
   1461         if (!hasWriteSecureSettingsPermission()) {
   1462             // If the caller doesn't hold WRITE_SECURE_SETTINGS, we verify whether this
   1463             // operation is allowed for the calling package through appops.
   1464             if (!Settings.checkAndNoteWriteSettingsOperation(getContext(),
   1465                     Binder.getCallingUid(), getCallingPackage(), true)) {
   1466                 return false;
   1467             }
   1468         }
   1469 
   1470         // Resolve the userId on whose behalf the call is made.
   1471         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(runAsUserId);
   1472 
   1473         if (name != null && mUserManagerInternal.isSettingRestrictedForUser(
   1474                 name, callingUserId, value, Binder.getCallingUid())) {
   1475             return false;
   1476         }
   1477 
   1478         // Enforce what the calling package can mutate the system settings.
   1479         enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name, callingUserId);
   1480 
   1481         // Determine the owning user as some profile settings are cloned from the parent.
   1482         final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
   1483 
   1484         // Only the owning user id can change the setting.
   1485         if (owningUserId != callingUserId) {
   1486             return false;
   1487         }
   1488 
   1489         // Invalidate any relevant cache files
   1490         String cacheName = null;
   1491         if (Settings.System.RINGTONE.equals(name)) {
   1492             cacheName = Settings.System.RINGTONE_CACHE;
   1493         } else if (Settings.System.NOTIFICATION_SOUND.equals(name)) {
   1494             cacheName = Settings.System.NOTIFICATION_SOUND_CACHE;
   1495         } else if (Settings.System.ALARM_ALERT.equals(name)) {
   1496             cacheName = Settings.System.ALARM_ALERT_CACHE;
   1497         }
   1498         if (cacheName != null) {
   1499             final File cacheFile = new File(
   1500                     getRingtoneCacheDir(owningUserId), cacheName);
   1501             cacheFile.delete();
   1502         }
   1503 
   1504         // Mutate the value.
   1505         synchronized (mLock) {
   1506             switch (operation) {
   1507                 case MUTATION_OPERATION_INSERT: {
   1508                     validateSystemSettingValue(name, value);
   1509                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SYSTEM,
   1510                             owningUserId, name, value, null, false, getCallingPackage(),
   1511                             false, null);
   1512                 }
   1513 
   1514                 case MUTATION_OPERATION_DELETE: {
   1515                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SYSTEM,
   1516                             owningUserId, name, false, null);
   1517                 }
   1518 
   1519                 case MUTATION_OPERATION_UPDATE: {
   1520                     validateSystemSettingValue(name, value);
   1521                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SYSTEM,
   1522                             owningUserId, name, value, null, false, getCallingPackage(),
   1523                             false, null);
   1524                 }
   1525             }
   1526 
   1527             return false;
   1528         }
   1529     }
   1530 
   1531     private boolean hasWriteSecureSettingsPermission() {
   1532         // Write secure settings is a more protected permission. If caller has it we are good.
   1533         if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
   1534                 == PackageManager.PERMISSION_GRANTED) {
   1535             return true;
   1536         }
   1537 
   1538         return false;
   1539     }
   1540 
   1541     private void validateSystemSettingValue(String name, String value) {
   1542         SettingsValidators.Validator validator = Settings.System.VALIDATORS.get(name);
   1543         if (validator != null && !validator.validate(value)) {
   1544             throw new IllegalArgumentException("Invalid value: " + value
   1545                     + " for setting: " + name);
   1546         }
   1547     }
   1548 
   1549     /**
   1550      * Returns {@code true} if the specified secure setting should be accessible to the caller.
   1551      */
   1552     private boolean isSecureSettingAccessible(String name, int callingUserId,
   1553             int owningUserId) {
   1554         // Special case for location (sigh).
   1555         // This check is not inside the name-based checks below because this method performs checks
   1556         // only if the calling user ID is not the same as the owning user ID.
   1557         if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) {
   1558             return false;
   1559         }
   1560 
   1561         switch (name) {
   1562             case "bluetooth_address":
   1563                 // BluetoothManagerService for some reason stores the Android's Bluetooth MAC
   1564                 // address in this secure setting. Secure settings can normally be read by any app,
   1565                 // which thus enables them to bypass the recently introduced restrictions on access
   1566                 // to device identifiers.
   1567                 // To mitigate this we make this setting available only to callers privileged to see
   1568                 // this device's MAC addresses, same as through public API
   1569                 // BluetoothAdapter.getAddress() (see BluetoothManagerService for details).
   1570                 return getContext().checkCallingOrSelfPermission(
   1571                         Manifest.permission.LOCAL_MAC_ADDRESS) == PackageManager.PERMISSION_GRANTED;
   1572             default:
   1573                 return true;
   1574         }
   1575     }
   1576 
   1577     private boolean isLocationProvidersAllowedRestricted(String name, int callingUserId,
   1578             int owningUserId) {
   1579         // Optimization - location providers are restricted only for managed profiles.
   1580         if (callingUserId == owningUserId) {
   1581             return false;
   1582         }
   1583         if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)
   1584                 && mUserManager.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION,
   1585                 new UserHandle(callingUserId))) {
   1586             return true;
   1587         }
   1588         return false;
   1589     }
   1590 
   1591     private int resolveOwningUserIdForSecureSettingLocked(int userId, String setting) {
   1592         return resolveOwningUserIdLocked(userId, sSecureCloneToManagedSettings, setting);
   1593     }
   1594 
   1595     private int resolveOwningUserIdForSystemSettingLocked(int userId, String setting) {
   1596         final int parentId;
   1597         // Resolves dependency if setting has a dependency and the calling user has a parent
   1598         if (sSystemCloneFromParentOnDependency.containsKey(setting)
   1599                 && (parentId = getGroupParentLocked(userId)) != userId) {
   1600             // The setting has a dependency and the profile has a parent
   1601             String dependency = sSystemCloneFromParentOnDependency.get(setting);
   1602             // Lookup the dependency setting as ourselves, some callers may not have access to it.
   1603             final long token = Binder.clearCallingIdentity();
   1604             try {
   1605                 Setting settingObj = getSecureSetting(dependency, userId);
   1606                 if (settingObj != null && settingObj.getValue().equals("1")) {
   1607                     return parentId;
   1608                 }
   1609             } finally {
   1610                 Binder.restoreCallingIdentity(token);
   1611             }
   1612         }
   1613         return resolveOwningUserIdLocked(userId, sSystemCloneToManagedSettings, setting);
   1614     }
   1615 
   1616     private int resolveOwningUserIdLocked(int userId, Set<String> keys, String name) {
   1617         final int parentId = getGroupParentLocked(userId);
   1618         if (parentId != userId && keys.contains(name)) {
   1619             return parentId;
   1620         }
   1621         return userId;
   1622     }
   1623 
   1624     private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation,
   1625             String name, int userId) {
   1626         // System/root/shell can mutate whatever secure settings they want.
   1627         final int callingUid = Binder.getCallingUid();
   1628         final int appId = UserHandle.getAppId(callingUid);
   1629         if (appId == android.os.Process.SYSTEM_UID
   1630                 || appId == Process.SHELL_UID
   1631                 || appId == Process.ROOT_UID) {
   1632             return;
   1633         }
   1634 
   1635         switch (operation) {
   1636             case MUTATION_OPERATION_INSERT:
   1637                 // Insert updates.
   1638             case MUTATION_OPERATION_UPDATE: {
   1639                 if (Settings.System.PUBLIC_SETTINGS.contains(name)) {
   1640                     return;
   1641                 }
   1642 
   1643                 // The calling package is already verified.
   1644                 PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
   1645 
   1646                 // Privileged apps can do whatever they want.
   1647                 if ((packageInfo.applicationInfo.privateFlags
   1648                         & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
   1649                     return;
   1650                 }
   1651 
   1652                 warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
   1653                         packageInfo.applicationInfo.targetSdkVersion, name);
   1654             } break;
   1655 
   1656             case MUTATION_OPERATION_DELETE: {
   1657                 if (Settings.System.PUBLIC_SETTINGS.contains(name)
   1658                         || Settings.System.PRIVATE_SETTINGS.contains(name)) {
   1659                     throw new IllegalArgumentException("You cannot delete system defined"
   1660                             + " secure settings.");
   1661                 }
   1662 
   1663                 // The calling package is already verified.
   1664                 PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
   1665 
   1666                 // Privileged apps can do whatever they want.
   1667                 if ((packageInfo.applicationInfo.privateFlags &
   1668                         ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
   1669                     return;
   1670                 }
   1671 
   1672                 warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
   1673                         packageInfo.applicationInfo.targetSdkVersion, name);
   1674             } break;
   1675         }
   1676     }
   1677 
   1678     private Set<String> getInstantAppAccessibleSettings(int settingsType) {
   1679         switch (settingsType) {
   1680             case SETTINGS_TYPE_GLOBAL:
   1681                 return Settings.Global.INSTANT_APP_SETTINGS;
   1682             case SETTINGS_TYPE_SECURE:
   1683                 return Settings.Secure.INSTANT_APP_SETTINGS;
   1684             case SETTINGS_TYPE_SYSTEM:
   1685                 return Settings.System.INSTANT_APP_SETTINGS;
   1686             default:
   1687                 throw new IllegalArgumentException("Invalid settings type: " + settingsType);
   1688         }
   1689     }
   1690 
   1691     private Set<String> getOverlayInstantAppAccessibleSettings(int settingsType) {
   1692         switch (settingsType) {
   1693             case SETTINGS_TYPE_GLOBAL:
   1694                 return OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS;
   1695             case SETTINGS_TYPE_SYSTEM:
   1696                 return OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS;
   1697             case SETTINGS_TYPE_SECURE:
   1698                 return OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS;
   1699             default:
   1700                 throw new IllegalArgumentException("Invalid settings type: " + settingsType);
   1701         }
   1702     }
   1703 
   1704     private List<String> getSettingsNamesLocked(int settingsType, int userId) {
   1705         // Don't enforce the instant app whitelist for now -- its too prone to unintended breakage
   1706         // in the current form.
   1707         return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId);
   1708     }
   1709 
   1710     private void enforceSettingReadable(String settingName, int settingsType, int userId) {
   1711         if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
   1712             return;
   1713         }
   1714         ApplicationInfo ai = getCallingApplicationInfoOrThrow();
   1715         if (!ai.isInstantApp()) {
   1716             return;
   1717         }
   1718         if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)
   1719                 && !getOverlayInstantAppAccessibleSettings(settingsType).contains(settingName)) {
   1720             // Don't enforce the instant app whitelist for now -- its too prone to unintended
   1721             // breakage in the current form.
   1722             Slog.w(LOG_TAG, "Instant App " + ai.packageName
   1723                     + " trying to access unexposed setting, this will be an error in the future.");
   1724         }
   1725     }
   1726 
   1727     private ApplicationInfo getCallingApplicationInfoOrThrow() {
   1728         // We always use the callingUid for this lookup. This means that if hypothetically an
   1729         // app was installed in user A with cross user and in user B as an Instant App
   1730         // the app in A would be able to see all the settings in user B. However since cross
   1731         // user is a system permission and the app must be uninstalled in B and then installed as
   1732         // an Instant App that situation is not realistic or supported.
   1733         ApplicationInfo ai = null;
   1734         try {
   1735             ai = mPackageManager.getApplicationInfo(getCallingPackage(), 0
   1736                     , UserHandle.getCallingUserId());
   1737         } catch (RemoteException ignored) {
   1738         }
   1739         if (ai == null) {
   1740             throw new IllegalStateException("Failed to lookup info for package "
   1741                     + getCallingPackage());
   1742         }
   1743         return ai;
   1744     }
   1745 
   1746     private PackageInfo getCallingPackageInfoOrThrow(int userId) {
   1747         try {
   1748             PackageInfo packageInfo = mPackageManager.getPackageInfo(
   1749                     getCallingPackage(), 0, userId);
   1750             if (packageInfo != null) {
   1751                 return packageInfo;
   1752             }
   1753         } catch (RemoteException e) {
   1754             /* ignore */
   1755         }
   1756         throw new IllegalStateException("Calling package doesn't exist");
   1757     }
   1758 
   1759     private int getGroupParentLocked(int userId) {
   1760         // Most frequent use case.
   1761         if (userId == UserHandle.USER_SYSTEM) {
   1762             return userId;
   1763         }
   1764         // We are in the same process with the user manager and the returned
   1765         // user info is a cached instance, so just look up instead of cache.
   1766         final long identity = Binder.clearCallingIdentity();
   1767         try {
   1768             // Just a lookup and not reentrant, so holding a lock is fine.
   1769             UserInfo userInfo = mUserManager.getProfileParent(userId);
   1770             return (userInfo != null) ? userInfo.id : userId;
   1771         } finally {
   1772             Binder.restoreCallingIdentity(identity);
   1773         }
   1774     }
   1775 
   1776     private void enforceWritePermission(String permission) {
   1777         if (getContext().checkCallingOrSelfPermission(permission)
   1778                 != PackageManager.PERMISSION_GRANTED) {
   1779             throw new SecurityException("Permission denial: writing to settings requires:"
   1780                     + permission);
   1781         }
   1782     }
   1783 
   1784     /*
   1785      * Used to parse changes to the value of Settings.Secure.LOCATION_PROVIDERS_ALLOWED.
   1786      * This setting contains a list of the currently enabled location providers.
   1787      * But helper functions in android.providers.Settings can enable or disable
   1788      * a single provider by using a "+" or "-" prefix before the provider name.
   1789      *
   1790      * <p>See also {@link com.android.server.pm.UserRestrictionsUtils#isSettingRestrictedForUser()}.
   1791      * If DISALLOW_SHARE_LOCATION is set, the said method will only allow values with
   1792      * the "-" prefix.
   1793      *
   1794      * @returns whether the enabled location providers changed.
   1795      */
   1796     private boolean updateLocationProvidersAllowedLocked(String value, String tag,
   1797             int owningUserId, boolean makeDefault, boolean forceNotify) {
   1798         if (TextUtils.isEmpty(value)) {
   1799             return false;
   1800         }
   1801         Setting oldSetting = getSecureSetting(
   1802                 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId);
   1803         if (oldSetting == null) {
   1804             return false;
   1805         }
   1806         String oldProviders = oldSetting.getValue();
   1807         List<String> oldProvidersList = TextUtils.isEmpty(oldProviders)
   1808                 ? new ArrayList<>() : new ArrayList<>(Arrays.asList(oldProviders.split(",")));
   1809         Set<String> newProvidersSet = new ArraySet<>();
   1810         newProvidersSet.addAll(oldProvidersList);
   1811 
   1812         String[] providerUpdates = value.split(",");
   1813         boolean inputError = false;
   1814         for (String provider : providerUpdates) {
   1815             // do not update location_providers_allowed when input is invalid
   1816             if (TextUtils.isEmpty(provider)) {
   1817                 inputError = true;
   1818                 break;
   1819             }
   1820             final char prefix = provider.charAt(0);
   1821             // do not update location_providers_allowed when input is invalid
   1822             if (prefix != '+' && prefix != '-') {
   1823                 inputError = true;
   1824                 break;
   1825             }
   1826             // skip prefix
   1827             provider = provider.substring(1);
   1828             if (prefix == '+') {
   1829                 newProvidersSet.add(provider);
   1830             } else if (prefix == '-') {
   1831                 newProvidersSet.remove(provider);
   1832             }
   1833         }
   1834         String newProviders = TextUtils.join(",", newProvidersSet.toArray());
   1835         if (inputError == true || newProviders.equals(oldProviders)) {
   1836             // nothing changed, so no need to update the database
   1837             if (forceNotify) {
   1838                 mSettingsRegistry.notifyForSettingsChange(
   1839                         makeKey(SETTINGS_TYPE_SECURE, owningUserId),
   1840                         Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
   1841             }
   1842             return false;
   1843         }
   1844         return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
   1845                 owningUserId, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, newProviders, tag,
   1846                 makeDefault, getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
   1847     }
   1848 
   1849     private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
   1850             int targetSdkVersion, String name) {
   1851         // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash.
   1852         if (targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
   1853             if (Settings.System.PRIVATE_SETTINGS.contains(name)) {
   1854                 Slog.w(LOG_TAG, "You shouldn't not change private system settings."
   1855                         + " This will soon become an error.");
   1856             } else {
   1857                 Slog.w(LOG_TAG, "You shouldn't keep your settings in the secure settings."
   1858                         + " This will soon become an error.");
   1859             }
   1860         } else {
   1861             if (Settings.System.PRIVATE_SETTINGS.contains(name)) {
   1862                 throw new IllegalArgumentException("You cannot change private secure settings.");
   1863             } else {
   1864                 throw new IllegalArgumentException("You cannot keep your settings in"
   1865                         + " the secure settings.");
   1866             }
   1867         }
   1868     }
   1869 
   1870     private static int resolveCallingUserIdEnforcingPermissionsLocked(int requestingUserId) {
   1871         if (requestingUserId == UserHandle.getCallingUserId()) {
   1872             return requestingUserId;
   1873         }
   1874         return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
   1875                 Binder.getCallingUid(), requestingUserId, false, true,
   1876                 "get/set setting for user", null);
   1877     }
   1878 
   1879     private Bundle packageValueForCallResult(Setting setting,
   1880             boolean trackingGeneration) {
   1881         if (!trackingGeneration) {
   1882             if (setting == null || setting.isNull()) {
   1883                 return NULL_SETTING_BUNDLE;
   1884             }
   1885             return Bundle.forPair(Settings.NameValueTable.VALUE, setting.getValue());
   1886         }
   1887         Bundle result = new Bundle();
   1888         result.putString(Settings.NameValueTable.VALUE,
   1889                 !setting.isNull() ? setting.getValue() : null);
   1890 
   1891         mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getKey());
   1892         return result;
   1893     }
   1894 
   1895     private static int getRequestingUserId(Bundle args) {
   1896         final int callingUserId = UserHandle.getCallingUserId();
   1897         return (args != null) ? args.getInt(Settings.CALL_METHOD_USER_KEY, callingUserId)
   1898                 : callingUserId;
   1899     }
   1900 
   1901     private boolean isTrackingGeneration(Bundle args) {
   1902         return args != null && args.containsKey(Settings.CALL_METHOD_TRACK_GENERATION_KEY);
   1903     }
   1904 
   1905     private static String getSettingValue(Bundle args) {
   1906         return (args != null) ? args.getString(Settings.NameValueTable.VALUE) : null;
   1907     }
   1908 
   1909     private static String getSettingTag(Bundle args) {
   1910         return (args != null) ? args.getString(Settings.CALL_METHOD_TAG_KEY) : null;
   1911     }
   1912 
   1913     private static boolean getSettingMakeDefault(Bundle args) {
   1914         return (args != null) && args.getBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY);
   1915     }
   1916 
   1917     private static int getResetModeEnforcingPermission(Bundle args) {
   1918         final int mode = (args != null) ? args.getInt(Settings.CALL_METHOD_RESET_MODE_KEY) : 0;
   1919         switch (mode) {
   1920             case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
   1921                 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
   1922                     throw new SecurityException("Only system, shell/root on a "
   1923                             + "debuggable build can reset to untrusted defaults");
   1924                 }
   1925                 return mode;
   1926             }
   1927             case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
   1928                 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
   1929                     throw new SecurityException("Only system, shell/root on a "
   1930                             + "debuggable build can reset untrusted changes");
   1931                 }
   1932                 return mode;
   1933             }
   1934             case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
   1935                 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
   1936                     throw new SecurityException("Only system, shell/root on a "
   1937                             + "debuggable build can reset to trusted defaults");
   1938                 }
   1939                 return mode;
   1940             }
   1941             case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
   1942                 return mode;
   1943             }
   1944         }
   1945         throw new IllegalArgumentException("Invalid reset mode: " + mode);
   1946     }
   1947 
   1948     private static boolean isCallerSystemOrShellOrRootOnDebuggableBuild() {
   1949         final int appId = UserHandle.getAppId(Binder.getCallingUid());
   1950         return appId == SYSTEM_UID || (Build.IS_DEBUGGABLE
   1951                 && (appId == SHELL_UID || appId == ROOT_UID));
   1952     }
   1953 
   1954     private static String getValidTableOrThrow(Uri uri) {
   1955         if (uri.getPathSegments().size() > 0) {
   1956             String table = uri.getPathSegments().get(0);
   1957             if (DatabaseHelper.isValidTable(table)) {
   1958                 return table;
   1959             }
   1960             throw new IllegalArgumentException("Bad root path: " + table);
   1961         }
   1962         throw new IllegalArgumentException("Invalid URI:" + uri);
   1963     }
   1964 
   1965     private static MatrixCursor packageSettingForQuery(Setting setting, String[] projection) {
   1966         if (setting.isNull()) {
   1967             return new MatrixCursor(projection, 0);
   1968         }
   1969         MatrixCursor cursor = new MatrixCursor(projection, 1);
   1970         appendSettingToCursor(cursor, setting);
   1971         return cursor;
   1972     }
   1973 
   1974     private static String[] normalizeProjection(String[] projection) {
   1975         if (projection == null) {
   1976             return ALL_COLUMNS;
   1977         }
   1978 
   1979         final int columnCount = projection.length;
   1980         for (int i = 0; i < columnCount; i++) {
   1981             String column = projection[i];
   1982             if (!ArrayUtils.contains(ALL_COLUMNS, column)) {
   1983                 throw new IllegalArgumentException("Invalid column: " + column);
   1984             }
   1985         }
   1986 
   1987         return projection;
   1988     }
   1989 
   1990     private static void appendSettingToCursor(MatrixCursor cursor, Setting setting) {
   1991         if (setting == null || setting.isNull()) {
   1992             return;
   1993         }
   1994         final int columnCount = cursor.getColumnCount();
   1995 
   1996         String[] values =  new String[columnCount];
   1997 
   1998         for (int i = 0; i < columnCount; i++) {
   1999             String column = cursor.getColumnName(i);
   2000 
   2001             switch (column) {
   2002                 case Settings.NameValueTable._ID: {
   2003                     values[i] = setting.getId();
   2004                 } break;
   2005 
   2006                 case Settings.NameValueTable.NAME: {
   2007                     values[i] = setting.getName();
   2008                 } break;
   2009 
   2010                 case Settings.NameValueTable.VALUE: {
   2011                     values[i] = setting.getValue();
   2012                 } break;
   2013             }
   2014         }
   2015 
   2016         cursor.addRow(values);
   2017     }
   2018 
   2019     private static boolean isKeyValid(String key) {
   2020         return !(TextUtils.isEmpty(key) || SettingsState.isBinary(key));
   2021     }
   2022 
   2023     private static final class Arguments {
   2024         private static final Pattern WHERE_PATTERN_WITH_PARAM_NO_BRACKETS =
   2025                 Pattern.compile("[\\s]*name[\\s]*=[\\s]*\\?[\\s]*");
   2026 
   2027         private static final Pattern WHERE_PATTERN_WITH_PARAM_IN_BRACKETS =
   2028                 Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*\\?[\\s]*\\)[\\s]*");
   2029 
   2030         private static final Pattern WHERE_PATTERN_NO_PARAM_IN_BRACKETS =
   2031                 Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*\\)[\\s]*");
   2032 
   2033         private static final Pattern WHERE_PATTERN_NO_PARAM_NO_BRACKETS =
   2034                 Pattern.compile("[\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*");
   2035 
   2036         public final String table;
   2037         public final String name;
   2038 
   2039         public Arguments(Uri uri, String where, String[] whereArgs, boolean supportAll) {
   2040             final int segmentSize = uri.getPathSegments().size();
   2041             switch (segmentSize) {
   2042                 case 1: {
   2043                     if (where != null
   2044                             && (WHERE_PATTERN_WITH_PARAM_NO_BRACKETS.matcher(where).matches()
   2045                                 || WHERE_PATTERN_WITH_PARAM_IN_BRACKETS.matcher(where).matches())
   2046                             && whereArgs.length == 1) {
   2047                         name = whereArgs[0];
   2048                         table = computeTableForSetting(uri, name);
   2049                         return;
   2050                     } else if (where != null
   2051                             && (WHERE_PATTERN_NO_PARAM_NO_BRACKETS.matcher(where).matches()
   2052                                 || WHERE_PATTERN_NO_PARAM_IN_BRACKETS.matcher(where).matches())) {
   2053                         final int startIndex = Math.max(where.indexOf("'"),
   2054                                 where.indexOf("\"")) + 1;
   2055                         final int endIndex = Math.max(where.lastIndexOf("'"),
   2056                                 where.lastIndexOf("\""));
   2057                         name = where.substring(startIndex, endIndex);
   2058                         table = computeTableForSetting(uri, name);
   2059                         return;
   2060                     } else if (supportAll && where == null && whereArgs == null) {
   2061                         name = null;
   2062                         table = computeTableForSetting(uri, null);
   2063                         return;
   2064                     }
   2065                 } break;
   2066 
   2067                 case 2: {
   2068                     if (where == null && whereArgs == null) {
   2069                         name = uri.getPathSegments().get(1);
   2070                         table = computeTableForSetting(uri, name);
   2071                         return;
   2072                     }
   2073                 } break;
   2074             }
   2075 
   2076             EventLogTags.writeUnsupportedSettingsQuery(
   2077                     uri.toSafeString(), where, Arrays.toString(whereArgs));
   2078             String message = String.format( "Supported SQL:\n"
   2079                     + "  uri content://some_table/some_property with null where and where args\n"
   2080                     + "  uri content://some_table with query name=? and single name as arg\n"
   2081                     + "  uri content://some_table with query name=some_name and null args\n"
   2082                     + "  but got - uri:%1s, where:%2s whereArgs:%3s", uri, where,
   2083                     Arrays.toString(whereArgs));
   2084             throw new IllegalArgumentException(message);
   2085         }
   2086 
   2087         private static String computeTableForSetting(Uri uri, String name) {
   2088             String table = getValidTableOrThrow(uri);
   2089 
   2090             if (name != null) {
   2091                 if (sSystemMovedToSecureSettings.contains(name)) {
   2092                     table = TABLE_SECURE;
   2093                 }
   2094 
   2095                 if (sSystemMovedToGlobalSettings.contains(name)) {
   2096                     table = TABLE_GLOBAL;
   2097                 }
   2098 
   2099                 if (sSecureMovedToGlobalSettings.contains(name)) {
   2100                     table = TABLE_GLOBAL;
   2101                 }
   2102 
   2103                 if (sGlobalMovedToSecureSettings.contains(name)) {
   2104                     table = TABLE_SECURE;
   2105                 }
   2106             }
   2107 
   2108             return table;
   2109         }
   2110     }
   2111 
   2112     final class SettingsRegistry {
   2113         private static final String DROPBOX_TAG_USERLOG = "restricted_profile_ssaid";
   2114 
   2115         private static final String SETTINGS_FILE_GLOBAL = "settings_global.xml";
   2116         private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml";
   2117         private static final String SETTINGS_FILE_SECURE = "settings_secure.xml";
   2118         private static final String SETTINGS_FILE_SSAID = "settings_ssaid.xml";
   2119 
   2120         private static final String SSAID_USER_KEY = "userkey";
   2121 
   2122         private final SparseArray<SettingsState> mSettingsStates = new SparseArray<>();
   2123 
   2124         private GenerationRegistry mGenerationRegistry;
   2125 
   2126         private final Handler mHandler;
   2127 
   2128         private final BackupManager mBackupManager;
   2129 
   2130         private String mSettingsCreationBuildId;
   2131 
   2132         public SettingsRegistry() {
   2133             mHandler = new MyHandler(getContext().getMainLooper());
   2134             mGenerationRegistry = new GenerationRegistry(mLock);
   2135             mBackupManager = new BackupManager(getContext());
   2136             migrateAllLegacySettingsIfNeeded();
   2137             syncSsaidTableOnStart();
   2138         }
   2139 
   2140         private void generateUserKeyLocked(int userId) {
   2141             // Generate a random key for each user used for creating a new ssaid.
   2142             final byte[] keyBytes = new byte[32];
   2143             final SecureRandom rand = new SecureRandom();
   2144             rand.nextBytes(keyBytes);
   2145 
   2146             // Convert to string for storage in settings table.
   2147             final String userKey = ByteStringUtils.toHexString(keyBytes);
   2148 
   2149             // Store the key in the ssaid table.
   2150             final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
   2151             final boolean success = ssaidSettings.insertSettingLocked(SSAID_USER_KEY, userKey, null,
   2152                     true, SettingsState.SYSTEM_PACKAGE_NAME);
   2153 
   2154             if (!success) {
   2155                 throw new IllegalStateException("Ssaid settings not accessible");
   2156             }
   2157         }
   2158 
   2159         private byte[] getLengthPrefix(byte[] data) {
   2160             return ByteBuffer.allocate(4).putInt(data.length).array();
   2161         }
   2162 
   2163         public Setting generateSsaidLocked(PackageInfo callingPkg, int userId) {
   2164             // Read the user's key from the ssaid table.
   2165             Setting userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
   2166             if (userKeySetting == null || userKeySetting.isNull()
   2167                     || userKeySetting.getValue() == null) {
   2168                 // Lazy initialize and store the user key.
   2169                 generateUserKeyLocked(userId);
   2170                 userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
   2171                 if (userKeySetting == null || userKeySetting.isNull()
   2172                         || userKeySetting.getValue() == null) {
   2173                     throw new IllegalStateException("User key not accessible");
   2174                 }
   2175             }
   2176             final String userKey = userKeySetting.getValue();
   2177 
   2178             // Convert the user's key back to a byte array.
   2179             final byte[] keyBytes = ByteStringUtils.fromHexToByteArray(userKey);
   2180 
   2181             // Validate that the key is of expected length.
   2182             // Keys are currently 32 bytes, but were once 16 bytes during Android O development.
   2183             if (keyBytes == null || (keyBytes.length != 16 && keyBytes.length != 32)) {
   2184                 throw new IllegalStateException("User key invalid");
   2185             }
   2186 
   2187             final Mac m;
   2188             try {
   2189                 m = Mac.getInstance("HmacSHA256");
   2190                 m.init(new SecretKeySpec(keyBytes, m.getAlgorithm()));
   2191             } catch (NoSuchAlgorithmException e) {
   2192                 throw new IllegalStateException("HmacSHA256 is not available", e);
   2193             } catch (InvalidKeyException e) {
   2194                 throw new IllegalStateException("Key is corrupted", e);
   2195             }
   2196 
   2197             // Mac each of the developer signatures.
   2198             for (int i = 0; i < callingPkg.signatures.length; i++) {
   2199                 byte[] sig = callingPkg.signatures[i].toByteArray();
   2200                 m.update(getLengthPrefix(sig), 0, 4);
   2201                 m.update(sig);
   2202             }
   2203 
   2204             // Convert result to a string for storage in settings table. Only want first 64 bits.
   2205             final String ssaid = ByteStringUtils.toHexString(m.doFinal()).substring(0, 16)
   2206                     .toLowerCase(Locale.US);
   2207 
   2208             // Save the ssaid in the ssaid table.
   2209             final String uid = Integer.toString(callingPkg.applicationInfo.uid);
   2210             final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
   2211             final boolean success = ssaidSettings.insertSettingLocked(uid, ssaid, null, true,
   2212                 callingPkg.packageName);
   2213 
   2214             if (!success) {
   2215                 throw new IllegalStateException("Ssaid settings not accessible");
   2216             }
   2217 
   2218             return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
   2219         }
   2220 
   2221         public void syncSsaidTableOnStart() {
   2222             synchronized (mLock) {
   2223                 // Verify that each user's packages and ssaid's are in sync.
   2224                 for (UserInfo user : mUserManager.getUsers(true)) {
   2225                     // Get all uids for the user's packages.
   2226                     final List<PackageInfo> packages;
   2227                     try {
   2228                         packages = mPackageManager.getInstalledPackages(
   2229                             PackageManager.MATCH_UNINSTALLED_PACKAGES,
   2230                             user.id).getList();
   2231                     } catch (RemoteException e) {
   2232                         throw new IllegalStateException("Package manager not available");
   2233                     }
   2234                     final Set<String> appUids = new HashSet<>();
   2235                     for (PackageInfo info : packages) {
   2236                         appUids.add(Integer.toString(info.applicationInfo.uid));
   2237                     }
   2238 
   2239                     // Get all uids currently stored in the user's ssaid table.
   2240                     final Set<String> ssaidUids = new HashSet<>(
   2241                             getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
   2242                     ssaidUids.remove(SSAID_USER_KEY);
   2243 
   2244                     // Perform a set difference for the appUids and ssaidUids.
   2245                     ssaidUids.removeAll(appUids);
   2246 
   2247                     // If there are ssaidUids left over they need to be removed from the table.
   2248                     final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
   2249                             user.id);
   2250                     for (String uid : ssaidUids) {
   2251                         ssaidSettings.deleteSettingLocked(uid);
   2252                     }
   2253                 }
   2254             }
   2255         }
   2256 
   2257         public List<String> getSettingsNamesLocked(int type, int userId) {
   2258             final int key = makeKey(type, userId);
   2259             SettingsState settingsState = peekSettingsStateLocked(key);
   2260             if (settingsState == null) {
   2261                 return new ArrayList<String>();
   2262             }
   2263             return settingsState.getSettingNamesLocked();
   2264         }
   2265 
   2266         public SparseBooleanArray getKnownUsersLocked() {
   2267             SparseBooleanArray users = new SparseBooleanArray();
   2268             for (int i = mSettingsStates.size()-1; i >= 0; i--) {
   2269                 users.put(getUserIdFromKey(mSettingsStates.keyAt(i)), true);
   2270             }
   2271             return users;
   2272         }
   2273 
   2274         @Nullable
   2275         public SettingsState getSettingsLocked(int type, int userId) {
   2276             final int key = makeKey(type, userId);
   2277             return peekSettingsStateLocked(key);
   2278         }
   2279 
   2280         public boolean ensureSettingsForUserLocked(int userId) {
   2281             // First make sure this user actually exists.
   2282             if (mUserManager.getUserInfo(userId) == null) {
   2283                 Slog.wtf(LOG_TAG, "Requested user " + userId + " does not exist");
   2284                 return false;
   2285             }
   2286 
   2287             // Migrate the setting for this user if needed.
   2288             migrateLegacySettingsForUserIfNeededLocked(userId);
   2289 
   2290             // Ensure global settings loaded if owner.
   2291             if (userId == UserHandle.USER_SYSTEM) {
   2292                 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
   2293                 ensureSettingsStateLocked(globalKey);
   2294             }
   2295 
   2296             // Ensure secure settings loaded.
   2297             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
   2298             ensureSettingsStateLocked(secureKey);
   2299 
   2300             // Make sure the secure settings have an Android id set.
   2301             SettingsState secureSettings = getSettingsLocked(SETTINGS_TYPE_SECURE, userId);
   2302             ensureSecureSettingAndroidIdSetLocked(secureSettings);
   2303 
   2304             // Ensure system settings loaded.
   2305             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
   2306             ensureSettingsStateLocked(systemKey);
   2307 
   2308             // Ensure secure settings loaded.
   2309             final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
   2310             ensureSettingsStateLocked(ssaidKey);
   2311 
   2312             // Upgrade the settings to the latest version.
   2313             UpgradeController upgrader = new UpgradeController(userId);
   2314             upgrader.upgradeIfNeededLocked();
   2315             return true;
   2316         }
   2317 
   2318         private void ensureSettingsStateLocked(int key) {
   2319             if (mSettingsStates.get(key) == null) {
   2320                 final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key));
   2321                 SettingsState settingsState = new SettingsState(getContext(), mLock,
   2322                         getSettingsFile(key), key, maxBytesPerPackage, mHandlerThread.getLooper());
   2323                 mSettingsStates.put(key, settingsState);
   2324             }
   2325         }
   2326 
   2327         public void removeUserStateLocked(int userId, boolean permanently) {
   2328             // We always keep the global settings in memory.
   2329 
   2330             // Nuke system settings.
   2331             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
   2332             final SettingsState systemSettingsState = mSettingsStates.get(systemKey);
   2333             if (systemSettingsState != null) {
   2334                 if (permanently) {
   2335                     mSettingsStates.remove(systemKey);
   2336                     systemSettingsState.destroyLocked(null);
   2337                 } else {
   2338                     systemSettingsState.destroyLocked(new Runnable() {
   2339                         @Override
   2340                         public void run() {
   2341                             mSettingsStates.remove(systemKey);
   2342                         }
   2343                     });
   2344                 }
   2345             }
   2346 
   2347             // Nuke secure settings.
   2348             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
   2349             final SettingsState secureSettingsState = mSettingsStates.get(secureKey);
   2350             if (secureSettingsState != null) {
   2351                 if (permanently) {
   2352                     mSettingsStates.remove(secureKey);
   2353                     secureSettingsState.destroyLocked(null);
   2354                 } else {
   2355                     secureSettingsState.destroyLocked(new Runnable() {
   2356                         @Override
   2357                         public void run() {
   2358                             mSettingsStates.remove(secureKey);
   2359                         }
   2360                     });
   2361                 }
   2362             }
   2363 
   2364             // Nuke ssaid settings.
   2365             final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
   2366             final SettingsState ssaidSettingsState = mSettingsStates.get(ssaidKey);
   2367             if (ssaidSettingsState != null) {
   2368                 if (permanently) {
   2369                     mSettingsStates.remove(ssaidKey);
   2370                     ssaidSettingsState.destroyLocked(null);
   2371                 } else {
   2372                     ssaidSettingsState.destroyLocked(new Runnable() {
   2373                         @Override
   2374                         public void run() {
   2375                             mSettingsStates.remove(ssaidKey);
   2376                         }
   2377                     });
   2378                 }
   2379             }
   2380 
   2381             // Nuke generation tracking data
   2382             mGenerationRegistry.onUserRemoved(userId);
   2383         }
   2384 
   2385         public boolean insertSettingLocked(int type, int userId, String name, String value,
   2386                 String tag, boolean makeDefault, String packageName, boolean forceNotify,
   2387                 Set<String> criticalSettings) {
   2388             final int key = makeKey(type, userId);
   2389 
   2390             boolean success = false;
   2391             SettingsState settingsState = peekSettingsStateLocked(key);
   2392             if (settingsState != null) {
   2393                 success = settingsState.insertSettingLocked(name, value,
   2394                         tag, makeDefault, packageName);
   2395             }
   2396 
   2397             if (success && criticalSettings != null && criticalSettings.contains(name)) {
   2398                 settingsState.persistSyncLocked();
   2399             }
   2400 
   2401             if (forceNotify || success) {
   2402                 notifyForSettingsChange(key, name);
   2403             }
   2404             return success;
   2405         }
   2406 
   2407         public boolean deleteSettingLocked(int type, int userId, String name, boolean forceNotify,
   2408                 Set<String> criticalSettings) {
   2409             final int key = makeKey(type, userId);
   2410 
   2411             boolean success = false;
   2412             SettingsState settingsState = peekSettingsStateLocked(key);
   2413             if (settingsState != null) {
   2414                 success = settingsState.deleteSettingLocked(name);
   2415             }
   2416 
   2417             if (success && criticalSettings != null && criticalSettings.contains(name)) {
   2418                 settingsState.persistSyncLocked();
   2419             }
   2420 
   2421             if (forceNotify || success) {
   2422                 notifyForSettingsChange(key, name);
   2423             }
   2424             return success;
   2425         }
   2426 
   2427         public boolean updateSettingLocked(int type, int userId, String name, String value,
   2428                 String tag, boolean makeDefault, String packageName, boolean forceNotify,
   2429                 Set<String> criticalSettings) {
   2430             final int key = makeKey(type, userId);
   2431 
   2432             boolean success = false;
   2433             SettingsState settingsState = peekSettingsStateLocked(key);
   2434             if (settingsState != null) {
   2435                 success = settingsState.updateSettingLocked(name, value, tag,
   2436                         makeDefault, packageName);
   2437             }
   2438 
   2439             if (success && criticalSettings != null && criticalSettings.contains(name)) {
   2440                 settingsState.persistSyncLocked();
   2441             }
   2442 
   2443             if (forceNotify || success) {
   2444                 notifyForSettingsChange(key, name);
   2445             }
   2446 
   2447             return success;
   2448         }
   2449 
   2450         public Setting getSettingLocked(int type, int userId, String name) {
   2451             final int key = makeKey(type, userId);
   2452 
   2453             SettingsState settingsState = peekSettingsStateLocked(key);
   2454             if (settingsState == null) {
   2455                 return null;
   2456             }
   2457 
   2458             // getSettingLocked will return non-null result
   2459             return settingsState.getSettingLocked(name);
   2460         }
   2461 
   2462         public void resetSettingsLocked(int type, int userId, String packageName, int mode,
   2463                 String tag) {
   2464             final int key = makeKey(type, userId);
   2465             SettingsState settingsState = peekSettingsStateLocked(key);
   2466             if (settingsState == null) {
   2467                 return;
   2468             }
   2469 
   2470             switch (mode) {
   2471                 case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
   2472                     for (String name : settingsState.getSettingNamesLocked()) {
   2473                         boolean someSettingChanged = false;
   2474                         Setting setting = settingsState.getSettingLocked(name);
   2475                         if (packageName.equals(setting.getPackageName())) {
   2476                             if (tag != null && !tag.equals(setting.getTag())) {
   2477                                 continue;
   2478                             }
   2479                             if (settingsState.resetSettingLocked(name)) {
   2480                                 someSettingChanged = true;
   2481                                 notifyForSettingsChange(key, name);
   2482                             }
   2483                         }
   2484                         if (someSettingChanged) {
   2485                             settingsState.persistSyncLocked();
   2486                         }
   2487                     }
   2488                 } break;
   2489 
   2490                 case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
   2491                     for (String name : settingsState.getSettingNamesLocked()) {
   2492                         boolean someSettingChanged = false;
   2493                         Setting setting = settingsState.getSettingLocked(name);
   2494                         if (!SettingsState.isSystemPackage(getContext(),
   2495                                 setting.getPackageName())) {
   2496                             if (settingsState.resetSettingLocked(name)) {
   2497                                 someSettingChanged = true;
   2498                                 notifyForSettingsChange(key, name);
   2499                             }
   2500                         }
   2501                         if (someSettingChanged) {
   2502                             settingsState.persistSyncLocked();
   2503                         }
   2504                     }
   2505                 } break;
   2506 
   2507                 case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
   2508                     for (String name : settingsState.getSettingNamesLocked()) {
   2509                         boolean someSettingChanged = false;
   2510                         Setting setting = settingsState.getSettingLocked(name);
   2511                         if (!SettingsState.isSystemPackage(getContext(),
   2512                                 setting.getPackageName())) {
   2513                             if (setting.isDefaultFromSystem()) {
   2514                                 if (settingsState.resetSettingLocked(name)) {
   2515                                     someSettingChanged = true;
   2516                                     notifyForSettingsChange(key, name);
   2517                                 }
   2518                             } else if (settingsState.deleteSettingLocked(name)) {
   2519                                 someSettingChanged = true;
   2520                                 notifyForSettingsChange(key, name);
   2521                             }
   2522                         }
   2523                         if (someSettingChanged) {
   2524                             settingsState.persistSyncLocked();
   2525                         }
   2526                     }
   2527                 } break;
   2528 
   2529                 case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
   2530                     for (String name : settingsState.getSettingNamesLocked()) {
   2531                         Setting setting = settingsState.getSettingLocked(name);
   2532                         boolean someSettingChanged = false;
   2533                         if (setting.isDefaultFromSystem()) {
   2534                             if (settingsState.resetSettingLocked(name)) {
   2535                                 someSettingChanged = true;
   2536                                 notifyForSettingsChange(key, name);
   2537                             }
   2538                         } else if (settingsState.deleteSettingLocked(name)) {
   2539                             someSettingChanged = true;
   2540                             notifyForSettingsChange(key, name);
   2541                         }
   2542                         if (someSettingChanged) {
   2543                             settingsState.persistSyncLocked();
   2544                         }
   2545                     }
   2546                 } break;
   2547             }
   2548         }
   2549 
   2550         public void onPackageRemovedLocked(String packageName, int userId) {
   2551             // Global and secure settings are signature protected. Apps signed
   2552             // by the platform certificate are generally not uninstalled  and
   2553             // the main exception is tests. We trust components signed
   2554             // by the platform certificate and do not do a clean up after them.
   2555 
   2556             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
   2557             SettingsState systemSettings = mSettingsStates.get(systemKey);
   2558             if (systemSettings != null) {
   2559                 systemSettings.onPackageRemovedLocked(packageName);
   2560             }
   2561         }
   2562 
   2563         public void onUidRemovedLocked(int uid) {
   2564             final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
   2565                     UserHandle.getUserId(uid));
   2566             if (ssaidSettings != null) {
   2567                 ssaidSettings.deleteSettingLocked(Integer.toString(uid));
   2568             }
   2569         }
   2570 
   2571         @Nullable
   2572         private SettingsState peekSettingsStateLocked(int key) {
   2573             SettingsState settingsState = mSettingsStates.get(key);
   2574             if (settingsState != null) {
   2575                 return settingsState;
   2576             }
   2577 
   2578             if (!ensureSettingsForUserLocked(getUserIdFromKey(key))) {
   2579                 return null;
   2580             }
   2581             return mSettingsStates.get(key);
   2582         }
   2583 
   2584         private void migrateAllLegacySettingsIfNeeded() {
   2585             synchronized (mLock) {
   2586                 final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
   2587                 File globalFile = getSettingsFile(key);
   2588                 if (SettingsState.stateFileExists(globalFile)) {
   2589                     return;
   2590                 }
   2591 
   2592                 mSettingsCreationBuildId = Build.ID;
   2593 
   2594                 final long identity = Binder.clearCallingIdentity();
   2595                 try {
   2596                     List<UserInfo> users = mUserManager.getUsers(true);
   2597 
   2598                     final int userCount = users.size();
   2599                     for (int i = 0; i < userCount; i++) {
   2600                         final int userId = users.get(i).id;
   2601 
   2602                         DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
   2603                         SQLiteDatabase database = dbHelper.getWritableDatabase();
   2604                         migrateLegacySettingsForUserLocked(dbHelper, database, userId);
   2605 
   2606                         // Upgrade to the latest version.
   2607                         UpgradeController upgrader = new UpgradeController(userId);
   2608                         upgrader.upgradeIfNeededLocked();
   2609 
   2610                         // Drop from memory if not a running user.
   2611                         if (!mUserManager.isUserRunning(new UserHandle(userId))) {
   2612                             removeUserStateLocked(userId, false);
   2613                         }
   2614                     }
   2615                 } finally {
   2616                     Binder.restoreCallingIdentity(identity);
   2617                 }
   2618             }
   2619         }
   2620 
   2621         private void migrateLegacySettingsForUserIfNeededLocked(int userId) {
   2622             // Every user has secure settings and if no file we need to migrate.
   2623             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
   2624             File secureFile = getSettingsFile(secureKey);
   2625             if (SettingsState.stateFileExists(secureFile)) {
   2626                 return;
   2627             }
   2628 
   2629             DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
   2630             SQLiteDatabase database = dbHelper.getWritableDatabase();
   2631 
   2632             migrateLegacySettingsForUserLocked(dbHelper, database, userId);
   2633         }
   2634 
   2635         private void migrateLegacySettingsForUserLocked(DatabaseHelper dbHelper,
   2636                 SQLiteDatabase database, int userId) {
   2637             // Move over the system settings.
   2638             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
   2639             ensureSettingsStateLocked(systemKey);
   2640             SettingsState systemSettings = mSettingsStates.get(systemKey);
   2641             migrateLegacySettingsLocked(systemSettings, database, TABLE_SYSTEM);
   2642             systemSettings.persistSyncLocked();
   2643 
   2644             // Move over the secure settings.
   2645             // Do this after System settings, since this is the first thing we check when deciding
   2646             // to skip over migration from db to xml for a secondary user.
   2647             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
   2648             ensureSettingsStateLocked(secureKey);
   2649             SettingsState secureSettings = mSettingsStates.get(secureKey);
   2650             migrateLegacySettingsLocked(secureSettings, database, TABLE_SECURE);
   2651             ensureSecureSettingAndroidIdSetLocked(secureSettings);
   2652             secureSettings.persistSyncLocked();
   2653 
   2654             // Move over the global settings if owner.
   2655             // Do this last, since this is the first thing we check when deciding
   2656             // to skip over migration from db to xml for owner user.
   2657             if (userId == UserHandle.USER_SYSTEM) {
   2658                 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, userId);
   2659                 ensureSettingsStateLocked(globalKey);
   2660                 SettingsState globalSettings = mSettingsStates.get(globalKey);
   2661                 migrateLegacySettingsLocked(globalSettings, database, TABLE_GLOBAL);
   2662                 // If this was just created
   2663                 if (mSettingsCreationBuildId != null) {
   2664                     globalSettings.insertSettingLocked(Settings.Global.DATABASE_CREATION_BUILDID,
   2665                             mSettingsCreationBuildId, null, true,
   2666                             SettingsState.SYSTEM_PACKAGE_NAME);
   2667                 }
   2668                 globalSettings.persistSyncLocked();
   2669             }
   2670 
   2671             // Drop the database as now all is moved and persisted.
   2672             if (DROP_DATABASE_ON_MIGRATION) {
   2673                 dbHelper.dropDatabase();
   2674             } else {
   2675                 dbHelper.backupDatabase();
   2676             }
   2677         }
   2678 
   2679         private void migrateLegacySettingsLocked(SettingsState settingsState,
   2680                 SQLiteDatabase database, String table) {
   2681             SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
   2682             queryBuilder.setTables(table);
   2683 
   2684             Cursor cursor = queryBuilder.query(database, ALL_COLUMNS,
   2685                     null, null, null, null, null);
   2686 
   2687             if (cursor == null) {
   2688                 return;
   2689             }
   2690 
   2691             try {
   2692                 if (!cursor.moveToFirst()) {
   2693                     return;
   2694                 }
   2695 
   2696                 final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME);
   2697                 final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
   2698 
   2699                 settingsState.setVersionLocked(database.getVersion());
   2700 
   2701                 while (!cursor.isAfterLast()) {
   2702                     String name = cursor.getString(nameColumnIdx);
   2703                     String value = cursor.getString(valueColumnIdx);
   2704                     settingsState.insertSettingLocked(name, value, null, true,
   2705                             SettingsState.SYSTEM_PACKAGE_NAME);
   2706                     cursor.moveToNext();
   2707                 }
   2708             } finally {
   2709                 cursor.close();
   2710             }
   2711         }
   2712 
   2713         private void ensureSecureSettingAndroidIdSetLocked(SettingsState secureSettings) {
   2714             Setting value = secureSettings.getSettingLocked(Settings.Secure.ANDROID_ID);
   2715 
   2716             if (!value.isNull()) {
   2717                 return;
   2718             }
   2719 
   2720             final int userId = getUserIdFromKey(secureSettings.mKey);
   2721 
   2722             final UserInfo user;
   2723             final long identity = Binder.clearCallingIdentity();
   2724             try {
   2725                 user = mUserManager.getUserInfo(userId);
   2726             } finally {
   2727                 Binder.restoreCallingIdentity(identity);
   2728             }
   2729             if (user == null) {
   2730                 // Can happen due to races when deleting users - treat as benign.
   2731                 return;
   2732             }
   2733 
   2734             String androidId = Long.toHexString(new SecureRandom().nextLong());
   2735             secureSettings.insertSettingLocked(Settings.Secure.ANDROID_ID, androidId,
   2736                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   2737 
   2738             Slog.d(LOG_TAG, "Generated and saved new ANDROID_ID [" + androidId
   2739                     + "] for user " + userId);
   2740 
   2741             // Write a drop box entry if it's a restricted profile
   2742             if (user.isRestricted()) {
   2743                 DropBoxManager dbm = (DropBoxManager) getContext().getSystemService(
   2744                         Context.DROPBOX_SERVICE);
   2745                 if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
   2746                     dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis()
   2747                             + "," + DROPBOX_TAG_USERLOG + "," + androidId + "\n");
   2748                 }
   2749             }
   2750         }
   2751 
   2752         private void notifyForSettingsChange(int key, String name) {
   2753             // Increment the generation first, so observers always see the new value
   2754             mGenerationRegistry.incrementGeneration(key);
   2755 
   2756             if (isGlobalSettingsKey(key)) {
   2757                 final long token = Binder.clearCallingIdentity();
   2758                 try {
   2759                     if (Global.LOCATION_GLOBAL_KILL_SWITCH.equals(name)) {
   2760                         // When the global kill switch is updated, send the
   2761                         // change notification for the location setting.
   2762                         notifyLocationChangeForRunningUsers();
   2763                     }
   2764                     notifyGlobalSettingChangeForRunningUsers(key, name);
   2765                 } finally {
   2766                     Binder.restoreCallingIdentity(token);
   2767                 }
   2768             } else {
   2769                 final int userId = getUserIdFromKey(key);
   2770                 final Uri uri = getNotificationUriFor(key, name);
   2771                 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
   2772                         userId, 0, uri).sendToTarget();
   2773                 if (isSecureSettingsKey(key)) {
   2774                     maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
   2775                             sSecureCloneToManagedSettings);
   2776                     maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name,
   2777                             sSystemCloneFromParentOnDependency.values());
   2778                 } else if (isSystemSettingsKey(key)) {
   2779                     maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
   2780                             sSystemCloneToManagedSettings);
   2781                 }
   2782             }
   2783 
   2784             // Always notify that our data changed
   2785             mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget();
   2786         }
   2787 
   2788         private void maybeNotifyProfiles(int type, int userId, Uri uri, String name,
   2789                 Collection<String> keysCloned) {
   2790             if (keysCloned.contains(name)) {
   2791                 for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
   2792                     // the notification for userId has already been sent.
   2793                     if (profileId != userId) {
   2794                         final int key = makeKey(type, profileId);
   2795                         // Increment the generation first, so observers always see the new value
   2796                         mGenerationRegistry.incrementGeneration(key);
   2797                         mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
   2798                                 profileId, 0, uri).sendToTarget();
   2799                     }
   2800                 }
   2801             }
   2802         }
   2803 
   2804         private void notifyGlobalSettingChangeForRunningUsers(int key, String name) {
   2805             // Important: No need to update generation for each user as there
   2806             // is a singleton generation entry for the global settings which
   2807             // is already incremented be the caller.
   2808             final Uri uri = getNotificationUriFor(key, name);
   2809             final List<UserInfo> users = mUserManager.getUsers(/*excludeDying*/ true);
   2810             for (int i = 0; i < users.size(); i++) {
   2811                 final int userId = users.get(i).id;
   2812                 if (mUserManager.isUserRunning(UserHandle.of(userId))) {
   2813                     mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
   2814                             userId, 0, uri).sendToTarget();
   2815                 }
   2816             }
   2817         }
   2818 
   2819         private void notifyLocationChangeForRunningUsers() {
   2820             final List<UserInfo> users = mUserManager.getUsers(/*excludeDying=*/ true);
   2821 
   2822             for (int i = 0; i < users.size(); i++) {
   2823                 final int userId = users.get(i).id;
   2824 
   2825                 if (!mUserManager.isUserRunning(UserHandle.of(userId))) {
   2826                     continue;
   2827                 }
   2828 
   2829                 // Increment the generation first, so observers always see the new value
   2830                 final int key = makeKey(SETTINGS_TYPE_SECURE, userId);
   2831                 mGenerationRegistry.incrementGeneration(key);
   2832 
   2833                 final Uri uri = getNotificationUriFor(key, Secure.LOCATION_PROVIDERS_ALLOWED);
   2834                 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
   2835                         userId, 0, uri).sendToTarget();
   2836             }
   2837         }
   2838 
   2839         private boolean isGlobalSettingsKey(int key) {
   2840             return getTypeFromKey(key) == SETTINGS_TYPE_GLOBAL;
   2841         }
   2842 
   2843         private boolean isSystemSettingsKey(int key) {
   2844             return getTypeFromKey(key) == SETTINGS_TYPE_SYSTEM;
   2845         }
   2846 
   2847         private boolean isSecureSettingsKey(int key) {
   2848             return getTypeFromKey(key) == SETTINGS_TYPE_SECURE;
   2849         }
   2850 
   2851         private boolean isSsaidSettingsKey(int key) {
   2852             return getTypeFromKey(key) == SETTINGS_TYPE_SSAID;
   2853         }
   2854 
   2855         private File getSettingsFile(int key) {
   2856             if (isGlobalSettingsKey(key)) {
   2857                 final int userId = getUserIdFromKey(key);
   2858                 return new File(Environment.getUserSystemDirectory(userId),
   2859                         SETTINGS_FILE_GLOBAL);
   2860             } else if (isSystemSettingsKey(key)) {
   2861                 final int userId = getUserIdFromKey(key);
   2862                 return new File(Environment.getUserSystemDirectory(userId),
   2863                         SETTINGS_FILE_SYSTEM);
   2864             } else if (isSecureSettingsKey(key)) {
   2865                 final int userId = getUserIdFromKey(key);
   2866                 return new File(Environment.getUserSystemDirectory(userId),
   2867                         SETTINGS_FILE_SECURE);
   2868             } else if (isSsaidSettingsKey(key)) {
   2869                 final int userId = getUserIdFromKey(key);
   2870                 return new File(Environment.getUserSystemDirectory(userId),
   2871                         SETTINGS_FILE_SSAID);
   2872             } else {
   2873                 throw new IllegalArgumentException("Invalid settings key:" + key);
   2874             }
   2875         }
   2876 
   2877         private Uri getNotificationUriFor(int key, String name) {
   2878             if (isGlobalSettingsKey(key)) {
   2879                 return (name != null) ? Uri.withAppendedPath(Settings.Global.CONTENT_URI, name)
   2880                         : Settings.Global.CONTENT_URI;
   2881             } else if (isSecureSettingsKey(key)) {
   2882                 return (name != null) ? Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name)
   2883                         : Settings.Secure.CONTENT_URI;
   2884             } else if (isSystemSettingsKey(key)) {
   2885                 return (name != null) ? Uri.withAppendedPath(Settings.System.CONTENT_URI, name)
   2886                         : Settings.System.CONTENT_URI;
   2887             } else {
   2888                 throw new IllegalArgumentException("Invalid settings key:" + key);
   2889             }
   2890         }
   2891 
   2892         private int getMaxBytesPerPackageForType(int type) {
   2893             switch (type) {
   2894                 case SETTINGS_TYPE_GLOBAL:
   2895                 case SETTINGS_TYPE_SECURE:
   2896                 case SETTINGS_TYPE_SSAID: {
   2897                     return SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED;
   2898                 }
   2899 
   2900                 default: {
   2901                     return SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED;
   2902                 }
   2903             }
   2904         }
   2905 
   2906         private final class MyHandler extends Handler {
   2907             private static final int MSG_NOTIFY_URI_CHANGED = 1;
   2908             private static final int MSG_NOTIFY_DATA_CHANGED = 2;
   2909 
   2910             public MyHandler(Looper looper) {
   2911                 super(looper);
   2912             }
   2913 
   2914             @Override
   2915             public void handleMessage(Message msg) {
   2916                 switch (msg.what) {
   2917                     case MSG_NOTIFY_URI_CHANGED: {
   2918                         final int userId = msg.arg1;
   2919                         Uri uri = (Uri) msg.obj;
   2920                         try {
   2921                             getContext().getContentResolver().notifyChange(uri, null, true, userId);
   2922                         } catch (SecurityException e) {
   2923                             Slog.w(LOG_TAG, "Failed to notify for " + userId + ": " + uri, e);
   2924                         }
   2925                         if (DEBUG || true) {
   2926                             Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri);
   2927                         }
   2928                     } break;
   2929 
   2930                     case MSG_NOTIFY_DATA_CHANGED: {
   2931                         mBackupManager.dataChanged();
   2932                     } break;
   2933                 }
   2934             }
   2935         }
   2936 
   2937         private final class UpgradeController {
   2938             private static final int SETTINGS_VERSION = 169;
   2939 
   2940             private final int mUserId;
   2941 
   2942             public UpgradeController(int userId) {
   2943                 mUserId = userId;
   2944             }
   2945 
   2946             public void upgradeIfNeededLocked() {
   2947                 // The version of all settings for a user is the same (all users have secure).
   2948                 SettingsState secureSettings = getSettingsLocked(
   2949                         SETTINGS_TYPE_SECURE, mUserId);
   2950 
   2951                 // Try an update from the current state.
   2952                 final int oldVersion = secureSettings.getVersionLocked();
   2953                 final int newVersion = SETTINGS_VERSION;
   2954 
   2955                 // If up do date - done.
   2956                 if (oldVersion == newVersion) {
   2957                     return;
   2958                 }
   2959 
   2960                 // Try to upgrade.
   2961                 final int curVersion = onUpgradeLocked(mUserId, oldVersion, newVersion);
   2962 
   2963                 // If upgrade failed start from scratch and upgrade.
   2964                 if (curVersion != newVersion) {
   2965                     // Drop state we have for this user.
   2966                     removeUserStateLocked(mUserId, true);
   2967 
   2968                     // Recreate the database.
   2969                     DatabaseHelper dbHelper = new DatabaseHelper(getContext(), mUserId);
   2970                     SQLiteDatabase database = dbHelper.getWritableDatabase();
   2971                     dbHelper.recreateDatabase(database, newVersion, curVersion, oldVersion);
   2972 
   2973                     // Migrate the settings for this user.
   2974                     migrateLegacySettingsForUserLocked(dbHelper, database, mUserId);
   2975 
   2976                     // Now upgrade should work fine.
   2977                     onUpgradeLocked(mUserId, oldVersion, newVersion);
   2978 
   2979                     // Make a note what happened, so we don't wonder why data was lost
   2980                     String reason = "Settings rebuilt! Current version: "
   2981                             + curVersion + " while expected: " + newVersion;
   2982                     getGlobalSettingsLocked().insertSettingLocked(
   2983                             Settings.Global.DATABASE_DOWNGRADE_REASON,
   2984                             reason, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   2985                 }
   2986 
   2987                 // Set the global settings version if owner.
   2988                 if (mUserId == UserHandle.USER_SYSTEM) {
   2989                     SettingsState globalSettings = getSettingsLocked(
   2990                             SETTINGS_TYPE_GLOBAL, mUserId);
   2991                     globalSettings.setVersionLocked(newVersion);
   2992                 }
   2993 
   2994                 // Set the secure settings version.
   2995                 secureSettings.setVersionLocked(newVersion);
   2996 
   2997                 // Set the system settings version.
   2998                 SettingsState systemSettings = getSettingsLocked(
   2999                         SETTINGS_TYPE_SYSTEM, mUserId);
   3000                 systemSettings.setVersionLocked(newVersion);
   3001             }
   3002 
   3003             private SettingsState getGlobalSettingsLocked() {
   3004                 return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
   3005             }
   3006 
   3007             private SettingsState getSecureSettingsLocked(int userId) {
   3008                 return getSettingsLocked(SETTINGS_TYPE_SECURE, userId);
   3009             }
   3010 
   3011             private SettingsState getSsaidSettingsLocked(int userId) {
   3012                 return getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
   3013             }
   3014 
   3015             private SettingsState getSystemSettingsLocked(int userId) {
   3016                 return getSettingsLocked(SETTINGS_TYPE_SYSTEM, userId);
   3017             }
   3018 
   3019             /**
   3020              * You must perform all necessary mutations to bring the settings
   3021              * for this user from the old to the new version. When you add a new
   3022              * upgrade step you *must* update SETTINGS_VERSION.
   3023              *
   3024              * This is an example of moving a setting from secure to global.
   3025              *
   3026              * // v119: Example settings changes.
   3027              * if (currentVersion == 118) {
   3028              *     if (userId == UserHandle.USER_OWNER) {
   3029              *         // Remove from the secure settings.
   3030              *         SettingsState secureSettings = getSecureSettingsLocked(userId);
   3031              *         String name = "example_setting_to_move";
   3032              *         String value = secureSettings.getSetting(name);
   3033              *         secureSettings.deleteSetting(name);
   3034              *
   3035              *         // Add to the global settings.
   3036              *         SettingsState globalSettings = getGlobalSettingsLocked();
   3037              *         globalSettings.insertSetting(name, value, SettingsState.SYSTEM_PACKAGE_NAME);
   3038              *     }
   3039              *
   3040              *     // Update the current version.
   3041              *     currentVersion = 119;
   3042              * }
   3043              */
   3044             private int onUpgradeLocked(int userId, int oldVersion, int newVersion) {
   3045                 if (DEBUG) {
   3046                     Slog.w(LOG_TAG, "Upgrading settings for user: " + userId + " from version: "
   3047                             + oldVersion + " to version: " + newVersion);
   3048                 }
   3049 
   3050                 int currentVersion = oldVersion;
   3051 
   3052                 // v119: Reset zen + ringer mode.
   3053                 if (currentVersion == 118) {
   3054                     if (userId == UserHandle.USER_SYSTEM) {
   3055                         final SettingsState globalSettings = getGlobalSettingsLocked();
   3056                         globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE,
   3057                                 Integer.toString(Settings.Global.ZEN_MODE_OFF), null,
   3058                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
   3059                         globalSettings.updateSettingLocked(Settings.Global.MODE_RINGER,
   3060                                 Integer.toString(AudioManager.RINGER_MODE_NORMAL), null,
   3061                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
   3062                     }
   3063                     currentVersion = 119;
   3064                 }
   3065 
   3066                 // v120: Add double tap to wake setting.
   3067                 if (currentVersion == 119) {
   3068                     SettingsState secureSettings = getSecureSettingsLocked(userId);
   3069                     secureSettings.insertSettingLocked(Settings.Secure.DOUBLE_TAP_TO_WAKE,
   3070                             getContext().getResources().getBoolean(
   3071                                     R.bool.def_double_tap_to_wake) ? "1" : "0", null, true,
   3072                             SettingsState.SYSTEM_PACKAGE_NAME);
   3073 
   3074                     currentVersion = 120;
   3075                 }
   3076 
   3077                 if (currentVersion == 120) {
   3078                     // Before 121, we used a different string encoding logic.  We just bump the
   3079                     // version here; SettingsState knows how to handle pre-version 120 files.
   3080                     currentVersion = 121;
   3081                 }
   3082 
   3083                 if (currentVersion == 121) {
   3084                     // Version 122: allow OEMs to set a default payment component in resources.
   3085                     // Note that we only write the default if no default has been set;
   3086                     // if there is, we just leave the default at whatever it currently is.
   3087                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3088                     String defaultComponent = (getContext().getResources().getString(
   3089                             R.string.def_nfc_payment_component));
   3090                     Setting currentSetting = secureSettings.getSettingLocked(
   3091                             Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
   3092                     if (defaultComponent != null && !defaultComponent.isEmpty() &&
   3093                         currentSetting.isNull()) {
   3094                         secureSettings.insertSettingLocked(
   3095                                 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
   3096                                 defaultComponent, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3097                     }
   3098                     currentVersion = 122;
   3099                 }
   3100 
   3101                 if (currentVersion == 122) {
   3102                     // Version 123: Adding a default value for the ability to add a user from
   3103                     // the lock screen.
   3104                     if (userId == UserHandle.USER_SYSTEM) {
   3105                         final SettingsState globalSettings = getGlobalSettingsLocked();
   3106                         Setting currentSetting = globalSettings.getSettingLocked(
   3107                                 Settings.Global.ADD_USERS_WHEN_LOCKED);
   3108                         if (currentSetting.isNull()) {
   3109                             globalSettings.insertSettingLocked(
   3110                                     Settings.Global.ADD_USERS_WHEN_LOCKED,
   3111                                     getContext().getResources().getBoolean(
   3112                                             R.bool.def_add_users_from_lockscreen) ? "1" : "0",
   3113                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3114                         }
   3115                     }
   3116                     currentVersion = 123;
   3117                 }
   3118 
   3119                 if (currentVersion == 123) {
   3120                     final SettingsState globalSettings = getGlobalSettingsLocked();
   3121                     String defaultDisabledProfiles = (getContext().getResources().getString(
   3122                             R.string.def_bluetooth_disabled_profiles));
   3123                     globalSettings.insertSettingLocked(Settings.Global.BLUETOOTH_DISABLED_PROFILES,
   3124                             defaultDisabledProfiles, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3125                     currentVersion = 124;
   3126                 }
   3127 
   3128                 if (currentVersion == 124) {
   3129                     // Version 124: allow OEMs to set a default value for whether IME should be
   3130                     // shown when a physical keyboard is connected.
   3131                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3132                     Setting currentSetting = secureSettings.getSettingLocked(
   3133                             Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
   3134                     if (currentSetting.isNull()) {
   3135                         secureSettings.insertSettingLocked(
   3136                                 Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
   3137                                 getContext().getResources().getBoolean(
   3138                                         R.bool.def_show_ime_with_hard_keyboard) ? "1" : "0",
   3139                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3140                     }
   3141                     currentVersion = 125;
   3142                 }
   3143 
   3144                 if (currentVersion == 125) {
   3145                     // Version 125: Allow OEMs to set the default VR service.
   3146                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3147 
   3148                     Setting currentSetting = secureSettings.getSettingLocked(
   3149                             Settings.Secure.ENABLED_VR_LISTENERS);
   3150                     if (currentSetting.isNull()) {
   3151                         ArraySet<ComponentName> l =
   3152                                 SystemConfig.getInstance().getDefaultVrComponents();
   3153 
   3154                         if (l != null && !l.isEmpty()) {
   3155                             StringBuilder b = new StringBuilder();
   3156                             boolean start = true;
   3157                             for (ComponentName c : l) {
   3158                                 if (!start) {
   3159                                     b.append(':');
   3160                                 }
   3161                                 b.append(c.flattenToString());
   3162                                 start = false;
   3163                             }
   3164                             secureSettings.insertSettingLocked(
   3165                                     Settings.Secure.ENABLED_VR_LISTENERS, b.toString(),
   3166                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3167                         }
   3168 
   3169                     }
   3170                     currentVersion = 126;
   3171                 }
   3172 
   3173                 if (currentVersion == 126) {
   3174                     // Version 126: copy the primary values of LOCK_SCREEN_SHOW_NOTIFICATIONS and
   3175                     // LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS into managed profile.
   3176                     if (mUserManager.isManagedProfile(userId)) {
   3177                         final SettingsState systemSecureSettings =
   3178                                 getSecureSettingsLocked(UserHandle.USER_SYSTEM);
   3179 
   3180                         final Setting showNotifications = systemSecureSettings.getSettingLocked(
   3181                                 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
   3182                         if (!showNotifications.isNull()) {
   3183                             final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3184                             secureSettings.insertSettingLocked(
   3185                                     Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
   3186                                     showNotifications.getValue(), null, true,
   3187                                     SettingsState.SYSTEM_PACKAGE_NAME);
   3188                         }
   3189 
   3190                         final Setting allowPrivate = systemSecureSettings.getSettingLocked(
   3191                                 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
   3192                         if (!allowPrivate.isNull()) {
   3193                             final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3194                             secureSettings.insertSettingLocked(
   3195                                     Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
   3196                                     allowPrivate.getValue(), null, true,
   3197                                     SettingsState.SYSTEM_PACKAGE_NAME);
   3198                         }
   3199                     }
   3200                     currentVersion = 127;
   3201                 }
   3202 
   3203                 if (currentVersion == 127) {
   3204                     // version 127 is no longer used.
   3205                     currentVersion = 128;
   3206                 }
   3207 
   3208                 if (currentVersion == 128) {
   3209                     // Version 128: Removed
   3210                     currentVersion = 129;
   3211                 }
   3212 
   3213                 if (currentVersion == 129) {
   3214                     // default longpress timeout changed from 500 to 400. If unchanged from the old
   3215                     // default, update to the new default.
   3216                     final SettingsState systemSecureSettings =
   3217                             getSecureSettingsLocked(userId);
   3218                     final String oldValue = systemSecureSettings.getSettingLocked(
   3219                             Settings.Secure.LONG_PRESS_TIMEOUT).getValue();
   3220                     if (TextUtils.equals("500", oldValue)) {
   3221                         systemSecureSettings.insertSettingLocked(
   3222                                 Settings.Secure.LONG_PRESS_TIMEOUT,
   3223                                 String.valueOf(getContext().getResources().getInteger(
   3224                                         R.integer.def_long_press_timeout_millis)),
   3225                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3226                     }
   3227                     currentVersion = 130;
   3228                 }
   3229 
   3230                 if (currentVersion == 130) {
   3231                     // Split Ambient settings
   3232                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3233                     boolean dozeExplicitlyDisabled = "0".equals(secureSettings.
   3234                             getSettingLocked(Settings.Secure.DOZE_ENABLED).getValue());
   3235 
   3236                     if (dozeExplicitlyDisabled) {
   3237                         secureSettings.insertSettingLocked(Settings.Secure.DOZE_PULSE_ON_PICK_UP,
   3238                                 "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3239                         secureSettings.insertSettingLocked(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
   3240                                 "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3241                     }
   3242                     currentVersion = 131;
   3243                 }
   3244 
   3245                 if (currentVersion == 131) {
   3246                     // Initialize new multi-press timeout to default value
   3247                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
   3248                     final String oldValue = systemSecureSettings.getSettingLocked(
   3249                             Settings.Secure.MULTI_PRESS_TIMEOUT).getValue();
   3250                     if (TextUtils.equals(null, oldValue)) {
   3251                         systemSecureSettings.insertSettingLocked(
   3252                                 Settings.Secure.MULTI_PRESS_TIMEOUT,
   3253                                 String.valueOf(getContext().getResources().getInteger(
   3254                                         R.integer.def_multi_press_timeout_millis)),
   3255                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3256                     }
   3257 
   3258                     currentVersion = 132;
   3259                 }
   3260 
   3261                 if (currentVersion == 132) {
   3262                     // Version 132: Allow managed profile to optionally use the parent's ringtones
   3263                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
   3264                     String defaultSyncParentSounds = (getContext().getResources()
   3265                             .getBoolean(R.bool.def_sync_parent_sounds) ? "1" : "0");
   3266                     systemSecureSettings.insertSettingLocked(
   3267                             Settings.Secure.SYNC_PARENT_SOUNDS, defaultSyncParentSounds,
   3268                             null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3269                     currentVersion = 133;
   3270                 }
   3271 
   3272                 if (currentVersion == 133) {
   3273                     // Version 133: Add default end button behavior
   3274                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
   3275                     if (systemSettings.getSettingLocked(Settings.System.END_BUTTON_BEHAVIOR) ==
   3276                             null) {
   3277                         String defaultEndButtonBehavior = Integer.toString(getContext()
   3278                                 .getResources().getInteger(R.integer.def_end_button_behavior));
   3279                         systemSettings.insertSettingLocked(Settings.System.END_BUTTON_BEHAVIOR,
   3280                                 defaultEndButtonBehavior, null, true,
   3281                                 SettingsState.SYSTEM_PACKAGE_NAME);
   3282                     }
   3283                     currentVersion = 134;
   3284                 }
   3285 
   3286                 if (currentVersion == 134) {
   3287                     // Remove setting that specifies if magnification values should be preserved.
   3288                     // This setting defaulted to true and never has a UI.
   3289                     getSecureSettingsLocked(userId).deleteSettingLocked(
   3290                             Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE);
   3291                     currentVersion = 135;
   3292                 }
   3293 
   3294                 if (currentVersion == 135) {
   3295                     // Version 135 no longer used.
   3296                     currentVersion = 136;
   3297                 }
   3298 
   3299                 if (currentVersion == 136) {
   3300                     // Version 136: Store legacy SSAID for all apps currently installed on the
   3301                     // device as first step in migrating SSAID to be unique per application.
   3302 
   3303                     final boolean isUpgrade;
   3304                     try {
   3305                         isUpgrade = mPackageManager.isUpgrade();
   3306                     } catch (RemoteException e) {
   3307                         throw new IllegalStateException("Package manager not available");
   3308                     }
   3309                     // Only retain legacy ssaid if the device is performing an OTA. After wiping
   3310                     // user data or first boot on a new device should use new ssaid generation.
   3311                     if (isUpgrade) {
   3312                         // Retrieve the legacy ssaid from the secure settings table.
   3313                         final Setting legacySsaidSetting = getSettingLocked(SETTINGS_TYPE_SECURE,
   3314                                 userId, Settings.Secure.ANDROID_ID);
   3315                         if (legacySsaidSetting == null || legacySsaidSetting.isNull()
   3316                                 || legacySsaidSetting.getValue() == null) {
   3317                             throw new IllegalStateException("Legacy ssaid not accessible");
   3318                         }
   3319                         final String legacySsaid = legacySsaidSetting.getValue();
   3320 
   3321                         // Fill each uid with the legacy ssaid to be backwards compatible.
   3322                         final List<PackageInfo> packages;
   3323                         try {
   3324                             packages = mPackageManager.getInstalledPackages(
   3325                                 PackageManager.MATCH_UNINSTALLED_PACKAGES,
   3326                                 userId).getList();
   3327                         } catch (RemoteException e) {
   3328                             throw new IllegalStateException("Package manager not available");
   3329                         }
   3330 
   3331                         final SettingsState ssaidSettings = getSsaidSettingsLocked(userId);
   3332                         for (PackageInfo info : packages) {
   3333                             // Check if the UID already has an entry in the table.
   3334                             final String uid = Integer.toString(info.applicationInfo.uid);
   3335                             final Setting ssaid = ssaidSettings.getSettingLocked(uid);
   3336 
   3337                             if (ssaid.isNull() || ssaid.getValue() == null) {
   3338                                 // Android Id doesn't exist for this package so create it.
   3339                                 ssaidSettings.insertSettingLocked(uid, legacySsaid, null, true,
   3340                                         info.packageName);
   3341                                 if (DEBUG) {
   3342                                     Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid);
   3343                                 }
   3344                             }
   3345                         }
   3346                     }
   3347 
   3348                     currentVersion = 137;
   3349                 }
   3350                 if (currentVersion == 137) {
   3351                     // Version 138: Settings.Secure#INSTALL_NON_MARKET_APPS is deprecated and its
   3352                     // default value set to 1. The user can no longer change the value of this
   3353                     // setting through the UI.
   3354                     final SettingsState secureSetting = getSecureSettingsLocked(userId);
   3355                     if (!mUserManager.hasUserRestriction(
   3356                             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, UserHandle.of(userId))
   3357                             && secureSetting.getSettingLocked(
   3358                             Settings.Secure.INSTALL_NON_MARKET_APPS).getValue().equals("0")) {
   3359 
   3360                         secureSetting.insertSettingLocked(Settings.Secure.INSTALL_NON_MARKET_APPS,
   3361                                 "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3362                         // For managed profiles with profile owners, DevicePolicyManagerService
   3363                         // may want to set the user restriction in this case
   3364                         secureSetting.insertSettingLocked(
   3365                                 Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, "1", null, true,
   3366                                 SettingsState.SYSTEM_PACKAGE_NAME);
   3367                     }
   3368                     currentVersion = 138;
   3369                 }
   3370 
   3371                 if (currentVersion == 138) {
   3372                     // Version 139: Removed.
   3373                     currentVersion = 139;
   3374                 }
   3375 
   3376                 if (currentVersion == 139) {
   3377                     // Version 140: Settings.Secure#ACCESSIBILITY_SPEAK_PASSWORD is deprecated and
   3378                     // the user can no longer change the value of this setting through the UI.
   3379                     // Force to true.
   3380                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3381                     secureSettings.updateSettingLocked(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
   3382                             "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3383                     currentVersion = 140;
   3384                 }
   3385 
   3386                 if (currentVersion == 140) {
   3387                     // Version 141: Removed
   3388                     currentVersion = 141;
   3389                 }
   3390 
   3391                 if (currentVersion == 141) {
   3392                     // This implementation was incorrectly setting the current value of
   3393                     // settings changed by non-system packages as the default which default
   3394                     // is set by the system. We add a new upgrade step at the end to properly
   3395                     // handle this case which would also fix incorrect changes made by the
   3396                     // old implementation of this step.
   3397                     currentVersion = 142;
   3398                 }
   3399 
   3400                 if (currentVersion == 142) {
   3401                     // Version 143: Set a default value for Wi-Fi wakeup feature.
   3402                     if (userId == UserHandle.USER_SYSTEM) {
   3403                         final SettingsState globalSettings = getGlobalSettingsLocked();
   3404                         Setting currentSetting = globalSettings.getSettingLocked(
   3405                                 Settings.Global.WIFI_WAKEUP_ENABLED);
   3406                         if (currentSetting.isNull()) {
   3407                             globalSettings.insertSettingLocked(
   3408                                     Settings.Global.WIFI_WAKEUP_ENABLED,
   3409                                     getContext().getResources().getBoolean(
   3410                                             R.bool.def_wifi_wakeup_enabled) ? "1" : "0",
   3411                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3412                         }
   3413                     }
   3414 
   3415                     currentVersion = 143;
   3416                 }
   3417 
   3418                 if (currentVersion == 143) {
   3419                     // Version 144: Set a default value for Autofill service.
   3420                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3421                     final Setting currentSetting = secureSettings
   3422                             .getSettingLocked(Settings.Secure.AUTOFILL_SERVICE);
   3423                     if (currentSetting.isNull()) {
   3424                         final String defaultValue = getContext().getResources().getString(
   3425                                 com.android.internal.R.string.config_defaultAutofillService);
   3426                         if (defaultValue != null) {
   3427                             Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as Autofill Service "
   3428                                     + "for user " + userId);
   3429                             secureSettings.insertSettingLocked(Settings.Secure.AUTOFILL_SERVICE,
   3430                                     defaultValue, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3431                         }
   3432                     }
   3433 
   3434                     currentVersion = 144;
   3435                 }
   3436 
   3437                 if (currentVersion == 144) {
   3438                     // Version 145: Removed
   3439                     currentVersion = 145;
   3440                 }
   3441 
   3442                 if (currentVersion == 145) {
   3443                     // Version 146: In step 142 we had a bug where incorrectly
   3444                     // some settings were considered system set and as a result
   3445                     // made the default and marked as the default being set by
   3446                     // the system. Here reevaluate the default and default system
   3447                     // set flags. This would both fix corruption by the old impl
   3448                     // of step 142 and also properly handle devices which never
   3449                     // run 142.
   3450                     if (userId == UserHandle.USER_SYSTEM) {
   3451                         SettingsState globalSettings = getGlobalSettingsLocked();
   3452                         ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings, userId);
   3453                         globalSettings.persistSyncLocked();
   3454                     }
   3455 
   3456                     SettingsState secureSettings = getSecureSettingsLocked(mUserId);
   3457                     ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings, userId);
   3458                     secureSettings.persistSyncLocked();
   3459 
   3460                     SettingsState systemSettings = getSystemSettingsLocked(mUserId);
   3461                     ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings, userId);
   3462                     systemSettings.persistSyncLocked();
   3463 
   3464                     currentVersion = 146;
   3465                 }
   3466 
   3467                 if (currentVersion == 146) {
   3468                     // Version 147: Removed. (This version previously allowed showing the
   3469                     // "wifi_wakeup_available" setting).
   3470                     // The setting that was added here is deleted in 153.
   3471                     currentVersion = 147;
   3472                 }
   3473 
   3474                 if (currentVersion == 147) {
   3475                     // Version 148: Set the default value for DEFAULT_RESTRICT_BACKGROUND_DATA.
   3476                     if (userId == UserHandle.USER_SYSTEM) {
   3477                         final SettingsState globalSettings = getGlobalSettingsLocked();
   3478                         final Setting currentSetting = globalSettings.getSettingLocked(
   3479                                 Global.DEFAULT_RESTRICT_BACKGROUND_DATA);
   3480                         if (currentSetting.isNull()) {
   3481                             globalSettings.insertSettingLocked(
   3482                                     Global.DEFAULT_RESTRICT_BACKGROUND_DATA,
   3483                                     getContext().getResources().getBoolean(
   3484                                             R.bool.def_restrict_background_data) ? "1" : "0",
   3485                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3486                         }
   3487                     }
   3488                     currentVersion = 148;
   3489                 }
   3490 
   3491                 if (currentVersion == 148) {
   3492                     // Version 149: Set the default value for BACKUP_MANAGER_CONSTANTS.
   3493                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
   3494                     final String oldValue = systemSecureSettings.getSettingLocked(
   3495                             Settings.Secure.BACKUP_MANAGER_CONSTANTS).getValue();
   3496                     if (TextUtils.equals(null, oldValue)) {
   3497                         final String defaultValue = getContext().getResources().getString(
   3498                                 R.string.def_backup_manager_constants);
   3499                         if (!TextUtils.isEmpty(defaultValue)) {
   3500                             systemSecureSettings.insertSettingLocked(
   3501                                     Settings.Secure.BACKUP_MANAGER_CONSTANTS, defaultValue, null,
   3502                                     true, SettingsState.SYSTEM_PACKAGE_NAME);
   3503                         }
   3504                     }
   3505                     currentVersion = 149;
   3506                 }
   3507 
   3508                 if (currentVersion == 149) {
   3509                     // Version 150: Set a default value for mobile data always on
   3510                     final SettingsState globalSettings = getGlobalSettingsLocked();
   3511                     final Setting currentSetting = globalSettings.getSettingLocked(
   3512                             Settings.Global.MOBILE_DATA_ALWAYS_ON);
   3513                     if (currentSetting.isNull()) {
   3514                         globalSettings.insertSettingLocked(
   3515                                 Settings.Global.MOBILE_DATA_ALWAYS_ON,
   3516                                 getContext().getResources().getBoolean(
   3517                                         R.bool.def_mobile_data_always_on) ? "1" : "0",
   3518                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3519                     }
   3520 
   3521                     currentVersion = 150;
   3522                 }
   3523 
   3524                 if (currentVersion == 150) {
   3525                     // Version 151: Removed.
   3526                     currentVersion = 151;
   3527                 }
   3528 
   3529                 if (currentVersion == 151) {
   3530                     // Version 152: Removed. (This version made the setting for wifi_wakeup enabled
   3531                     // by default but it is now no longer configurable).
   3532                     // The setting updated here is deleted in 153.
   3533                     currentVersion = 152;
   3534                 }
   3535 
   3536                 if (currentVersion == 152) {
   3537                     getGlobalSettingsLocked().deleteSettingLocked("wifi_wakeup_available");
   3538                     currentVersion = 153;
   3539                 }
   3540 
   3541                 if (currentVersion == 153) {
   3542                     // Version 154: Read notification badge configuration from config.
   3543                     // If user has already set the value, don't do anything.
   3544                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
   3545                     final Setting showNotificationBadges = systemSecureSettings.getSettingLocked(
   3546                             Settings.Secure.NOTIFICATION_BADGING);
   3547                     if (showNotificationBadges.isNull()) {
   3548                         final boolean defaultValue = getContext().getResources().getBoolean(
   3549                                 com.android.internal.R.bool.config_notificationBadging);
   3550                         systemSecureSettings.insertSettingLocked(
   3551                                 Secure.NOTIFICATION_BADGING,
   3552                                 defaultValue ? "1" : "0",
   3553                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3554                     }
   3555                     currentVersion = 154;
   3556                 }
   3557 
   3558                 if (currentVersion == 154) {
   3559                     // Version 155: Set the default value for BACKUP_LOCAL_TRANSPORT_PARAMETERS.
   3560                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
   3561                     final String oldValue = systemSecureSettings.getSettingLocked(
   3562                             Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS).getValue();
   3563                     if (TextUtils.equals(null, oldValue)) {
   3564                         final String defaultValue = getContext().getResources().getString(
   3565                                 R.string.def_backup_local_transport_parameters);
   3566                         if (!TextUtils.isEmpty(defaultValue)) {
   3567                             systemSecureSettings.insertSettingLocked(
   3568                                     Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS, defaultValue,
   3569                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3570                         }
   3571 
   3572                     }
   3573                     currentVersion = 155;
   3574                 }
   3575 
   3576                 if (currentVersion == 155) {
   3577                     // Version 156: Set the default value for CHARGING_STARTED_SOUND.
   3578                     final SettingsState globalSettings = getGlobalSettingsLocked();
   3579                     final String oldValue = globalSettings.getSettingLocked(
   3580                             Global.CHARGING_STARTED_SOUND).getValue();
   3581                     final String oldDefault = getContext().getResources().getString(
   3582                             R.string.def_wireless_charging_started_sound);
   3583                     if (TextUtils.equals(null, oldValue)
   3584                             || TextUtils.equals(oldValue, oldDefault)) {
   3585                         final String defaultValue = getContext().getResources().getString(
   3586                                 R.string.def_charging_started_sound);
   3587                         if (!TextUtils.isEmpty(defaultValue)) {
   3588                             globalSettings.insertSettingLocked(
   3589                                     Settings.Global.CHARGING_STARTED_SOUND, defaultValue,
   3590                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3591                         }
   3592 
   3593                     }
   3594                     currentVersion = 156;
   3595                 }
   3596 
   3597                 if (currentVersion == 156) {
   3598                     // Version 157: Set a default value for zen duration
   3599                     final SettingsState globalSettings = getGlobalSettingsLocked();
   3600                     final Setting currentSetting = globalSettings.getSettingLocked(
   3601                             Global.ZEN_DURATION);
   3602                     if (currentSetting.isNull()) {
   3603                         String defaultZenDuration = Integer.toString(getContext()
   3604                                 .getResources().getInteger(R.integer.def_zen_duration));
   3605                         globalSettings.insertSettingLocked(
   3606                                 Global.ZEN_DURATION, defaultZenDuration,
   3607                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3608                     }
   3609                     currentVersion = 157;
   3610                 }
   3611 
   3612                 if (currentVersion == 157) {
   3613                     // Version 158: Set default value for BACKUP_AGENT_TIMEOUT_PARAMETERS.
   3614                     final SettingsState globalSettings = getGlobalSettingsLocked();
   3615                     final String oldValue = globalSettings.getSettingLocked(
   3616                             Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS).getValue();
   3617                     if (TextUtils.equals(null, oldValue)) {
   3618                         final String defaultValue = getContext().getResources().getString(
   3619                                 R.string.def_backup_agent_timeout_parameters);
   3620                         if (!TextUtils.isEmpty(defaultValue)) {
   3621                             globalSettings.insertSettingLocked(
   3622                                     Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS, defaultValue,
   3623                                     null, true,
   3624                                     SettingsState.SYSTEM_PACKAGE_NAME);
   3625                         }
   3626                     }
   3627                     currentVersion = 158;
   3628                 }
   3629 
   3630                 if (currentVersion == 158) {
   3631                     // Remove setting that specifies wifi bgscan throttling params
   3632                     getGlobalSettingsLocked().deleteSettingLocked(
   3633                         "wifi_scan_background_throttle_interval_ms");
   3634                     getGlobalSettingsLocked().deleteSettingLocked(
   3635                         "wifi_scan_background_throttle_package_whitelist");
   3636                     currentVersion = 159;
   3637                 }
   3638 
   3639                 if (currentVersion == 159) {
   3640                     // Version 160: Hiding notifications from the lockscreen is only available as
   3641                     // primary user option, profiles can only make them redacted. If a profile was
   3642                     // configured to not show lockscreen notifications, ensure that at the very
   3643                     // least these will be come hidden.
   3644                     if (mUserManager.isManagedProfile(userId)) {
   3645                         final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3646                         Setting showNotifications = secureSettings.getSettingLocked(
   3647                             Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
   3648                         // The default value is "1", check if user has turned it off.
   3649                         if ("0".equals(showNotifications.getValue())) {
   3650                             secureSettings.insertSettingLocked(
   3651                                 Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, "0",
   3652                                 null /* tag */, false /* makeDefault */,
   3653                                 SettingsState.SYSTEM_PACKAGE_NAME);
   3654                         }
   3655                         // The setting is no longer valid for managed profiles, it should be
   3656                         // treated as if it was set to "1".
   3657                         secureSettings.deleteSettingLocked(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
   3658                     }
   3659                     currentVersion = 160;
   3660                 }
   3661 
   3662                 if (currentVersion == 160) {
   3663                     // Version 161: Set the default value for
   3664                     // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY and
   3665                     // SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT
   3666                     final SettingsState globalSettings = getGlobalSettingsLocked();
   3667 
   3668                     String oldValue = globalSettings.getSettingLocked(
   3669                             Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY).getValue();
   3670                     if (TextUtils.equals(null, oldValue)) {
   3671                         globalSettings.insertSettingLocked(
   3672                                 Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
   3673                                 Integer.toString(getContext().getResources().getInteger(
   3674                                         R.integer.def_max_sound_trigger_detection_service_ops_per_day)),
   3675                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3676                     }
   3677 
   3678                     oldValue = globalSettings.getSettingLocked(
   3679                             Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT).getValue();
   3680                     if (TextUtils.equals(null, oldValue)) {
   3681                         globalSettings.insertSettingLocked(
   3682                                 Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT,
   3683                                 Integer.toString(getContext().getResources().getInteger(
   3684                                         R.integer.def_sound_trigger_detection_service_op_timeout)),
   3685                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3686                     }
   3687                     currentVersion = 161;
   3688                 }
   3689 
   3690                 if (currentVersion == 161) {
   3691                     // Version 161: Add a gesture for silencing phones
   3692                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3693                     final Setting currentSetting = secureSettings.getSettingLocked(
   3694                             Secure.VOLUME_HUSH_GESTURE);
   3695                     if (currentSetting.isNull()) {
   3696                         secureSettings.insertSettingLocked(
   3697                                 Secure.VOLUME_HUSH_GESTURE,
   3698                                 Integer.toString(Secure.VOLUME_HUSH_VIBRATE),
   3699                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3700                     }
   3701 
   3702                     currentVersion = 162;
   3703                 }
   3704 
   3705                 if (currentVersion == 162) {
   3706                     // Version 162: REMOVED: Add a gesture for silencing phones
   3707                     currentVersion = 163;
   3708                 }
   3709 
   3710                 if (currentVersion == 163) {
   3711                     // Version 163: Update default value of
   3712                     // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY from old to new default
   3713                     final SettingsState settings = getGlobalSettingsLocked();
   3714                     final Setting currentSetting = settings.getSettingLocked(
   3715                             Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY);
   3716                     if (currentSetting.isDefaultFromSystem()) {
   3717                         settings.insertSettingLocked(
   3718                                 Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
   3719                                 Integer.toString(getContext().getResources().getInteger(
   3720                                         R.integer
   3721                                         .def_max_sound_trigger_detection_service_ops_per_day)),
   3722                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3723                     }
   3724 
   3725                     currentVersion = 164;
   3726                 }
   3727 
   3728                 if (currentVersion == 164) {
   3729                     // Version 164: show zen upgrade notification
   3730                     final SettingsState settings = getGlobalSettingsLocked();
   3731                     final Setting currentSetting = settings.getSettingLocked(
   3732                             Global.SHOW_ZEN_UPGRADE_NOTIFICATION);
   3733                     if (!currentSetting.isNull()
   3734                             && TextUtils.equals("0", currentSetting.getValue())) {
   3735                         settings.insertSettingLocked(
   3736                                 Global.SHOW_ZEN_UPGRADE_NOTIFICATION, "1",
   3737                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3738                     }
   3739 
   3740                     currentVersion = 165;
   3741                 }
   3742 
   3743                 if (currentVersion == 165) {
   3744                     // Version 165: Show zen settings suggestion and zen updated
   3745                     final SettingsState settings = getGlobalSettingsLocked();
   3746                     final Setting currentSetting = settings.getSettingLocked(
   3747                             Global.SHOW_ZEN_SETTINGS_SUGGESTION);
   3748                     if (currentSetting.isNull()) {
   3749                         settings.insertSettingLocked(
   3750                                 Global.SHOW_ZEN_SETTINGS_SUGGESTION, "1",
   3751                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3752                     }
   3753 
   3754                     final Setting currentUpdatedSetting = settings.getSettingLocked(
   3755                             Global.ZEN_SETTINGS_UPDATED);
   3756                     if (currentUpdatedSetting.isNull()) {
   3757                         settings.insertSettingLocked(
   3758                                 Global.ZEN_SETTINGS_UPDATED, "0",
   3759                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3760                     }
   3761 
   3762                     final Setting currentSettingSuggestionViewed = settings.getSettingLocked(
   3763                             Global.ZEN_SETTINGS_SUGGESTION_VIEWED);
   3764                     if (currentSettingSuggestionViewed.isNull()) {
   3765                         settings.insertSettingLocked(
   3766                                 Global.ZEN_SETTINGS_SUGGESTION_VIEWED, "0",
   3767                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3768                     }
   3769 
   3770                     currentVersion = 166;
   3771                 }
   3772 
   3773                 if (currentVersion == 166) {
   3774                     // Version 166: add default values for hush gesture used and manual ringer
   3775                     // toggle
   3776                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
   3777                     Setting currentHushUsedSetting = secureSettings.getSettingLocked(
   3778                             Secure.HUSH_GESTURE_USED);
   3779                     if (currentHushUsedSetting.isNull()) {
   3780                         secureSettings.insertSettingLocked(
   3781                                 Settings.Secure.HUSH_GESTURE_USED, "0", null, true,
   3782                                 SettingsState.SYSTEM_PACKAGE_NAME);
   3783                     }
   3784 
   3785                     Setting currentRingerToggleCountSetting = secureSettings.getSettingLocked(
   3786                             Secure.MANUAL_RINGER_TOGGLE_COUNT);
   3787                     if (currentRingerToggleCountSetting.isNull()) {
   3788                         secureSettings.insertSettingLocked(
   3789                                 Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, "0", null, true,
   3790                                 SettingsState.SYSTEM_PACKAGE_NAME);
   3791                     }
   3792                     currentVersion = 167;
   3793                 }
   3794 
   3795                 if (currentVersion == 167) {
   3796                     // Version 167: by default, vibrate for wireless charging
   3797                     final SettingsState globalSettings = getGlobalSettingsLocked();
   3798                     final Setting currentSetting = globalSettings.getSettingLocked(
   3799                             Global.CHARGING_VIBRATION_ENABLED);
   3800                     if (currentSetting.isNull()) {
   3801                         globalSettings.insertSettingLocked(
   3802                                 Global.CHARGING_VIBRATION_ENABLED, "1",
   3803                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3804                     }
   3805                     currentVersion = 168;
   3806                 }
   3807 
   3808                 if (currentVersion == 168) {
   3809                     // Version 168: by default, vibrate for phone calls
   3810                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
   3811                     final Setting currentSetting = systemSettings.getSettingLocked(
   3812                             Settings.System.VIBRATE_WHEN_RINGING);
   3813                     if (currentSetting.isNull()) {
   3814                         systemSettings.insertSettingLocked(
   3815                                 Settings.System.VIBRATE_WHEN_RINGING,
   3816                                 getContext().getResources().getBoolean(
   3817                                         R.bool.def_vibrate_when_ringing) ? "1" : "0",
   3818                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
   3819                     }
   3820                     currentVersion = 169;
   3821                 }
   3822 
   3823                 // vXXX: Add new settings above this point.
   3824 
   3825                 if (currentVersion != newVersion) {
   3826                     Slog.wtf("SettingsProvider", "warning: upgrading settings database to version "
   3827                             + newVersion + " left it at "
   3828                             + currentVersion +
   3829                             " instead; this is probably a bug. Did you update SETTINGS_VERSION?",
   3830                             new Throwable());
   3831                     if (DEBUG) {
   3832                         throw new RuntimeException("db upgrade error");
   3833                     }
   3834                 }
   3835 
   3836                 // Return the current version.
   3837                 return currentVersion;
   3838             }
   3839         }
   3840 
   3841         private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings,
   3842                 int userId) {
   3843             List<String> names = settings.getSettingNamesLocked();
   3844             final int nameCount = names.size();
   3845             for (int i = 0; i < nameCount; i++) {
   3846                 String name = names.get(i);
   3847                 Setting setting = settings.getSettingLocked(name);
   3848 
   3849                 // In the upgrade case we pretend the call is made from the app
   3850                 // that made the last change to the setting to properly determine
   3851                 // whether the call has been made by a system component.
   3852                 int callingUid = -1;
   3853                 try {
   3854                     callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId);
   3855                 } catch (RemoteException e) {
   3856                     /* ignore - handled below */
   3857                 }
   3858                 if (callingUid < 0) {
   3859                     Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName());
   3860                     continue;
   3861                 }
   3862                 try {
   3863                     final boolean systemSet = SettingsState.isSystemPackage(getContext(),
   3864                             setting.getPackageName(), callingUid);
   3865                     if (systemSet) {
   3866                         settings.insertSettingLocked(name, setting.getValue(),
   3867                                 setting.getTag(), true, setting.getPackageName());
   3868                     } else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) {
   3869                         // We had a bug where changes by non-system packages were marked
   3870                         // as system made and as a result set as the default. Therefore, if
   3871                         // the package changed the setting last is not a system one but the
   3872                         // setting is marked as its default coming from the system we clear
   3873                         // the default and clear the system set flag.
   3874                         settings.resetSettingDefaultValueLocked(name);
   3875                     }
   3876                 } catch (IllegalStateException e) {
   3877                     // If the package goes over its quota during the upgrade, don't
   3878                     // crash but just log the error as the system does the upgrade.
   3879                     Slog.e(LOG_TAG, "Error upgrading setting: " + setting.getName(), e);
   3880 
   3881                 }
   3882             }
   3883         }
   3884     }
   3885 }
   3886