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