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