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