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 makeKey(int type, int userId)281 public static int makeKey(int type, int userId) { 282 return SettingsState.makeKey(type, userId); 283 } 284 getTypeFromKey(int key)285 public static int getTypeFromKey(int key) { 286 return SettingsState.getTypeFromKey(key); 287 } 288 getUserIdFromKey(int key)289 public static int getUserIdFromKey(int key) { 290 return SettingsState.getUserIdFromKey(key); 291 } 292 settingTypeToString(int type)293 public static String settingTypeToString(int type) { 294 return SettingsState.settingTypeToString(type); 295 } 296 keyToString(int key)297 public static String keyToString(int key) { 298 return SettingsState.keyToString(key); 299 } 300 301 @Override onCreate()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 ensureAllBackedUpSystemSettingsHaveValidators()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 ensureAllBackedUpGlobalSettingsHaveValidators()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 ensureAllBackedUpSecureSettingsHaveValidators()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 failToBootIfOffendersPresent(String offenders, String settingsType)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 getOffenders(String[] settingsToBackup, Map<String, SettingsValidators.Validator> validators)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 concat(String[] first, String[] second)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 call(String method, String name, Bundle args)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 getType(Uri uri)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 query(Uri uri, String[] projection, String where, String[] whereArgs, String order)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 insert(Uri uri, ContentValues values)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 bulkInsert(Uri uri, ContentValues[] allValues)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 delete(Uri uri, String where, String[] whereArgs)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 update(Uri uri, ContentValues values, String where, String[] whereArgs)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 openFile(Uri uri, String mode)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 getRingtoneCacheDir(int userId)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 */ dumpProto(@onNull FileDescriptor fd)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 dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args)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 dumpForUserLocked(int userId, PrintWriter pw)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 dumpSettingsLocked(SettingsState settingsState, PrintWriter pw)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 toDumpString(String s)781 private static String toDumpString(String s) { 782 if (s != null) { 783 return s; 784 } 785 return "{null}"; 786 } 787 registerBroadcastReceivers()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 startWatchingUserRestrictionChanges()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 getAllGlobalSettings(String[] projection)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 getGlobalSetting(String name)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 updateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, boolean forceNotify)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 insertGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, boolean forceNotify)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 deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify)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 resetGlobalSetting(int requestingUserId, int mode, String tag)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 mutateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode)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 getCallingPackageInfo(int userId)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 getAllSecureSettings(int userId, String[] projection)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 getSecureSetting(String name, int requestingUserId)1119 private Setting getSecureSetting(String name, int requestingUserId) { 1120 return getSecureSetting(name, requestingUserId, /*enableOverride=*/ false); 1121 } 1122 getSecureSetting(String name, int requestingUserId, boolean enableOverride)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 isNewSsaidSetting(String name)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 getSsaidSettingLocked(PackageInfo callingPkg, int owningUserId)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 mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting)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