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