• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import static android.provider.Settings.Config.SYNC_DISABLED_MODE_NONE;
23 import static android.provider.Settings.Config.SYNC_DISABLED_MODE_PERSISTENT;
24 import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT;
25 import static android.provider.Settings.SET_ALL_RESULT_DISABLED;
26 import static android.provider.Settings.SET_ALL_RESULT_FAILURE;
27 import static android.provider.Settings.SET_ALL_RESULT_SUCCESS;
28 import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER;
29 import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
30 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
31 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
32 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
33 
34 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
35 import static com.android.providers.settings.SettingsState.FALLBACK_FILE_SUFFIX;
36 
37 import android.Manifest;
38 import android.annotation.NonNull;
39 import android.annotation.Nullable;
40 import android.app.ActivityManager;
41 import android.app.AppGlobals;
42 import android.app.backup.BackupManager;
43 import android.app.compat.CompatChanges;
44 import android.app.job.JobInfo;
45 import android.app.job.JobScheduler;
46 import android.compat.annotation.ChangeId;
47 import android.compat.annotation.EnabledSince;
48 import android.content.BroadcastReceiver;
49 import android.content.ComponentName;
50 import android.content.ContentProvider;
51 import android.content.ContentValues;
52 import android.content.Context;
53 import android.content.Intent;
54 import android.content.IntentFilter;
55 import android.content.om.IOverlayManager;
56 import android.content.om.OverlayInfo;
57 import android.content.pm.ApplicationInfo;
58 import android.content.pm.IPackageManager;
59 import android.content.pm.PackageInfo;
60 import android.content.pm.PackageManager;
61 import android.content.pm.UserInfo;
62 import android.content.res.Resources;
63 import android.database.Cursor;
64 import android.database.MatrixCursor;
65 import android.database.sqlite.SQLiteDatabase;
66 import android.database.sqlite.SQLiteQueryBuilder;
67 import android.hardware.camera2.utils.ArrayUtils;
68 import android.media.AudioManager;
69 import android.net.Uri;
70 import android.os.Binder;
71 import android.os.Build;
72 import android.os.Bundle;
73 import android.os.DropBoxManager;
74 import android.os.Environment;
75 import android.os.FileUtils;
76 import android.os.Handler;
77 import android.os.HandlerThread;
78 import android.os.IUserRestrictionsListener;
79 import android.os.Looper;
80 import android.os.Message;
81 import android.os.ParcelFileDescriptor;
82 import android.os.PersistableBundle;
83 import android.os.Process;
84 import android.os.RemoteCallback;
85 import android.os.RemoteException;
86 import android.os.SELinux;
87 import android.os.ServiceManager;
88 import android.os.UserHandle;
89 import android.os.UserManager;
90 import android.provider.DeviceConfig;
91 import android.provider.Settings;
92 import android.provider.Settings.Config.SyncDisabledMode;
93 import android.provider.Settings.Global;
94 import android.provider.Settings.Secure;
95 import android.provider.Settings.SetAllResult;
96 import android.provider.settings.validators.SystemSettingsValidators;
97 import android.provider.settings.validators.Validator;
98 import android.text.TextUtils;
99 import android.util.ArrayMap;
100 import android.util.ArraySet;
101 import android.util.Slog;
102 import android.util.SparseArray;
103 import android.util.SparseBooleanArray;
104 import android.util.proto.ProtoOutputStream;
105 
106 import com.android.internal.annotations.GuardedBy;
107 import com.android.internal.content.PackageMonitor;
108 import com.android.internal.os.BackgroundThread;
109 import com.android.providers.settings.SettingsState.Setting;
110 import com.android.server.SystemConfig;
111 
112 import com.google.android.collect.Sets;
113 
114 import libcore.util.HexEncoding;
115 
116 import java.io.File;
117 import java.io.FileDescriptor;
118 import java.io.FileNotFoundException;
119 import java.io.IOException;
120 import java.io.PrintWriter;
121 import java.nio.ByteBuffer;
122 import java.security.InvalidKeyException;
123 import java.security.NoSuchAlgorithmException;
124 import java.security.SecureRandom;
125 import java.util.ArrayList;
126 import java.util.Arrays;
127 import java.util.Collection;
128 import java.util.Collections;
129 import java.util.HashMap;
130 import java.util.HashSet;
131 import java.util.List;
132 import java.util.Map;
133 import java.util.Set;
134 import java.util.regex.Pattern;
135 
136 import javax.crypto.Mac;
137 import javax.crypto.spec.SecretKeySpec;
138 
139 
140 /**
141  * <p>
142  * This class is a content provider that publishes the system settings.
143  * It can be accessed via the content provider APIs or via custom call
144  * commands. The latter is a bit faster and is the preferred way to access
145  * the platform settings.
146  * </p>
147  * <p>
148  * There are three settings types, global (with signature level protection
149  * and shared across users), secure (with signature permission level
150  * protection and per user), and system (with dangerous permission level
151  * protection and per user). Global settings are stored under the device owner.
152  * Each of these settings is represented by a {@link
153  * com.android.providers.settings.SettingsState} object mapped to an integer
154  * key derived from the setting type in the most significant bits and user
155  * id in the least significant bits. Settings are synchronously loaded on
156  * instantiation of a SettingsState and asynchronously persisted on mutation.
157  * Settings are stored in the user specific system directory.
158  * </p>
159  * <p>
160  * Apps targeting APIs Lollipop MR1 and lower can add custom settings entries
161  * and get a warning. Targeting higher API version prohibits this as the
162  * system settings are not a place for apps to save their state. When a package
163  * is removed the settings it added are deleted. Apps cannot delete system
164  * settings added by the platform. System settings values are validated to
165  * ensure the clients do not put bad values. Global and secure settings are
166  * changed only by trusted parties, therefore no validation is performed. Also
167  * there is a limit on the amount of app specific settings that can be added
168  * to prevent unlimited growth of the system process memory footprint.
169  * </p>
170  */
171 @SuppressWarnings("deprecation")
172 public class SettingsProvider extends ContentProvider {
173     static final boolean DEBUG = false;
174 
175     private static final boolean DROP_DATABASE_ON_MIGRATION = true;
176 
177     private static final String LOG_TAG = "SettingsProvider";
178 
179     public static final String TABLE_SYSTEM = "system";
180     public static final String TABLE_SECURE = "secure";
181     public static final String TABLE_GLOBAL = "global";
182     public static final String TABLE_SSAID = "ssaid";
183     public static final String TABLE_CONFIG = "config";
184 
185     // Old tables no longer exist.
186     private static final String TABLE_FAVORITES = "favorites";
187     private static final String TABLE_OLD_FAVORITES = "old_favorites";
188     private static final String TABLE_BLUETOOTH_DEVICES = "bluetooth_devices";
189     private static final String TABLE_BOOKMARKS = "bookmarks";
190     private static final String TABLE_ANDROID_METADATA = "android_metadata";
191 
192     // The set of removed legacy tables.
193     private static final Set<String> REMOVED_LEGACY_TABLES = new ArraySet<>();
194     static {
195         REMOVED_LEGACY_TABLES.add(TABLE_FAVORITES);
196         REMOVED_LEGACY_TABLES.add(TABLE_OLD_FAVORITES);
197         REMOVED_LEGACY_TABLES.add(TABLE_BLUETOOTH_DEVICES);
198         REMOVED_LEGACY_TABLES.add(TABLE_BOOKMARKS);
199         REMOVED_LEGACY_TABLES.add(TABLE_ANDROID_METADATA);
200     }
201 
202     private static final int MUTATION_OPERATION_INSERT = 1;
203     private static final int MUTATION_OPERATION_DELETE = 2;
204     private static final int MUTATION_OPERATION_UPDATE = 3;
205     private static final int MUTATION_OPERATION_RESET = 4;
206 
207     private static final String[] LEGACY_SQL_COLUMNS = new String[] {
208             Settings.NameValueTable._ID,
209             Settings.NameValueTable.NAME,
210             Settings.NameValueTable.VALUE,
211     };
212 
213     private static final String[] ALL_COLUMNS = new String[] {
214             Settings.NameValueTable._ID,
215             Settings.NameValueTable.NAME,
216             Settings.NameValueTable.VALUE,
217             Settings.NameValueTable.IS_PRESERVED_IN_RESTORE,
218     };
219 
220     public static final int SETTINGS_TYPE_GLOBAL = SettingsState.SETTINGS_TYPE_GLOBAL;
221     public static final int SETTINGS_TYPE_SYSTEM = SettingsState.SETTINGS_TYPE_SYSTEM;
222     public static final int SETTINGS_TYPE_SECURE = SettingsState.SETTINGS_TYPE_SECURE;
223     public static final int SETTINGS_TYPE_SSAID = SettingsState.SETTINGS_TYPE_SSAID;
224     public static final int SETTINGS_TYPE_CONFIG = SettingsState.SETTINGS_TYPE_CONFIG;
225 
226     private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair(
227             Settings.NameValueTable.VALUE, null);
228 
229     public static final String RESULT_ROWS_DELETED = "result_rows_deleted";
230     public static final String RESULT_SETTINGS_LIST = "result_settings_list";
231 
232     // Used for scheduling jobs to make a copy for the settings files
233     public static final int WRITE_FALLBACK_SETTINGS_FILES_JOB_ID = 1;
234     public static final long ONE_DAY_INTERVAL_MILLIS = 24 * 60 * 60 * 1000L;
235 
236     // Overlay specified settings whitelisted for Instant Apps
237     private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>();
238     private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
239     private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>();
240 
241     static {
242         for (String name : Resources.getSystem().getStringArray(
243                 com.android.internal.R.array.config_allowedGlobalInstantAppSettings)) {
244             OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS.add(name);
245         }
246         for (String name : Resources.getSystem().getStringArray(
247                 com.android.internal.R.array.config_allowedSystemInstantAppSettings)) {
248             OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS.add(name);
249         }
250         for (String name : Resources.getSystem().getStringArray(
251                 com.android.internal.R.array.config_allowedSecureInstantAppSettings)) {
252             OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS.add(name);
253         }
254     }
255 
256     // Changes to these global settings are synchronously persisted
257     private static final Set<String> CRITICAL_GLOBAL_SETTINGS = new ArraySet<>();
258     static {
259         CRITICAL_GLOBAL_SETTINGS.add(Settings.Global.DEVICE_PROVISIONED);
260     }
261 
262     // Changes to these secure settings are synchronously persisted
263     private static final Set<String> CRITICAL_SECURE_SETTINGS = new ArraySet<>();
264     static {
265         CRITICAL_SECURE_SETTINGS.add(Settings.Secure.USER_SETUP_COMPLETE);
266     }
267 
268     // Per user secure settings that moved to the for all users global settings.
269     static final Set<String> sSecureMovedToGlobalSettings = new ArraySet<>();
270     static {
271         Settings.Secure.getMovedToGlobalSettings(sSecureMovedToGlobalSettings);
272     }
273 
274     // Per user system settings that moved to the for all users global settings.
275     static final Set<String> sSystemMovedToGlobalSettings = new ArraySet<>();
276     static {
277         Settings.System.getMovedToGlobalSettings(sSystemMovedToGlobalSettings);
278     }
279 
280     // Per user system settings that moved to the per user secure settings.
281     static final Set<String> sSystemMovedToSecureSettings = new ArraySet<>();
282     static {
283         Settings.System.getMovedToSecureSettings(sSystemMovedToSecureSettings);
284     }
285 
286     // Per all users global settings that moved to the per user secure settings.
287     static final Set<String> sGlobalMovedToSecureSettings = new ArraySet<>();
288     static {
289         Settings.Global.getMovedToSecureSettings(sGlobalMovedToSecureSettings);
290     }
291 
292     // Per user secure settings that are cloned for the managed profiles of the user.
293     private static final Set<String> sSecureCloneToManagedSettings = new ArraySet<>();
294     static {
295         Settings.Secure.getCloneToManagedProfileSettings(sSecureCloneToManagedSettings);
296     }
297 
298     // Per user system settings that are cloned for the managed profiles of the user.
299     private static final Set<String> sSystemCloneToManagedSettings = new ArraySet<>();
300     static {
301         Settings.System.getCloneToManagedProfileSettings(sSystemCloneToManagedSettings);
302     }
303 
304     // Per user system settings that are cloned from the profile's parent when a dependency
305     // in {@link Settings.Secure} is set to "1".
306     public static final Map<String, String> sSystemCloneFromParentOnDependency = new ArrayMap<>();
307     static {
308         Settings.System.getCloneFromParentOnValueSettings(sSystemCloneFromParentOnDependency);
309     }
310 
311     private static final Set<String> sAllSecureSettings = new ArraySet<>();
312     private static final Set<String> sReadableSecureSettings = new ArraySet<>();
313     private static final ArrayMap<String, Integer> sReadableSecureSettingsWithMaxTargetSdk =
314             new ArrayMap<>();
315     static {
Settings.Secure.getPublicSettings(sAllSecureSettings, sReadableSecureSettings, sReadableSecureSettingsWithMaxTargetSdk)316         Settings.Secure.getPublicSettings(sAllSecureSettings, sReadableSecureSettings,
317                 sReadableSecureSettingsWithMaxTargetSdk);
318     }
319 
320     private static final Set<String> sAllSystemSettings = new ArraySet<>();
321     private static final Set<String> sReadableSystemSettings = new ArraySet<>();
322     private static final ArrayMap<String, Integer> sReadableSystemSettingsWithMaxTargetSdk =
323             new ArrayMap<>();
324     static {
Settings.System.getPublicSettings(sAllSystemSettings, sReadableSystemSettings, sReadableSystemSettingsWithMaxTargetSdk)325         Settings.System.getPublicSettings(sAllSystemSettings, sReadableSystemSettings,
326                 sReadableSystemSettingsWithMaxTargetSdk);
327     }
328 
329     private static final Set<String> sAllGlobalSettings = new ArraySet<>();
330     private static final Set<String> sReadableGlobalSettings = new ArraySet<>();
331     private static final ArrayMap<String, Integer> sReadableGlobalSettingsWithMaxTargetSdk =
332             new ArrayMap<>();
333     static {
Settings.Global.getPublicSettings(sAllGlobalSettings, sReadableGlobalSettings, sReadableGlobalSettingsWithMaxTargetSdk)334         Settings.Global.getPublicSettings(sAllGlobalSettings, sReadableGlobalSettings,
335                 sReadableGlobalSettingsWithMaxTargetSdk);
336     }
337 
338     private final Object mLock = new Object();
339 
340     @GuardedBy("mLock")
341     private RemoteCallback mConfigMonitorCallback;
342 
343     @GuardedBy("mLock")
344     private SettingsRegistry mSettingsRegistry;
345 
346     @GuardedBy("mLock")
347     private HandlerThread mHandlerThread;
348 
349     @GuardedBy("mLock")
350     private Handler mHandler;
351 
352     // We have to call in the user manager with no lock held,
353     private volatile UserManager mUserManager;
354 
355     // We have to call in the package manager with no lock held,
356     private volatile IPackageManager mPackageManager;
357 
358     @GuardedBy("mLock")
359     private boolean mSyncConfigDisabledUntilReboot;
360 
makeKey(int type, int userId)361     public static int makeKey(int type, int userId) {
362         return SettingsState.makeKey(type, userId);
363     }
364 
getTypeFromKey(int key)365     public static int getTypeFromKey(int key) {
366         return SettingsState.getTypeFromKey(key);
367     }
368 
getUserIdFromKey(int key)369     public static int getUserIdFromKey(int key) {
370         return SettingsState.getUserIdFromKey(key);
371     }
372 
keyToString(int key)373     public static String keyToString(int key) {
374         return SettingsState.keyToString(key);
375     }
376     @ChangeId
377     @EnabledSince(targetSdkVersion=android.os.Build.VERSION_CODES.S)
378     private static final long ENFORCE_READ_PERMISSION_FOR_MULTI_SIM_DATA_CALL = 172670679L;
379 
380     @Override
onCreate()381     public boolean onCreate() {
382         Settings.setInSystemServer();
383 
384         synchronized (mLock) {
385             mUserManager = UserManager.get(getContext());
386             mPackageManager = AppGlobals.getPackageManager();
387             mHandlerThread = new HandlerThread(LOG_TAG,
388                     Process.THREAD_PRIORITY_BACKGROUND);
389             mHandlerThread.start();
390             mHandler = new Handler(mHandlerThread.getLooper());
391             mSettingsRegistry = new SettingsRegistry();
392         }
393         SettingsState.cacheSystemPackageNamesAndSystemSignature(getContext());
394         synchronized (mLock) {
395             mSettingsRegistry.migrateAllLegacySettingsIfNeededLocked();
396             mSettingsRegistry.syncSsaidTableOnStartLocked();
397         }
398         mHandler.post(() -> {
399             registerBroadcastReceivers();
400             startWatchingUserRestrictionChanges();
401         });
402         ServiceManager.addService("settings", new SettingsService(this));
403         ServiceManager.addService("device_config", new DeviceConfigService(this));
404         return true;
405     }
406 
407     @Override
call(String method, String name, Bundle args)408     public Bundle call(String method, String name, Bundle args) {
409         final int requestingUserId = getRequestingUserId(args);
410         switch (method) {
411             case Settings.CALL_METHOD_GET_CONFIG: {
412                 Setting setting = getConfigSetting(name);
413                 return packageValueForCallResult(setting, isTrackingGeneration(args));
414             }
415 
416             case Settings.CALL_METHOD_GET_GLOBAL: {
417                 Setting setting = getGlobalSetting(name);
418                 return packageValueForCallResult(setting, isTrackingGeneration(args));
419             }
420 
421             case Settings.CALL_METHOD_GET_SECURE: {
422                 Setting setting = getSecureSetting(name, requestingUserId);
423                 return packageValueForCallResult(setting, isTrackingGeneration(args));
424             }
425 
426             case Settings.CALL_METHOD_GET_SYSTEM: {
427                 Setting setting = getSystemSetting(name, requestingUserId);
428                 return packageValueForCallResult(setting, isTrackingGeneration(args));
429             }
430 
431             case Settings.CALL_METHOD_PUT_CONFIG: {
432                 String value = getSettingValue(args);
433                 final boolean makeDefault = getSettingMakeDefault(args);
434                 insertConfigSetting(name, value, makeDefault);
435                 break;
436             }
437 
438             case Settings.CALL_METHOD_PUT_GLOBAL: {
439                 String value = getSettingValue(args);
440                 String tag = getSettingTag(args);
441                 final boolean makeDefault = getSettingMakeDefault(args);
442                 final boolean overrideableByRestore = getSettingOverrideableByRestore(args);
443                 insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false,
444                         overrideableByRestore);
445                 break;
446             }
447 
448             case Settings.CALL_METHOD_PUT_SECURE: {
449                 String value = getSettingValue(args);
450                 String tag = getSettingTag(args);
451                 final boolean makeDefault = getSettingMakeDefault(args);
452                 final boolean overrideableByRestore = getSettingOverrideableByRestore(args);
453                 insertSecureSetting(name, value, tag, makeDefault, requestingUserId, false,
454                         overrideableByRestore);
455                 break;
456             }
457 
458             case Settings.CALL_METHOD_PUT_SYSTEM: {
459                 String value = getSettingValue(args);
460                 boolean overrideableByRestore = getSettingOverrideableByRestore(args);
461                 insertSystemSetting(name, value, requestingUserId, overrideableByRestore);
462                 break;
463             }
464 
465             case Settings.CALL_METHOD_SET_ALL_CONFIG: {
466                 String prefix = getSettingPrefix(args);
467                 Map<String, String> flags = getSettingFlags(args);
468                 Bundle result = new Bundle();
469                 result.putInt(Settings.KEY_CONFIG_SET_ALL_RETURN,
470                         setAllConfigSettings(prefix, flags));
471                 return result;
472             }
473 
474             case Settings.CALL_METHOD_SET_SYNC_DISABLED_CONFIG: {
475                 final int mode = getSyncDisabledMode(args);
476                 setSyncDisabledConfig(mode);
477                 break;
478             }
479 
480             case Settings.CALL_METHOD_IS_SYNC_DISABLED_CONFIG: {
481                 Bundle result = new Bundle();
482                 result.putBoolean(Settings.KEY_CONFIG_IS_SYNC_DISABLED_RETURN,
483                         isSyncDisabledConfig());
484                 return result;
485             }
486 
487             case Settings.CALL_METHOD_RESET_CONFIG: {
488                 final int mode = getResetModeEnforcingPermission(args);
489                 String prefix = getSettingPrefix(args);
490                 resetConfigSetting(mode, prefix);
491                 break;
492             }
493 
494             case Settings.CALL_METHOD_RESET_GLOBAL: {
495                 final int mode = getResetModeEnforcingPermission(args);
496                 String tag = getSettingTag(args);
497                 resetGlobalSetting(requestingUserId, mode, tag);
498                 break;
499             }
500 
501             case Settings.CALL_METHOD_RESET_SECURE: {
502                 final int mode = getResetModeEnforcingPermission(args);
503                 String tag = getSettingTag(args);
504                 resetSecureSetting(requestingUserId, mode, tag);
505                 break;
506             }
507 
508             case Settings.CALL_METHOD_DELETE_CONFIG: {
509                 int rows  = deleteConfigSetting(name) ? 1 : 0;
510                 Bundle result = new Bundle();
511                 result.putInt(RESULT_ROWS_DELETED, rows);
512                 return result;
513             }
514 
515             case Settings.CALL_METHOD_DELETE_GLOBAL: {
516                 int rows = deleteGlobalSetting(name, requestingUserId, false) ? 1 : 0;
517                 Bundle result = new Bundle();
518                 result.putInt(RESULT_ROWS_DELETED, rows);
519                 return result;
520             }
521 
522             case Settings.CALL_METHOD_DELETE_SECURE: {
523                 int rows = deleteSecureSetting(name, requestingUserId, false) ? 1 : 0;
524                 Bundle result = new Bundle();
525                 result.putInt(RESULT_ROWS_DELETED, rows);
526                 return result;
527             }
528 
529             case Settings.CALL_METHOD_DELETE_SYSTEM: {
530                 int rows = deleteSystemSetting(name, requestingUserId) ? 1 : 0;
531                 Bundle result = new Bundle();
532                 result.putInt(RESULT_ROWS_DELETED, rows);
533                 return result;
534             }
535 
536             case Settings.CALL_METHOD_LIST_CONFIG: {
537                 String prefix = getSettingPrefix(args);
538                 Bundle result = packageValuesForCallResult(getAllConfigFlags(prefix),
539                         isTrackingGeneration(args));
540                 reportDeviceConfigAccess(prefix);
541                 return result;
542             }
543 
544             case Settings.CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG: {
545                 RemoteCallback callback = args.getParcelable(
546                         Settings.CALL_METHOD_MONITOR_CALLBACK_KEY);
547                 setMonitorCallback(callback);
548                 break;
549             }
550 
551             case Settings.CALL_METHOD_LIST_GLOBAL: {
552                 Bundle result = new Bundle();
553                 result.putStringArrayList(RESULT_SETTINGS_LIST,
554                         buildSettingsList(getAllGlobalSettings(null)));
555                 return result;
556             }
557 
558             case Settings.CALL_METHOD_LIST_SECURE: {
559                 Bundle result = new Bundle();
560                 result.putStringArrayList(RESULT_SETTINGS_LIST,
561                         buildSettingsList(getAllSecureSettings(requestingUserId, null)));
562                 return result;
563             }
564 
565             case Settings.CALL_METHOD_LIST_SYSTEM: {
566                 Bundle result = new Bundle();
567                 result.putStringArrayList(RESULT_SETTINGS_LIST,
568                         buildSettingsList(getAllSystemSettings(requestingUserId, null)));
569                 return result;
570             }
571 
572             default: {
573                 Slog.w(LOG_TAG, "call() with invalid method: " + method);
574             } break;
575         }
576 
577         return null;
578     }
579 
580     @Override
getType(Uri uri)581     public String getType(Uri uri) {
582         Arguments args = new Arguments(uri, null, null, true);
583         if (TextUtils.isEmpty(args.name)) {
584             return "vnd.android.cursor.dir/" + args.table;
585         } else {
586             return "vnd.android.cursor.item/" + args.table;
587         }
588     }
589 
590     @Override
query(Uri uri, String[] projection, String where, String[] whereArgs, String order)591     public Cursor query(Uri uri, String[] projection, String where, String[] whereArgs,
592             String order) {
593         if (DEBUG) {
594             Slog.v(LOG_TAG, "query() for user: " + UserHandle.getCallingUserId());
595         }
596 
597         Arguments args = new Arguments(uri, where, whereArgs, true);
598         String[] normalizedProjection = normalizeProjection(projection);
599 
600         // If a legacy table that is gone, done.
601         if (REMOVED_LEGACY_TABLES.contains(args.table)) {
602             return new MatrixCursor(normalizedProjection, 0);
603         }
604 
605         switch (args.table) {
606             case TABLE_GLOBAL: {
607                 if (args.name != null) {
608                     Setting setting = getGlobalSetting(args.name);
609                     return packageSettingForQuery(setting, normalizedProjection);
610                 } else {
611                     return getAllGlobalSettings(projection);
612                 }
613             }
614 
615             case TABLE_SECURE: {
616                 final int userId = UserHandle.getCallingUserId();
617                 if (args.name != null) {
618                     Setting setting = getSecureSetting(args.name, userId);
619                     return packageSettingForQuery(setting, normalizedProjection);
620                 } else {
621                     return getAllSecureSettings(userId, projection);
622                 }
623             }
624 
625             case TABLE_SYSTEM: {
626                 final int userId = UserHandle.getCallingUserId();
627                 if (args.name != null) {
628                     Setting setting = getSystemSetting(args.name, userId);
629                     return packageSettingForQuery(setting, normalizedProjection);
630                 } else {
631                     return getAllSystemSettings(userId, projection);
632                 }
633             }
634 
635             default: {
636                 throw new IllegalArgumentException("Invalid Uri path:" + uri);
637             }
638         }
639     }
640 
buildSettingsList(Cursor cursor)641     private ArrayList<String> buildSettingsList(Cursor cursor) {
642         final ArrayList<String> lines = new ArrayList<>();
643         try {
644             while (cursor != null && cursor.moveToNext()) {
645                 lines.add(cursor.getString(1) + "=" + cursor.getString(2));
646             }
647         } finally {
648             if (cursor != null) {
649                 cursor.close();
650             }
651         }
652         return lines;
653     }
654 
655     @Override
insert(Uri uri, ContentValues values)656     public Uri insert(Uri uri, ContentValues values) {
657         if (DEBUG) {
658             Slog.v(LOG_TAG, "insert() for user: " + UserHandle.getCallingUserId());
659         }
660 
661         String table = getValidTableOrThrow(uri);
662 
663         // If a legacy table that is gone, done.
664         if (REMOVED_LEGACY_TABLES.contains(table)) {
665             return null;
666         }
667 
668         String name = values.getAsString(Settings.Secure.NAME);
669         if (!isKeyValid(name)) {
670             return null;
671         }
672 
673         String value = values.getAsString(Settings.Secure.VALUE);
674 
675         switch (table) {
676             case TABLE_GLOBAL: {
677                 if (insertGlobalSetting(name, value, null, false,
678                         UserHandle.getCallingUserId(), false,
679                         /* overrideableByRestore */ false)) {
680                     return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
681                 }
682             } break;
683 
684             case TABLE_SECURE: {
685                 if (insertSecureSetting(name, value, null, false,
686                         UserHandle.getCallingUserId(), false,
687                         /* overrideableByRestore */ false)) {
688                     return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
689                 }
690             } break;
691 
692             case TABLE_SYSTEM: {
693                 if (insertSystemSetting(name, value, UserHandle.getCallingUserId(),
694                         /* overridableByRestore */ false)) {
695                     return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
696                 }
697             } break;
698 
699             default: {
700                 throw new IllegalArgumentException("Bad Uri path:" + uri);
701             }
702         }
703 
704         return null;
705     }
706 
707     @Override
bulkInsert(Uri uri, ContentValues[] allValues)708     public int bulkInsert(Uri uri, ContentValues[] allValues) {
709         if (DEBUG) {
710             Slog.v(LOG_TAG, "bulkInsert() for user: " + UserHandle.getCallingUserId());
711         }
712 
713         int insertionCount = 0;
714         final int valuesCount = allValues.length;
715         for (int i = 0; i < valuesCount; i++) {
716             ContentValues values = allValues[i];
717             if (insert(uri, values) != null) {
718                 insertionCount++;
719             }
720         }
721 
722         return insertionCount;
723     }
724 
725     @Override
delete(Uri uri, String where, String[] whereArgs)726     public int delete(Uri uri, String where, String[] whereArgs) {
727         if (DEBUG) {
728             Slog.v(LOG_TAG, "delete() for user: " + UserHandle.getCallingUserId());
729         }
730 
731         Arguments args = new Arguments(uri, where, whereArgs, false);
732 
733         // If a legacy table that is gone, done.
734         if (REMOVED_LEGACY_TABLES.contains(args.table)) {
735             return 0;
736         }
737 
738         if (!isKeyValid(args.name)) {
739             return 0;
740         }
741 
742         switch (args.table) {
743             case TABLE_GLOBAL: {
744                 final int userId = UserHandle.getCallingUserId();
745                 return deleteGlobalSetting(args.name, userId, false) ? 1 : 0;
746             }
747 
748             case TABLE_SECURE: {
749                 final int userId = UserHandle.getCallingUserId();
750                 return deleteSecureSetting(args.name, userId, false) ? 1 : 0;
751             }
752 
753             case TABLE_SYSTEM: {
754                 final int userId = UserHandle.getCallingUserId();
755                 return deleteSystemSetting(args.name, userId) ? 1 : 0;
756             }
757 
758             default: {
759                 throw new IllegalArgumentException("Bad Uri path:" + uri);
760             }
761         }
762     }
763 
764     @Override
update(Uri uri, ContentValues values, String where, String[] whereArgs)765     public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
766         if (DEBUG) {
767             Slog.v(LOG_TAG, "update() for user: " + UserHandle.getCallingUserId());
768         }
769 
770         Arguments args = new Arguments(uri, where, whereArgs, false);
771 
772         // If a legacy table that is gone, done.
773         if (REMOVED_LEGACY_TABLES.contains(args.table)) {
774             return 0;
775         }
776 
777         String name = values.getAsString(Settings.Secure.NAME);
778         if (!isKeyValid(name)) {
779             return 0;
780         }
781         String value = values.getAsString(Settings.Secure.VALUE);
782 
783         switch (args.table) {
784             case TABLE_GLOBAL: {
785                 final int userId = UserHandle.getCallingUserId();
786                 return updateGlobalSetting(args.name, value, null, false,
787                         userId, false) ? 1 : 0;
788             }
789 
790             case TABLE_SECURE: {
791                 final int userId = UserHandle.getCallingUserId();
792                 return updateSecureSetting(args.name, value, null, false,
793                         userId, false) ? 1 : 0;
794             }
795 
796             case TABLE_SYSTEM: {
797                 final int userId = UserHandle.getCallingUserId();
798                 return updateSystemSetting(args.name, value, userId) ? 1 : 0;
799             }
800 
801             default: {
802                 throw new IllegalArgumentException("Invalid Uri path:" + uri);
803             }
804         }
805     }
806 
807     @Override
openFile(Uri uri, String mode)808     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
809         final int userId = getUserIdFromUri(uri, UserHandle.getCallingUserId());
810         if (userId != UserHandle.getCallingUserId()) {
811             getContext().enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS,
812                     "Access files from the settings of another user");
813         }
814         uri = ContentProvider.getUriWithoutUserId(uri);
815 
816         final String cacheRingtoneSetting;
817         final String cacheName;
818         if (Settings.System.RINGTONE_CACHE_URI.equals(uri)) {
819             cacheRingtoneSetting = Settings.System.RINGTONE;
820             cacheName = Settings.System.RINGTONE_CACHE;
821         } else if (Settings.System.NOTIFICATION_SOUND_CACHE_URI.equals(uri)) {
822             cacheRingtoneSetting = Settings.System.NOTIFICATION_SOUND;
823             cacheName = Settings.System.NOTIFICATION_SOUND_CACHE;
824         } else if (Settings.System.ALARM_ALERT_CACHE_URI.equals(uri)) {
825             cacheRingtoneSetting = Settings.System.ALARM_ALERT;
826             cacheName = Settings.System.ALARM_ALERT_CACHE;
827         } else {
828             throw new FileNotFoundException("Direct file access no longer supported; "
829                     + "ringtone playback is available through android.media.Ringtone");
830         }
831 
832         int actualCacheOwner;
833         // Redirect cache to parent if ringtone setting is owned by profile parent
834         synchronized (mLock) {
835             actualCacheOwner = resolveOwningUserIdForSystemSettingLocked(userId,
836                     cacheRingtoneSetting);
837         }
838         final File cacheFile = new File(getRingtoneCacheDir(actualCacheOwner), cacheName);
839         return ParcelFileDescriptor.open(cacheFile, ParcelFileDescriptor.parseMode(mode));
840     }
841 
getRingtoneCacheDir(int userId)842     private File getRingtoneCacheDir(int userId) {
843         final File cacheDir = new File(Environment.getDataSystemDeDirectory(userId), "ringtones");
844         cacheDir.mkdir();
845         SELinux.restorecon(cacheDir);
846         return cacheDir;
847     }
848 
849     /**
850      * Dump all settings as a proto buf.
851      *
852      * @param fd The file to dump to
853      */
dumpProto(@onNull FileDescriptor fd)854     void dumpProto(@NonNull FileDescriptor fd) {
855         ProtoOutputStream proto = new ProtoOutputStream(fd);
856 
857         synchronized (mLock) {
858             SettingsProtoDumpUtil.dumpProtoLocked(mSettingsRegistry, proto);
859         }
860 
861         proto.flush();
862     }
863 
dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args)864     public void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) {
865         synchronized (mLock) {
866             final long identity = Binder.clearCallingIdentity();
867             try {
868                 SparseBooleanArray users = mSettingsRegistry.getKnownUsersLocked();
869                 final int userCount = users.size();
870                 for (int i = 0; i < userCount; i++) {
871                     dumpForUserLocked(users.keyAt(i), pw);
872                 }
873             } finally {
874                 Binder.restoreCallingIdentity(identity);
875             }
876         }
877     }
878 
879     @GuardedBy("mLock")
dumpForUserLocked(int userId, PrintWriter pw)880     private void dumpForUserLocked(int userId, PrintWriter pw) {
881         if (userId == UserHandle.USER_SYSTEM) {
882             pw.println("CONFIG SETTINGS (user " + userId + ")");
883             SettingsState configSettings = mSettingsRegistry.getSettingsLocked(
884                     SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
885             if (configSettings != null) {
886                 dumpSettingsLocked(configSettings, pw);
887                 pw.println();
888                 configSettings.dumpHistoricalOperations(pw);
889             }
890 
891             pw.println("GLOBAL SETTINGS (user " + userId + ")");
892             SettingsState globalSettings = mSettingsRegistry.getSettingsLocked(
893                     SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
894             if (globalSettings != null) {
895                 dumpSettingsLocked(globalSettings, pw);
896                 pw.println();
897                 globalSettings.dumpHistoricalOperations(pw);
898             }
899         }
900 
901         pw.println("SECURE SETTINGS (user " + userId + ")");
902         SettingsState secureSettings = mSettingsRegistry.getSettingsLocked(
903                 SETTINGS_TYPE_SECURE, userId);
904         if (secureSettings != null) {
905             dumpSettingsLocked(secureSettings, pw);
906             pw.println();
907             secureSettings.dumpHistoricalOperations(pw);
908         }
909 
910         pw.println("SYSTEM SETTINGS (user " + userId + ")");
911         SettingsState systemSettings = mSettingsRegistry.getSettingsLocked(
912                 SETTINGS_TYPE_SYSTEM, userId);
913         if (systemSettings != null) {
914             dumpSettingsLocked(systemSettings, pw);
915             pw.println();
916             systemSettings.dumpHistoricalOperations(pw);
917         }
918     }
919 
dumpSettingsLocked(SettingsState settingsState, PrintWriter pw)920     private void dumpSettingsLocked(SettingsState settingsState, PrintWriter pw) {
921         List<String> names = settingsState.getSettingNamesLocked();
922 
923         final int nameCount = names.size();
924 
925         for (int i = 0; i < nameCount; i++) {
926             String name = names.get(i);
927             Setting setting = settingsState.getSettingLocked(name);
928             pw.print("_id:"); pw.print(toDumpString(setting.getId()));
929             pw.print(" name:"); pw.print(toDumpString(name));
930             if (setting.getPackageName() != null) {
931                 pw.print(" pkg:"); pw.print(setting.getPackageName());
932             }
933             pw.print(" value:"); pw.print(toDumpString(setting.getValue()));
934             if (setting.getDefaultValue() != null) {
935                 pw.print(" default:"); pw.print(setting.getDefaultValue());
936                 pw.print(" defaultSystemSet:"); pw.print(setting.isDefaultFromSystem());
937             }
938             if (setting.getTag() != null) {
939                 pw.print(" tag:"); pw.print(setting.getTag());
940             }
941             pw.println();
942         }
943     }
944 
toDumpString(String s)945     private static String toDumpString(String s) {
946         if (s != null) {
947             return s;
948         }
949         return "{null}";
950     }
951 
registerBroadcastReceivers()952     private void registerBroadcastReceivers() {
953         IntentFilter userFilter = new IntentFilter();
954         userFilter.addAction(Intent.ACTION_USER_REMOVED);
955         userFilter.addAction(Intent.ACTION_USER_STOPPED);
956 
957         getContext().registerReceiver(new BroadcastReceiver() {
958             @Override
959             public void onReceive(Context context, Intent intent) {
960                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
961                         UserHandle.USER_SYSTEM);
962 
963                 switch (intent.getAction()) {
964                     case Intent.ACTION_USER_REMOVED: {
965                         synchronized (mLock) {
966                             mSettingsRegistry.removeUserStateLocked(userId, true);
967                         }
968                     } break;
969 
970                     case Intent.ACTION_USER_STOPPED: {
971                         synchronized (mLock) {
972                             mSettingsRegistry.removeUserStateLocked(userId, false);
973                         }
974                     } break;
975                 }
976             }
977         }, userFilter);
978 
979         PackageMonitor monitor = new PackageMonitor() {
980             @Override
981             public void onPackageRemoved(String packageName, int uid) {
982                 synchronized (mLock) {
983                     mSettingsRegistry.removeSettingsForPackageLocked(packageName,
984                             UserHandle.getUserId(uid));
985                 }
986             }
987 
988             @Override
989             public void onUidRemoved(int uid) {
990                 synchronized (mLock) {
991                     mSettingsRegistry.onUidRemovedLocked(uid);
992                 }
993             }
994 
995             @Override
996             public void onPackageDataCleared(String packageName, int uid) {
997                 synchronized (mLock) {
998                     mSettingsRegistry.removeSettingsForPackageLocked(packageName,
999                             UserHandle.getUserId(uid));
1000                 }
1001             }
1002         };
1003 
1004         // package changes
1005         monitor.register(getContext(), BackgroundThread.getHandler().getLooper(),
1006                 UserHandle.ALL, true);
1007     }
1008 
startWatchingUserRestrictionChanges()1009     private void startWatchingUserRestrictionChanges() {
1010         // TODO: The current design of settings looking different based on user restrictions
1011         // should be reworked to keep them separate and system code should check the setting
1012         // first followed by checking the user restriction before performing an operation.
1013         IUserRestrictionsListener listener = new IUserRestrictionsListener.Stub() {
1014             @Override
1015             public void onUserRestrictionsChanged(int userId,
1016                     Bundle newRestrictions, Bundle prevRestrictions) {
1017                 Set<String> changedRestrictions =
1018                         getRestrictionDiff(prevRestrictions, newRestrictions);
1019                 // We are changing the settings affected by restrictions to their current
1020                 // value with a forced update to ensure that all cross profile dependencies
1021                 // are taken into account. Also make sure the settings update to.. the same
1022                 // value passes the security checks, so clear binder calling id.
1023                 if (changedRestrictions.contains(UserManager.DISALLOW_SHARE_LOCATION)) {
1024                     final long identity = Binder.clearCallingIdentity();
1025                     try {
1026                         synchronized (mLock) {
1027                             Setting setting = getSecureSetting(
1028                                     Settings.Secure.LOCATION_MODE, userId);
1029                             updateSecureSetting(Settings.Secure.LOCATION_MODE,
1030                                     setting != null ? setting.getValue() : null, null,
1031                                             true, userId, true);
1032                         }
1033                     } finally {
1034                         Binder.restoreCallingIdentity(identity);
1035                     }
1036                 }
1037                 if (changedRestrictions.contains(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
1038                         || changedRestrictions.contains(
1039                                 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY)) {
1040                     final long identity = Binder.clearCallingIdentity();
1041                     try {
1042                         synchronized (mLock) {
1043                             Setting setting = getGlobalSetting(
1044                                     Settings.Global.INSTALL_NON_MARKET_APPS);
1045                             String value = setting != null ? setting.getValue() : null;
1046                             updateGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS,
1047                                     value, null, true, userId, true);
1048                         }
1049                     } finally {
1050                         Binder.restoreCallingIdentity(identity);
1051                     }
1052                 }
1053                 if (changedRestrictions.contains(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
1054                     final long identity = Binder.clearCallingIdentity();
1055                     try {
1056                         synchronized (mLock) {
1057                             Setting setting = getGlobalSetting(Settings.Global.ADB_ENABLED);
1058                             String value = setting != null ? setting.getValue() : null;
1059                             updateGlobalSetting(Settings.Global.ADB_ENABLED,
1060                                     value, null, true, userId, true);
1061 
1062                             setting = getGlobalSetting(Settings.Global.ADB_WIFI_ENABLED);
1063                             value = setting != null ? setting.getValue() : null;
1064                             updateGlobalSetting(Settings.Global.ADB_WIFI_ENABLED,
1065                                     value, null, true, userId, true);
1066                         }
1067                     } finally {
1068                         Binder.restoreCallingIdentity(identity);
1069                     }
1070                 }
1071                 if (changedRestrictions.contains(UserManager.ENSURE_VERIFY_APPS)) {
1072                     final long identity = Binder.clearCallingIdentity();
1073                     try {
1074                         synchronized (mLock) {
1075                             Setting include = getGlobalSetting(
1076                                     Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB);
1077                             String includeValue = include != null ? include.getValue() : null;
1078                             updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB,
1079                                     includeValue, null, true, userId, true);
1080                         }
1081                     } finally {
1082                         Binder.restoreCallingIdentity(identity);
1083                     }
1084                 }
1085                 if (changedRestrictions.contains(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
1086                     final long identity = Binder.clearCallingIdentity();
1087                     try {
1088                         synchronized (mLock) {
1089                             Setting setting = getGlobalSetting(
1090                                     Settings.Global.PREFERRED_NETWORK_MODE);
1091                             String value = setting != null ? setting.getValue() : null;
1092                             updateGlobalSetting(Settings.Global.PREFERRED_NETWORK_MODE,
1093                                     value, null, true, userId, true);
1094                         }
1095                     } finally {
1096                         Binder.restoreCallingIdentity(identity);
1097                     }
1098                 }
1099             }
1100         };
1101         mUserManager.addUserRestrictionsListener(listener);
1102     }
1103 
getRestrictionDiff(Bundle prevRestrictions, Bundle newRestrictions)1104     private static Set<String> getRestrictionDiff(Bundle prevRestrictions, Bundle newRestrictions) {
1105         Set<String> restrictionNames = Sets.newArraySet();
1106         restrictionNames.addAll(prevRestrictions.keySet());
1107         restrictionNames.addAll(newRestrictions.keySet());
1108         Set<String> diff = Sets.newArraySet();
1109         for (String restrictionName : restrictionNames) {
1110             if (prevRestrictions.getBoolean(restrictionName) != newRestrictions.getBoolean(
1111                     restrictionName)) {
1112                 diff.add(restrictionName);
1113             }
1114         }
1115         return diff;
1116     }
1117 
getConfigSetting(String name)1118     private Setting getConfigSetting(String name) {
1119         if (DEBUG) {
1120             Slog.v(LOG_TAG, "getConfigSetting(" + name + ")");
1121         }
1122 
1123         DeviceConfig.enforceReadPermission(getContext(), /*namespace=*/name.split("/")[0]);
1124 
1125         // Get the value.
1126         synchronized (mLock) {
1127             return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_CONFIG,
1128                     UserHandle.USER_SYSTEM, name);
1129         }
1130     }
1131 
insertConfigSetting(String name, String value, boolean makeDefault)1132     private boolean insertConfigSetting(String name, String value, boolean makeDefault) {
1133         if (DEBUG) {
1134             Slog.v(LOG_TAG, "insertConfigSetting(" + name + ", " + value  + ", "
1135                     + makeDefault + ")");
1136         }
1137         return mutateConfigSetting(name, value, null, makeDefault,
1138                 MUTATION_OPERATION_INSERT, 0);
1139     }
1140 
1141 
setAllConfigSettings(String prefix, Map<String, String> keyValues)1142     private @SetAllResult int setAllConfigSettings(String prefix, Map<String, String> keyValues) {
1143         if (DEBUG) {
1144             Slog.v(LOG_TAG, "setAllConfigSettings for prefix: " + prefix);
1145         }
1146 
1147         enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
1148         final String callingPackage = resolveCallingPackage();
1149 
1150         synchronized (mLock) {
1151             if (isSyncDisabledConfigLocked()) {
1152                 return SET_ALL_RESULT_DISABLED;
1153             }
1154             final int key = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
1155             boolean success = mSettingsRegistry.setConfigSettingsLocked(key, prefix, keyValues,
1156                     callingPackage);
1157             return success ? SET_ALL_RESULT_SUCCESS : SET_ALL_RESULT_FAILURE;
1158         }
1159     }
1160 
setSyncDisabledConfig(@yncDisabledMode int syncDisabledMode)1161     private void setSyncDisabledConfig(@SyncDisabledMode int syncDisabledMode) {
1162         if (DEBUG) {
1163             Slog.v(LOG_TAG, "setSyncDisabledConfig(" + syncDisabledMode + ")");
1164         }
1165 
1166         enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
1167 
1168         synchronized (mLock) {
1169             setSyncDisabledConfigLocked(syncDisabledMode);
1170         }
1171     }
1172 
isSyncDisabledConfig()1173     private boolean isSyncDisabledConfig() {
1174         if (DEBUG) {
1175             Slog.v(LOG_TAG, "isSyncDisabledConfig");
1176         }
1177 
1178         enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
1179 
1180         synchronized (mLock) {
1181             return isSyncDisabledConfigLocked();
1182         }
1183     }
1184 
1185     @GuardedBy("mLock")
setSyncDisabledConfigLocked(@yncDisabledMode int syncDisabledMode)1186     private void setSyncDisabledConfigLocked(@SyncDisabledMode int syncDisabledMode) {
1187         boolean persistentValue;
1188         boolean inMemoryValue;
1189         if (syncDisabledMode == SYNC_DISABLED_MODE_NONE) {
1190             persistentValue = false;
1191             inMemoryValue = false;
1192         } else if (syncDisabledMode == SYNC_DISABLED_MODE_PERSISTENT) {
1193             persistentValue = true;
1194             inMemoryValue = false;
1195         } else if (syncDisabledMode == SYNC_DISABLED_MODE_UNTIL_REBOOT) {
1196             persistentValue = false;
1197             inMemoryValue = true;
1198         } else {
1199             throw new IllegalArgumentException(Integer.toString(syncDisabledMode));
1200         }
1201 
1202         mSyncConfigDisabledUntilReboot = inMemoryValue;
1203 
1204         CallingIdentity callingIdentity = clearCallingIdentity();
1205         try {
1206             String globalSettingValue = persistentValue ? "1" : "0";
1207             mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
1208                     UserHandle.USER_SYSTEM, Settings.Global.DEVICE_CONFIG_SYNC_DISABLED,
1209                     globalSettingValue, /*tag=*/null, /*makeDefault=*/false,
1210                     SettingsState.SYSTEM_PACKAGE_NAME, /*forceNotify=*/false,
1211                     /*criticalSettings=*/null, Settings.DEFAULT_OVERRIDEABLE_BY_RESTORE);
1212         } finally {
1213             restoreCallingIdentity(callingIdentity);
1214         }
1215     }
1216 
1217     @GuardedBy("mLock")
isSyncDisabledConfigLocked()1218     private boolean isSyncDisabledConfigLocked() {
1219         // Check the values used for both SYNC_DISABLED_MODE_PERSISTENT and
1220         // SYNC_DISABLED_MODE_UNTIL_REBOOT.
1221 
1222         // The SYNC_DISABLED_MODE_UNTIL_REBOOT value is cheap to check first.
1223         if (mSyncConfigDisabledUntilReboot) {
1224             return true;
1225         }
1226 
1227         // Now check the global setting used to implement SYNC_DISABLED_MODE_PERSISTENT.
1228         CallingIdentity callingIdentity = clearCallingIdentity();
1229         try {
1230             Setting settingLocked = mSettingsRegistry.getSettingLocked(
1231                     SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM,
1232                     Global.DEVICE_CONFIG_SYNC_DISABLED);
1233             if (settingLocked == null) {
1234                 return false;
1235             }
1236             String settingValue = settingLocked.getValue();
1237             return settingValue != null && !"0".equals(settingValue);
1238         } finally {
1239             restoreCallingIdentity(callingIdentity);
1240         }
1241     }
1242 
deleteConfigSetting(String name)1243     private boolean deleteConfigSetting(String name) {
1244         if (DEBUG) {
1245             Slog.v(LOG_TAG, "deleteConfigSetting(" + name + ")");
1246         }
1247         return mutateConfigSetting(name, null, null, false,
1248                 MUTATION_OPERATION_DELETE, 0);
1249     }
1250 
resetConfigSetting(int mode, String prefix)1251     private void resetConfigSetting(int mode, String prefix) {
1252         if (DEBUG) {
1253             Slog.v(LOG_TAG, "resetConfigSetting(" + mode + ", " + prefix + ")");
1254         }
1255         mutateConfigSetting(null, null, prefix, false,
1256                 MUTATION_OPERATION_RESET, mode);
1257     }
1258 
mutateConfigSetting(String name, String value, String prefix, boolean makeDefault, int operation, int mode)1259     private boolean mutateConfigSetting(String name, String value, String prefix,
1260             boolean makeDefault, int operation, int mode) {
1261         enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
1262         final String callingPackage = resolveCallingPackage();
1263 
1264         // Perform the mutation.
1265         synchronized (mLock) {
1266             switch (operation) {
1267                 case MUTATION_OPERATION_INSERT: {
1268                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
1269                             UserHandle.USER_SYSTEM, name, value, null, makeDefault, true,
1270                             callingPackage, false, null,
1271                             /* overrideableByRestore */ false);
1272                 }
1273 
1274                 case MUTATION_OPERATION_DELETE: {
1275                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_CONFIG,
1276                             UserHandle.USER_SYSTEM, name, false, null);
1277                 }
1278 
1279                 case MUTATION_OPERATION_RESET: {
1280                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG,
1281                             UserHandle.USER_SYSTEM, callingPackage, mode, null, prefix);
1282                 } return true;
1283             }
1284         }
1285 
1286         return false;
1287     }
1288 
getAllConfigFlags(@ullable String prefix)1289     private HashMap<String, String> getAllConfigFlags(@Nullable String prefix) {
1290         if (DEBUG) {
1291             Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix);
1292         }
1293 
1294         DeviceConfig.enforceReadPermission(getContext(),
1295                 prefix != null ? prefix.split("/")[0] : null);
1296 
1297         synchronized (mLock) {
1298             // Get the settings.
1299             SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
1300                     SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
1301             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_CONFIG,
1302                     UserHandle.USER_SYSTEM);
1303 
1304             final int nameCount = names.size();
1305             HashMap<String, String> flagsToValues = new HashMap<>(names.size());
1306 
1307             for (int i = 0; i < nameCount; i++) {
1308                 String name = names.get(i);
1309                 Setting setting = settingsState.getSettingLocked(name);
1310                 if (prefix == null || setting.getName().startsWith(prefix)) {
1311                     flagsToValues.put(setting.getName(), setting.getValue());
1312                 }
1313             }
1314 
1315             return flagsToValues;
1316         }
1317     }
1318 
getAllGlobalSettings(String[] projection)1319     private Cursor getAllGlobalSettings(String[] projection) {
1320         if (DEBUG) {
1321             Slog.v(LOG_TAG, "getAllGlobalSettings()");
1322         }
1323 
1324         synchronized (mLock) {
1325             // Get the settings.
1326             SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
1327                     SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
1328 
1329             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_GLOBAL,
1330                     UserHandle.USER_SYSTEM);
1331 
1332             final int nameCount = names.size();
1333 
1334             String[] normalizedProjection = normalizeProjection(projection);
1335             MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
1336 
1337             // Anyone can get the global settings, so no security checks.
1338             for (int i = 0; i < nameCount; i++) {
1339                 String name = names.get(i);
1340                 Setting setting = settingsState.getSettingLocked(name);
1341                 appendSettingToCursor(result, setting);
1342             }
1343 
1344             return result;
1345         }
1346     }
1347 
getGlobalSetting(String name)1348     private Setting getGlobalSetting(String name) {
1349         if (DEBUG) {
1350             Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")");
1351         }
1352 
1353         // Ensure the caller can access the setting.
1354         enforceSettingReadable(name, SETTINGS_TYPE_GLOBAL, UserHandle.getCallingUserId());
1355 
1356         // Get the value.
1357         synchronized (mLock) {
1358             return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_GLOBAL,
1359                     UserHandle.USER_SYSTEM, name);
1360         }
1361     }
1362 
updateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, boolean forceNotify)1363     private boolean updateGlobalSetting(String name, String value, String tag,
1364             boolean makeDefault, int requestingUserId, boolean forceNotify) {
1365         if (DEBUG) {
1366             Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ", "
1367                     + ", " + tag + ", " + makeDefault + ", " + requestingUserId
1368                     + ", " + forceNotify + ")");
1369         }
1370         return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
1371                 MUTATION_OPERATION_UPDATE, forceNotify, 0);
1372     }
1373 
insertGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, boolean forceNotify, boolean overrideableByRestore)1374     private boolean insertGlobalSetting(String name, String value, String tag,
1375             boolean makeDefault, int requestingUserId, boolean forceNotify,
1376             boolean overrideableByRestore) {
1377         if (DEBUG) {
1378             Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value  + ", "
1379                     + ", " + tag + ", " + makeDefault + ", " + requestingUserId
1380                     + ", " + forceNotify + ")");
1381         }
1382         return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
1383                 MUTATION_OPERATION_INSERT, forceNotify, 0, overrideableByRestore);
1384     }
1385 
deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify)1386     private boolean deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify) {
1387         if (DEBUG) {
1388             Slog.v(LOG_TAG, "deleteGlobalSetting(" + name + ", " + requestingUserId
1389                     + ", " + forceNotify + ")");
1390         }
1391         return mutateGlobalSetting(name, null, null, false, requestingUserId,
1392                 MUTATION_OPERATION_DELETE, forceNotify, 0);
1393     }
1394 
resetGlobalSetting(int requestingUserId, int mode, String tag)1395     private void resetGlobalSetting(int requestingUserId, int mode, String tag) {
1396         if (DEBUG) {
1397             Slog.v(LOG_TAG, "resetGlobalSetting(" + requestingUserId + ", "
1398                     + mode + ", " + tag + ")");
1399         }
1400         mutateGlobalSetting(null, null, tag, false, requestingUserId,
1401                 MUTATION_OPERATION_RESET, false, mode);
1402     }
1403 
isSettingRestrictedForUser(String name, int userId, String value, int callerUid)1404     private boolean isSettingRestrictedForUser(String name, int userId,
1405             String value, int callerUid) {
1406         final long oldId = Binder.clearCallingIdentity();
1407         try {
1408             return (name != null
1409                     && mUserManager.isSettingRestrictedForUser(name, userId, value, callerUid));
1410         } finally {
1411             Binder.restoreCallingIdentity(oldId);
1412         }
1413     }
1414 
mutateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode)1415     private boolean mutateGlobalSetting(String name, String value, String tag,
1416             boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
1417             int mode) {
1418         // overrideableByRestore = false as by default settings values shouldn't be overrideable by
1419         // restore.
1420         return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId, operation,
1421                 forceNotify, mode, /* overrideableByRestore */ false);
1422     }
1423 
mutateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode, boolean overrideableByRestore)1424     private boolean mutateGlobalSetting(String name, String value, String tag,
1425             boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
1426             int mode, boolean overrideableByRestore) {
1427         // Make sure the caller can change the settings - treated as secure.
1428         enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
1429 
1430         // Resolve the userId on whose behalf the call is made.
1431         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
1432 
1433         // If this is a setting that is currently restricted for this user, do not allow
1434         // unrestricting changes.
1435         if (isSettingRestrictedForUser(name, callingUserId, value, Binder.getCallingUid())) {
1436             return false;
1437         }
1438 
1439         final String callingPackage = getCallingPackage();
1440 
1441         // Perform the mutation.
1442         synchronized (mLock) {
1443             switch (operation) {
1444                 case MUTATION_OPERATION_INSERT: {
1445                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
1446                             UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
1447                             callingPackage, forceNotify,
1448                             CRITICAL_GLOBAL_SETTINGS, overrideableByRestore);
1449                 }
1450 
1451                 case MUTATION_OPERATION_DELETE: {
1452                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_GLOBAL,
1453                             UserHandle.USER_SYSTEM, name, forceNotify, CRITICAL_GLOBAL_SETTINGS);
1454                 }
1455 
1456                 case MUTATION_OPERATION_UPDATE: {
1457                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_GLOBAL,
1458                             UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
1459                             callingPackage, forceNotify, CRITICAL_GLOBAL_SETTINGS);
1460                 }
1461 
1462                 case MUTATION_OPERATION_RESET: {
1463                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_GLOBAL,
1464                             UserHandle.USER_SYSTEM, callingPackage, mode, tag);
1465                 } return true;
1466             }
1467         }
1468 
1469         return false;
1470     }
1471 
getCallingPackageInfo(int userId)1472     private PackageInfo getCallingPackageInfo(int userId) {
1473         final String callingPackage = getCallingPackage();
1474         try {
1475             return mPackageManager.getPackageInfo(callingPackage,
1476                     PackageManager.GET_SIGNATURES, userId);
1477         } catch (RemoteException e) {
1478             throw new IllegalStateException("Package " + callingPackage + " doesn't exist");
1479         }
1480     }
1481 
getAllSecureSettings(int userId, String[] projection)1482     private Cursor getAllSecureSettings(int userId, String[] projection) {
1483         if (DEBUG) {
1484             Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")");
1485         }
1486 
1487         // Resolve the userId on whose behalf the call is made.
1488         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
1489 
1490         // The relevant "calling package" userId will be the owning userId for some
1491         // profiles, and we can't do the lookup inside our [lock held] loop, so work out
1492         // up front who the effective "new SSAID" user ID for that settings name will be.
1493         final int ssaidUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
1494                 Settings.Secure.ANDROID_ID);
1495         final PackageInfo ssaidCallingPkg = getCallingPackageInfo(ssaidUserId);
1496 
1497         synchronized (mLock) {
1498             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SECURE, callingUserId);
1499 
1500             final int nameCount = names.size();
1501 
1502             String[] normalizedProjection = normalizeProjection(projection);
1503             MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
1504 
1505             for (int i = 0; i < nameCount; i++) {
1506                 String name = names.get(i);
1507                 // Determine the owning user as some profile settings are cloned from the parent.
1508                 final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
1509                         name);
1510 
1511                 if (!isSecureSettingAccessible(name)) {
1512                     // This caller is not permitted to access this setting. Pretend the setting
1513                     // doesn't exist.
1514                     continue;
1515                 }
1516 
1517                 // As of Android O, the SSAID is read from an app-specific entry in table
1518                 // SETTINGS_FILE_SSAID, unless accessed by a system process.
1519                 final Setting setting;
1520                 if (isNewSsaidSetting(name)) {
1521                     setting = getSsaidSettingLocked(ssaidCallingPkg, owningUserId);
1522                 } else {
1523                     setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE, owningUserId,
1524                             name);
1525                 }
1526                 appendSettingToCursor(result, setting);
1527             }
1528 
1529             return result;
1530         }
1531     }
1532 
getSecureSetting(String name, int requestingUserId)1533     private Setting getSecureSetting(String name, int requestingUserId) {
1534         if (DEBUG) {
1535             Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")");
1536         }
1537 
1538         // Resolve the userId on whose behalf the call is made.
1539         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
1540 
1541         // Ensure the caller can access the setting.
1542         enforceSettingReadable(name, SETTINGS_TYPE_SECURE, UserHandle.getCallingUserId());
1543 
1544         // Determine the owning user as some profile settings are cloned from the parent.
1545         final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);
1546 
1547         if (!isSecureSettingAccessible(name)) {
1548             // This caller is not permitted to access this setting. Pretend the setting doesn't
1549             // exist.
1550             SettingsState settings = mSettingsRegistry.getSettingsLocked(SETTINGS_TYPE_SECURE,
1551                     owningUserId);
1552             return settings != null ? settings.getNullSetting() : null;
1553         }
1554 
1555         // As of Android O, the SSAID is read from an app-specific entry in table
1556         // SETTINGS_FILE_SSAID, unless accessed by a system process.
1557         if (isNewSsaidSetting(name)) {
1558             PackageInfo callingPkg = getCallingPackageInfo(owningUserId);
1559             synchronized (mLock) {
1560                 return getSsaidSettingLocked(callingPkg, owningUserId);
1561             }
1562         }
1563 
1564         // Not the SSAID; do a straight lookup
1565         synchronized (mLock) {
1566             return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE,
1567                     owningUserId, name);
1568         }
1569     }
1570 
isNewSsaidSetting(String name)1571     private boolean isNewSsaidSetting(String name) {
1572         return Settings.Secure.ANDROID_ID.equals(name)
1573                 && UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID;
1574     }
1575 
1576     @GuardedBy("mLock")
getSsaidSettingLocked(PackageInfo callingPkg, int owningUserId)1577     private Setting getSsaidSettingLocked(PackageInfo callingPkg, int owningUserId) {
1578         // Get uid of caller (key) used to store ssaid value
1579         String name = Integer.toString(
1580                 UserHandle.getUid(owningUserId, UserHandle.getAppId(Binder.getCallingUid())));
1581 
1582         if (DEBUG) {
1583             Slog.v(LOG_TAG, "getSsaidSettingLocked(" + name + "," + owningUserId + ")");
1584         }
1585 
1586         // Retrieve the ssaid from the table if present.
1587         final Setting ssaid = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId,
1588                 name);
1589         // If the app is an Instant App use its stored SSAID instead of our own.
1590         final String instantSsaid;
1591         final long token = Binder.clearCallingIdentity();
1592         try {
1593             instantSsaid = mPackageManager.getInstantAppAndroidId(callingPkg.packageName,
1594                     owningUserId);
1595         } catch (RemoteException e) {
1596             Slog.e(LOG_TAG, "Failed to get Instant App Android ID", e);
1597             return null;
1598         } finally {
1599             Binder.restoreCallingIdentity(token);
1600         }
1601 
1602         final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked(
1603                 SETTINGS_TYPE_SSAID, owningUserId);
1604 
1605         if (instantSsaid != null) {
1606             // Use the stored value if it is still valid.
1607             if (ssaid != null && instantSsaid.equals(ssaid.getValue())) {
1608                 return mascaradeSsaidSetting(ssaidSettings, ssaid);
1609             }
1610             // The value has changed, update the stored value.
1611             final boolean success = ssaidSettings.insertSettingLocked(name, instantSsaid, null,
1612                     true, callingPkg.packageName);
1613             if (!success) {
1614                 throw new IllegalStateException("Failed to update instant app android id");
1615             }
1616             Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID,
1617                     owningUserId, name);
1618             return mascaradeSsaidSetting(ssaidSettings, setting);
1619         }
1620 
1621         // Lazy initialize ssaid if not yet present in ssaid table.
1622         if (ssaid == null || ssaid.isNull() || ssaid.getValue() == null) {
1623             Setting setting = mSettingsRegistry.generateSsaidLocked(callingPkg, owningUserId);
1624             return mascaradeSsaidSetting(ssaidSettings, setting);
1625         }
1626 
1627         return mascaradeSsaidSetting(ssaidSettings, ssaid);
1628     }
1629 
mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting)1630     private Setting mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting) {
1631         // SSAID settings are located in a dedicated table for internal bookkeeping
1632         // but for the world they reside in the secure table, so adjust the key here.
1633         // We have a special name when looking it up but want the world to see it as
1634         // "android_id".
1635         if (ssaidSetting != null) {
1636             return settingsState.new Setting(ssaidSetting) {
1637                 @Override
1638                 public int getKey() {
1639                     final int userId = getUserIdFromKey(super.getKey());
1640                     return makeKey(SETTINGS_TYPE_SECURE, userId);
1641                 }
1642 
1643                 @Override
1644                 public String getName() {
1645                     return Settings.Secure.ANDROID_ID;
1646                 }
1647             };
1648         }
1649         return null;
1650     }
1651 
1652     private boolean insertSecureSetting(String name, String value, String tag,
1653             boolean makeDefault, int requestingUserId, boolean forceNotify,
1654             boolean overrideableByRestore) {
1655         if (DEBUG) {
1656             Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", "
1657                     + ", " + tag  + ", " + makeDefault + ", "  + requestingUserId
1658                     + ", " + forceNotify + ")");
1659         }
1660         return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
1661                 MUTATION_OPERATION_INSERT, forceNotify, 0, overrideableByRestore);
1662     }
1663 
1664     private boolean deleteSecureSetting(String name, int requestingUserId, boolean forceNotify) {
1665         if (DEBUG) {
1666             Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId
1667                     + ", " + forceNotify + ")");
1668         }
1669 
1670         return mutateSecureSetting(name, null, null, false, requestingUserId,
1671                 MUTATION_OPERATION_DELETE, forceNotify, 0);
1672     }
1673 
1674     private boolean updateSecureSetting(String name, String value, String tag,
1675             boolean makeDefault, int requestingUserId, boolean forceNotify) {
1676         if (DEBUG) {
1677             Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", "
1678                     + ", " + tag  + ", " + makeDefault + ", "  + requestingUserId
1679                     + ", "  + forceNotify +")");
1680         }
1681 
1682         return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
1683                 MUTATION_OPERATION_UPDATE, forceNotify, 0);
1684     }
1685 
1686     private void resetSecureSetting(int requestingUserId, int mode, String tag) {
1687         if (DEBUG) {
1688             Slog.v(LOG_TAG, "resetSecureSetting(" + requestingUserId + ", "
1689                     + mode + ", " + tag + ")");
1690         }
1691 
1692         mutateSecureSetting(null, null, tag, false, requestingUserId,
1693                 MUTATION_OPERATION_RESET, false, mode);
1694     }
1695 
1696     private boolean mutateSecureSetting(String name, String value, String tag,
1697             boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
1698             int mode) {
1699         // overrideableByRestore = false as by default settings values shouldn't be overrideable by
1700         // restore.
1701         return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId, operation,
1702                 forceNotify, mode, /* overrideableByRestore */ false);
1703     }
1704 
1705     private boolean mutateSecureSetting(String name, String value, String tag,
1706             boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
1707             int mode, boolean overrideableByRestore) {
1708         // Make sure the caller can change the settings.
1709         enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
1710 
1711         // Resolve the userId on whose behalf the call is made.
1712         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
1713 
1714         // If this is a setting that is currently restricted for this user, do not allow
1715         // unrestricting changes.
1716         if (isSettingRestrictedForUser(name, callingUserId, value, Binder.getCallingUid())) {
1717             return false;
1718         }
1719 
1720         // Determine the owning user as some profile settings are cloned from the parent.
1721         final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);
1722 
1723         // Only the owning user can change the setting.
1724         if (owningUserId != callingUserId) {
1725             return false;
1726         }
1727 
1728         final String callingPackage = getCallingPackage();
1729 
1730         // Mutate the value.
1731         synchronized (mLock) {
1732             switch (operation) {
1733                 case MUTATION_OPERATION_INSERT: {
1734                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
1735                             owningUserId, name, value, tag, makeDefault,
1736                             callingPackage, forceNotify, CRITICAL_SECURE_SETTINGS,
1737                             overrideableByRestore);
1738                 }
1739 
1740                 case MUTATION_OPERATION_DELETE: {
1741                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SECURE,
1742                             owningUserId, name, forceNotify, CRITICAL_SECURE_SETTINGS);
1743                 }
1744 
1745                 case MUTATION_OPERATION_UPDATE: {
1746                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SECURE,
1747                             owningUserId, name, value, tag, makeDefault,
1748                             callingPackage, forceNotify, CRITICAL_SECURE_SETTINGS);
1749                 }
1750 
1751                 case MUTATION_OPERATION_RESET: {
1752                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_SECURE,
1753                             UserHandle.USER_SYSTEM, callingPackage, mode, tag);
1754                 } return true;
1755             }
1756         }
1757 
1758         return false;
1759     }
1760 
1761     private Cursor getAllSystemSettings(int userId, String[] projection) {
1762         if (DEBUG) {
1763             Slog.v(LOG_TAG, "getAllSecureSystem(" + userId + ")");
1764         }
1765 
1766         // Resolve the userId on whose behalf the call is made.
1767         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
1768 
1769         synchronized (mLock) {
1770             List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SYSTEM, callingUserId);
1771 
1772             final int nameCount = names.size();
1773 
1774             String[] normalizedProjection = normalizeProjection(projection);
1775             MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
1776 
1777             for (int i = 0; i < nameCount; i++) {
1778                 String name = names.get(i);
1779 
1780                 // Determine the owning user as some profile settings are cloned from the parent.
1781                 final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId,
1782                         name);
1783 
1784                 Setting setting = mSettingsRegistry.getSettingLocked(
1785                         SETTINGS_TYPE_SYSTEM, owningUserId, name);
1786                 appendSettingToCursor(result, setting);
1787             }
1788 
1789             return result;
1790         }
1791     }
1792 
1793     private Setting getSystemSetting(String name, int requestingUserId) {
1794         if (DEBUG) {
1795             Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")");
1796         }
1797 
1798         // Resolve the userId on whose behalf the call is made.
1799         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
1800 
1801         // Ensure the caller can access the setting.
1802         enforceSettingReadable(name, SETTINGS_TYPE_SYSTEM, UserHandle.getCallingUserId());
1803 
1804         // Determine the owning user as some profile settings are cloned from the parent.
1805         final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
1806 
1807         // Get the value.
1808         synchronized (mLock) {
1809             return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SYSTEM, owningUserId, name);
1810         }
1811     }
1812 
1813     private boolean insertSystemSetting(String name, String value, int requestingUserId,
1814             boolean overrideableByRestore) {
1815         if (DEBUG) {
1816             Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", "
1817                     + requestingUserId + ")");
1818         }
1819 
1820         return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT,
1821                 overrideableByRestore);
1822     }
1823 
1824     private boolean deleteSystemSetting(String name, int requestingUserId) {
1825         if (DEBUG) {
1826             Slog.v(LOG_TAG, "deleteSystemSetting(" + name + ", " + requestingUserId + ")");
1827         }
1828 
1829         return mutateSystemSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
1830     }
1831 
1832     private boolean updateSystemSetting(String name, String value, int requestingUserId) {
1833         if (DEBUG) {
1834             Slog.v(LOG_TAG, "updateSystemSetting(" + name + ", " + value + ", "
1835                     + requestingUserId + ")");
1836         }
1837 
1838         return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
1839     }
1840 
1841     private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation) {
1842         // overrideableByRestore = false as by default settings values shouldn't be overrideable by
1843         // restore.
1844         return mutateSystemSetting(name, value, runAsUserId, operation,
1845                 /* overrideableByRestore */ false);
1846     }
1847 
1848     private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation,
1849             boolean overrideableByRestore) {
1850         final String callingPackage = getCallingPackage();
1851         if (!hasWriteSecureSettingsPermission()) {
1852             // If the caller doesn't hold WRITE_SECURE_SETTINGS, we verify whether this
1853             // operation is allowed for the calling package through appops.
1854             if (!Settings.checkAndNoteWriteSettingsOperation(getContext(),
1855                     Binder.getCallingUid(), callingPackage, getCallingAttributionTag(),
1856                     true)) {
1857                 return false;
1858             }
1859         }
1860 
1861         // Resolve the userId on whose behalf the call is made.
1862         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(runAsUserId);
1863 
1864         if (isSettingRestrictedForUser(name, callingUserId, value, Binder.getCallingUid())) {
1865             return false;
1866         }
1867 
1868         // Enforce what the calling package can mutate the system settings.
1869         enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name, callingUserId);
1870 
1871         // Determine the owning user as some profile settings are cloned from the parent.
1872         final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
1873 
1874         // Only the owning user id can change the setting.
1875         if (owningUserId != callingUserId) {
1876             return false;
1877         }
1878 
1879         // Invalidate any relevant cache files
1880         String cacheName = null;
1881         if (Settings.System.RINGTONE.equals(name)) {
1882             cacheName = Settings.System.RINGTONE_CACHE;
1883         } else if (Settings.System.NOTIFICATION_SOUND.equals(name)) {
1884             cacheName = Settings.System.NOTIFICATION_SOUND_CACHE;
1885         } else if (Settings.System.ALARM_ALERT.equals(name)) {
1886             cacheName = Settings.System.ALARM_ALERT_CACHE;
1887         }
1888         if (cacheName != null) {
1889             final File cacheFile = new File(
1890                     getRingtoneCacheDir(owningUserId), cacheName);
1891             cacheFile.delete();
1892         }
1893 
1894         // Mutate the value.
1895         synchronized (mLock) {
1896             switch (operation) {
1897                 case MUTATION_OPERATION_INSERT: {
1898                     validateSystemSettingValue(name, value);
1899                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SYSTEM,
1900                             owningUserId, name, value, null, false, callingPackage,
1901                             false, null, overrideableByRestore);
1902                 }
1903 
1904                 case MUTATION_OPERATION_DELETE: {
1905                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SYSTEM,
1906                             owningUserId, name, false, null);
1907                 }
1908 
1909                 case MUTATION_OPERATION_UPDATE: {
1910                     validateSystemSettingValue(name, value);
1911                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SYSTEM,
1912                             owningUserId, name, value, null, false, callingPackage,
1913                             false, null);
1914                 }
1915             }
1916 
1917             return false;
1918         }
1919     }
1920 
1921     private boolean hasWriteSecureSettingsPermission() {
1922         // Write secure settings is a more protected permission. If caller has it we are good.
1923         return getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
1924                 == PackageManager.PERMISSION_GRANTED;
1925     }
1926 
1927     private void validateSystemSettingValue(String name, String value) {
1928         Validator validator = SystemSettingsValidators.VALIDATORS.get(name);
1929         if (validator != null && !validator.validate(value)) {
1930             throw new IllegalArgumentException("Invalid value: " + value
1931                     + " for setting: " + name);
1932         }
1933     }
1934 
1935     /**
1936      * Returns {@code true} if the specified secure setting should be accessible to the caller.
1937      */
1938     private boolean isSecureSettingAccessible(String name) {
1939         switch (name) {
1940             case "bluetooth_address":
1941                 // BluetoothManagerService for some reason stores the Android's Bluetooth MAC
1942                 // address in this secure setting. Secure settings can normally be read by any app,
1943                 // which thus enables them to bypass the recently introduced restrictions on access
1944                 // to device identifiers.
1945                 // To mitigate this we make this setting available only to callers privileged to see
1946                 // this device's MAC addresses, same as through public API
1947                 // BluetoothAdapter.getAddress() (see BluetoothManagerService for details).
1948                 return getContext().checkCallingOrSelfPermission(
1949                         Manifest.permission.LOCAL_MAC_ADDRESS) == PackageManager.PERMISSION_GRANTED;
1950             default:
1951                 return true;
1952         }
1953     }
1954 
1955     private int resolveOwningUserIdForSecureSettingLocked(int userId, String setting) {
1956         return resolveOwningUserIdLocked(userId, sSecureCloneToManagedSettings, setting);
1957     }
1958 
1959     private int resolveOwningUserIdForSystemSettingLocked(int userId, String setting) {
1960         final int parentId;
1961         // Resolves dependency if setting has a dependency and the calling user has a parent
1962         if (sSystemCloneFromParentOnDependency.containsKey(setting)
1963                 && (parentId = getGroupParentLocked(userId)) != userId) {
1964             // The setting has a dependency and the profile has a parent
1965             String dependency = sSystemCloneFromParentOnDependency.get(setting);
1966             // Lookup the dependency setting as ourselves, some callers may not have access to it.
1967             final long token = Binder.clearCallingIdentity();
1968             try {
1969                 Setting settingObj = getSecureSetting(dependency, userId);
1970                 if (settingObj != null && settingObj.getValue().equals("1")) {
1971                     return parentId;
1972                 }
1973             } finally {
1974                 Binder.restoreCallingIdentity(token);
1975             }
1976         }
1977         return resolveOwningUserIdLocked(userId, sSystemCloneToManagedSettings, setting);
1978     }
1979 
1980     private int resolveOwningUserIdLocked(int userId, Set<String> keys, String name) {
1981         final int parentId = getGroupParentLocked(userId);
1982         if (parentId != userId && keys.contains(name)) {
1983             return parentId;
1984         }
1985         return userId;
1986     }
1987 
1988     private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation,
1989             String name, int userId) {
1990         // System/root/shell can mutate whatever secure settings they want.
1991         final int callingUid = Binder.getCallingUid();
1992         final int appId = UserHandle.getAppId(callingUid);
1993         if (appId == android.os.Process.SYSTEM_UID
1994                 || appId == Process.SHELL_UID
1995                 || appId == Process.ROOT_UID) {
1996             return;
1997         }
1998 
1999         switch (operation) {
2000             case MUTATION_OPERATION_INSERT:
2001                 // Insert updates.
2002             case MUTATION_OPERATION_UPDATE: {
2003                 if (Settings.System.PUBLIC_SETTINGS.contains(name)) {
2004                     return;
2005                 }
2006 
2007                 // The calling package is already verified.
2008                 PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
2009 
2010                 // Privileged apps can do whatever they want.
2011                 if ((packageInfo.applicationInfo.privateFlags
2012                         & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
2013                     return;
2014                 }
2015 
2016                 warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
2017                         packageInfo.applicationInfo.targetSdkVersion, name);
2018             } break;
2019 
2020             case MUTATION_OPERATION_DELETE: {
2021                 if (Settings.System.PUBLIC_SETTINGS.contains(name)
2022                         || Settings.System.PRIVATE_SETTINGS.contains(name)) {
2023                     throw new IllegalArgumentException("You cannot delete system defined"
2024                             + " secure settings.");
2025                 }
2026 
2027                 // The calling package is already verified.
2028                 PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
2029 
2030                 // Privileged apps can do whatever they want.
2031                 if ((packageInfo.applicationInfo.privateFlags &
2032                         ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
2033                     return;
2034                 }
2035 
2036                 warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
2037                         packageInfo.applicationInfo.targetSdkVersion, name);
2038             } break;
2039         }
2040     }
2041 
2042     private Set<String> getInstantAppAccessibleSettings(int settingsType) {
2043         switch (settingsType) {
2044             case SETTINGS_TYPE_GLOBAL:
2045                 return Settings.Global.INSTANT_APP_SETTINGS;
2046             case SETTINGS_TYPE_SECURE:
2047                 return Settings.Secure.INSTANT_APP_SETTINGS;
2048             case SETTINGS_TYPE_SYSTEM:
2049                 return Settings.System.INSTANT_APP_SETTINGS;
2050             default:
2051                 throw new IllegalArgumentException("Invalid settings type: " + settingsType);
2052         }
2053     }
2054 
2055     private Set<String> getOverlayInstantAppAccessibleSettings(int settingsType) {
2056         switch (settingsType) {
2057             case SETTINGS_TYPE_GLOBAL:
2058                 return OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS;
2059             case SETTINGS_TYPE_SYSTEM:
2060                 return OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS;
2061             case SETTINGS_TYPE_SECURE:
2062                 return OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS;
2063             default:
2064                 throw new IllegalArgumentException("Invalid settings type: " + settingsType);
2065         }
2066     }
2067 
2068     @GuardedBy("mLock")
2069     private List<String> getSettingsNamesLocked(int settingsType, int userId) {
2070         // Don't enforce the instant app whitelist for now -- its too prone to unintended breakage
2071         // in the current form.
2072         return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId);
2073     }
2074 
2075     private void enforceSettingReadable(String settingName, int settingsType, int userId) {
2076         if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
2077             return;
2078         }
2079         ApplicationInfo ai = getCallingApplicationInfoOrThrow();
2080         if (ai.isSystemApp() || ai.isSignedWithPlatformKey()) {
2081             return;
2082         }
2083         if ((ai.flags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
2084             // Skip checking readable annotations for test_only apps
2085             checkReadableAnnotation(settingsType, settingName, ai.targetSandboxVersion);
2086         }
2087         /**
2088          * some settings need additional permission check, this is to have a matching security
2089          * control from other API alternatives returning the same settings values.
2090          * note, the permission enforcement should be based on app's targetSDKlevel to better handle
2091          * app-compat.
2092          */
2093         switch (settingName) {
2094             // missing READ_PRIVILEGED_PHONE_STATE permission protection
2095             // see alternative API {@link SubscriptionManager#getPreferredDataSubscriptionId()
2096             case Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION:
2097                 // app-compat handling, not break apps targeting on previous SDKs.
2098                 if (CompatChanges.isChangeEnabled(
2099                         ENFORCE_READ_PERMISSION_FOR_MULTI_SIM_DATA_CALL)) {
2100                     getContext().enforceCallingOrSelfPermission(
2101                             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
2102                             "access global settings MULTI_SIM_DATA_CALL_SUBSCRIPTION");
2103                 }
2104                 break;
2105         }
2106         if (!ai.isInstantApp()) {
2107             return;
2108         }
2109         if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)
2110                 && !getOverlayInstantAppAccessibleSettings(settingsType).contains(settingName)) {
2111             // Don't enforce the instant app whitelist for now -- its too prone to unintended
2112             // breakage in the current form.
2113             Slog.w(LOG_TAG, "Instant App " + ai.packageName
2114                     + " trying to access unexposed setting, this will be an error in the future.");
2115         }
2116     }
2117 
2118     /**
2119      * Check if the target settings key is readable. Reject if the caller app is trying to access a
2120      * settings key defined in the Settings.Secure, Settings.System or Settings.Global and is not
2121      * annotated as @Readable. Reject if the caller app is targeting an SDK level that is higher
2122      * than the maxTargetSdk specified in the @Readable annotation.
2123      * Notice that a key string that is not defined in any of the Settings.* classes will still be
2124      * regarded as readable.
2125      */
2126     private void checkReadableAnnotation(int settingsType, String settingName,
2127             int targetSdkVersion) {
2128         final Set<String> allFields;
2129         final Set<String> readableFields;
2130         final ArrayMap<String, Integer> readableFieldsWithMaxTargetSdk;
2131         switch (settingsType) {
2132             case SETTINGS_TYPE_GLOBAL:
2133                 allFields = sAllGlobalSettings;
2134                 readableFields = sReadableGlobalSettings;
2135                 readableFieldsWithMaxTargetSdk = sReadableGlobalSettingsWithMaxTargetSdk;
2136                 break;
2137             case SETTINGS_TYPE_SYSTEM:
2138                 allFields = sAllSystemSettings;
2139                 readableFields = sReadableSystemSettings;
2140                 readableFieldsWithMaxTargetSdk = sReadableSystemSettingsWithMaxTargetSdk;
2141                 break;
2142             case SETTINGS_TYPE_SECURE:
2143                 allFields = sAllSecureSettings;
2144                 readableFields = sReadableSecureSettings;
2145                 readableFieldsWithMaxTargetSdk = sReadableSecureSettingsWithMaxTargetSdk;
2146                 break;
2147             default:
2148                 throw new IllegalArgumentException("Invalid settings type: " + settingsType);
2149         }
2150 
2151         if (allFields.contains(settingName)) {
2152             if (!readableFields.contains(settingName)) {
2153                 throw new SecurityException(
2154                         "Settings key: <" + settingName + "> is not readable. From S+, settings "
2155                                 + "keys annotated with @hide are restricted to system_server and "
2156                                 + "system apps only, unless they are annotated with @Readable."
2157                 );
2158             } else {
2159                 if (readableFieldsWithMaxTargetSdk.containsKey(settingName)) {
2160                     final int maxTargetSdk = readableFieldsWithMaxTargetSdk.get(settingName);
2161                     if (targetSdkVersion > maxTargetSdk) {
2162                         throw new SecurityException(
2163                                 "Settings key: <" + settingName + "> is only readable to apps with "
2164                                         + "targetSdkVersion lower than or equal to: "
2165                                         + maxTargetSdk
2166                         );
2167                     }
2168                 }
2169             }
2170         }
2171     }
2172 
2173     private ApplicationInfo getCallingApplicationInfoOrThrow() {
2174         // We always use the callingUid for this lookup. This means that if hypothetically an
2175         // app was installed in user A with cross user and in user B as an Instant App
2176         // the app in A would be able to see all the settings in user B. However since cross
2177         // user is a system permission and the app must be uninstalled in B and then installed as
2178         // an Instant App that situation is not realistic or supported.
2179         ApplicationInfo ai = null;
2180         final String callingPackage = getCallingPackage();
2181         try {
2182             ai = mPackageManager.getApplicationInfo(callingPackage, 0
2183                     , UserHandle.getCallingUserId());
2184         } catch (RemoteException ignored) {
2185         }
2186         if (ai == null) {
2187             throw new IllegalStateException("Failed to lookup info for package "
2188                     + callingPackage);
2189         }
2190         return ai;
2191     }
2192 
2193     private PackageInfo getCallingPackageInfoOrThrow(int userId) {
2194         try {
2195             PackageInfo packageInfo = mPackageManager.getPackageInfo(
2196                     getCallingPackage(), 0, userId);
2197             if (packageInfo != null) {
2198                 return packageInfo;
2199             }
2200         } catch (RemoteException e) {
2201             /* ignore */
2202         }
2203         throw new IllegalStateException("Calling package doesn't exist");
2204     }
2205 
2206     private int getGroupParentLocked(int userId) {
2207         // Most frequent use case.
2208         if (userId == UserHandle.USER_SYSTEM) {
2209             return userId;
2210         }
2211         // We are in the same process with the user manager and the returned
2212         // user info is a cached instance, so just look up instead of cache.
2213         final long identity = Binder.clearCallingIdentity();
2214         try {
2215             // Just a lookup and not reentrant, so holding a lock is fine.
2216             UserInfo userInfo = mUserManager.getProfileParent(userId);
2217             return (userInfo != null) ? userInfo.id : userId;
2218         } finally {
2219             Binder.restoreCallingIdentity(identity);
2220         }
2221     }
2222 
2223     private void enforceWritePermission(String permission) {
2224         if (getContext().checkCallingOrSelfPermission(permission)
2225                 != PackageManager.PERMISSION_GRANTED) {
2226             throw new SecurityException("Permission denial: writing to settings requires:"
2227                     + permission);
2228         }
2229     }
2230 
2231     private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
2232             int targetSdkVersion, String name) {
2233         // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash.
2234         if (targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
2235             if (Settings.System.PRIVATE_SETTINGS.contains(name)) {
2236                 Slog.w(LOG_TAG, "You shouldn't not change private system settings."
2237                         + " This will soon become an error.");
2238             } else {
2239                 Slog.w(LOG_TAG, "You shouldn't keep your settings in the secure settings."
2240                         + " This will soon become an error.");
2241             }
2242         } else {
2243             if (Settings.System.PRIVATE_SETTINGS.contains(name)) {
2244                 throw new IllegalArgumentException("You cannot change private secure settings.");
2245             } else {
2246                 throw new IllegalArgumentException("You cannot keep your settings in"
2247                         + " the secure settings.");
2248             }
2249         }
2250     }
2251 
2252     private static int resolveCallingUserIdEnforcingPermissionsLocked(int requestingUserId) {
2253         if (requestingUserId == UserHandle.getCallingUserId()) {
2254             return requestingUserId;
2255         }
2256         return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
2257                 Binder.getCallingUid(), requestingUserId, false, true,
2258                 "get/set setting for user", null);
2259     }
2260 
2261     private Bundle packageValueForCallResult(Setting setting, boolean trackingGeneration) {
2262         if (!trackingGeneration) {
2263             if (setting == null || setting.isNull()) {
2264                 return NULL_SETTING_BUNDLE;
2265             }
2266             return Bundle.forPair(Settings.NameValueTable.VALUE, setting.getValue());
2267         }
2268         Bundle result = new Bundle();
2269         result.putString(Settings.NameValueTable.VALUE,
2270                 !setting.isNull() ? setting.getValue() : null);
2271 
2272         mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getKey());
2273         return result;
2274     }
2275 
2276     private Bundle packageValuesForCallResult(HashMap<String, String> keyValues,
2277             boolean trackingGeneration) {
2278         Bundle result = new Bundle();
2279         result.putSerializable(Settings.NameValueTable.VALUE, keyValues);
2280         if (trackingGeneration) {
2281             synchronized (mLock) {
2282                 mSettingsRegistry.mGenerationRegistry.addGenerationData(result,
2283                         mSettingsRegistry.getSettingsLocked(
2284                                 SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM).mKey);
2285             }
2286         }
2287 
2288         return result;
2289     }
2290 
2291     private void setMonitorCallback(RemoteCallback callback) {
2292         if (callback == null) {
2293             return;
2294         }
2295         getContext().enforceCallingOrSelfPermission(
2296                 Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS,
2297                 "Permission denial: registering for config access requires: "
2298                         + Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS);
2299         synchronized (mLock) {
2300             mConfigMonitorCallback = callback;
2301         }
2302     }
2303 
2304     private void reportDeviceConfigAccess(@Nullable String prefix) {
2305         if (prefix == null) {
2306             return;
2307         }
2308         String callingPackage = resolveCallingPackage();
2309         String namespace = prefix.replace("/", "");
2310         if (DeviceConfig.getPublicNamespaces().contains(namespace)) {
2311             return;
2312         }
2313         synchronized (mLock) {
2314             if (mConfigMonitorCallback != null) {
2315                 Bundle callbackResult = new Bundle();
2316                 callbackResult.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE,
2317                         Settings.EXTRA_ACCESS_CALLBACK);
2318                 callbackResult.putString(Settings.EXTRA_CALLING_PACKAGE, callingPackage);
2319                 callbackResult.putString(Settings.EXTRA_NAMESPACE, namespace);
2320                 mConfigMonitorCallback.sendResult(callbackResult);
2321             }
2322         }
2323     }
2324 
2325     private void reportDeviceConfigUpdate(@Nullable String prefix) {
2326         if (prefix == null) {
2327             return;
2328         }
2329         String namespace = prefix.replace("/", "");
2330         if (DeviceConfig.getPublicNamespaces().contains(namespace)) {
2331             return;
2332         }
2333         synchronized (mLock) {
2334             if (mConfigMonitorCallback != null) {
2335                 Bundle callbackResult = new Bundle();
2336                 callbackResult.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE,
2337                         Settings.EXTRA_NAMESPACE_UPDATED_CALLBACK);
2338                 callbackResult.putString(Settings.EXTRA_NAMESPACE, namespace);
2339                 mConfigMonitorCallback.sendResult(callbackResult);
2340             }
2341         }
2342     }
2343 
2344     private static int getRequestingUserId(Bundle args) {
2345         final int callingUserId = UserHandle.getCallingUserId();
2346         return (args != null) ? args.getInt(Settings.CALL_METHOD_USER_KEY, callingUserId)
2347                 : callingUserId;
2348     }
2349 
2350     private boolean isTrackingGeneration(Bundle args) {
2351         return args != null && args.containsKey(Settings.CALL_METHOD_TRACK_GENERATION_KEY);
2352     }
2353 
2354     private static String getSettingValue(Bundle args) {
2355         return (args != null) ? args.getString(Settings.NameValueTable.VALUE) : null;
2356     }
2357 
2358     private static String getSettingTag(Bundle args) {
2359         return (args != null) ? args.getString(Settings.CALL_METHOD_TAG_KEY) : null;
2360     }
2361 
2362     private static String getSettingPrefix(Bundle args) {
2363         return (args != null) ? args.getString(Settings.CALL_METHOD_PREFIX_KEY) : null;
2364     }
2365 
2366     private static Map<String, String> getSettingFlags(Bundle args) {
2367         return (args != null) ? (HashMap) args.getSerializable(Settings.CALL_METHOD_FLAGS_KEY)
2368                 : Collections.emptyMap();
2369     }
2370 
2371     private static boolean getSettingMakeDefault(Bundle args) {
2372         return (args != null) && args.getBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY);
2373     }
2374 
2375     private static boolean getSettingOverrideableByRestore(Bundle args) {
2376         return (args != null) && args.getBoolean(Settings.CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY);
2377     }
2378 
2379     private static int getSyncDisabledMode(Bundle args) {
2380         final int mode = (args != null)
2381                 ? args.getInt(Settings.CALL_METHOD_SYNC_DISABLED_MODE_KEY) : -1;
2382         if (mode == SYNC_DISABLED_MODE_NONE || mode == SYNC_DISABLED_MODE_UNTIL_REBOOT
2383                 || mode == SYNC_DISABLED_MODE_PERSISTENT) {
2384             return mode;
2385         }
2386         throw new IllegalArgumentException("Invalid sync disabled mode: " + mode);
2387     }
2388 
2389     private static int getResetModeEnforcingPermission(Bundle args) {
2390         final int mode = (args != null) ? args.getInt(Settings.CALL_METHOD_RESET_MODE_KEY) : 0;
2391         switch (mode) {
2392             case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
2393                 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
2394                     throw new SecurityException("Only system, shell/root on a "
2395                             + "debuggable build can reset to untrusted defaults");
2396                 }
2397                 return mode;
2398             }
2399             case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
2400                 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
2401                     throw new SecurityException("Only system, shell/root on a "
2402                             + "debuggable build can reset untrusted changes");
2403                 }
2404                 return mode;
2405             }
2406             case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
2407                 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
2408                     throw new SecurityException("Only system, shell/root on a "
2409                             + "debuggable build can reset to trusted defaults");
2410                 }
2411                 return mode;
2412             }
2413             case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
2414                 return mode;
2415             }
2416         }
2417         throw new IllegalArgumentException("Invalid reset mode: " + mode);
2418     }
2419 
2420     private static boolean isCallerSystemOrShellOrRootOnDebuggableBuild() {
2421         final int appId = UserHandle.getAppId(Binder.getCallingUid());
2422         return appId == SYSTEM_UID || (Build.IS_DEBUGGABLE
2423                 && (appId == SHELL_UID || appId == ROOT_UID));
2424     }
2425 
2426     private static String getValidTableOrThrow(Uri uri) {
2427         if (uri.getPathSegments().size() > 0) {
2428             String table = uri.getPathSegments().get(0);
2429             if (DatabaseHelper.isValidTable(table)) {
2430                 return table;
2431             }
2432             throw new IllegalArgumentException("Bad root path: " + table);
2433         }
2434         throw new IllegalArgumentException("Invalid URI:" + uri);
2435     }
2436 
2437     private static MatrixCursor packageSettingForQuery(Setting setting, String[] projection) {
2438         if (setting.isNull()) {
2439             return new MatrixCursor(projection, 0);
2440         }
2441         MatrixCursor cursor = new MatrixCursor(projection, 1);
2442         appendSettingToCursor(cursor, setting);
2443         return cursor;
2444     }
2445 
2446     private static String[] normalizeProjection(String[] projection) {
2447         if (projection == null) {
2448             return ALL_COLUMNS;
2449         }
2450 
2451         final int columnCount = projection.length;
2452         for (int i = 0; i < columnCount; i++) {
2453             String column = projection[i];
2454             if (!ArrayUtils.contains(ALL_COLUMNS, column)) {
2455                 throw new IllegalArgumentException("Invalid column: " + column);
2456             }
2457         }
2458 
2459         return projection;
2460     }
2461 
2462     private static void appendSettingToCursor(MatrixCursor cursor, Setting setting) {
2463         if (setting == null || setting.isNull()) {
2464             return;
2465         }
2466         final int columnCount = cursor.getColumnCount();
2467 
2468         String[] values =  new String[columnCount];
2469 
2470         for (int i = 0; i < columnCount; i++) {
2471             String column = cursor.getColumnName(i);
2472 
2473             switch (column) {
2474                 case Settings.NameValueTable._ID: {
2475                     values[i] = setting.getId();
2476                 } break;
2477 
2478                 case Settings.NameValueTable.NAME: {
2479                     values[i] = setting.getName();
2480                 } break;
2481 
2482                 case Settings.NameValueTable.VALUE: {
2483                     values[i] = setting.getValue();
2484                 } break;
2485 
2486                 case Settings.NameValueTable.IS_PRESERVED_IN_RESTORE: {
2487                     values[i] = String.valueOf(setting.isValuePreservedInRestore());
2488                 } break;
2489             }
2490         }
2491 
2492         cursor.addRow(values);
2493     }
2494 
2495     private static boolean isKeyValid(String key) {
2496         return !(TextUtils.isEmpty(key) || SettingsState.isBinary(key));
2497     }
2498 
2499     private String resolveCallingPackage() {
2500         switch (Binder.getCallingUid()) {
2501             case Process.ROOT_UID: {
2502                 return "root";
2503             }
2504 
2505             case Process.SHELL_UID: {
2506                 return "com.android.shell";
2507             }
2508 
2509             default: {
2510                 return getCallingPackage();
2511             }
2512         }
2513     }
2514 
2515     private static final class Arguments {
2516         private static final Pattern WHERE_PATTERN_WITH_PARAM_NO_BRACKETS =
2517                 Pattern.compile("[\\s]*name[\\s]*=[\\s]*\\?[\\s]*");
2518 
2519         private static final Pattern WHERE_PATTERN_WITH_PARAM_IN_BRACKETS =
2520                 Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*\\?[\\s]*\\)[\\s]*");
2521 
2522         private static final Pattern WHERE_PATTERN_NO_PARAM_IN_BRACKETS =
2523                 Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*\\)[\\s]*");
2524 
2525         private static final Pattern WHERE_PATTERN_NO_PARAM_NO_BRACKETS =
2526                 Pattern.compile("[\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*");
2527 
2528         public final String table;
2529         public final String name;
2530 
2531         public Arguments(Uri uri, String where, String[] whereArgs, boolean supportAll) {
2532             final int segmentSize = uri.getPathSegments().size();
2533             switch (segmentSize) {
2534                 case 1: {
2535                     if (where != null
2536                             && (WHERE_PATTERN_WITH_PARAM_NO_BRACKETS.matcher(where).matches()
2537                                 || WHERE_PATTERN_WITH_PARAM_IN_BRACKETS.matcher(where).matches())
2538                             && whereArgs.length == 1) {
2539                         name = whereArgs[0];
2540                         table = computeTableForSetting(uri, name);
2541                         return;
2542                     } else if (where != null
2543                             && (WHERE_PATTERN_NO_PARAM_NO_BRACKETS.matcher(where).matches()
2544                                 || WHERE_PATTERN_NO_PARAM_IN_BRACKETS.matcher(where).matches())) {
2545                         final int startIndex = Math.max(where.indexOf("'"),
2546                                 where.indexOf("\"")) + 1;
2547                         final int endIndex = Math.max(where.lastIndexOf("'"),
2548                                 where.lastIndexOf("\""));
2549                         name = where.substring(startIndex, endIndex);
2550                         table = computeTableForSetting(uri, name);
2551                         return;
2552                     } else if (supportAll && where == null && whereArgs == null) {
2553                         name = null;
2554                         table = computeTableForSetting(uri, null);
2555                         return;
2556                     }
2557                 } break;
2558 
2559                 case 2: {
2560                     if (where == null && whereArgs == null) {
2561                         name = uri.getPathSegments().get(1);
2562                         table = computeTableForSetting(uri, name);
2563                         return;
2564                     }
2565                 } break;
2566             }
2567 
2568             EventLogTags.writeUnsupportedSettingsQuery(
2569                     uri.toSafeString(), where, Arrays.toString(whereArgs));
2570             String message = String.format( "Supported SQL:\n"
2571                     + "  uri content://some_table/some_property with null where and where args\n"
2572                     + "  uri content://some_table with query name=? and single name as arg\n"
2573                     + "  uri content://some_table with query name=some_name and null args\n"
2574                     + "  but got - uri:%1s, where:%2s whereArgs:%3s", uri, where,
2575                     Arrays.toString(whereArgs));
2576             throw new IllegalArgumentException(message);
2577         }
2578 
2579         private static String computeTableForSetting(Uri uri, String name) {
2580             String table = getValidTableOrThrow(uri);
2581 
2582             if (name != null) {
2583                 if (sSystemMovedToSecureSettings.contains(name)) {
2584                     table = TABLE_SECURE;
2585                 }
2586 
2587                 if (sSystemMovedToGlobalSettings.contains(name)) {
2588                     table = TABLE_GLOBAL;
2589                 }
2590 
2591                 if (sSecureMovedToGlobalSettings.contains(name)) {
2592                     table = TABLE_GLOBAL;
2593                 }
2594 
2595                 if (sGlobalMovedToSecureSettings.contains(name)) {
2596                     table = TABLE_SECURE;
2597                 }
2598             }
2599 
2600             return table;
2601         }
2602     }
2603 
2604     /**
2605      * Schedule the job service to make a copy of all the settings files.
2606      */
2607     public void scheduleWriteFallbackFilesJob() {
2608         final Context context = getContext();
2609         final JobScheduler jobScheduler =
2610                 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
2611         if (jobScheduler == null) {
2612             // Might happen: SettingsProvider is created before JobSchedulerService in system server
2613             return;
2614         }
2615         // Check if the job is already scheduled. If so, skip scheduling another one
2616         if (jobScheduler.getPendingJob(WRITE_FALLBACK_SETTINGS_FILES_JOB_ID) != null) {
2617             return;
2618         }
2619         // Back up all settings files
2620         final PersistableBundle bundle = new PersistableBundle();
2621         final File globalSettingsFile = mSettingsRegistry.getSettingsFile(
2622                 makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM));
2623         final File systemSettingsFile = mSettingsRegistry.getSettingsFile(
2624                 makeKey(SETTINGS_TYPE_SYSTEM, UserHandle.USER_SYSTEM));
2625         final File secureSettingsFile = mSettingsRegistry.getSettingsFile(
2626                 makeKey(SETTINGS_TYPE_SECURE, UserHandle.USER_SYSTEM));
2627         final File ssaidSettingsFile = mSettingsRegistry.getSettingsFile(
2628                 makeKey(SETTINGS_TYPE_SSAID, UserHandle.USER_SYSTEM));
2629         final File configSettingsFile = mSettingsRegistry.getSettingsFile(
2630                 makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM));
2631         bundle.putString(TABLE_GLOBAL, globalSettingsFile.getAbsolutePath());
2632         bundle.putString(TABLE_SYSTEM, systemSettingsFile.getAbsolutePath());
2633         bundle.putString(TABLE_SECURE, secureSettingsFile.getAbsolutePath());
2634         bundle.putString(TABLE_SSAID, ssaidSettingsFile.getAbsolutePath());
2635         bundle.putString(TABLE_CONFIG, configSettingsFile.getAbsolutePath());
2636         // Schedule the job to write the fallback files, once daily when phone is charging
2637         jobScheduler.schedule(new JobInfo.Builder(WRITE_FALLBACK_SETTINGS_FILES_JOB_ID,
2638                 new ComponentName(context, WriteFallbackSettingsFilesJobService.class))
2639                 .setExtras(bundle)
2640                 .setPeriodic(ONE_DAY_INTERVAL_MILLIS)
2641                 .setRequiresCharging(true)
2642                 .setPersisted(true)
2643                 .build());
2644     }
2645 
2646     /**
2647      * For each file in the given list, if it exists, copy it to a back up file. Ignore failures.
2648      * @param filePaths List of paths of files that need to be backed up
2649      */
2650     public static void writeFallBackSettingsFiles(List<String> filePaths) {
2651         final int numFiles = filePaths.size();
2652         for (int i = 0; i < numFiles; i++) {
2653             final String filePath = filePaths.get(i);
2654             final File originalFile = new File(filePath);
2655             if (SettingsState.stateFileExists(originalFile)) {
2656                 final File fallBackFile = new File(filePath + FALLBACK_FILE_SUFFIX);
2657                 try {
2658                     FileUtils.copy(originalFile, fallBackFile);
2659                 } catch (IOException ex) {
2660                     Slog.w(LOG_TAG, "Failed to write fallback file for: " + filePath);
2661                 }
2662             }
2663         }
2664     }
2665 
2666     final class SettingsRegistry {
2667         private static final String DROPBOX_TAG_USERLOG = "restricted_profile_ssaid";
2668 
2669         private static final String SETTINGS_FILE_GLOBAL = "settings_global.xml";
2670         private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml";
2671         private static final String SETTINGS_FILE_SECURE = "settings_secure.xml";
2672         private static final String SETTINGS_FILE_SSAID = "settings_ssaid.xml";
2673         private static final String SETTINGS_FILE_CONFIG = "settings_config.xml";
2674 
2675         private static final String SSAID_USER_KEY = "userkey";
2676 
2677         private final SparseArray<SettingsState> mSettingsStates = new SparseArray<>();
2678 
2679         private GenerationRegistry mGenerationRegistry;
2680 
2681         private final Handler mHandler;
2682 
2683         private final BackupManager mBackupManager;
2684 
2685         private String mSettingsCreationBuildId;
2686 
2687         public SettingsRegistry() {
2688             mHandler = new MyHandler(getContext().getMainLooper());
2689             mGenerationRegistry = new GenerationRegistry(mLock);
2690             mBackupManager = new BackupManager(getContext());
2691         }
2692 
2693         private void generateUserKeyLocked(int userId) {
2694             // Generate a random key for each user used for creating a new ssaid.
2695             final byte[] keyBytes = new byte[32];
2696             final SecureRandom rand = new SecureRandom();
2697             rand.nextBytes(keyBytes);
2698 
2699             // Convert to string for storage in settings table.
2700             final String userKey = HexEncoding.encodeToString(keyBytes, true /* upperCase */);
2701 
2702             // Store the key in the ssaid table.
2703             final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
2704             final boolean success = ssaidSettings.insertSettingLocked(SSAID_USER_KEY, userKey, null,
2705                     true, SettingsState.SYSTEM_PACKAGE_NAME);
2706 
2707             if (!success) {
2708                 throw new IllegalStateException("Ssaid settings not accessible");
2709             }
2710         }
2711 
2712         private byte[] getLengthPrefix(byte[] data) {
2713             return ByteBuffer.allocate(4).putInt(data.length).array();
2714         }
2715 
2716         public Setting generateSsaidLocked(PackageInfo callingPkg, int userId) {
2717             // Read the user's key from the ssaid table.
2718             Setting userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
2719             if (userKeySetting == null || userKeySetting.isNull()
2720                     || userKeySetting.getValue() == null) {
2721                 // Lazy initialize and store the user key.
2722                 generateUserKeyLocked(userId);
2723                 userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
2724                 if (userKeySetting == null || userKeySetting.isNull()
2725                         || userKeySetting.getValue() == null) {
2726                     throw new IllegalStateException("User key not accessible");
2727                 }
2728             }
2729             final String userKey = userKeySetting.getValue();
2730             if (userKey == null || userKey.length() % 2 != 0) {
2731                 throw new IllegalStateException("User key invalid");
2732             }
2733 
2734             // Convert the user's key back to a byte array.
2735             final byte[] keyBytes = HexEncoding.decode(userKey);
2736 
2737             // Validate that the key is of expected length.
2738             // Keys are currently 32 bytes, but were once 16 bytes during Android O development.
2739             if (keyBytes.length != 16 && keyBytes.length != 32) {
2740                 throw new IllegalStateException("User key invalid");
2741             }
2742 
2743             final Mac m;
2744             try {
2745                 m = Mac.getInstance("HmacSHA256");
2746                 m.init(new SecretKeySpec(keyBytes, m.getAlgorithm()));
2747             } catch (NoSuchAlgorithmException e) {
2748                 throw new IllegalStateException("HmacSHA256 is not available", e);
2749             } catch (InvalidKeyException e) {
2750                 throw new IllegalStateException("Key is corrupted", e);
2751             }
2752 
2753             // Mac each of the developer signatures.
2754             for (int i = 0; i < callingPkg.signatures.length; i++) {
2755                 byte[] sig = callingPkg.signatures[i].toByteArray();
2756                 m.update(getLengthPrefix(sig), 0, 4);
2757                 m.update(sig);
2758             }
2759 
2760             // Convert result to a string for storage in settings table. Only want first 64 bits.
2761             final String ssaid = HexEncoding.encodeToString(m.doFinal(), false /* upperCase */)
2762                     .substring(0, 16);
2763 
2764             // Save the ssaid in the ssaid table.
2765             final String uid = Integer.toString(callingPkg.applicationInfo.uid);
2766             final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
2767             final boolean success = ssaidSettings.insertSettingLocked(uid, ssaid, null, true,
2768                 callingPkg.packageName);
2769 
2770             if (!success) {
2771                 throw new IllegalStateException("Ssaid settings not accessible");
2772             }
2773 
2774             return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
2775         }
2776 
2777         private void syncSsaidTableOnStartLocked() {
2778             // Verify that each user's packages and ssaid's are in sync.
2779             for (UserInfo user : mUserManager.getAliveUsers()) {
2780                 // Get all uids for the user's packages.
2781                 final List<PackageInfo> packages;
2782                 try {
2783                     packages = mPackageManager.getInstalledPackages(
2784                             PackageManager.MATCH_UNINSTALLED_PACKAGES,
2785                             user.id).getList();
2786                 } catch (RemoteException e) {
2787                     throw new IllegalStateException("Package manager not available");
2788                 }
2789                 final Set<String> appUids = new HashSet<>();
2790                 for (PackageInfo info : packages) {
2791                     appUids.add(Integer.toString(info.applicationInfo.uid));
2792                 }
2793 
2794                 // Get all uids currently stored in the user's ssaid table.
2795                 final Set<String> ssaidUids = new HashSet<>(
2796                         getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
2797                 ssaidUids.remove(SSAID_USER_KEY);
2798 
2799                 // Perform a set difference for the appUids and ssaidUids.
2800                 ssaidUids.removeAll(appUids);
2801 
2802                 // If there are ssaidUids left over they need to be removed from the table.
2803                 final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
2804                         user.id);
2805                 for (String uid : ssaidUids) {
2806                     ssaidSettings.deleteSettingLocked(uid);
2807                 }
2808             }
2809         }
2810 
2811         public List<String> getSettingsNamesLocked(int type, int userId) {
2812             final int key = makeKey(type, userId);
2813             SettingsState settingsState = peekSettingsStateLocked(key);
2814             if (settingsState == null) {
2815                 return new ArrayList<>();
2816             }
2817             return settingsState.getSettingNamesLocked();
2818         }
2819 
2820         public SparseBooleanArray getKnownUsersLocked() {
2821             SparseBooleanArray users = new SparseBooleanArray();
2822             for (int i = mSettingsStates.size()-1; i >= 0; i--) {
2823                 users.put(getUserIdFromKey(mSettingsStates.keyAt(i)), true);
2824             }
2825             return users;
2826         }
2827 
2828         @Nullable
2829         public SettingsState getSettingsLocked(int type, int userId) {
2830             final int key = makeKey(type, userId);
2831             return peekSettingsStateLocked(key);
2832         }
2833 
2834         public boolean ensureSettingsForUserLocked(int userId) {
2835             // First make sure this user actually exists.
2836             if (mUserManager.getUserInfo(userId) == null) {
2837                 Slog.wtf(LOG_TAG, "Requested user " + userId + " does not exist");
2838                 return false;
2839             }
2840 
2841             // Migrate the setting for this user if needed.
2842             migrateLegacySettingsForUserIfNeededLocked(userId);
2843 
2844             // Ensure config settings loaded if owner.
2845             if (userId == UserHandle.USER_SYSTEM) {
2846                 final int configKey
2847                         = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
2848                 ensureSettingsStateLocked(configKey);
2849             }
2850 
2851             // Ensure global settings loaded if owner.
2852             if (userId == UserHandle.USER_SYSTEM) {
2853                 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
2854                 ensureSettingsStateLocked(globalKey);
2855             }
2856 
2857             // Ensure secure settings loaded.
2858             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
2859             ensureSettingsStateLocked(secureKey);
2860 
2861             // Make sure the secure settings have an Android id set.
2862             SettingsState secureSettings = getSettingsLocked(SETTINGS_TYPE_SECURE, userId);
2863             ensureSecureSettingAndroidIdSetLocked(secureSettings);
2864 
2865             // Ensure system settings loaded.
2866             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
2867             ensureSettingsStateLocked(systemKey);
2868 
2869             // Ensure secure settings loaded.
2870             final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
2871             ensureSettingsStateLocked(ssaidKey);
2872 
2873             // Upgrade the settings to the latest version.
2874             UpgradeController upgrader = new UpgradeController(userId);
2875             upgrader.upgradeIfNeededLocked();
2876             return true;
2877         }
2878 
2879         private void ensureSettingsStateLocked(int key) {
2880             if (mSettingsStates.get(key) == null) {
2881                 final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key));
2882                 SettingsState settingsState = new SettingsState(getContext(), mLock,
2883                         getSettingsFile(key), key, maxBytesPerPackage, mHandlerThread.getLooper());
2884                 mSettingsStates.put(key, settingsState);
2885             }
2886         }
2887 
2888         public void removeUserStateLocked(int userId, boolean permanently) {
2889             // We always keep the global settings in memory.
2890 
2891             // Nuke system settings.
2892             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
2893             final SettingsState systemSettingsState = mSettingsStates.get(systemKey);
2894             if (systemSettingsState != null) {
2895                 if (permanently) {
2896                     mSettingsStates.remove(systemKey);
2897                     systemSettingsState.destroyLocked(null);
2898                 } else {
2899                     systemSettingsState.destroyLocked(new Runnable() {
2900                         @Override
2901                         public void run() {
2902                             mSettingsStates.remove(systemKey);
2903                         }
2904                     });
2905                 }
2906             }
2907 
2908             // Nuke secure settings.
2909             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
2910             final SettingsState secureSettingsState = mSettingsStates.get(secureKey);
2911             if (secureSettingsState != null) {
2912                 if (permanently) {
2913                     mSettingsStates.remove(secureKey);
2914                     secureSettingsState.destroyLocked(null);
2915                 } else {
2916                     secureSettingsState.destroyLocked(new Runnable() {
2917                         @Override
2918                         public void run() {
2919                             mSettingsStates.remove(secureKey);
2920                         }
2921                     });
2922                 }
2923             }
2924 
2925             // Nuke ssaid settings.
2926             final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
2927             final SettingsState ssaidSettingsState = mSettingsStates.get(ssaidKey);
2928             if (ssaidSettingsState != null) {
2929                 if (permanently) {
2930                     mSettingsStates.remove(ssaidKey);
2931                     ssaidSettingsState.destroyLocked(null);
2932                 } else {
2933                     ssaidSettingsState.destroyLocked(new Runnable() {
2934                         @Override
2935                         public void run() {
2936                             mSettingsStates.remove(ssaidKey);
2937                         }
2938                     });
2939                 }
2940             }
2941 
2942             // Nuke generation tracking data
2943             mGenerationRegistry.onUserRemoved(userId);
2944         }
2945 
2946         public boolean insertSettingLocked(int type, int userId, String name, String value,
2947                 String tag, boolean makeDefault, String packageName, boolean forceNotify,
2948                 Set<String> criticalSettings, boolean overrideableByRestore) {
2949             return insertSettingLocked(type, userId, name, value, tag, makeDefault, false,
2950                     packageName, forceNotify, criticalSettings, overrideableByRestore);
2951         }
2952 
2953         public boolean insertSettingLocked(int type, int userId, String name, String value,
2954                 String tag, boolean makeDefault, boolean forceNonSystemPackage, String packageName,
2955                 boolean forceNotify, Set<String> criticalSettings, boolean overrideableByRestore) {
2956             if (overrideableByRestore != Settings.DEFAULT_OVERRIDEABLE_BY_RESTORE) {
2957                 getContext().enforceCallingOrSelfPermission(
2958                         Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE,
2959                         "Caller is not allowed to modify settings overrideable by restore");
2960             }
2961             final int key = makeKey(type, userId);
2962 
2963             boolean success = false;
2964             SettingsState settingsState = peekSettingsStateLocked(key);
2965             if (settingsState != null) {
2966                 success = settingsState.insertSettingLocked(name, value,
2967                         tag, makeDefault, forceNonSystemPackage, packageName, overrideableByRestore);
2968             }
2969 
2970             if (success && criticalSettings != null && criticalSettings.contains(name)) {
2971                 settingsState.persistSyncLocked();
2972             }
2973 
2974             if (forceNotify || success) {
2975                 notifyForSettingsChange(key, name);
2976             }
2977             return success;
2978         }
2979 
2980         /**
2981          * Set Config Settings using consumed keyValues, returns true if the keyValues can be set,
2982          * false otherwise.
2983          */
2984         public boolean setConfigSettingsLocked(int key, String prefix,
2985                 Map<String, String> keyValues, String packageName) {
2986             SettingsState settingsState = peekSettingsStateLocked(key);
2987             if (settingsState != null) {
2988                 if (settingsState.isNewConfigBannedLocked(prefix, keyValues)) {
2989                     return false;
2990                 }
2991                 settingsState.unbanAllConfigIfBannedConfigUpdatedLocked(prefix);
2992                 List<String> changedSettings =
2993                         settingsState.setSettingsLocked(prefix, keyValues, packageName);
2994                 if (!changedSettings.isEmpty()) {
2995                     reportDeviceConfigUpdate(prefix);
2996                     notifyForConfigSettingsChangeLocked(key, prefix, changedSettings);
2997                 }
2998             }
2999             // keyValues aren't banned and can be set
3000             return true;
3001         }
3002 
3003         public boolean deleteSettingLocked(int type, int userId, String name, boolean forceNotify,
3004                 Set<String> criticalSettings) {
3005             final int key = makeKey(type, userId);
3006 
3007             boolean success = false;
3008             SettingsState settingsState = peekSettingsStateLocked(key);
3009             if (settingsState != null) {
3010                 success = settingsState.deleteSettingLocked(name);
3011             }
3012 
3013             if (success && criticalSettings != null && criticalSettings.contains(name)) {
3014                 settingsState.persistSyncLocked();
3015             }
3016 
3017             if (forceNotify || success) {
3018                 notifyForSettingsChange(key, name);
3019             }
3020             return success;
3021         }
3022 
3023         public boolean updateSettingLocked(int type, int userId, String name, String value,
3024                 String tag, boolean makeDefault, String packageName, boolean forceNotify,
3025                 Set<String> criticalSettings) {
3026             final int key = makeKey(type, userId);
3027 
3028             boolean success = false;
3029             SettingsState settingsState = peekSettingsStateLocked(key);
3030             if (settingsState != null) {
3031                 success = settingsState.updateSettingLocked(name, value, tag,
3032                         makeDefault, packageName);
3033             }
3034 
3035             if (success && criticalSettings != null && criticalSettings.contains(name)) {
3036                 settingsState.persistSyncLocked();
3037             }
3038 
3039             if (forceNotify || success) {
3040                 notifyForSettingsChange(key, name);
3041             }
3042 
3043             return success;
3044         }
3045 
3046         public Setting getSettingLocked(int type, int userId, String name) {
3047             final int key = makeKey(type, userId);
3048 
3049             SettingsState settingsState = peekSettingsStateLocked(key);
3050             if (settingsState == null) {
3051                 return null;
3052             }
3053 
3054             // getSettingLocked will return non-null result
3055             return settingsState.getSettingLocked(name);
3056         }
3057 
3058         public void resetSettingsLocked(int type, int userId, String packageName, int mode,
3059                 String tag) {
3060             resetSettingsLocked(type, userId, packageName, mode, tag, /*prefix=*/
3061                     null);
3062         }
3063 
3064         public void resetSettingsLocked(int type, int userId, String packageName, int mode,
3065                 String tag, @Nullable String prefix) {
3066             final int key = makeKey(type, userId);
3067             SettingsState settingsState = peekSettingsStateLocked(key);
3068             if (settingsState == null) {
3069                 return;
3070             }
3071 
3072             banConfigurationIfNecessary(type, prefix, settingsState);
3073             switch (mode) {
3074                 case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
3075                     for (String name : settingsState.getSettingNamesLocked()) {
3076                         boolean someSettingChanged = false;
3077                         Setting setting = settingsState.getSettingLocked(name);
3078                         if (packageName.equals(setting.getPackageName())) {
3079                             if ((tag != null && !tag.equals(setting.getTag()))
3080                                     || (prefix != null && !setting.getName().startsWith(prefix))) {
3081                                 continue;
3082                             }
3083                             if (settingsState.resetSettingLocked(name)) {
3084                                 someSettingChanged = true;
3085                                 notifyForSettingsChange(key, name);
3086                             }
3087                         }
3088                         if (someSettingChanged) {
3089                             settingsState.persistSyncLocked();
3090                         }
3091                     }
3092                 } break;
3093 
3094                 case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
3095                     for (String name : settingsState.getSettingNamesLocked()) {
3096                         boolean someSettingChanged = false;
3097                         Setting setting = settingsState.getSettingLocked(name);
3098                         if (!SettingsState.isSystemPackage(getContext(),
3099                                 setting.getPackageName())) {
3100                             if (prefix != null && !setting.getName().startsWith(prefix)) {
3101                                 continue;
3102                             }
3103                             if (settingsState.resetSettingLocked(name)) {
3104                                 someSettingChanged = true;
3105                                 notifyForSettingsChange(key, name);
3106                             }
3107                         }
3108                         if (someSettingChanged) {
3109                             settingsState.persistSyncLocked();
3110                         }
3111                     }
3112                 } break;
3113 
3114                 case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
3115                     for (String name : settingsState.getSettingNamesLocked()) {
3116                         boolean someSettingChanged = false;
3117                         Setting setting = settingsState.getSettingLocked(name);
3118                         if (!SettingsState.isSystemPackage(getContext(),
3119                                 setting.getPackageName())) {
3120                             if (prefix != null && !setting.getName().startsWith(prefix)) {
3121                                 continue;
3122                             }
3123                             if (setting.isDefaultFromSystem()) {
3124                                 if (settingsState.resetSettingLocked(name)) {
3125                                     someSettingChanged = true;
3126                                     notifyForSettingsChange(key, name);
3127                                 }
3128                             } else if (settingsState.deleteSettingLocked(name)) {
3129                                 someSettingChanged = true;
3130                                 notifyForSettingsChange(key, name);
3131                             }
3132                         }
3133                         if (someSettingChanged) {
3134                             settingsState.persistSyncLocked();
3135                         }
3136                     }
3137                 } break;
3138 
3139                 case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
3140                     for (String name : settingsState.getSettingNamesLocked()) {
3141                         Setting setting = settingsState.getSettingLocked(name);
3142                         boolean someSettingChanged = false;
3143                         if (prefix != null && !setting.getName().startsWith(prefix)) {
3144                             continue;
3145                         }
3146                         if (setting.isDefaultFromSystem()) {
3147                             if (settingsState.resetSettingLocked(name)) {
3148                                 someSettingChanged = true;
3149                                 notifyForSettingsChange(key, name);
3150                             }
3151                         } else if (settingsState.deleteSettingLocked(name)) {
3152                             someSettingChanged = true;
3153                             notifyForSettingsChange(key, name);
3154                         }
3155                         if (someSettingChanged) {
3156                             settingsState.persistSyncLocked();
3157                         }
3158                     }
3159                 } break;
3160             }
3161         }
3162 
3163         public void removeSettingsForPackageLocked(String packageName, int userId) {
3164             // Global and secure settings are signature protected. Apps signed
3165             // by the platform certificate are generally not uninstalled  and
3166             // the main exception is tests. We trust components signed
3167             // by the platform certificate and do not do a clean up after them.
3168 
3169             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
3170             SettingsState systemSettings = mSettingsStates.get(systemKey);
3171             if (systemSettings != null) {
3172                 systemSettings.removeSettingsForPackageLocked(packageName);
3173             }
3174         }
3175 
3176         public void onUidRemovedLocked(int uid) {
3177             final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
3178                     UserHandle.getUserId(uid));
3179             if (ssaidSettings != null) {
3180                 ssaidSettings.deleteSettingLocked(Integer.toString(uid));
3181             }
3182         }
3183 
3184         @Nullable
3185         private SettingsState peekSettingsStateLocked(int key) {
3186             SettingsState settingsState = mSettingsStates.get(key);
3187             if (settingsState != null) {
3188                 return settingsState;
3189             }
3190 
3191             if (!ensureSettingsForUserLocked(getUserIdFromKey(key))) {
3192                 return null;
3193             }
3194             return mSettingsStates.get(key);
3195         }
3196 
3197         private void migrateAllLegacySettingsIfNeededLocked() {
3198             final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
3199             File globalFile = getSettingsFile(key);
3200             if (SettingsState.stateFileExists(globalFile)) {
3201                 return;
3202             }
3203 
3204             mSettingsCreationBuildId = Build.ID;
3205 
3206             final long identity = Binder.clearCallingIdentity();
3207             try {
3208                 List<UserInfo> users = mUserManager.getAliveUsers();
3209 
3210                 final int userCount = users.size();
3211                 for (int i = 0; i < userCount; i++) {
3212                     final int userId = users.get(i).id;
3213 
3214                     DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
3215                     SQLiteDatabase database = dbHelper.getWritableDatabase();
3216                     migrateLegacySettingsForUserLocked(dbHelper, database, userId);
3217 
3218                     // Upgrade to the latest version.
3219                     UpgradeController upgrader = new UpgradeController(userId);
3220                     upgrader.upgradeIfNeededLocked();
3221 
3222                     // Drop from memory if not a running user.
3223                     if (!mUserManager.isUserRunning(new UserHandle(userId))) {
3224                         removeUserStateLocked(userId, false);
3225                     }
3226                 }
3227             } finally {
3228                 Binder.restoreCallingIdentity(identity);
3229             }
3230         }
3231 
3232         private void migrateLegacySettingsForUserIfNeededLocked(int userId) {
3233             // Every user has secure settings and if no file we need to migrate.
3234             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
3235             File secureFile = getSettingsFile(secureKey);
3236             if (SettingsState.stateFileExists(secureFile)) {
3237                 return;
3238             }
3239 
3240             DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
3241             SQLiteDatabase database = dbHelper.getWritableDatabase();
3242 
3243             migrateLegacySettingsForUserLocked(dbHelper, database, userId);
3244         }
3245 
3246         private void migrateLegacySettingsForUserLocked(DatabaseHelper dbHelper,
3247                 SQLiteDatabase database, int userId) {
3248             // Move over the system settings.
3249             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
3250             ensureSettingsStateLocked(systemKey);
3251             SettingsState systemSettings = mSettingsStates.get(systemKey);
3252             migrateLegacySettingsLocked(systemSettings, database, TABLE_SYSTEM);
3253             systemSettings.persistSyncLocked();
3254 
3255             // Move over the secure settings.
3256             // Do this after System settings, since this is the first thing we check when deciding
3257             // to skip over migration from db to xml for a secondary user.
3258             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
3259             ensureSettingsStateLocked(secureKey);
3260             SettingsState secureSettings = mSettingsStates.get(secureKey);
3261             migrateLegacySettingsLocked(secureSettings, database, TABLE_SECURE);
3262             ensureSecureSettingAndroidIdSetLocked(secureSettings);
3263             secureSettings.persistSyncLocked();
3264 
3265             // Move over the global settings if owner.
3266             // Do this last, since this is the first thing we check when deciding
3267             // to skip over migration from db to xml for owner user.
3268             if (userId == UserHandle.USER_SYSTEM) {
3269                 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, userId);
3270                 ensureSettingsStateLocked(globalKey);
3271                 SettingsState globalSettings = mSettingsStates.get(globalKey);
3272                 migrateLegacySettingsLocked(globalSettings, database, TABLE_GLOBAL);
3273                 // If this was just created
3274                 if (mSettingsCreationBuildId != null) {
3275                     globalSettings.insertSettingLocked(Settings.Global.DATABASE_CREATION_BUILDID,
3276                             mSettingsCreationBuildId, null, true,
3277                             SettingsState.SYSTEM_PACKAGE_NAME);
3278                 }
3279                 globalSettings.persistSyncLocked();
3280             }
3281 
3282             // Drop the database as now all is moved and persisted.
3283             if (DROP_DATABASE_ON_MIGRATION) {
3284                 dbHelper.dropDatabase();
3285             } else {
3286                 dbHelper.backupDatabase();
3287             }
3288         }
3289 
3290         private void migrateLegacySettingsLocked(SettingsState settingsState,
3291                 SQLiteDatabase database, String table) {
3292             SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
3293             queryBuilder.setTables(table);
3294 
3295             Cursor cursor = queryBuilder.query(database, LEGACY_SQL_COLUMNS,
3296                     null, null, null, null, null);
3297 
3298             if (cursor == null) {
3299                 return;
3300             }
3301 
3302             try {
3303                 if (!cursor.moveToFirst()) {
3304                     return;
3305                 }
3306 
3307                 final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME);
3308                 final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
3309 
3310                 settingsState.setVersionLocked(database.getVersion());
3311 
3312                 while (!cursor.isAfterLast()) {
3313                     String name = cursor.getString(nameColumnIdx);
3314                     String value = cursor.getString(valueColumnIdx);
3315                     settingsState.insertSettingLocked(name, value, null, true,
3316                             SettingsState.SYSTEM_PACKAGE_NAME);
3317                     cursor.moveToNext();
3318                 }
3319             } finally {
3320                 cursor.close();
3321             }
3322         }
3323 
3324         @GuardedBy("secureSettings.mLock")
3325         private void ensureSecureSettingAndroidIdSetLocked(SettingsState secureSettings) {
3326             Setting value = secureSettings.getSettingLocked(Settings.Secure.ANDROID_ID);
3327 
3328             if (!value.isNull()) {
3329                 return;
3330             }
3331 
3332             final int userId = getUserIdFromKey(secureSettings.mKey);
3333 
3334             final UserInfo user;
3335             final long identity = Binder.clearCallingIdentity();
3336             try {
3337                 user = mUserManager.getUserInfo(userId);
3338             } finally {
3339                 Binder.restoreCallingIdentity(identity);
3340             }
3341             if (user == null) {
3342                 // Can happen due to races when deleting users - treat as benign.
3343                 return;
3344             }
3345 
3346             String androidId = Long.toHexString(new SecureRandom().nextLong());
3347             secureSettings.insertSettingLocked(Settings.Secure.ANDROID_ID, androidId,
3348                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3349 
3350             Slog.d(LOG_TAG, "Generated and saved new ANDROID_ID [" + androidId
3351                     + "] for user " + userId);
3352 
3353             // Write a drop box entry if it's a restricted profile
3354             if (user.isRestricted()) {
3355                 DropBoxManager dbm = (DropBoxManager) getContext().getSystemService(
3356                         Context.DROPBOX_SERVICE);
3357                 if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
3358                     dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis()
3359                             + "," + DROPBOX_TAG_USERLOG + "," + androidId + "\n");
3360                 }
3361             }
3362         }
3363 
3364         private void notifyForSettingsChange(int key, String name) {
3365             // Increment the generation first, so observers always see the new value
3366             mGenerationRegistry.incrementGeneration(key);
3367 
3368             if (isGlobalSettingsKey(key) || isConfigSettingsKey(key)) {
3369                 final long token = Binder.clearCallingIdentity();
3370                 try {
3371                     notifySettingChangeForRunningUsers(key, name);
3372                 } finally {
3373                     Binder.restoreCallingIdentity(token);
3374                 }
3375             } else {
3376                 final int userId = getUserIdFromKey(key);
3377                 final Uri uri = getNotificationUriFor(key, name);
3378                 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
3379                         userId, 0, uri).sendToTarget();
3380                 if (isSecureSettingsKey(key)) {
3381                     maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
3382                             sSecureCloneToManagedSettings);
3383                     maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name,
3384                             sSystemCloneFromParentOnDependency.values());
3385                 } else if (isSystemSettingsKey(key)) {
3386                     maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
3387                             sSystemCloneToManagedSettings);
3388                 }
3389             }
3390 
3391             // Always notify that our data changed
3392             mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget();
3393         }
3394 
3395         private void notifyForConfigSettingsChangeLocked(int key, String prefix,
3396                 List<String> changedSettings) {
3397 
3398             // Increment the generation first, so observers always see the new value
3399             mGenerationRegistry.incrementGeneration(key);
3400 
3401             StringBuilder stringBuilder = new StringBuilder(prefix);
3402             for (int i = 0; i < changedSettings.size(); ++i) {
3403                 stringBuilder.append(changedSettings.get(i).split("/")[1]).append("/");
3404             }
3405 
3406             final long token = Binder.clearCallingIdentity();
3407             try {
3408                 notifySettingChangeForRunningUsers(key, stringBuilder.toString());
3409             } finally {
3410                 Binder.restoreCallingIdentity(token);
3411             }
3412 
3413             // Always notify that our data changed
3414             mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget();
3415         }
3416 
3417         private void maybeNotifyProfiles(int type, int userId, Uri uri, String name,
3418                 Collection<String> keysCloned) {
3419             if (keysCloned.contains(name)) {
3420                 for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
3421                     // the notification for userId has already been sent.
3422                     if (profileId != userId) {
3423                         final int key = makeKey(type, profileId);
3424                         // Increment the generation first, so observers always see the new value
3425                         mGenerationRegistry.incrementGeneration(key);
3426                         mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
3427                                 profileId, 0, uri).sendToTarget();
3428                     }
3429                 }
3430             }
3431         }
3432 
3433         private void notifySettingChangeForRunningUsers(int key, String name) {
3434             // Important: No need to update generation for each user as there
3435             // is a singleton generation entry for the global settings which
3436             // is already incremented be the caller.
3437             final Uri uri = getNotificationUriFor(key, name);
3438             final List<UserInfo> users = mUserManager.getAliveUsers();
3439             for (int i = 0; i < users.size(); i++) {
3440                 final int userId = users.get(i).id;
3441                 if (mUserManager.isUserRunning(UserHandle.of(userId))) {
3442                     mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
3443                             userId, 0, uri).sendToTarget();
3444                 }
3445             }
3446         }
3447 
3448         private boolean isConfigSettingsKey(int key) {
3449             return getTypeFromKey(key) == SETTINGS_TYPE_CONFIG;
3450         }
3451 
3452         private boolean isGlobalSettingsKey(int key) {
3453             return getTypeFromKey(key) == SETTINGS_TYPE_GLOBAL;
3454         }
3455 
3456         private boolean isSystemSettingsKey(int key) {
3457             return getTypeFromKey(key) == SETTINGS_TYPE_SYSTEM;
3458         }
3459 
3460         private boolean isSecureSettingsKey(int key) {
3461             return getTypeFromKey(key) == SETTINGS_TYPE_SECURE;
3462         }
3463 
3464         private boolean isSsaidSettingsKey(int key) {
3465             return getTypeFromKey(key) == SETTINGS_TYPE_SSAID;
3466         }
3467 
3468         private boolean shouldBan(int type) {
3469             if (SETTINGS_TYPE_CONFIG != type) {
3470                 return false;
3471             }
3472             final int callingUid = Binder.getCallingUid();
3473             final int appId = UserHandle.getAppId(callingUid);
3474 
3475             // Only non-shell resets should result in namespace banning
3476             return appId != SHELL_UID;
3477         }
3478 
3479         private void banConfigurationIfNecessary(int type, @Nullable String prefix,
3480                 SettingsState settingsState) {
3481             // Banning should be performed only for Settings.Config and for non-shell reset calls
3482             if (!shouldBan(type)) {
3483                 return;
3484             }
3485             if (prefix != null) {
3486                 settingsState.banConfigurationLocked(prefix, getAllConfigFlags(prefix));
3487             } else {
3488                 Set<String> configPrefixes = settingsState.getAllConfigPrefixesLocked();
3489                 for (String configPrefix : configPrefixes) {
3490                     settingsState.banConfigurationLocked(configPrefix,
3491                             getAllConfigFlags(configPrefix));
3492                 }
3493             }
3494         }
3495 
3496         private File getSettingsFile(int key) {
3497             if (isConfigSettingsKey(key)) {
3498                 final int userId = getUserIdFromKey(key);
3499                 return new File(Environment.getUserSystemDirectory(userId),
3500                         SETTINGS_FILE_CONFIG);
3501             } else if (isGlobalSettingsKey(key)) {
3502                 final int userId = getUserIdFromKey(key);
3503                 return new File(Environment.getUserSystemDirectory(userId),
3504                         SETTINGS_FILE_GLOBAL);
3505             } else if (isSystemSettingsKey(key)) {
3506                 final int userId = getUserIdFromKey(key);
3507                 return new File(Environment.getUserSystemDirectory(userId),
3508                         SETTINGS_FILE_SYSTEM);
3509             } else if (isSecureSettingsKey(key)) {
3510                 final int userId = getUserIdFromKey(key);
3511                 return new File(Environment.getUserSystemDirectory(userId),
3512                         SETTINGS_FILE_SECURE);
3513             } else if (isSsaidSettingsKey(key)) {
3514                 final int userId = getUserIdFromKey(key);
3515                 return new File(Environment.getUserSystemDirectory(userId),
3516                         SETTINGS_FILE_SSAID);
3517             } else {
3518                 throw new IllegalArgumentException("Invalid settings key:" + key);
3519             }
3520         }
3521 
3522         private Uri getNotificationUriFor(int key, String name) {
3523             if (isConfigSettingsKey(key)) {
3524                 return (name != null) ? Uri.withAppendedPath(DeviceConfig.CONTENT_URI, name)
3525                         : DeviceConfig.CONTENT_URI;
3526             } else if (isGlobalSettingsKey(key)) {
3527                 return (name != null) ? Uri.withAppendedPath(Settings.Global.CONTENT_URI, name)
3528                         : Settings.Global.CONTENT_URI;
3529             } else if (isSecureSettingsKey(key)) {
3530                 return (name != null) ? Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name)
3531                         : Settings.Secure.CONTENT_URI;
3532             } else if (isSystemSettingsKey(key)) {
3533                 return (name != null) ? Uri.withAppendedPath(Settings.System.CONTENT_URI, name)
3534                         : Settings.System.CONTENT_URI;
3535             } else {
3536                 throw new IllegalArgumentException("Invalid settings key:" + key);
3537             }
3538         }
3539 
3540         private int getMaxBytesPerPackageForType(int type) {
3541             switch (type) {
3542                 case SETTINGS_TYPE_CONFIG:
3543                 case SETTINGS_TYPE_GLOBAL:
3544                 case SETTINGS_TYPE_SECURE:
3545                 case SETTINGS_TYPE_SSAID: {
3546                     return SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED;
3547                 }
3548 
3549                 default: {
3550                     return SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED;
3551                 }
3552             }
3553         }
3554 
3555         private final class MyHandler extends Handler {
3556             private static final int MSG_NOTIFY_URI_CHANGED = 1;
3557             private static final int MSG_NOTIFY_DATA_CHANGED = 2;
3558 
3559             public MyHandler(Looper looper) {
3560                 super(looper);
3561             }
3562 
3563             @Override
3564             public void handleMessage(Message msg) {
3565                 switch (msg.what) {
3566                     case MSG_NOTIFY_URI_CHANGED: {
3567                         final int userId = msg.arg1;
3568                         Uri uri = (Uri) msg.obj;
3569                         try {
3570                             getContext().getContentResolver().notifyChange(uri, null, true, userId);
3571                         } catch (SecurityException e) {
3572                             Slog.w(LOG_TAG, "Failed to notify for " + userId + ": " + uri, e);
3573                         }
3574                         if (DEBUG) {
3575                             Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri);
3576                         }
3577                     } break;
3578 
3579                     case MSG_NOTIFY_DATA_CHANGED: {
3580                         mBackupManager.dataChanged();
3581                         scheduleWriteFallbackFilesJob();
3582                     } break;
3583                 }
3584             }
3585         }
3586 
3587         private final class UpgradeController {
3588             private static final int SETTINGS_VERSION = 204;
3589 
3590             private final int mUserId;
3591 
3592             public UpgradeController(int userId) {
3593                 mUserId = userId;
3594             }
3595 
3596             public void upgradeIfNeededLocked() {
3597                 // The version of all settings for a user is the same (all users have secure).
3598                 SettingsState secureSettings = getSettingsLocked(
3599                         SETTINGS_TYPE_SECURE, mUserId);
3600 
3601                 // Try an update from the current state.
3602                 final int oldVersion = secureSettings.getVersionLocked();
3603                 final int newVersion = SETTINGS_VERSION;
3604 
3605                 // If up do date - done.
3606                 if (oldVersion == newVersion) {
3607                     return;
3608                 }
3609 
3610                 // Try to upgrade.
3611                 final int curVersion = onUpgradeLocked(mUserId, oldVersion, newVersion);
3612 
3613                 // If upgrade failed start from scratch and upgrade.
3614                 if (curVersion != newVersion) {
3615                     // Drop state we have for this user.
3616                     removeUserStateLocked(mUserId, true);
3617 
3618                     // Recreate the database.
3619                     DatabaseHelper dbHelper = new DatabaseHelper(getContext(), mUserId);
3620                     SQLiteDatabase database = dbHelper.getWritableDatabase();
3621                     dbHelper.recreateDatabase(database, newVersion, curVersion, oldVersion);
3622 
3623                     // Migrate the settings for this user.
3624                     migrateLegacySettingsForUserLocked(dbHelper, database, mUserId);
3625 
3626                     // Now upgrade should work fine.
3627                     onUpgradeLocked(mUserId, oldVersion, newVersion);
3628 
3629                     // Make a note what happened, so we don't wonder why data was lost
3630                     String reason = "Settings rebuilt! Current version: "
3631                             + curVersion + " while expected: " + newVersion;
3632                     getGlobalSettingsLocked().insertSettingLocked(
3633                             Settings.Global.DATABASE_DOWNGRADE_REASON,
3634                             reason, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3635                 }
3636 
3637                 // Set the global settings version if owner.
3638                 if (mUserId == UserHandle.USER_SYSTEM) {
3639                     SettingsState globalSettings = getSettingsLocked(
3640                             SETTINGS_TYPE_GLOBAL, mUserId);
3641                     globalSettings.setVersionLocked(newVersion);
3642                 }
3643 
3644                 // Set the secure settings version.
3645                 secureSettings.setVersionLocked(newVersion);
3646 
3647                 // Set the system settings version.
3648                 SettingsState systemSettings = getSettingsLocked(
3649                         SETTINGS_TYPE_SYSTEM, mUserId);
3650                 systemSettings.setVersionLocked(newVersion);
3651             }
3652 
3653             private SettingsState getGlobalSettingsLocked() {
3654                 return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
3655             }
3656 
3657             private SettingsState getSecureSettingsLocked(int userId) {
3658                 return getSettingsLocked(SETTINGS_TYPE_SECURE, userId);
3659             }
3660 
3661             private SettingsState getSsaidSettingsLocked(int userId) {
3662                 return getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
3663             }
3664 
3665             private SettingsState getSystemSettingsLocked(int userId) {
3666                 return getSettingsLocked(SETTINGS_TYPE_SYSTEM, userId);
3667             }
3668 
3669             /**
3670              * You must perform all necessary mutations to bring the settings
3671              * for this user from the old to the new version. When you add a new
3672              * upgrade step you *must* update SETTINGS_VERSION.
3673              *
3674              * All settings modifications should be made through
3675              * {@link SettingsState#insertSettingOverrideableByRestoreLocked(String, String, String,
3676              * boolean, String)} so that restore can override those values if needed.
3677              *
3678              * This is an example of moving a setting from secure to global.
3679              *
3680              * // v119: Example settings changes.
3681              * if (currentVersion == 118) {
3682              *     if (userId == UserHandle.USER_OWNER) {
3683              *         // Remove from the secure settings.
3684              *         SettingsState secureSettings = getSecureSettingsLocked(userId);
3685              *         String name = "example_setting_to_move";
3686              *         String value = secureSettings.getSetting(name);
3687              *         secureSettings.deleteSetting(name);
3688              *
3689              *         // Add to the global settings.
3690              *         SettingsState globalSettings = getGlobalSettingsLocked();
3691              *         globalSettings.insertSetting(name, value, SettingsState.SYSTEM_PACKAGE_NAME);
3692              *     }
3693              *
3694              *     // Update the current version.
3695              *     currentVersion = 119;
3696              * }
3697              */
3698             private int onUpgradeLocked(int userId, int oldVersion, int newVersion) {
3699                 if (DEBUG) {
3700                     Slog.w(LOG_TAG, "Upgrading settings for user: " + userId + " from version: "
3701                             + oldVersion + " to version: " + newVersion);
3702                 }
3703 
3704                 int currentVersion = oldVersion;
3705 
3706                 // v119: Reset zen + ringer mode.
3707                 if (currentVersion == 118) {
3708                     if (userId == UserHandle.USER_SYSTEM) {
3709                         final SettingsState globalSettings = getGlobalSettingsLocked();
3710                         globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE,
3711                                 Integer.toString(Settings.Global.ZEN_MODE_OFF), null,
3712                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
3713                         globalSettings.updateSettingLocked(Settings.Global.MODE_RINGER,
3714                                 Integer.toString(AudioManager.RINGER_MODE_NORMAL), null,
3715                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
3716                     }
3717                     currentVersion = 119;
3718                 }
3719 
3720                 // v120: Add double tap to wake setting.
3721                 if (currentVersion == 119) {
3722                     SettingsState secureSettings = getSecureSettingsLocked(userId);
3723                     secureSettings.insertSettingOverrideableByRestoreLocked(
3724                             Settings.Secure.DOUBLE_TAP_TO_WAKE,
3725                             getContext().getResources().getBoolean(
3726                                     R.bool.def_double_tap_to_wake) ? "1" : "0", null, true,
3727                             SettingsState.SYSTEM_PACKAGE_NAME);
3728 
3729                     currentVersion = 120;
3730                 }
3731 
3732                 if (currentVersion == 120) {
3733                     // Before 121, we used a different string encoding logic.  We just bump the
3734                     // version here; SettingsState knows how to handle pre-version 120 files.
3735                     currentVersion = 121;
3736                 }
3737 
3738                 if (currentVersion == 121) {
3739                     // Version 122: allow OEMs to set a default payment component in resources.
3740                     // Note that we only write the default if no default has been set;
3741                     // if there is, we just leave the default at whatever it currently is.
3742                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
3743                     String defaultComponent = (getContext().getResources().getString(
3744                             R.string.def_nfc_payment_component));
3745                     Setting currentSetting = secureSettings.getSettingLocked(
3746                             Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
3747                     if (defaultComponent != null && !defaultComponent.isEmpty() &&
3748                         currentSetting.isNull()) {
3749                         secureSettings.insertSettingOverrideableByRestoreLocked(
3750                                 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
3751                                 defaultComponent, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3752                     }
3753                     currentVersion = 122;
3754                 }
3755 
3756                 if (currentVersion == 122) {
3757                     // Version 123: Adding a default value for the ability to add a user from
3758                     // the lock screen.
3759                     if (userId == UserHandle.USER_SYSTEM) {
3760                         final SettingsState globalSettings = getGlobalSettingsLocked();
3761                         Setting currentSetting = globalSettings.getSettingLocked(
3762                                 Settings.Global.ADD_USERS_WHEN_LOCKED);
3763                         if (currentSetting.isNull()) {
3764                             globalSettings.insertSettingOverrideableByRestoreLocked(
3765                                     Settings.Global.ADD_USERS_WHEN_LOCKED,
3766                                     getContext().getResources().getBoolean(
3767                                             R.bool.def_add_users_from_lockscreen) ? "1" : "0",
3768                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3769                         }
3770                     }
3771                     currentVersion = 123;
3772                 }
3773 
3774                 if (currentVersion == 123) {
3775                     final SettingsState globalSettings = getGlobalSettingsLocked();
3776                     String defaultDisabledProfiles = (getContext().getResources().getString(
3777                             R.string.def_bluetooth_disabled_profiles));
3778                     globalSettings.insertSettingOverrideableByRestoreLocked(
3779                             Settings.Global.BLUETOOTH_DISABLED_PROFILES, defaultDisabledProfiles,
3780                             null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3781                     currentVersion = 124;
3782                 }
3783 
3784                 if (currentVersion == 124) {
3785                     // Version 124: allow OEMs to set a default value for whether IME should be
3786                     // shown when a physical keyboard is connected.
3787                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
3788                     Setting currentSetting = secureSettings.getSettingLocked(
3789                             Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
3790                     if (currentSetting.isNull()) {
3791                         secureSettings.insertSettingOverrideableByRestoreLocked(
3792                                 Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
3793                                 getContext().getResources().getBoolean(
3794                                         R.bool.def_show_ime_with_hard_keyboard) ? "1" : "0",
3795                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3796                     }
3797                     currentVersion = 125;
3798                 }
3799 
3800                 if (currentVersion == 125) {
3801                     // Version 125: Allow OEMs to set the default VR service.
3802                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
3803 
3804                     Setting currentSetting = secureSettings.getSettingLocked(
3805                             Settings.Secure.ENABLED_VR_LISTENERS);
3806                     if (currentSetting.isNull()) {
3807                         ArraySet<ComponentName> l =
3808                                 SystemConfig.getInstance().getDefaultVrComponents();
3809 
3810                         if (l != null && !l.isEmpty()) {
3811                             StringBuilder b = new StringBuilder();
3812                             boolean start = true;
3813                             for (ComponentName c : l) {
3814                                 if (!start) {
3815                                     b.append(':');
3816                                 }
3817                                 b.append(c.flattenToString());
3818                                 start = false;
3819                             }
3820                             secureSettings.insertSettingOverrideableByRestoreLocked(
3821                                     Settings.Secure.ENABLED_VR_LISTENERS, b.toString(),
3822                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3823                         }
3824 
3825                     }
3826                     currentVersion = 126;
3827                 }
3828 
3829                 if (currentVersion == 126) {
3830                     // Version 126: copy the primary values of LOCK_SCREEN_SHOW_NOTIFICATIONS and
3831                     // LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS into managed profile.
3832                     if (mUserManager.isManagedProfile(userId)) {
3833                         final SettingsState systemSecureSettings =
3834                                 getSecureSettingsLocked(UserHandle.USER_SYSTEM);
3835 
3836                         final Setting showNotifications = systemSecureSettings.getSettingLocked(
3837                                 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
3838                         if (!showNotifications.isNull()) {
3839                             final SettingsState secureSettings = getSecureSettingsLocked(userId);
3840                             secureSettings.insertSettingOverrideableByRestoreLocked(
3841                                     Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
3842                                     showNotifications.getValue(), null, true,
3843                                     SettingsState.SYSTEM_PACKAGE_NAME);
3844                         }
3845 
3846                         final Setting allowPrivate = systemSecureSettings.getSettingLocked(
3847                                 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
3848                         if (!allowPrivate.isNull()) {
3849                             final SettingsState secureSettings = getSecureSettingsLocked(userId);
3850                             secureSettings.insertSettingOverrideableByRestoreLocked(
3851                                     Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
3852                                     allowPrivate.getValue(), null, true,
3853                                     SettingsState.SYSTEM_PACKAGE_NAME);
3854                         }
3855                     }
3856                     currentVersion = 127;
3857                 }
3858 
3859                 if (currentVersion == 127) {
3860                     // version 127 is no longer used.
3861                     currentVersion = 128;
3862                 }
3863 
3864                 if (currentVersion == 128) {
3865                     // Version 128: Removed
3866                     currentVersion = 129;
3867                 }
3868 
3869                 if (currentVersion == 129) {
3870                     // default longpress timeout changed from 500 to 400. If unchanged from the old
3871                     // default, update to the new default.
3872                     final SettingsState systemSecureSettings =
3873                             getSecureSettingsLocked(userId);
3874                     final String oldValue = systemSecureSettings.getSettingLocked(
3875                             Settings.Secure.LONG_PRESS_TIMEOUT).getValue();
3876                     if (TextUtils.equals("500", oldValue)) {
3877                         systemSecureSettings.insertSettingOverrideableByRestoreLocked(
3878                                 Settings.Secure.LONG_PRESS_TIMEOUT,
3879                                 String.valueOf(getContext().getResources().getInteger(
3880                                         R.integer.def_long_press_timeout_millis)),
3881                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3882                     }
3883                     currentVersion = 130;
3884                 }
3885 
3886                 if (currentVersion == 130) {
3887                     // Split Ambient settings
3888                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
3889                     boolean dozeExplicitlyDisabled = "0".equals(secureSettings.
3890                             getSettingLocked(Settings.Secure.DOZE_ENABLED).getValue());
3891 
3892                     if (dozeExplicitlyDisabled) {
3893                         secureSettings.insertSettingOverrideableByRestoreLocked(
3894                                 Settings.Secure.DOZE_PICK_UP_GESTURE, "0", null, true,
3895                                 SettingsState.SYSTEM_PACKAGE_NAME);
3896                         secureSettings.insertSettingOverrideableByRestoreLocked(
3897                                 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, "0", null, true,
3898                                 SettingsState.SYSTEM_PACKAGE_NAME);
3899                     }
3900                     currentVersion = 131;
3901                 }
3902 
3903                 if (currentVersion == 131) {
3904                     // Initialize new multi-press timeout to default value
3905                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
3906                     final String oldValue = systemSecureSettings.getSettingLocked(
3907                             Settings.Secure.MULTI_PRESS_TIMEOUT).getValue();
3908                     if (TextUtils.equals(null, oldValue)) {
3909                         systemSecureSettings.insertSettingOverrideableByRestoreLocked(
3910                                 Settings.Secure.MULTI_PRESS_TIMEOUT,
3911                                 String.valueOf(getContext().getResources().getInteger(
3912                                         R.integer.def_multi_press_timeout_millis)),
3913                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3914                     }
3915 
3916                     currentVersion = 132;
3917                 }
3918 
3919                 if (currentVersion == 132) {
3920                     // Version 132: Allow managed profile to optionally use the parent's ringtones
3921                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
3922                     String defaultSyncParentSounds = (getContext().getResources()
3923                             .getBoolean(R.bool.def_sync_parent_sounds) ? "1" : "0");
3924                     systemSecureSettings.insertSettingOverrideableByRestoreLocked(
3925                             Settings.Secure.SYNC_PARENT_SOUNDS, defaultSyncParentSounds,
3926                             null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3927                     currentVersion = 133;
3928                 }
3929 
3930                 if (currentVersion == 133) {
3931                     // Version 133: Add default end button behavior
3932                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
3933                     if (systemSettings.getSettingLocked(Settings.System.END_BUTTON_BEHAVIOR)
3934                             .isNull()) {
3935                         String defaultEndButtonBehavior = Integer.toString(getContext()
3936                                 .getResources().getInteger(R.integer.def_end_button_behavior));
3937                         systemSettings.insertSettingOverrideableByRestoreLocked(
3938                                 Settings.System.END_BUTTON_BEHAVIOR, defaultEndButtonBehavior, null,
3939                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
3940                     }
3941                     currentVersion = 134;
3942                 }
3943 
3944                 if (currentVersion == 134) {
3945                     // Remove setting that specifies if magnification values should be preserved.
3946                     // This setting defaulted to true and never has a UI.
3947                     getSecureSettingsLocked(userId).deleteSettingLocked(
3948                             Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE);
3949                     currentVersion = 135;
3950                 }
3951 
3952                 if (currentVersion == 135) {
3953                     // Version 135 no longer used.
3954                     currentVersion = 136;
3955                 }
3956 
3957                 if (currentVersion == 136) {
3958                     // Version 136: Store legacy SSAID for all apps currently installed on the
3959                     // device as first step in migrating SSAID to be unique per application.
3960 
3961                     final boolean isUpgrade;
3962                     try {
3963                         isUpgrade = mPackageManager.isDeviceUpgrading();
3964                     } catch (RemoteException e) {
3965                         throw new IllegalStateException("Package manager not available");
3966                     }
3967                     // Only retain legacy ssaid if the device is performing an OTA. After wiping
3968                     // user data or first boot on a new device should use new ssaid generation.
3969                     if (isUpgrade) {
3970                         // Retrieve the legacy ssaid from the secure settings table.
3971                         final Setting legacySsaidSetting = getSettingLocked(SETTINGS_TYPE_SECURE,
3972                                 userId, Settings.Secure.ANDROID_ID);
3973                         if (legacySsaidSetting == null || legacySsaidSetting.isNull()
3974                                 || legacySsaidSetting.getValue() == null) {
3975                             throw new IllegalStateException("Legacy ssaid not accessible");
3976                         }
3977                         final String legacySsaid = legacySsaidSetting.getValue();
3978 
3979                         // Fill each uid with the legacy ssaid to be backwards compatible.
3980                         final List<PackageInfo> packages;
3981                         try {
3982                             packages = mPackageManager.getInstalledPackages(
3983                                 PackageManager.MATCH_UNINSTALLED_PACKAGES,
3984                                 userId).getList();
3985                         } catch (RemoteException e) {
3986                             throw new IllegalStateException("Package manager not available");
3987                         }
3988 
3989                         final SettingsState ssaidSettings = getSsaidSettingsLocked(userId);
3990                         for (PackageInfo info : packages) {
3991                             // Check if the UID already has an entry in the table.
3992                             final String uid = Integer.toString(info.applicationInfo.uid);
3993                             final Setting ssaid = ssaidSettings.getSettingLocked(uid);
3994 
3995                             if (ssaid.isNull() || ssaid.getValue() == null) {
3996                                 // Android Id doesn't exist for this package so create it.
3997                                 ssaidSettings.insertSettingOverrideableByRestoreLocked(uid,
3998                                         legacySsaid, null, true, info.packageName);
3999                                 if (DEBUG) {
4000                                     Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid);
4001                                 }
4002                             }
4003                         }
4004                     }
4005 
4006                     currentVersion = 137;
4007                 }
4008                 if (currentVersion == 137) {
4009                     // Version 138: Settings.Secure#INSTALL_NON_MARKET_APPS is deprecated and its
4010                     // default value set to 1. The user can no longer change the value of this
4011                     // setting through the UI.
4012                     final SettingsState secureSetting = getSecureSettingsLocked(userId);
4013                     if (!mUserManager.hasUserRestriction(
4014                             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, UserHandle.of(userId))
4015                             && secureSetting.getSettingLocked(
4016                             Settings.Secure.INSTALL_NON_MARKET_APPS).getValue().equals("0")) {
4017 
4018                         secureSetting.insertSettingOverrideableByRestoreLocked(
4019                                 Settings.Secure.INSTALL_NON_MARKET_APPS, "1", null, true,
4020                                 SettingsState.SYSTEM_PACKAGE_NAME);
4021                         // For managed profiles with profile owners, DevicePolicyManagerService
4022                         // may want to set the user restriction in this case
4023                         secureSetting.insertSettingOverrideableByRestoreLocked(
4024                                 Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, "1", null,
4025                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
4026                     }
4027                     currentVersion = 138;
4028                 }
4029 
4030                 if (currentVersion == 138) {
4031                     // Version 139: Removed.
4032                     currentVersion = 139;
4033                 }
4034 
4035                 if (currentVersion == 139) {
4036                     // Version 140: Settings.Secure#ACCESSIBILITY_SPEAK_PASSWORD is deprecated and
4037                     // the user can no longer change the value of this setting through the UI.
4038                     // Force to true.
4039                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4040                     secureSettings.updateSettingLocked(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
4041                             "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4042                     currentVersion = 140;
4043                 }
4044 
4045                 if (currentVersion == 140) {
4046                     // Version 141: Removed
4047                     currentVersion = 141;
4048                 }
4049 
4050                 if (currentVersion == 141) {
4051                     // This implementation was incorrectly setting the current value of
4052                     // settings changed by non-system packages as the default which default
4053                     // is set by the system. We add a new upgrade step at the end to properly
4054                     // handle this case which would also fix incorrect changes made by the
4055                     // old implementation of this step.
4056                     currentVersion = 142;
4057                 }
4058 
4059                 if (currentVersion == 142) {
4060                     // Version 143: Set a default value for Wi-Fi wakeup feature.
4061                     if (userId == UserHandle.USER_SYSTEM) {
4062                         final SettingsState globalSettings = getGlobalSettingsLocked();
4063                         Setting currentSetting = globalSettings.getSettingLocked(
4064                                 Settings.Global.WIFI_WAKEUP_ENABLED);
4065                         if (currentSetting.isNull()) {
4066                             globalSettings.insertSettingOverrideableByRestoreLocked(
4067                                     Settings.Global.WIFI_WAKEUP_ENABLED,
4068                                     getContext().getResources().getBoolean(
4069                                             R.bool.def_wifi_wakeup_enabled) ? "1" : "0",
4070                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4071                         }
4072                     }
4073 
4074                     currentVersion = 143;
4075                 }
4076 
4077                 if (currentVersion == 143) {
4078                     // Version 144: Set a default value for Autofill service.
4079                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4080                     final Setting currentSetting = secureSettings
4081                             .getSettingLocked(Settings.Secure.AUTOFILL_SERVICE);
4082                     if (currentSetting.isNull()) {
4083                         final String defaultValue = getContext().getResources().getString(
4084                                 com.android.internal.R.string.config_defaultAutofillService);
4085                         if (defaultValue != null) {
4086                             Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as Autofill Service "
4087                                     + "for user " + userId);
4088                             secureSettings.insertSettingOverrideableByRestoreLocked(
4089                                     Settings.Secure.AUTOFILL_SERVICE, defaultValue, null, true,
4090                                     SettingsState.SYSTEM_PACKAGE_NAME);
4091                         }
4092                     }
4093 
4094                     currentVersion = 144;
4095                 }
4096 
4097                 if (currentVersion == 144) {
4098                     // Version 145: Removed
4099                     currentVersion = 145;
4100                 }
4101 
4102                 if (currentVersion == 145) {
4103                     // Version 146: In step 142 we had a bug where incorrectly
4104                     // some settings were considered system set and as a result
4105                     // made the default and marked as the default being set by
4106                     // the system. Here reevaluate the default and default system
4107                     // set flags. This would both fix corruption by the old impl
4108                     // of step 142 and also properly handle devices which never
4109                     // run 142.
4110                     if (userId == UserHandle.USER_SYSTEM) {
4111                         SettingsState globalSettings = getGlobalSettingsLocked();
4112                         ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings, userId);
4113                         globalSettings.persistSyncLocked();
4114                     }
4115 
4116                     SettingsState secureSettings = getSecureSettingsLocked(mUserId);
4117                     ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings, userId);
4118                     secureSettings.persistSyncLocked();
4119 
4120                     SettingsState systemSettings = getSystemSettingsLocked(mUserId);
4121                     ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings, userId);
4122                     systemSettings.persistSyncLocked();
4123 
4124                     currentVersion = 146;
4125                 }
4126 
4127                 if (currentVersion == 146) {
4128                     // Version 147: Removed. (This version previously allowed showing the
4129                     // "wifi_wakeup_available" setting).
4130                     // The setting that was added here is deleted in 153.
4131                     currentVersion = 147;
4132                 }
4133 
4134                 if (currentVersion == 147) {
4135                     // Version 148: Set the default value for DEFAULT_RESTRICT_BACKGROUND_DATA.
4136                     if (userId == UserHandle.USER_SYSTEM) {
4137                         final SettingsState globalSettings = getGlobalSettingsLocked();
4138                         final Setting currentSetting = globalSettings.getSettingLocked(
4139                                 Global.DEFAULT_RESTRICT_BACKGROUND_DATA);
4140                         if (currentSetting.isNull()) {
4141                             globalSettings.insertSettingOverrideableByRestoreLocked(
4142                                     Global.DEFAULT_RESTRICT_BACKGROUND_DATA,
4143                                     getContext().getResources().getBoolean(
4144                                             R.bool.def_restrict_background_data) ? "1" : "0",
4145                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4146                         }
4147                     }
4148                     currentVersion = 148;
4149                 }
4150 
4151                 if (currentVersion == 148) {
4152                     // Version 149: Set the default value for BACKUP_MANAGER_CONSTANTS.
4153                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
4154                     final String oldValue = systemSecureSettings.getSettingLocked(
4155                             Settings.Secure.BACKUP_MANAGER_CONSTANTS).getValue();
4156                     if (TextUtils.equals(null, oldValue)) {
4157                         final String defaultValue = getContext().getResources().getString(
4158                                 R.string.def_backup_manager_constants);
4159                         if (!TextUtils.isEmpty(defaultValue)) {
4160                             systemSecureSettings.insertSettingOverrideableByRestoreLocked(
4161                                     Settings.Secure.BACKUP_MANAGER_CONSTANTS, defaultValue, null,
4162                                     true, SettingsState.SYSTEM_PACKAGE_NAME);
4163                         }
4164                     }
4165                     currentVersion = 149;
4166                 }
4167 
4168                 if (currentVersion == 149) {
4169                     // Version 150: Set a default value for mobile data always on
4170                     final SettingsState globalSettings = getGlobalSettingsLocked();
4171                     final Setting currentSetting = globalSettings.getSettingLocked(
4172                             Settings.Global.MOBILE_DATA_ALWAYS_ON);
4173                     if (currentSetting.isNull()) {
4174                         globalSettings.insertSettingOverrideableByRestoreLocked(
4175                                 Settings.Global.MOBILE_DATA_ALWAYS_ON,
4176                                 getContext().getResources().getBoolean(
4177                                         R.bool.def_mobile_data_always_on) ? "1" : "0",
4178                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4179                     }
4180 
4181                     currentVersion = 150;
4182                 }
4183 
4184                 if (currentVersion == 150) {
4185                     // Version 151: Removed.
4186                     currentVersion = 151;
4187                 }
4188 
4189                 if (currentVersion == 151) {
4190                     // Version 152: Removed. (This version made the setting for wifi_wakeup enabled
4191                     // by default but it is now no longer configurable).
4192                     // The setting updated here is deleted in 153.
4193                     currentVersion = 152;
4194                 }
4195 
4196                 if (currentVersion == 152) {
4197                     getGlobalSettingsLocked().deleteSettingLocked("wifi_wakeup_available");
4198                     currentVersion = 153;
4199                 }
4200 
4201                 if (currentVersion == 153) {
4202                     // Version 154: Read notification badge configuration from config.
4203                     // If user has already set the value, don't do anything.
4204                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
4205                     final Setting showNotificationBadges = systemSecureSettings.getSettingLocked(
4206                             Settings.Secure.NOTIFICATION_BADGING);
4207                     if (showNotificationBadges.isNull()) {
4208                         final boolean defaultValue = getContext().getResources().getBoolean(
4209                                 com.android.internal.R.bool.config_notificationBadging);
4210                         systemSecureSettings.insertSettingOverrideableByRestoreLocked(
4211                                 Secure.NOTIFICATION_BADGING,
4212                                 defaultValue ? "1" : "0",
4213                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4214                     }
4215                     currentVersion = 154;
4216                 }
4217 
4218                 if (currentVersion == 154) {
4219                     // Version 155: Set the default value for BACKUP_LOCAL_TRANSPORT_PARAMETERS.
4220                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
4221                     final String oldValue = systemSecureSettings.getSettingLocked(
4222                             Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS).getValue();
4223                     if (TextUtils.equals(null, oldValue)) {
4224                         final String defaultValue = getContext().getResources().getString(
4225                                 R.string.def_backup_local_transport_parameters);
4226                         if (!TextUtils.isEmpty(defaultValue)) {
4227                             systemSecureSettings.insertSettingOverrideableByRestoreLocked(
4228                                     Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS, defaultValue,
4229                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4230                         }
4231 
4232                     }
4233                     currentVersion = 155;
4234                 }
4235 
4236                 if (currentVersion == 155) {
4237                     // Version 156: migrated to version 184
4238                     currentVersion = 156;
4239                 }
4240 
4241                 if (currentVersion == 156) {
4242                     // Version 157: Set a default value for zen duration,
4243                     // in version 169, zen duration is moved to secure settings
4244                     final SettingsState globalSettings = getGlobalSettingsLocked();
4245                     final Setting currentSetting = globalSettings.getSettingLocked(
4246                             Global.ZEN_DURATION);
4247                     if (currentSetting.isNull()) {
4248                         String defaultZenDuration = Integer.toString(getContext()
4249                                 .getResources().getInteger(R.integer.def_zen_duration));
4250                         globalSettings.insertSettingOverrideableByRestoreLocked(
4251                                 Global.ZEN_DURATION, defaultZenDuration,
4252                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4253                     }
4254                     currentVersion = 157;
4255                 }
4256 
4257                 if (currentVersion == 157) {
4258                     // Version 158: Set default value for BACKUP_AGENT_TIMEOUT_PARAMETERS.
4259                     final SettingsState globalSettings = getGlobalSettingsLocked();
4260                     final String oldValue = globalSettings.getSettingLocked(
4261                             Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS).getValue();
4262                     if (TextUtils.equals(null, oldValue)) {
4263                         final String defaultValue = getContext().getResources().getString(
4264                                 R.string.def_backup_agent_timeout_parameters);
4265                         if (!TextUtils.isEmpty(defaultValue)) {
4266                             globalSettings.insertSettingOverrideableByRestoreLocked(
4267                                     Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS, defaultValue,
4268                                     null, true,
4269                                     SettingsState.SYSTEM_PACKAGE_NAME);
4270                         }
4271                     }
4272                     currentVersion = 158;
4273                 }
4274 
4275                 if (currentVersion == 158) {
4276                     // Remove setting that specifies wifi bgscan throttling params
4277                     getGlobalSettingsLocked().deleteSettingLocked(
4278                         "wifi_scan_background_throttle_interval_ms");
4279                     getGlobalSettingsLocked().deleteSettingLocked(
4280                         "wifi_scan_background_throttle_package_whitelist");
4281                     currentVersion = 159;
4282                 }
4283 
4284                 if (currentVersion == 159) {
4285                     // Version 160: Hiding notifications from the lockscreen is only available as
4286                     // primary user option, profiles can only make them redacted. If a profile was
4287                     // configured to not show lockscreen notifications, ensure that at the very
4288                     // least these will be come hidden.
4289                     if (mUserManager.isManagedProfile(userId)) {
4290                         final SettingsState secureSettings = getSecureSettingsLocked(userId);
4291                         Setting showNotifications = secureSettings.getSettingLocked(
4292                             Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
4293                         // The default value is "1", check if user has turned it off.
4294                         if ("0".equals(showNotifications.getValue())) {
4295                             secureSettings.insertSettingOverrideableByRestoreLocked(
4296                                 Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, "0",
4297                                 null /* tag */, false /* makeDefault */,
4298                                 SettingsState.SYSTEM_PACKAGE_NAME);
4299                         }
4300                         // The setting is no longer valid for managed profiles, it should be
4301                         // treated as if it was set to "1".
4302                         secureSettings.deleteSettingLocked(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
4303                     }
4304                     currentVersion = 160;
4305                 }
4306 
4307                 if (currentVersion == 160) {
4308                     // Version 161: Set the default value for
4309                     // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY and
4310                     // SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT
4311                     final SettingsState globalSettings = getGlobalSettingsLocked();
4312 
4313                     String oldValue = globalSettings.getSettingLocked(
4314                             Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY).getValue();
4315                     if (TextUtils.equals(null, oldValue)) {
4316                         globalSettings.insertSettingOverrideableByRestoreLocked(
4317                                 Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
4318                                 Integer.toString(getContext().getResources().getInteger(
4319                                         R.integer.def_max_sound_trigger_detection_service_ops_per_day)),
4320                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4321                     }
4322 
4323                     oldValue = globalSettings.getSettingLocked(
4324                             Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT).getValue();
4325                     if (TextUtils.equals(null, oldValue)) {
4326                         globalSettings.insertSettingOverrideableByRestoreLocked(
4327                                 Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT,
4328                                 Integer.toString(getContext().getResources().getInteger(
4329                                         R.integer.def_sound_trigger_detection_service_op_timeout)),
4330                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4331                     }
4332                     currentVersion = 161;
4333                 }
4334 
4335                 if (currentVersion == 161) {
4336                     // Version 161: Add a gesture for silencing phones
4337                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4338                     final Setting currentSetting = secureSettings.getSettingLocked(
4339                             Secure.VOLUME_HUSH_GESTURE);
4340                     if (currentSetting.isNull()) {
4341                         secureSettings.insertSettingOverrideableByRestoreLocked(
4342                                 Secure.VOLUME_HUSH_GESTURE,
4343                                 Integer.toString(Secure.VOLUME_HUSH_VIBRATE),
4344                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4345                     }
4346 
4347                     currentVersion = 162;
4348                 }
4349 
4350                 if (currentVersion == 162) {
4351                     // Version 162: REMOVED: Add a gesture for silencing phones
4352                     currentVersion = 163;
4353                 }
4354 
4355                 if (currentVersion == 163) {
4356                     // Version 163: Update default value of
4357                     // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY from old to new default
4358                     final SettingsState settings = getGlobalSettingsLocked();
4359                     final Setting currentSetting = settings.getSettingLocked(
4360                             Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY);
4361                     if (currentSetting.isDefaultFromSystem()) {
4362                         settings.insertSettingOverrideableByRestoreLocked(
4363                                 Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
4364                                 Integer.toString(getContext().getResources().getInteger(
4365                                         R.integer
4366                                         .def_max_sound_trigger_detection_service_ops_per_day)),
4367                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4368                     }
4369 
4370                     currentVersion = 164;
4371                 }
4372 
4373                 if (currentVersion == 164) {
4374                     // Version 164: REMOVED: show zen upgrade notification
4375                     currentVersion = 165;
4376                 }
4377 
4378                 if (currentVersion == 165) {
4379                     // Version 165: MOVED: Show zen settings suggestion and zen updated settings
4380                     // moved to secure settings and are set in version 169
4381                     currentVersion = 166;
4382                 }
4383 
4384                 if (currentVersion == 166) {
4385                     // Version 166: add default values for hush gesture used and manual ringer
4386                     // toggle
4387                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4388                     Setting currentHushUsedSetting = secureSettings.getSettingLocked(
4389                             Secure.HUSH_GESTURE_USED);
4390                     if (currentHushUsedSetting.isNull()) {
4391                         secureSettings.insertSettingOverrideableByRestoreLocked(
4392                                 Settings.Secure.HUSH_GESTURE_USED, "0", null, true,
4393                                 SettingsState.SYSTEM_PACKAGE_NAME);
4394                     }
4395 
4396                     Setting currentRingerToggleCountSetting = secureSettings.getSettingLocked(
4397                             Secure.MANUAL_RINGER_TOGGLE_COUNT);
4398                     if (currentRingerToggleCountSetting.isNull()) {
4399                         secureSettings.insertSettingOverrideableByRestoreLocked(
4400                                 Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, "0", null, true,
4401                                 SettingsState.SYSTEM_PACKAGE_NAME);
4402                     }
4403                     currentVersion = 167;
4404                 }
4405 
4406                 if (currentVersion == 167) {
4407                     // Version 167: MOVED - Settings.Global.CHARGING_VIBRATION_ENABLED moved to
4408                     // Settings.Secure.CHARGING_VIBRATION_ENABLED, set in version 170
4409                     currentVersion = 168;
4410                 }
4411 
4412                 if (currentVersion == 168) {
4413                     // Version 168: by default, vibrate for phone calls
4414                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
4415                     final Setting currentSetting = systemSettings.getSettingLocked(
4416                             Settings.System.VIBRATE_WHEN_RINGING);
4417                     if (currentSetting.isNull()) {
4418                         systemSettings.insertSettingOverrideableByRestoreLocked(
4419                                 Settings.System.VIBRATE_WHEN_RINGING,
4420                                 getContext().getResources().getBoolean(
4421                                         R.bool.def_vibrate_when_ringing) ? "1" : "0",
4422                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4423                     }
4424                     currentVersion = 169;
4425                 }
4426 
4427                 if (currentVersion == 169) {
4428                     // Version 169: Set the default value for Secure Settings ZEN_DURATION,
4429                     // SHOW_ZEN_SETTINGS_SUGGESTION, ZEN_SETTINGS_UPDATE and
4430                     // ZEN_SETTINGS_SUGGESTION_VIEWED
4431 
4432                     final SettingsState globalSettings = getGlobalSettingsLocked();
4433                     final Setting globalZenDuration = globalSettings.getSettingLocked(
4434                             Global.ZEN_DURATION);
4435 
4436                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4437                     final Setting secureZenDuration = secureSettings.getSettingLocked(
4438                             Secure.ZEN_DURATION);
4439 
4440                     // ZEN_DURATION
4441                     if (!globalZenDuration.isNull()) {
4442                         secureSettings.insertSettingOverrideableByRestoreLocked(
4443                                 Secure.ZEN_DURATION, globalZenDuration.getValue(), null, false,
4444                                 SettingsState.SYSTEM_PACKAGE_NAME);
4445 
4446                         // set global zen duration setting to null since it's deprecated
4447                         globalSettings.insertSettingOverrideableByRestoreLocked(
4448                                 Global.ZEN_DURATION, null, null, true,
4449                                 SettingsState.SYSTEM_PACKAGE_NAME);
4450                     } else if (secureZenDuration.isNull()) {
4451                         String defaultZenDuration = Integer.toString(getContext()
4452                                 .getResources().getInteger(R.integer.def_zen_duration));
4453                         secureSettings.insertSettingOverrideableByRestoreLocked(
4454                                 Secure.ZEN_DURATION, defaultZenDuration, null, true,
4455                                 SettingsState.SYSTEM_PACKAGE_NAME);
4456                     }
4457 
4458                     // SHOW_ZEN_SETTINGS_SUGGESTION
4459                     final Setting currentShowZenSettingSuggestion = secureSettings.getSettingLocked(
4460                             Secure.SHOW_ZEN_SETTINGS_SUGGESTION);
4461                     if (currentShowZenSettingSuggestion.isNull()) {
4462                         secureSettings.insertSettingOverrideableByRestoreLocked(
4463                                 Secure.SHOW_ZEN_SETTINGS_SUGGESTION, "1",
4464                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4465                     }
4466 
4467                     // ZEN_SETTINGS_UPDATED
4468                     final Setting currentUpdatedSetting = secureSettings.getSettingLocked(
4469                             Secure.ZEN_SETTINGS_UPDATED);
4470                     if (currentUpdatedSetting.isNull()) {
4471                         secureSettings.insertSettingOverrideableByRestoreLocked(
4472                                 Secure.ZEN_SETTINGS_UPDATED, "0",
4473                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4474                     }
4475 
4476                     // ZEN_SETTINGS_SUGGESTION_VIEWED
4477                     final Setting currentSettingSuggestionViewed = secureSettings.getSettingLocked(
4478                             Secure.ZEN_SETTINGS_SUGGESTION_VIEWED);
4479                     if (currentSettingSuggestionViewed.isNull()) {
4480                         secureSettings.insertSettingOverrideableByRestoreLocked(
4481                                 Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, "0",
4482                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4483                     }
4484 
4485                     currentVersion = 170;
4486                 }
4487 
4488                 if (currentVersion == 170) {
4489                     // Version 170: Set the default value for Secure Settings:
4490                     // CHARGING_SOUNDS_ENABLED and CHARGING_VIBRATION_ENABLED
4491 
4492                     final SettingsState globalSettings = getGlobalSettingsLocked();
4493                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4494 
4495                     // CHARGING_SOUNDS_ENABLED
4496                     final Setting globalChargingSoundEnabled = globalSettings.getSettingLocked(
4497                             Global.CHARGING_SOUNDS_ENABLED);
4498                     final Setting secureChargingSoundsEnabled = secureSettings.getSettingLocked(
4499                             Secure.CHARGING_SOUNDS_ENABLED);
4500 
4501                     if (!globalChargingSoundEnabled.isNull()) {
4502                         if (secureChargingSoundsEnabled.isNull()) {
4503                             secureSettings.insertSettingOverrideableByRestoreLocked(
4504                                     Secure.CHARGING_SOUNDS_ENABLED,
4505                                     globalChargingSoundEnabled.getValue(), null, false,
4506                                     SettingsState.SYSTEM_PACKAGE_NAME);
4507                         }
4508 
4509                         // set global charging_sounds_enabled setting to null since it's deprecated
4510                         globalSettings.insertSettingOverrideableByRestoreLocked(
4511                                 Global.CHARGING_SOUNDS_ENABLED, null, null, true,
4512                                 SettingsState.SYSTEM_PACKAGE_NAME);
4513                     } else if (secureChargingSoundsEnabled.isNull()) {
4514                         String defChargingSoundsEnabled = getContext().getResources()
4515                                 .getBoolean(R.bool.def_charging_sounds_enabled) ? "1" : "0";
4516                         secureSettings.insertSettingOverrideableByRestoreLocked(
4517                                 Secure.CHARGING_SOUNDS_ENABLED, defChargingSoundsEnabled, null,
4518                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
4519                     }
4520 
4521                     // CHARGING_VIBRATION_ENABLED
4522                     final Setting secureChargingVibrationEnabled = secureSettings.getSettingLocked(
4523                             Secure.CHARGING_VIBRATION_ENABLED);
4524 
4525                     if (secureChargingVibrationEnabled.isNull()) {
4526                         String defChargingVibrationEnabled = getContext().getResources()
4527                                 .getBoolean(R.bool.def_charging_vibration_enabled) ? "1" : "0";
4528                         secureSettings.insertSettingOverrideableByRestoreLocked(
4529                                 Secure.CHARGING_VIBRATION_ENABLED, defChargingVibrationEnabled,
4530                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4531                     }
4532 
4533                     currentVersion = 171;
4534                 }
4535 
4536                 if (currentVersion == 171) {
4537                     // Version 171: by default, add STREAM_VOICE_CALL to list of streams that can
4538                     // be muted.
4539                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
4540                     final Setting currentSetting = systemSettings.getSettingLocked(
4541                               Settings.System.MUTE_STREAMS_AFFECTED);
4542                     if (!currentSetting.isNull()) {
4543                         try {
4544                             int currentSettingIntegerValue = Integer.parseInt(
4545                                     currentSetting.getValue());
4546                             if ((currentSettingIntegerValue
4547                                  & (1 << AudioManager.STREAM_VOICE_CALL)) == 0) {
4548                                 systemSettings.insertSettingOverrideableByRestoreLocked(
4549                                     Settings.System.MUTE_STREAMS_AFFECTED,
4550                                     Integer.toString(
4551                                         currentSettingIntegerValue
4552                                         | (1 << AudioManager.STREAM_VOICE_CALL)),
4553                                     null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4554                             }
4555                         } catch (NumberFormatException e) {
4556                             // remove the setting in case it is not a valid integer
4557                             Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED"
4558                                    + "setting, removing setting", e);
4559                             systemSettings.deleteSettingLocked(
4560                                 Settings.System.MUTE_STREAMS_AFFECTED);
4561                         }
4562 
4563                     }
4564                     currentVersion = 172;
4565                 }
4566 
4567                 if (currentVersion == 172) {
4568                     // Version 172: Set the default value for Secure Settings: LOCATION_MODE
4569 
4570                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4571 
4572                     final Setting locationMode = secureSettings.getSettingLocked(
4573                             Secure.LOCATION_MODE);
4574 
4575                     if (locationMode.isNull()) {
4576                         final Setting locationProvidersAllowed = secureSettings.getSettingLocked(
4577                                 Secure.LOCATION_PROVIDERS_ALLOWED);
4578 
4579                         final int defLocationMode;
4580                         if (locationProvidersAllowed.isNull()) {
4581                             defLocationMode = getContext().getResources().getInteger(
4582                                     R.integer.def_location_mode);
4583                         } else {
4584                             defLocationMode =
4585                                     !TextUtils.isEmpty(locationProvidersAllowed.getValue())
4586                                             ? Secure.LOCATION_MODE_ON
4587                                             : Secure.LOCATION_MODE_OFF;
4588                         }
4589                         secureSettings.insertSettingOverrideableByRestoreLocked(
4590                                 Secure.LOCATION_MODE, Integer.toString(defLocationMode),
4591                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4592                     }
4593 
4594                     currentVersion = 173;
4595                 }
4596 
4597                 if (currentVersion == 173) {
4598                     // Version 173: Set the default value for Secure Settings: NOTIFICATION_BUBBLES
4599                     // Removed. Moved NOTIFICATION_BUBBLES to Global Settings.
4600                     currentVersion = 174;
4601                 }
4602 
4603                 if (currentVersion == 174) {
4604                     // Version 174: Set the default value for Global Settings: APPLY_RAMPING_RINGER
4605 
4606                     final SettingsState globalSettings = getGlobalSettingsLocked();
4607 
4608                     Setting currentRampingRingerSetting = globalSettings.getSettingLocked(
4609                             Settings.Global.APPLY_RAMPING_RINGER);
4610                     if (currentRampingRingerSetting.isNull()) {
4611                         globalSettings.insertSettingOverrideableByRestoreLocked(
4612                                 Settings.Global.APPLY_RAMPING_RINGER,
4613                                 getContext().getResources().getBoolean(
4614                                         R.bool.def_apply_ramping_ringer) ? "1" : "0", null,
4615                                 true, SettingsState.SYSTEM_PACKAGE_NAME);
4616                     }
4617 
4618                     currentVersion = 175;
4619                 }
4620 
4621                 if (currentVersion == 175) {
4622                     // Version 175: Set the default value for System Settings:
4623                     // RING_VIBRATION_INTENSITY. If the notification vibration intensity has been
4624                     // set and ring vibration intensity hasn't, the ring vibration intensity should
4625                     // followed notification vibration intensity.
4626 
4627                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
4628 
4629                     Setting notificationVibrationIntensity = systemSettings.getSettingLocked(
4630                             Settings.System.NOTIFICATION_VIBRATION_INTENSITY);
4631 
4632                     Setting ringVibrationIntensity = systemSettings.getSettingLocked(
4633                             Settings.System.RING_VIBRATION_INTENSITY);
4634 
4635                     if (!notificationVibrationIntensity.isNull()
4636                             && ringVibrationIntensity.isNull()) {
4637                         systemSettings.insertSettingOverrideableByRestoreLocked(
4638                                 Settings.System.RING_VIBRATION_INTENSITY,
4639                                 notificationVibrationIntensity.getValue(),
4640                                 null , true, SettingsState.SYSTEM_PACKAGE_NAME);
4641                     }
4642 
4643                     currentVersion = 176;
4644                 }
4645 
4646                 if (currentVersion == 176) {
4647                     // Version 176: Migrate the existing swipe up setting into the resource overlay
4648                     //              for the navigation bar interaction mode.  We do so only if the
4649                     //              setting is set.
4650 
4651                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4652                     final Setting swipeUpSetting = secureSettings.getSettingLocked(
4653                             "swipe_up_to_switch_apps_enabled");
4654                     if (swipeUpSetting != null && !swipeUpSetting.isNull()
4655                             && swipeUpSetting.getValue().equals("1")) {
4656                         final IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
4657                                 ServiceManager.getService(Context.OVERLAY_SERVICE));
4658                         try {
4659                             overlayManager.setEnabledExclusiveInCategory(
4660                                     NAV_BAR_MODE_2BUTTON_OVERLAY, UserHandle.USER_CURRENT);
4661                         } catch (SecurityException | IllegalStateException | RemoteException e) {
4662                             throw new IllegalStateException(
4663                                     "Failed to set nav bar interaction mode overlay");
4664                         }
4665                     }
4666 
4667                     currentVersion = 177;
4668                 }
4669 
4670                 if (currentVersion == 177) {
4671                     // Version 177: Set the default value for Secure Settings: AWARE_ENABLED
4672 
4673                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4674 
4675                     final Setting awareEnabled = secureSettings.getSettingLocked(
4676                             Secure.AWARE_ENABLED);
4677 
4678                     if (awareEnabled.isNull()) {
4679                         final boolean defAwareEnabled = getContext().getResources().getBoolean(
4680                                 R.bool.def_aware_enabled);
4681                         secureSettings.insertSettingOverrideableByRestoreLocked(
4682                                 Secure.AWARE_ENABLED, defAwareEnabled ? "1" : "0",
4683                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4684                     }
4685 
4686                     currentVersion = 178;
4687                 }
4688 
4689                 if (currentVersion == 178) {
4690                     // Version 178: Set the default value for Secure Settings:
4691                     // SKIP_GESTURE & SILENCE_GESTURE
4692 
4693                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4694 
4695                     final Setting skipGesture = secureSettings.getSettingLocked(
4696                             Secure.SKIP_GESTURE);
4697 
4698                     if (skipGesture.isNull()) {
4699                         final boolean defSkipGesture = getContext().getResources().getBoolean(
4700                                 R.bool.def_skip_gesture);
4701                         secureSettings.insertSettingOverrideableByRestoreLocked(
4702                                 Secure.SKIP_GESTURE, defSkipGesture ? "1" : "0",
4703                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4704                     }
4705 
4706                     final Setting silenceGesture = secureSettings.getSettingLocked(
4707                             Secure.SILENCE_GESTURE);
4708 
4709                     if (silenceGesture.isNull()) {
4710                         final boolean defSilenceGesture = getContext().getResources().getBoolean(
4711                                 R.bool.def_silence_gesture);
4712                         secureSettings.insertSettingOverrideableByRestoreLocked(
4713                                 Secure.SILENCE_GESTURE, defSilenceGesture ? "1" : "0",
4714                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4715                     }
4716 
4717                     currentVersion = 179;
4718                 }
4719 
4720                 if (currentVersion == 179) {
4721                     // Version 178: Reset the default for Secure Settings: NOTIFICATION_BUBBLES
4722                     // This is originally set in version 173, however, the default value changed
4723                     // so this step is to ensure the value is updated to the correct default.
4724 
4725                     // Removed. Moved NOTIFICATION_BUBBLES to Global Settings.
4726                     currentVersion = 180;
4727                 }
4728 
4729                 if (currentVersion == 180) {
4730                     // Version 180: Set the default value for Secure Settings: AWARE_LOCK_ENABLED
4731 
4732                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4733 
4734                     final Setting awareLockEnabled = secureSettings.getSettingLocked(
4735                             Secure.AWARE_LOCK_ENABLED);
4736 
4737                     if (awareLockEnabled.isNull()) {
4738                         final boolean defAwareLockEnabled = getContext().getResources().getBoolean(
4739                                 R.bool.def_aware_lock_enabled);
4740                         secureSettings.insertSettingOverrideableByRestoreLocked(
4741                                 Secure.AWARE_LOCK_ENABLED, defAwareLockEnabled ? "1" : "0",
4742                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4743                     }
4744 
4745                     currentVersion = 181;
4746                 }
4747 
4748                 if (currentVersion == 181) {
4749                     // Version cd : by default, add STREAM_BLUETOOTH_SCO to list of streams that can
4750                     // be muted.
4751                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
4752                     final Setting currentSetting = systemSettings.getSettingLocked(
4753                               Settings.System.MUTE_STREAMS_AFFECTED);
4754                     if (!currentSetting.isNull()) {
4755                         try {
4756                             int currentSettingIntegerValue = Integer.parseInt(
4757                                     currentSetting.getValue());
4758                             if ((currentSettingIntegerValue
4759                                     & (1 << AudioManager.STREAM_BLUETOOTH_SCO)) == 0) {
4760                                 systemSettings.insertSettingOverrideableByRestoreLocked(
4761                                         Settings.System.MUTE_STREAMS_AFFECTED,
4762                                         Integer.toString(
4763                                         currentSettingIntegerValue
4764                                         | (1 << AudioManager.STREAM_BLUETOOTH_SCO)),
4765                                         null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4766                             }
4767                         } catch (NumberFormatException e) {
4768                             // remove the setting in case it is not a valid integer
4769                             Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED"
4770                                     + "setting, removing setting", e);
4771                             systemSettings.deleteSettingLocked(
4772                                     Settings.System.MUTE_STREAMS_AFFECTED);
4773                         }
4774 
4775                     }
4776                     currentVersion = 182;
4777                 }
4778 
4779                 if (currentVersion == 182) {
4780                     // Remove secure bubble settings; it's in global now.
4781                     getSecureSettingsLocked(userId).deleteSettingLocked("notification_bubbles");
4782 
4783                     // Removed. Updated NOTIFICATION_BUBBLES to be true by default, see 184.
4784                     currentVersion = 183;
4785                 }
4786 
4787                 if (currentVersion == 183) {
4788                     // Version 183: Set default values for WIRELESS_CHARGING_STARTED_SOUND
4789                     // and CHARGING_STARTED_SOUND
4790                     final SettingsState globalSettings = getGlobalSettingsLocked();
4791 
4792                     final String oldValueWireless = globalSettings.getSettingLocked(
4793                             Global.WIRELESS_CHARGING_STARTED_SOUND).getValue();
4794                     final String oldValueWired = globalSettings.getSettingLocked(
4795                             Global.CHARGING_STARTED_SOUND).getValue();
4796 
4797                     final String defaultValueWireless = getContext().getResources().getString(
4798                             R.string.def_wireless_charging_started_sound);
4799                     final String defaultValueWired = getContext().getResources().getString(
4800                             R.string.def_charging_started_sound);
4801 
4802                     // wireless charging sound
4803                     if (oldValueWireless == null
4804                             || TextUtils.equals(oldValueWireless, defaultValueWired)) {
4805                         if (!TextUtils.isEmpty(defaultValueWireless)) {
4806                             globalSettings.insertSettingOverrideableByRestoreLocked(
4807                                     Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWireless,
4808                                     null /* tag */, true /* makeDefault */,
4809                                     SettingsState.SYSTEM_PACKAGE_NAME);
4810                         } else if (!TextUtils.isEmpty(defaultValueWired)) {
4811                             // if the wireless sound is empty, use the wired charging sound
4812                             globalSettings.insertSettingOverrideableByRestoreLocked(
4813                                     Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWired,
4814                                     null /* tag */, true /* makeDefault */,
4815                                     SettingsState.SYSTEM_PACKAGE_NAME);
4816                         }
4817                     }
4818 
4819                     // wired charging sound
4820                     if (oldValueWired == null && !TextUtils.isEmpty(defaultValueWired)) {
4821                         globalSettings.insertSettingOverrideableByRestoreLocked(
4822                                 Global.CHARGING_STARTED_SOUND, defaultValueWired,
4823                                 null /* tag */, true /* makeDefault */,
4824                                 SettingsState.SYSTEM_PACKAGE_NAME);
4825                     }
4826                     currentVersion = 184;
4827                 }
4828 
4829                 if (currentVersion == 184) {
4830                     // Version 184: Reset the default for Global Settings: NOTIFICATION_BUBBLES
4831                     // This is originally set in version 182, however, the default value changed
4832                     // so this step is to ensure the value is updated to the correct default.
4833 
4834                     // Removed. Bubbles moved to secure settings. See version 197.
4835                     currentVersion = 185;
4836                 }
4837 
4838                 if (currentVersion == 185) {
4839                     // Deprecate ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, and migrate it
4840                     // to ACCESSIBILITY_BUTTON_TARGETS.
4841                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4842                     final Setting magnifyNavbarEnabled = secureSettings.getSettingLocked(
4843                             Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
4844                     if ("1".equals(magnifyNavbarEnabled.getValue())) {
4845                         secureSettings.insertSettingLocked(
4846                                 Secure.ACCESSIBILITY_BUTTON_TARGETS,
4847                                 ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER,
4848                                 null /* tag */, false /* makeDefault */,
4849                                 SettingsState.SYSTEM_PACKAGE_NAME);
4850                     }
4851                     secureSettings.deleteSettingLocked(
4852                             Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
4853                     currentVersion = 186;
4854                 }
4855 
4856                 if (currentVersion == 186) {
4857                     // Remove unused wifi settings
4858                     getGlobalSettingsLocked().deleteSettingLocked(
4859                             "wifi_rtt_background_exec_gap_ms");
4860                     getGlobalSettingsLocked().deleteSettingLocked(
4861                             "network_recommendation_request_timeout_ms");
4862                     getGlobalSettingsLocked().deleteSettingLocked(
4863                             "wifi_suspend_optimizations_enabled");
4864                     getGlobalSettingsLocked().deleteSettingLocked(
4865                             "wifi_is_unusable_event_metrics_enabled");
4866                     getGlobalSettingsLocked().deleteSettingLocked(
4867                             "wifi_data_stall_min_tx_bad");
4868                     getGlobalSettingsLocked().deleteSettingLocked(
4869                             "wifi_data_stall_min_tx_success_without_rx");
4870                     getGlobalSettingsLocked().deleteSettingLocked(
4871                             "wifi_link_speed_metrics_enabled");
4872                     getGlobalSettingsLocked().deleteSettingLocked(
4873                             "wifi_pno_frequency_culling_enabled");
4874                     getGlobalSettingsLocked().deleteSettingLocked(
4875                             "wifi_pno_recency_sorting_enabled");
4876                     getGlobalSettingsLocked().deleteSettingLocked(
4877                             "wifi_link_probing_enabled");
4878                     getGlobalSettingsLocked().deleteSettingLocked(
4879                             "wifi_saved_state");
4880                     currentVersion = 187;
4881                 }
4882 
4883                 if (currentVersion == 187) {
4884                     // Migrate adaptive sleep setting from System to Secure.
4885                     if (userId == UserHandle.USER_OWNER) {
4886                         // Remove from the system settings.
4887                         SettingsState systemSettings = getSystemSettingsLocked(userId);
4888                         String name = Settings.System.ADAPTIVE_SLEEP;
4889                         Setting setting = systemSettings.getSettingLocked(name);
4890                         systemSettings.deleteSettingLocked(name);
4891 
4892                         // Add to the secure settings.
4893                         SettingsState secureSettings = getSecureSettingsLocked(userId);
4894                         secureSettings.insertSettingLocked(name, setting.getValue(), null /* tag */,
4895                                 false /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME);
4896                     }
4897                     currentVersion = 188;
4898                 }
4899 
4900                 if (currentVersion == 188) {
4901                     // Deprecate ACCESSIBILITY_SHORTCUT_ENABLED, and migrate it
4902                     // to ACCESSIBILITY_SHORTCUT_TARGET_SERVICE.
4903                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4904                     final Setting shortcutEnabled = secureSettings.getSettingLocked(
4905                             "accessibility_shortcut_enabled");
4906                     if ("0".equals(shortcutEnabled.getValue())) {
4907                         // Clear shortcut key targets list setting.
4908                         secureSettings.insertSettingLocked(
4909                                 Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
4910                                 "", null /* tag */, false /* makeDefault */,
4911                                 SettingsState.SYSTEM_PACKAGE_NAME);
4912                     }
4913                     secureSettings.deleteSettingLocked("accessibility_shortcut_enabled");
4914                     currentVersion = 189;
4915                 }
4916 
4917                 if (currentVersion == 189) {
4918                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4919                     final Setting showNotifications = secureSettings.getSettingLocked(
4920                             Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
4921                     final Setting allowPrivateNotifications = secureSettings.getSettingLocked(
4922                             Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
4923                     if ("1".equals(showNotifications.getValue())
4924                             && "1".equals(allowPrivateNotifications.getValue())) {
4925                         secureSettings.insertSettingLocked(
4926                                 Secure.POWER_MENU_LOCKED_SHOW_CONTENT,
4927                                 "1", null /* tag */, false /* makeDefault */,
4928                                 SettingsState.SYSTEM_PACKAGE_NAME);
4929                     } else if ("0".equals(showNotifications.getValue())
4930                             || "0".equals(allowPrivateNotifications.getValue())) {
4931                         secureSettings.insertSettingLocked(
4932                                 Secure.POWER_MENU_LOCKED_SHOW_CONTENT,
4933                                 "0", null /* tag */, false /* makeDefault */,
4934                                 SettingsState.SYSTEM_PACKAGE_NAME);
4935                     }
4936                     currentVersion = 190;
4937                 }
4938 
4939                 if (currentVersion == 190) {
4940                     // Version 190: get HDMI auto device off from overlay
4941                     final SettingsState globalSettings = getGlobalSettingsLocked();
4942                     final Setting currentSetting = globalSettings.getSettingLocked(
4943                             Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED);
4944                     if (currentSetting.isNull()) {
4945                         globalSettings.insertSettingLocked(
4946                                 Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
4947                                 getContext().getResources().getBoolean(
4948                                         R.bool.def_hdmiControlAutoDeviceOff) ? "1" : "0",
4949                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4950                     }
4951                     currentVersion = 191;
4952                 }
4953 
4954                 if (currentVersion == 191) {
4955                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4956                     int mode = getContext().getResources().getInteger(
4957                             com.android.internal.R.integer.config_navBarInteractionMode);
4958                     if (mode == NAV_BAR_MODE_GESTURAL) {
4959                         switchToDefaultGestureNavBackInset(userId, secureSettings);
4960                     }
4961                     migrateBackGestureSensitivity(Secure.BACK_GESTURE_INSET_SCALE_LEFT, userId,
4962                             secureSettings);
4963                     migrateBackGestureSensitivity(Secure.BACK_GESTURE_INSET_SCALE_RIGHT, userId,
4964                             secureSettings);
4965                     currentVersion = 192;
4966                 }
4967 
4968                 if (currentVersion == 192) {
4969                     // Version 192: set the default value for magnification capabilities.
4970                     // If the device supports magnification area and magnification is enabled
4971                     // by the user, set it to full-screen, and set a value to show a prompt
4972                     // when using the magnification first time after upgrading.
4973                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
4974                     final Setting magnificationCapabilities = secureSettings.getSettingLocked(
4975                             Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY);
4976                     final boolean supportMagnificationArea = getContext().getResources().getBoolean(
4977                             com.android.internal.R.bool.config_magnification_area);
4978                     final int capability = supportMagnificationArea
4979                             ? R.integer.def_accessibility_magnification_capabilities
4980                             : Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
4981                     final String supportShowPrompt = supportMagnificationArea ? "1" : "0";
4982                     if (magnificationCapabilities.isNull()) {
4983                         secureSettings.insertSettingLocked(
4984                                 Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
4985                                 String.valueOf(getContext().getResources().getInteger(capability)),
4986                                 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
4987 
4988                         if (isMagnificationSettingsOn(secureSettings)) {
4989                             secureSettings.insertSettingLocked(
4990                                     Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY, String.valueOf(
4991                                             Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN),
4992                                     null, false  /* makeDefault */,
4993                                     SettingsState.SYSTEM_PACKAGE_NAME);
4994                             secureSettings.insertSettingLocked(
4995                                     Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT,
4996                                     supportShowPrompt,
4997                                     null, false /* makeDefault */,
4998                                     SettingsState.SYSTEM_PACKAGE_NAME);
4999                         }
5000                     }
5001                     currentVersion = 193;
5002                 }
5003 
5004                 if (currentVersion == 193) {
5005                     // Version 193: remove obsolete LOCATION_PROVIDERS_ALLOWED settings
5006                     getSecureSettingsLocked(userId).deleteSettingLocked(
5007                             Secure.LOCATION_PROVIDERS_ALLOWED);
5008                     currentVersion = 194;
5009                 }
5010 
5011                 if (currentVersion == 194) {
5012                     // Version 194: migrate the GNSS_SATELLITE_BLOCKLIST setting
5013                     final SettingsState globalSettings = getGlobalSettingsLocked();
5014                     final Setting newSetting = globalSettings.getSettingLocked(
5015                             Global.GNSS_SATELLITE_BLOCKLIST);
5016                     final String oldName = "gnss_satellite_blacklist";
5017                     final Setting oldSetting = globalSettings.getSettingLocked(oldName);
5018                     if (newSetting.isNull() && !oldSetting.isNull()) {
5019                         globalSettings.insertSettingLocked(
5020                                 Global.GNSS_SATELLITE_BLOCKLIST, oldSetting.getValue(), null, true,
5021                                 SettingsState.SYSTEM_PACKAGE_NAME);
5022                         globalSettings.deleteSettingLocked(oldName);
5023                     }
5024                     currentVersion = 195;
5025                 }
5026 
5027                 if (currentVersion == 195) {
5028                     // Version 195: delete obsolete manged services settings
5029                     getSecureSettingsLocked(userId).deleteSettingLocked(
5030                             Secure.ENABLED_NOTIFICATION_ASSISTANT);
5031                     getSecureSettingsLocked(userId).deleteSettingLocked(
5032                             Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
5033                     currentVersion = 196;
5034                 }
5035 
5036                 if (currentVersion == 196) {
5037                     // Version 196: Set the default value for Secure Settings:
5038                     // SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED & ONE_HANDED_MODE_ENABLED
5039                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
5040                     final Setting swipeNotification = secureSettings.getSettingLocked(
5041                             Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED);
5042                     if (swipeNotification.isNull()) {
5043                         final boolean defSwipeNotification = getContext().getResources()
5044                                 .getBoolean(R.bool.def_swipe_bottom_to_notification_enabled);
5045                         secureSettings.insertSettingLocked(
5046                                 Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
5047                                 defSwipeNotification ? "1" : "0", null, true,
5048                                 SettingsState.SYSTEM_PACKAGE_NAME);
5049                     }
5050 
5051                     final Setting oneHandedModeEnabled = secureSettings.getSettingLocked(
5052                             Secure.ONE_HANDED_MODE_ENABLED);
5053                     if (oneHandedModeEnabled.isNull()) {
5054                         final boolean defOneHandedModeEnabled = getContext().getResources()
5055                                 .getBoolean(R.bool.def_one_handed_mode_enabled);
5056                         secureSettings.insertSettingLocked(
5057                                 Secure.ONE_HANDED_MODE_ENABLED,
5058                                 defOneHandedModeEnabled ? "1" : "0", null, true,
5059                                 SettingsState.SYSTEM_PACKAGE_NAME);
5060                     }
5061 
5062                     currentVersion = 197;
5063                 }
5064 
5065                 if (currentVersion == 197) {
5066                     // Version 197: Set the default value for Global Settings:
5067                     // DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW
5068                     final SettingsState globalSettings = getGlobalSettingsLocked();
5069                     final Setting enableNonResizableMultiWindow = globalSettings.getSettingLocked(
5070                             Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW);
5071                     if (enableNonResizableMultiWindow.isNull()) {
5072                         final boolean defEnableNonResizableMultiWindow = getContext().getResources()
5073                                 .getBoolean(R.bool.def_enable_non_resizable_multi_window);
5074                         globalSettings.insertSettingLocked(
5075                                 Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
5076                                 defEnableNonResizableMultiWindow ? "1" : "0", null, true,
5077                                 SettingsState.SYSTEM_PACKAGE_NAME);
5078                     }
5079                     currentVersion = 198;
5080                 }
5081 
5082                 if (currentVersion == 198) {
5083                     // Version 198: Set the default value for accessibility button. If the user
5084                     // uses accessibility button in the navigation bar to trigger their
5085                     // accessibility features (check if ACCESSIBILITY_BUTTON_TARGETS has value)
5086                     // then leave accessibility button mode in the navigation bar, otherwise, set it
5087                     // to the floating menu.
5088                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
5089                     final Setting accessibilityButtonMode = secureSettings.getSettingLocked(
5090                             Secure.ACCESSIBILITY_BUTTON_MODE);
5091                     if (accessibilityButtonMode.isNull()) {
5092                         if (isAccessibilityButtonInNavigationBarOn(secureSettings)) {
5093                             secureSettings.insertSettingLocked(Secure.ACCESSIBILITY_BUTTON_MODE,
5094                                     String.valueOf(
5095                                             Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR),
5096                                     /*tag= */ null, /* makeDefault= */ false,
5097                                     SettingsState.SYSTEM_PACKAGE_NAME);
5098                         } else {
5099                             final int defAccessibilityButtonMode =
5100                                     getContext().getResources().getInteger(
5101                                             R.integer.def_accessibility_button_mode);
5102                             secureSettings.insertSettingLocked(Secure.ACCESSIBILITY_BUTTON_MODE,
5103                                     String.valueOf(defAccessibilityButtonMode), /* tag= */
5104                                     null, /* makeDefault= */ true,
5105                                     SettingsState.SYSTEM_PACKAGE_NAME);
5106 
5107                             if (hasValueInA11yButtonTargets(secureSettings)) {
5108                                 secureSettings.insertSettingLocked(
5109                                         Secure.ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT,
5110                                         /* enabled */ "1",
5111                                         /* tag= */ null,
5112                                         /* makeDefault= */ false,
5113                                         SettingsState.SYSTEM_PACKAGE_NAME);
5114                             }
5115                         }
5116                     }
5117 
5118                     currentVersion = 199;
5119                 }
5120 
5121                 if (currentVersion == 199) {
5122                     // Version 199: Bubbles moved to secure settings. Use the global value for
5123                     // the newly inserted secure setting; we'll delete the global value in the
5124                     // next version step.
5125                     // If this is a new profile, check if a secure setting exists for the
5126                     // owner of the profile and use that value for the work profile.
5127                     int owningId = resolveOwningUserIdForSecureSettingLocked(userId,
5128                             NOTIFICATION_BUBBLES);
5129                     Setting previous = getGlobalSettingsLocked()
5130                             .getSettingLocked("notification_bubbles");
5131                     Setting secureBubbles = getSecureSettingsLocked(owningId)
5132                             .getSettingLocked(NOTIFICATION_BUBBLES);
5133                     String oldValue = "1";
5134                     if (!previous.isNull()) {
5135                         oldValue = previous.getValue();
5136                     } else if (!secureBubbles.isNull()) {
5137                         oldValue = secureBubbles.getValue();
5138                     }
5139                     if (secureBubbles.isNull()) {
5140                         boolean isDefault = oldValue.equals("1");
5141                         getSecureSettingsLocked(userId).insertSettingLocked(
5142                                 Secure.NOTIFICATION_BUBBLES, oldValue, null /* tag */,
5143                                 isDefault, SettingsState.SYSTEM_PACKAGE_NAME);
5144                     }
5145                     currentVersion = 200;
5146                 }
5147 
5148                 if (currentVersion == 200) {
5149                     // Version 200: delete the global bubble setting which was moved to secure in
5150                     // version 199.
5151                     getGlobalSettingsLocked().deleteSettingLocked("notification_bubbles");
5152                     currentVersion = 201;
5153                 }
5154 
5155                 if (currentVersion == 201) {
5156                     // Version 201: Set the default value for Secure Settings:
5157                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
5158                     final Setting oneHandedModeActivated = secureSettings.getSettingLocked(
5159                             Secure.ONE_HANDED_MODE_ACTIVATED);
5160                     if (oneHandedModeActivated.isNull()) {
5161                         final boolean defOneHandedModeActivated = getContext().getResources()
5162                                 .getBoolean(R.bool.def_one_handed_mode_activated);
5163                         secureSettings.insertSettingLocked(
5164                                 Secure.ONE_HANDED_MODE_ACTIVATED,
5165                                 defOneHandedModeActivated ? "1" : "0", null, true,
5166                                 SettingsState.SYSTEM_PACKAGE_NAME);
5167                     }
5168                     currentVersion = 202;
5169                 }
5170 
5171                 if (currentVersion == 202) {
5172                     // Version 202: Power menu has been removed, and the privacy setting
5173                     // has been split into two for wallet and controls
5174                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
5175                     final Setting showLockedContent = secureSettings.getSettingLocked(
5176                             Secure.POWER_MENU_LOCKED_SHOW_CONTENT);
5177                     if (!showLockedContent.isNull()) {
5178                         String currentValue = showLockedContent.getValue();
5179 
5180                         secureSettings.insertSettingOverrideableByRestoreLocked(
5181                                 Secure.LOCKSCREEN_SHOW_CONTROLS,
5182                                 currentValue, null /* tag */, false /* makeDefault */,
5183                                 SettingsState.SYSTEM_PACKAGE_NAME);
5184                         secureSettings.insertSettingOverrideableByRestoreLocked(
5185                                 Secure.LOCKSCREEN_SHOW_WALLET,
5186                                 currentValue, null /* tag */, false /* makeDefault */,
5187                                 SettingsState.SYSTEM_PACKAGE_NAME);
5188                     }
5189                     currentVersion = 203;
5190                 }
5191 
5192                 if (currentVersion == 203) {
5193                     // Version 204: Replace 'wifi' or 'cell' tiles with 'internet' if existed.
5194                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
5195                     final Setting currentValue = secureSettings.getSettingLocked(Secure.QS_TILES);
5196                     if (!currentValue.isNull()) {
5197                         String tileList = currentValue.getValue();
5198                         String[] tileSplit = tileList.split(",");
5199                         final ArrayList<String> tiles = new ArrayList<String>();
5200                         boolean hasInternetTile = false;
5201                         for (int i = 0; i < tileSplit.length; i++) {
5202                             String tile = tileSplit[i].trim();
5203                             if (tile.isEmpty()) continue;
5204                             tiles.add(tile);
5205                             if (tile.equals("internet")) hasInternetTile = true;
5206                         }
5207                         if (!hasInternetTile) {
5208                             if (tiles.contains("wifi")) {
5209                                 // Replace the WiFi with Internet, and remove the Cell
5210                                 tiles.set(tiles.indexOf("wifi"), "internet");
5211                                 tiles.remove("cell");
5212                             } else if (tiles.contains("cell")) {
5213                                 // Replace the Cell with Internet
5214                                 tiles.set(tiles.indexOf("cell"), "internet");
5215                             }
5216                         } else {
5217                             tiles.remove("wifi");
5218                             tiles.remove("cell");
5219                         }
5220                         secureSettings.insertSettingOverrideableByRestoreLocked(
5221                                 Secure.QS_TILES,
5222                                 TextUtils.join(",", tiles),
5223                                 null /* tag */,
5224                                 true /* makeDefault */,
5225                                 SettingsState.SYSTEM_PACKAGE_NAME);
5226                     }
5227                     currentVersion = 204;
5228                 }
5229 
5230                 // vXXX: Add new settings above this point.
5231 
5232                 if (currentVersion != newVersion) {
5233                     Slog.wtf("SettingsProvider", "warning: upgrading settings database to version "
5234                             + newVersion + " left it at "
5235                             + currentVersion +
5236                             " instead; this is probably a bug. Did you update SETTINGS_VERSION?",
5237                             new Throwable());
5238                     if (DEBUG) {
5239                         throw new RuntimeException("db upgrade error");
5240                     }
5241                 }
5242 
5243                 // Return the current version.
5244                 return currentVersion;
5245             }
5246         }
5247 
5248         /**
5249          * Previously, We were using separate overlay packages for different back inset sizes. Now,
5250          * we have a single overlay package for gesture navigation mode, and set the inset size via
5251          * a secure.settings field.
5252          *
5253          * If a non-default overlay package is enabled, then enable the default overlay exclusively,
5254          * and set the calculated inset size difference as a scale value in secure.settings.
5255          */
5256         private void switchToDefaultGestureNavBackInset(int userId, SettingsState secureSettings) {
5257             try {
5258                 final IOverlayManager om = IOverlayManager.Stub.asInterface(
5259                         ServiceManager.getService(Context.OVERLAY_SERVICE));
5260                 final OverlayInfo info = om.getOverlayInfo(NAV_BAR_MODE_GESTURAL_OVERLAY, userId);
5261                 if (info != null && !info.isEnabled()) {
5262                     final int curInset = getContext().getResources().getDimensionPixelSize(
5263                             com.android.internal.R.dimen.config_backGestureInset);
5264                     om.setEnabledExclusiveInCategory(NAV_BAR_MODE_GESTURAL_OVERLAY, userId);
5265                     final int defInset = getContext().getResources().getDimensionPixelSize(
5266                             com.android.internal.R.dimen.config_backGestureInset);
5267 
5268                     final float scale = defInset == 0 ? 1.0f : ((float) curInset) / defInset;
5269                     if (scale != 1.0f) {
5270                         secureSettings.insertSettingLocked(
5271                                 Secure.BACK_GESTURE_INSET_SCALE_LEFT,
5272                                 Float.toString(scale), null /* tag */, false /* makeDefault */,
5273                                 SettingsState.SYSTEM_PACKAGE_NAME);
5274                         secureSettings.insertSettingLocked(
5275                                 Secure.BACK_GESTURE_INSET_SCALE_RIGHT,
5276                                 Float.toString(scale), null /* tag */, false /* makeDefault */,
5277                                 SettingsState.SYSTEM_PACKAGE_NAME);
5278                         if (DEBUG) {
5279                             Slog.v(LOG_TAG, "Moved back sensitivity for user " + userId
5280                                     + " to scale " + scale);
5281                         }
5282                     }
5283                 }
5284             } catch (SecurityException | IllegalStateException | RemoteException e) {
5285                 Slog.e(LOG_TAG, "Failed to switch to default gesture nav overlay for user "
5286                         + userId);
5287             }
5288         }
5289 
5290         private void migrateBackGestureSensitivity(String side, int userId,
5291                 SettingsState secureSettings) {
5292             final Setting currentScale = secureSettings.getSettingLocked(side);
5293             if (currentScale.isNull()) {
5294                 return;
5295             }
5296             float current = 1.0f;
5297             try {
5298                 current = Float.parseFloat(currentScale.getValue());
5299             } catch (NumberFormatException e) {
5300                 // Do nothing. Overwrite with default value.
5301             }
5302 
5303             // Inset scale migration across all devices
5304             //     Old(24dp): 0.66  0.75  0.83  1.00  1.08  1.33  1.66
5305             //     New(30dp): 0.60  0.60  1.00  1.00  1.00  1.00  1.33
5306             final float low = 0.76f;   // Values smaller than this will map to 0.6
5307             final float high = 1.65f;  // Values larger than this will map to 1.33
5308             float newScale;
5309             if (current < low) {
5310                 newScale = 0.6f;
5311             } else if (current < high) {
5312                 newScale = 1.0f;
5313             } else {
5314                 newScale = 1.33f;
5315             }
5316             secureSettings.insertSettingLocked(side, Float.toString(newScale),
5317                     null /* tag */, false /* makeDefault */,
5318                     SettingsState.SYSTEM_PACKAGE_NAME);
5319             if (DEBUG) {
5320                 Slog.v(LOG_TAG, "Changed back sensitivity from " + current + " to " + newScale
5321                         + " for user " + userId + " on " + side);
5322             }
5323         }
5324 
5325         private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings,
5326                 int userId) {
5327             List<String> names = settings.getSettingNamesLocked();
5328             final int nameCount = names.size();
5329             for (int i = 0; i < nameCount; i++) {
5330                 String name = names.get(i);
5331                 Setting setting = settings.getSettingLocked(name);
5332 
5333                 // In the upgrade case we pretend the call is made from the app
5334                 // that made the last change to the setting to properly determine
5335                 // whether the call has been made by a system component.
5336                 try {
5337                     final boolean systemSet = SettingsState.isSystemPackage(
5338                             getContext(), setting.getPackageName());
5339                     if (systemSet) {
5340                         settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(),
5341                                 setting.getTag(), true, setting.getPackageName());
5342                     } else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) {
5343                         // We had a bug where changes by non-system packages were marked
5344                         // as system made and as a result set as the default. Therefore, if
5345                         // the package changed the setting last is not a system one but the
5346                         // setting is marked as its default coming from the system we clear
5347                         // the default and clear the system set flag.
5348                         settings.resetSettingDefaultValueLocked(name);
5349                     }
5350                 } catch (IllegalStateException e) {
5351                     // If the package goes over its quota during the upgrade, don't
5352                     // crash but just log the error as the system does the upgrade.
5353                     Slog.e(LOG_TAG, "Error upgrading setting: " + setting.getName(), e);
5354 
5355                 }
5356             }
5357         }
5358 
5359         private boolean isMagnificationSettingsOn(SettingsState secureSettings) {
5360             if ("1".equals(secureSettings.getSettingLocked(
5361                     Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED).getValue())) {
5362                 return true;
5363             }
5364 
5365             final Set<String> a11yButtonTargets = transformColonDelimitedStringToSet(
5366                     secureSettings.getSettingLocked(
5367                             Secure.ACCESSIBILITY_BUTTON_TARGETS).getValue());
5368             if (a11yButtonTargets != null && a11yButtonTargets.contains(
5369                     MAGNIFICATION_CONTROLLER_NAME)) {
5370                 return true;
5371             }
5372 
5373             final Set<String> a11yShortcutServices = transformColonDelimitedStringToSet(
5374                     secureSettings.getSettingLocked(
5375                             Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE).getValue());
5376             if (a11yShortcutServices != null && a11yShortcutServices.contains(
5377                     MAGNIFICATION_CONTROLLER_NAME)) {
5378                 return true;
5379             }
5380             return false;
5381         }
5382 
5383         @Nullable
5384         private Set<String> transformColonDelimitedStringToSet(String value) {
5385             if (TextUtils.isEmpty(value)) return null;
5386             final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(':');
5387             splitter.setString(value);
5388             final Set<String> items = new HashSet<>();
5389             while (splitter.hasNext()) {
5390                 final String str = splitter.next();
5391                 if (TextUtils.isEmpty(str)) {
5392                     continue;
5393                 }
5394                 items.add(str);
5395             }
5396             return items;
5397         }
5398 
5399         private boolean isAccessibilityButtonInNavigationBarOn(SettingsState secureSettings) {
5400             return hasValueInA11yButtonTargets(secureSettings) && !isGestureNavigateEnabled();
5401         }
5402 
5403         private boolean isGestureNavigateEnabled() {
5404             final int navigationMode = getContext().getResources().getInteger(
5405                     com.android.internal.R.integer.config_navBarInteractionMode);
5406             return navigationMode == NAV_BAR_MODE_GESTURAL;
5407         }
5408 
5409         private boolean hasValueInA11yButtonTargets(SettingsState secureSettings) {
5410             final Setting a11yButtonTargetsSettings =
5411                     secureSettings.getSettingLocked(Secure.ACCESSIBILITY_BUTTON_TARGETS);
5412 
5413             return !a11yButtonTargetsSettings.isNull()
5414                     && !TextUtils.isEmpty(a11yButtonTargetsSettings.getValue());
5415         }
5416     }
5417 }
5418