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