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