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