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