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