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