OSDN Git Service

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