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