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