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