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