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