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