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