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.DeviceConfig.SYNC_DISABLED_MODE_NONE; 23 import static android.provider.DeviceConfig.SYNC_DISABLED_MODE_PERSISTENT; 24 import static android.provider.DeviceConfig.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_BUTTON_MODE_FLOATING_MENU; 29 import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER; 30 import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES; 31 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY; 32 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; 33 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; 34 35 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; 36 import static com.android.internal.accessibility.util.AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM; 37 import static com.android.providers.settings.SettingsState.FALLBACK_FILE_SUFFIX; 38 import static com.android.providers.settings.SettingsState.getTypeFromKey; 39 import static com.android.providers.settings.SettingsState.getUserIdFromKey; 40 import static com.android.providers.settings.SettingsState.isConfigSettingsKey; 41 import static com.android.providers.settings.SettingsState.isGlobalSettingsKey; 42 import static com.android.providers.settings.SettingsState.isSecureSettingsKey; 43 import static com.android.providers.settings.SettingsState.isSystemSettingsKey; 44 import static com.android.providers.settings.SettingsState.makeKey; 45 46 import android.Manifest; 47 import android.aconfigd.AconfigdFlagInfo; 48 import android.annotation.NonNull; 49 import android.annotation.Nullable; 50 import android.app.ActivityManager; 51 import android.app.AppGlobals; 52 import android.app.backup.BackupManager; 53 import android.app.compat.CompatChanges; 54 import android.app.job.JobInfo; 55 import android.app.job.JobScheduler; 56 import android.compat.annotation.ChangeId; 57 import android.compat.annotation.EnabledSince; 58 import android.content.BroadcastReceiver; 59 import android.content.ComponentName; 60 import android.content.ContentProvider; 61 import android.content.ContentResolver; 62 import android.content.ContentValues; 63 import android.content.Context; 64 import android.content.Intent; 65 import android.content.IntentFilter; 66 import android.content.om.IOverlayManager; 67 import android.content.om.OverlayInfo; 68 import android.content.pm.ApplicationInfo; 69 import android.content.pm.IPackageManager; 70 import android.content.pm.PackageInfo; 71 import android.content.pm.PackageManager; 72 import android.content.pm.UserInfo; 73 import android.content.res.Resources; 74 import android.database.Cursor; 75 import android.database.MatrixCursor; 76 import android.database.sqlite.SQLiteDatabase; 77 import android.database.sqlite.SQLiteQueryBuilder; 78 import android.hardware.camera2.utils.ArrayUtils; 79 import android.media.AudioManager; 80 import android.media.IRingtonePlayer; 81 import android.net.Uri; 82 import android.os.Binder; 83 import android.os.Build; 84 import android.os.Bundle; 85 import android.os.DropBoxManager; 86 import android.os.Environment; 87 import android.os.FileUtils; 88 import android.os.Handler; 89 import android.os.HandlerThread; 90 import android.os.IUserRestrictionsListener; 91 import android.os.Looper; 92 import android.os.Message; 93 import android.os.ParcelFileDescriptor; 94 import android.os.PersistableBundle; 95 import android.os.Process; 96 import android.os.RemoteCallback; 97 import android.os.RemoteException; 98 import android.os.SELinux; 99 import android.os.ServiceManager; 100 import android.os.SystemConfigManager; 101 import android.os.SystemProperties; 102 import android.os.UserHandle; 103 import android.os.UserManager; 104 import android.provider.DeviceConfig; 105 import android.provider.Settings; 106 import android.provider.Settings.Config.SyncDisabledMode; 107 import android.provider.Settings.Global; 108 import android.provider.Settings.Secure; 109 import android.provider.Settings.SetAllResult; 110 import android.provider.settings.validators.SystemSettingsValidators; 111 import android.provider.settings.validators.Validator; 112 import android.text.TextUtils; 113 import android.util.ArrayMap; 114 import android.util.ArraySet; 115 import android.util.Log; 116 import android.util.Slog; 117 import android.util.SparseArray; 118 import android.util.SparseBooleanArray; 119 import android.util.proto.ProtoOutputStream; 120 121 import com.android.internal.accessibility.util.AccessibilityUtils; 122 import com.android.internal.annotations.GuardedBy; 123 import com.android.internal.annotations.VisibleForTesting; 124 import com.android.internal.content.PackageMonitor; 125 import com.android.internal.display.RefreshRateSettingsUtils; 126 import com.android.internal.os.BackgroundThread; 127 import com.android.internal.util.FrameworkStatsLog; 128 import com.android.providers.settings.SettingsState.Setting; 129 130 import com.google.android.collect.Sets; 131 132 import libcore.util.HexEncoding; 133 134 import java.io.BufferedReader; 135 import java.io.File; 136 import java.io.FileDescriptor; 137 import java.io.FileNotFoundException; 138 import java.io.FileOutputStream; 139 import java.io.FileReader; 140 import java.io.IOException; 141 import java.io.InputStream; 142 import java.io.OutputStream; 143 import java.io.PrintWriter; 144 import java.nio.ByteBuffer; 145 import java.security.InvalidKeyException; 146 import java.security.NoSuchAlgorithmException; 147 import java.security.SecureRandom; 148 import java.util.ArrayList; 149 import java.util.Arrays; 150 import java.util.Collection; 151 import java.util.Collections; 152 import java.util.HashMap; 153 import java.util.HashSet; 154 import java.util.List; 155 import java.util.Map; 156 import java.util.Set; 157 import java.util.regex.Pattern; 158 159 import javax.crypto.Mac; 160 import javax.crypto.spec.SecretKeySpec; 161 162 /** 163 * <p> 164 * This class is a content provider that publishes the system settings. 165 * It can be accessed via the content provider APIs or via custom call 166 * commands. The latter is a bit faster and is the preferred way to access 167 * the platform settings. 168 * </p> 169 * <p> 170 * There are three settings types, global (with signature level protection 171 * and shared across users), secure (with signature permission level 172 * protection and per user), and system (with dangerous permission level 173 * protection and per user). Global settings are stored under the device owner. 174 * Each of these settings is represented by a {@link 175 * com.android.providers.settings.SettingsState} object mapped to an integer 176 * key derived from the setting type in the most significant bits and user 177 * id in the least significant bits. Settings are synchronously loaded on 178 * instantiation of a SettingsState and asynchronously persisted on mutation. 179 * Settings are stored in the user specific system directory. 180 * </p> 181 * <p> 182 * Apps targeting APIs Lollipop MR1 and lower can add custom settings entries 183 * and get a warning. Targeting higher API version prohibits this as the 184 * system settings are not a place for apps to save their state. When a package 185 * is removed the settings it added are deleted. Apps cannot delete system 186 * settings added by the platform. System settings values are validated to 187 * ensure the clients do not put bad values. Global and secure settings are 188 * changed only by trusted parties, therefore no validation is performed. Also 189 * there is a limit on the amount of app specific settings that can be added 190 * to prevent unlimited growth of the system process memory footprint. 191 * </p> 192 */ 193 @SuppressWarnings("deprecation") 194 public class SettingsProvider extends ContentProvider { 195 static final boolean DEBUG = false; 196 197 private static final boolean DROP_DATABASE_ON_MIGRATION = true; 198 199 private static final String LOG_TAG = "SettingsProvider"; 200 201 public static final String TABLE_SYSTEM = "system"; 202 public static final String TABLE_SECURE = "secure"; 203 public static final String TABLE_GLOBAL = "global"; 204 public static final String TABLE_SSAID = "ssaid"; 205 public static final String TABLE_CONFIG = "config"; 206 207 // Old tables no longer exist. 208 private static final String TABLE_FAVORITES = "favorites"; 209 private static final String TABLE_OLD_FAVORITES = "old_favorites"; 210 private static final String TABLE_BLUETOOTH_DEVICES = "bluetooth_devices"; 211 private static final String TABLE_BOOKMARKS = "bookmarks"; 212 private static final String TABLE_ANDROID_METADATA = "android_metadata"; 213 214 // The set of removed legacy tables. 215 private static final Set<String> REMOVED_LEGACY_TABLES = new ArraySet<>(); 216 static { 217 REMOVED_LEGACY_TABLES.add(TABLE_FAVORITES); 218 REMOVED_LEGACY_TABLES.add(TABLE_OLD_FAVORITES); 219 REMOVED_LEGACY_TABLES.add(TABLE_BLUETOOTH_DEVICES); 220 REMOVED_LEGACY_TABLES.add(TABLE_BOOKMARKS); 221 REMOVED_LEGACY_TABLES.add(TABLE_ANDROID_METADATA); 222 } 223 224 private static final int MUTATION_OPERATION_INSERT = 1; 225 private static final int MUTATION_OPERATION_DELETE = 2; 226 private static final int MUTATION_OPERATION_UPDATE = 3; 227 private static final int MUTATION_OPERATION_RESET = 4; 228 229 private static final String[] LEGACY_SQL_COLUMNS = new String[] { 230 Settings.NameValueTable._ID, 231 Settings.NameValueTable.NAME, 232 Settings.NameValueTable.VALUE, 233 }; 234 235 private static final String[] ALL_COLUMNS = new String[] { 236 Settings.NameValueTable._ID, 237 Settings.NameValueTable.NAME, 238 Settings.NameValueTable.VALUE, 239 Settings.NameValueTable.IS_PRESERVED_IN_RESTORE, 240 }; 241 242 public static final int SETTINGS_TYPE_GLOBAL = SettingsState.SETTINGS_TYPE_GLOBAL; 243 public static final int SETTINGS_TYPE_SYSTEM = SettingsState.SETTINGS_TYPE_SYSTEM; 244 public static final int SETTINGS_TYPE_SECURE = SettingsState.SETTINGS_TYPE_SECURE; 245 public static final int SETTINGS_TYPE_SSAID = SettingsState.SETTINGS_TYPE_SSAID; 246 public static final int SETTINGS_TYPE_CONFIG = SettingsState.SETTINGS_TYPE_CONFIG; 247 248 private static final int CHANGE_TYPE_INSERT = 0; 249 private static final int CHANGE_TYPE_DELETE = 1; 250 private static final int CHANGE_TYPE_UPDATE = 2; 251 private static final int CHANGE_TYPE_RESET = 3; 252 253 private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair( 254 Settings.NameValueTable.VALUE, null); 255 256 public static final String RESULT_ROWS_DELETED = "result_rows_deleted"; 257 public static final String RESULT_SETTINGS_LIST = "result_settings_list"; 258 259 public static final String SETTINGS_PROVIDER_JOBS_NS = "SettingsProviderJobsNamespace"; 260 // Used for scheduling jobs to make a copy for the settings files 261 public static final int WRITE_FALLBACK_SETTINGS_FILES_JOB_ID = 1; 262 public static final long ONE_DAY_INTERVAL_MILLIS = 24 * 60 * 60 * 1000L; 263 264 // Overlay specified settings allowlisted for Instant Apps 265 private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>(); 266 private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>(); 267 private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>(); 268 269 static { 270 for (String name : Resources.getSystem().getStringArray( 271 com.android.internal.R.array.config_allowedGlobalInstantAppSettings)) { 272 OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS.add(name); 273 } 274 for (String name : Resources.getSystem().getStringArray( 275 com.android.internal.R.array.config_allowedSystemInstantAppSettings)) { 276 OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS.add(name); 277 } 278 for (String name : Resources.getSystem().getStringArray( 279 com.android.internal.R.array.config_allowedSecureInstantAppSettings)) { 280 OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS.add(name); 281 } 282 } 283 284 // Changes to these global settings are synchronously persisted 285 private static final Set<String> CRITICAL_GLOBAL_SETTINGS = new ArraySet<>(); 286 static { 287 CRITICAL_GLOBAL_SETTINGS.add(Settings.Global.DEVICE_PROVISIONED); 288 } 289 290 // Changes to these secure settings are synchronously persisted 291 private static final Set<String> CRITICAL_SECURE_SETTINGS = new ArraySet<>(); 292 static { 293 CRITICAL_SECURE_SETTINGS.add(Settings.Secure.USER_SETUP_COMPLETE); 294 } 295 296 // Per user secure settings that moved to the for all users global settings. 297 static final Set<String> sSecureMovedToGlobalSettings = new ArraySet<>(); 298 static { 299 Settings.Secure.getMovedToGlobalSettings(sSecureMovedToGlobalSettings); 300 } 301 302 // Per user system settings that moved to the for all users global settings. 303 static final Set<String> sSystemMovedToGlobalSettings = new ArraySet<>(); 304 static { 305 Settings.System.getMovedToGlobalSettings(sSystemMovedToGlobalSettings); 306 } 307 308 // Per user system settings that moved to the per user secure settings. 309 static final Set<String> sSystemMovedToSecureSettings = new ArraySet<>(); 310 static { 311 Settings.System.getMovedToSecureSettings(sSystemMovedToSecureSettings); 312 } 313 314 // Per all users global settings that moved to the per user secure settings. 315 static final Set<String> sGlobalMovedToSecureSettings = new ArraySet<>(); 316 static { 317 Settings.Global.getMovedToSecureSettings(sGlobalMovedToSecureSettings); 318 } 319 320 // Per all users global settings that moved to the per user system settings. 321 static final Set<String> sGlobalMovedToSystemSettings = new ArraySet<>(); 322 static { 323 Settings.Global.getMovedToSystemSettings(sGlobalMovedToSystemSettings); 324 } 325 326 // Per user secure settings that are cloned for the managed profiles of the user. 327 private static final Set<String> sSecureCloneToManagedSettings = new ArraySet<>(); 328 static { 329 Settings.Secure.getCloneToManagedProfileSettings(sSecureCloneToManagedSettings); 330 } 331 332 // Per user system settings that are cloned for the managed profiles of the user. 333 private static final Set<String> sSystemCloneToManagedSettings = new ArraySet<>(); 334 static { 335 Settings.System.getCloneToManagedProfileSettings(sSystemCloneToManagedSettings); 336 } 337 338 // Per user system settings that are cloned from the profile's parent when a dependency 339 // in {@link Settings.Secure} is set to "1". 340 public static final Map<String, String> sSystemCloneFromParentOnDependency = new ArrayMap<>(); 341 static { 342 Settings.System.getCloneFromParentOnValueSettings(sSystemCloneFromParentOnDependency); 343 } 344 345 private static final Set<String> sAllSecureSettings = new ArraySet<>(); 346 private static final Set<String> sReadableSecureSettings = new ArraySet<>(); 347 private static final ArrayMap<String, Integer> sReadableSecureSettingsWithMaxTargetSdk = 348 new ArrayMap<>(); 349 static { Settings.Secure.getPublicSettings(sAllSecureSettings, sReadableSecureSettings, sReadableSecureSettingsWithMaxTargetSdk)350 Settings.Secure.getPublicSettings(sAllSecureSettings, sReadableSecureSettings, 351 sReadableSecureSettingsWithMaxTargetSdk); 352 } 353 354 private static final Set<String> sAllSystemSettings = new ArraySet<>(); 355 private static final Set<String> sReadableSystemSettings = new ArraySet<>(); 356 private static final ArrayMap<String, Integer> sReadableSystemSettingsWithMaxTargetSdk = 357 new ArrayMap<>(); 358 static { Settings.System.getPublicSettings(sAllSystemSettings, sReadableSystemSettings, sReadableSystemSettingsWithMaxTargetSdk)359 Settings.System.getPublicSettings(sAllSystemSettings, sReadableSystemSettings, 360 sReadableSystemSettingsWithMaxTargetSdk); 361 } 362 363 private static final Set<String> sAllGlobalSettings = new ArraySet<>(); 364 private static final Set<String> sReadableGlobalSettings = new ArraySet<>(); 365 private static final ArrayMap<String, Integer> sReadableGlobalSettingsWithMaxTargetSdk = 366 new ArrayMap<>(); 367 static { Settings.Global.getPublicSettings(sAllGlobalSettings, sReadableGlobalSettings, sReadableGlobalSettingsWithMaxTargetSdk)368 Settings.Global.getPublicSettings(sAllGlobalSettings, sReadableGlobalSettings, 369 sReadableGlobalSettingsWithMaxTargetSdk); 370 } 371 372 private final Object mLock = new Object(); 373 374 @GuardedBy("mLock") 375 private RemoteCallback mConfigMonitorCallback; 376 377 @GuardedBy("mLock") 378 private SettingsRegistry mSettingsRegistry; 379 380 @GuardedBy("mLock") 381 private HandlerThread mHandlerThread; 382 383 @GuardedBy("mLock") 384 private Handler mHandler; 385 386 private static final Set<String> sDeviceConfigAllowlistedNamespaces = new ArraySet<>(); 387 388 // TODO(b/388901162): Remove this when the same constant is exposed as an API in DeviceConfig. 389 private static final String DEVICE_CONFIG_OVERRIDES_NAMESPACE = "device_config_overrides"; 390 391 // We have to call in the user manager with no lock held, 392 private volatile UserManager mUserManager; 393 394 // We have to call in the package manager with no lock held, 395 private volatile IPackageManager mPackageManager; 396 397 private volatile SystemConfigManager mSysConfigManager; 398 399 private PackageMonitor mPackageMonitor; 400 401 @GuardedBy("mLock") 402 private boolean mSyncConfigDisabledUntilReboot; 403 404 @ChangeId 405 @EnabledSince(targetSdkVersion=android.os.Build.VERSION_CODES.S) 406 private static final long ENFORCE_READ_PERMISSION_FOR_MULTI_SIM_DATA_CALL = 172670679L; 407 408 409 @Override onCreate()410 public boolean onCreate() { 411 Settings.setInSystemServer(); 412 413 synchronized (mLock) { 414 mUserManager = UserManager.get(getContext()); 415 mPackageManager = AppGlobals.getPackageManager(); 416 mSysConfigManager = getContext().getSystemService(SystemConfigManager.class); 417 mHandlerThread = new HandlerThread(LOG_TAG, 418 Process.THREAD_PRIORITY_BACKGROUND); 419 mHandlerThread.start(); 420 mHandler = new Handler(mHandlerThread.getLooper()); 421 mSettingsRegistry = new SettingsRegistry(mHandlerThread.getLooper()); 422 } 423 SettingsState.cacheSystemPackageNamesAndSystemSignature(getContext()); 424 synchronized (mLock) { 425 mSettingsRegistry.migrateAllLegacySettingsIfNeededLocked(); 426 for (UserInfo user : mUserManager.getAliveUsers()) { 427 mSettingsRegistry.ensureSettingsForUserLocked(user.id); 428 } 429 mSettingsRegistry.syncSsaidTableOnStartLocked(); 430 } 431 mHandler.post(() -> { 432 registerBroadcastReceivers(); 433 startWatchingUserRestrictionChanges(); 434 }); 435 ServiceManager.addService("settings", new SettingsService(this)); 436 ServiceManager.addService("device_config", new DeviceConfigService(this)); 437 return true; 438 } 439 440 @Override call(String method, String name, Bundle args)441 public Bundle call(String method, String name, Bundle args) { 442 final int requestingUserId = getRequestingUserId(args); 443 switch (method) { 444 case Settings.CALL_METHOD_GET_CONFIG -> { 445 Setting setting = getConfigSetting(name); 446 return packageValueForCallResult(SETTINGS_TYPE_CONFIG, name, requestingUserId, 447 setting, isTrackingGeneration(args)); 448 } 449 case Settings.CALL_METHOD_GET_GLOBAL -> { 450 Setting setting = getGlobalSetting(name); 451 return packageValueForCallResult(SETTINGS_TYPE_GLOBAL, name, requestingUserId, 452 setting, isTrackingGeneration(args)); 453 } 454 case Settings.CALL_METHOD_GET_SECURE -> { 455 Setting setting = getSecureSetting(name, requestingUserId); 456 return packageValueForCallResult(SETTINGS_TYPE_SECURE, name, requestingUserId, 457 setting, isTrackingGeneration(args)); 458 } 459 case Settings.CALL_METHOD_GET_SYSTEM -> { 460 Setting setting = getSystemSetting(name, requestingUserId); 461 return packageValueForCallResult(SETTINGS_TYPE_SYSTEM, name, requestingUserId, 462 setting, isTrackingGeneration(args)); 463 } 464 case Settings.CALL_METHOD_PUT_CONFIG -> { 465 String value = getSettingValue(args); 466 final boolean makeDefault = getSettingMakeDefault(args); 467 insertConfigSetting(name, value, makeDefault); 468 } 469 case Settings.CALL_METHOD_PUT_GLOBAL -> { 470 String value = getSettingValue(args); 471 String tag = getSettingTag(args); 472 final boolean makeDefault = getSettingMakeDefault(args); 473 final boolean overrideableByRestore = getSettingOverrideableByRestore(args); 474 insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false, 475 overrideableByRestore); 476 } 477 case Settings.CALL_METHOD_PUT_SECURE -> { 478 String value = getSettingValue(args); 479 String tag = getSettingTag(args); 480 final boolean makeDefault = getSettingMakeDefault(args); 481 final boolean overrideableByRestore = getSettingOverrideableByRestore(args); 482 insertSecureSetting(name, value, tag, makeDefault, requestingUserId, false, 483 overrideableByRestore); 484 } 485 case Settings.CALL_METHOD_PUT_SYSTEM -> { 486 String value = getSettingValue(args); 487 boolean overrideableByRestore = getSettingOverrideableByRestore(args); 488 insertSystemSetting(name, value, requestingUserId, overrideableByRestore); 489 } 490 case Settings.CALL_METHOD_SET_ALL_CONFIG -> { 491 String prefix = getSettingPrefix(args); 492 Map<String, String> flags = getSettingFlags(args); 493 Bundle result = new Bundle(); 494 result.putInt(Settings.KEY_CONFIG_SET_ALL_RETURN, 495 setAllConfigSettings(prefix, flags)); 496 return result; 497 } 498 case Settings.CALL_METHOD_SET_SYNC_DISABLED_MODE_CONFIG -> { 499 final int mode = getSyncDisabledMode(args); 500 setSyncDisabledModeConfig(mode); 501 } 502 case Settings.CALL_METHOD_GET_SYNC_DISABLED_MODE_CONFIG -> { 503 Bundle result = new Bundle(); 504 result.putInt(Settings.KEY_CONFIG_GET_SYNC_DISABLED_MODE_RETURN, 505 getSyncDisabledModeConfig()); 506 return result; 507 } 508 case Settings.CALL_METHOD_RESET_CONFIG -> { 509 final int mode = getResetModeEnforcingPermission(args); 510 String prefix = getSettingPrefix(args); 511 resetConfigSetting(mode, prefix); 512 } 513 case Settings.CALL_METHOD_RESET_GLOBAL -> { 514 final int mode = getResetModeEnforcingPermission(args); 515 String tag = getSettingTag(args); 516 resetGlobalSetting(requestingUserId, mode, tag); 517 } 518 case Settings.CALL_METHOD_RESET_SECURE -> { 519 final int mode = getResetModeEnforcingPermission(args); 520 String tag = getSettingTag(args); 521 resetSecureSetting(requestingUserId, mode, tag); 522 } 523 case Settings.CALL_METHOD_RESET_SYSTEM -> { 524 final int mode = getResetModeEnforcingPermission(args); 525 String tag = getSettingTag(args); 526 resetSystemSetting(requestingUserId, mode, tag); 527 } 528 case Settings.CALL_METHOD_DELETE_CONFIG -> { 529 int rows = deleteConfigSetting(name) ? 1 : 0; 530 Bundle result = new Bundle(); 531 result.putInt(RESULT_ROWS_DELETED, rows); 532 return result; 533 } 534 case Settings.CALL_METHOD_DELETE_GLOBAL -> { 535 int rows = deleteGlobalSetting(name, requestingUserId, false) ? 1 : 0; 536 Bundle result = new Bundle(); 537 result.putInt(RESULT_ROWS_DELETED, rows); 538 return result; 539 } 540 case Settings.CALL_METHOD_DELETE_SECURE -> { 541 int rows = deleteSecureSetting(name, requestingUserId, false) ? 1 : 0; 542 Bundle result = new Bundle(); 543 result.putInt(RESULT_ROWS_DELETED, rows); 544 return result; 545 } 546 case Settings.CALL_METHOD_DELETE_SYSTEM -> { 547 int rows = deleteSystemSetting(name, requestingUserId) ? 1 : 0; 548 Bundle result = new Bundle(); 549 result.putInt(RESULT_ROWS_DELETED, rows); 550 return result; 551 } 552 case Settings.CALL_METHOD_LIST_CONFIG -> { 553 String prefix = getSettingPrefix(args); 554 Bundle result = packageValuesForCallResult(prefix, getAllConfigFlags(prefix), 555 isTrackingGeneration(args)); 556 reportDeviceConfigAccess(prefix); 557 return result; 558 } 559 case Settings.CALL_METHOD_LIST_NAMESPACES_CONFIG -> { 560 Bundle result = packageNamespacesForCallResult(getAllConfigFlagNamespaces()); 561 return result; 562 } 563 case Settings.CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG -> { 564 RemoteCallback callback = args.getParcelable( 565 Settings.CALL_METHOD_MONITOR_CALLBACK_KEY); 566 setMonitorCallback(callback); 567 } 568 case Settings.CALL_METHOD_UNREGISTER_MONITOR_CALLBACK_CONFIG -> { 569 clearMonitorCallback(); 570 } 571 case Settings.CALL_METHOD_LIST_GLOBAL -> { 572 Bundle result = new Bundle(); 573 result.putStringArrayList(RESULT_SETTINGS_LIST, 574 buildSettingsList(getAllGlobalSettings(null))); 575 return result; 576 } 577 case Settings.CALL_METHOD_LIST_SECURE -> { 578 Bundle result = new Bundle(); 579 result.putStringArrayList(RESULT_SETTINGS_LIST, 580 buildSettingsList(getAllSecureSettings(requestingUserId, null))); 581 return result; 582 } 583 case Settings.CALL_METHOD_LIST_SYSTEM -> { 584 Bundle result = new Bundle(); 585 result.putStringArrayList(RESULT_SETTINGS_LIST, 586 buildSettingsList(getAllSystemSettings(requestingUserId, null))); 587 return result; 588 } 589 default -> { 590 Slog.w(LOG_TAG, "call() with invalid method: " + method); 591 } 592 } 593 594 return null; 595 } 596 597 @Override getType(Uri uri)598 public String getType(Uri uri) { 599 Arguments args = new Arguments(uri, null, null, true); 600 if (TextUtils.isEmpty(args.name)) { 601 return "vnd.android.cursor.dir/" + args.table; 602 } else { 603 return "vnd.android.cursor.item/" + args.table; 604 } 605 } 606 607 @Override query(Uri uri, String[] projection, String where, String[] whereArgs, String order)608 public Cursor query(Uri uri, String[] projection, String where, String[] whereArgs, 609 String order) { 610 if (DEBUG) { 611 Slog.v(LOG_TAG, "query() for user: " + UserHandle.getCallingUserId()); 612 } 613 614 Arguments args = new Arguments(uri, where, whereArgs, true); 615 String[] normalizedProjection = normalizeProjection(projection); 616 617 // If a legacy table that is gone, done. 618 if (REMOVED_LEGACY_TABLES.contains(args.table)) { 619 return new MatrixCursor(normalizedProjection, 0); 620 } 621 622 switch (args.table) { 623 case TABLE_GLOBAL -> { 624 if (args.name != null) { 625 Setting setting = getGlobalSetting(args.name); 626 return packageSettingForQuery(setting, normalizedProjection); 627 } else { 628 return getAllGlobalSettings(projection); 629 } 630 } 631 case TABLE_SECURE -> { 632 final int userId = UserHandle.getCallingUserId(); 633 if (args.name != null) { 634 Setting setting = getSecureSetting(args.name, userId); 635 return packageSettingForQuery(setting, normalizedProjection); 636 } else { 637 return getAllSecureSettings(userId, projection); 638 } 639 } 640 case TABLE_SYSTEM -> { 641 final int userId = UserHandle.getCallingUserId(); 642 if (args.name != null) { 643 Setting setting = getSystemSetting(args.name, userId); 644 return packageSettingForQuery(setting, normalizedProjection); 645 } else { 646 return getAllSystemSettings(userId, projection); 647 } 648 } 649 default -> { 650 throw new IllegalArgumentException("Invalid Uri path:" + uri); 651 } 652 } 653 } 654 buildSettingsList(Cursor cursor)655 private ArrayList<String> buildSettingsList(Cursor cursor) { 656 final ArrayList<String> lines = new ArrayList<>(); 657 try { 658 while (cursor != null && cursor.moveToNext()) { 659 lines.add(cursor.getString(1) + "=" + cursor.getString(2)); 660 } 661 } finally { 662 if (cursor != null) { 663 cursor.close(); 664 } 665 } 666 return lines; 667 } 668 669 @Override insert(Uri uri, ContentValues values)670 public Uri insert(Uri uri, ContentValues values) { 671 if (DEBUG) { 672 Slog.v(LOG_TAG, "insert() for user: " + UserHandle.getCallingUserId()); 673 } 674 675 String table = getValidTableOrThrow(uri); 676 677 // If a legacy table that is gone, done. 678 if (REMOVED_LEGACY_TABLES.contains(table)) { 679 return null; 680 } 681 682 String name = values.getAsString(Settings.Secure.NAME); 683 if (!isKeyValid(name)) { 684 return null; 685 } 686 687 String value = values.getAsString(Settings.Secure.VALUE); 688 689 switch (table) { 690 case TABLE_GLOBAL -> { 691 if (insertGlobalSetting(name, value, null, false, 692 UserHandle.getCallingUserId(), false, 693 /* overrideableByRestore */ false)) { 694 return Uri.withAppendedPath(Global.CONTENT_URI, name); 695 } 696 } 697 case TABLE_SECURE -> { 698 if (insertSecureSetting(name, value, null, false, 699 UserHandle.getCallingUserId(), false, 700 /* overrideableByRestore */ false)) { 701 return Uri.withAppendedPath(Secure.CONTENT_URI, name); 702 } 703 } 704 case TABLE_SYSTEM -> { 705 if (insertSystemSetting(name, value, UserHandle.getCallingUserId(), 706 /* overridableByRestore */ false)) { 707 return Uri.withAppendedPath(Settings.System.CONTENT_URI, name); 708 } 709 } 710 default -> { 711 throw new IllegalArgumentException("Bad Uri path:" + uri); 712 } 713 } 714 715 return null; 716 } 717 718 @Override bulkInsert(Uri uri, ContentValues[] allValues)719 public int bulkInsert(Uri uri, ContentValues[] allValues) { 720 if (DEBUG) { 721 Slog.v(LOG_TAG, "bulkInsert() for user: " + UserHandle.getCallingUserId()); 722 } 723 724 int insertionCount = 0; 725 final int valuesCount = allValues.length; 726 for (int i = 0; i < valuesCount; i++) { 727 ContentValues values = allValues[i]; 728 if (insert(uri, values) != null) { 729 insertionCount++; 730 } 731 } 732 733 return insertionCount; 734 } 735 736 @Override delete(Uri uri, String where, String[] whereArgs)737 public int delete(Uri uri, String where, String[] whereArgs) { 738 if (DEBUG) { 739 Slog.v(LOG_TAG, "delete() for user: " + UserHandle.getCallingUserId()); 740 } 741 742 Arguments args = new Arguments(uri, where, whereArgs, false); 743 744 // If a legacy table that is gone, done. 745 if (REMOVED_LEGACY_TABLES.contains(args.table)) { 746 return 0; 747 } 748 749 if (!isKeyValid(args.name)) { 750 return 0; 751 } 752 753 switch (args.table) { 754 case TABLE_GLOBAL -> { 755 final int userId = UserHandle.getCallingUserId(); 756 return deleteGlobalSetting(args.name, userId, false) ? 1 : 0; 757 } 758 case TABLE_SECURE -> { 759 final int userId = UserHandle.getCallingUserId(); 760 return deleteSecureSetting(args.name, userId, false) ? 1 : 0; 761 } 762 case TABLE_SYSTEM -> { 763 final int userId = UserHandle.getCallingUserId(); 764 return deleteSystemSetting(args.name, userId) ? 1 : 0; 765 } 766 default -> { 767 throw new IllegalArgumentException("Bad Uri path:" + uri); 768 } 769 } 770 } 771 772 @Override update(Uri uri, ContentValues values, String where, String[] whereArgs)773 public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { 774 if (DEBUG) { 775 Slog.v(LOG_TAG, "update() for user: " + UserHandle.getCallingUserId()); 776 } 777 778 Arguments args = new Arguments(uri, where, whereArgs, false); 779 780 // If a legacy table that is gone, done. 781 if (REMOVED_LEGACY_TABLES.contains(args.table)) { 782 return 0; 783 } 784 785 String name = values.getAsString(Settings.Secure.NAME); 786 if (!isKeyValid(name)) { 787 return 0; 788 } 789 String value = values.getAsString(Settings.Secure.VALUE); 790 791 switch (args.table) { 792 case TABLE_GLOBAL -> { 793 final int userId = UserHandle.getCallingUserId(); 794 return updateGlobalSetting(args.name, value, null, false, 795 userId, false) ? 1 : 0; 796 } 797 case TABLE_SECURE -> { 798 final int userId = UserHandle.getCallingUserId(); 799 return updateSecureSetting(args.name, value, null, false, 800 userId, false) ? 1 : 0; 801 } 802 case TABLE_SYSTEM -> { 803 final int userId = UserHandle.getCallingUserId(); 804 return updateSystemSetting(args.name, value, userId) ? 1 : 0; 805 } 806 default -> { 807 throw new IllegalArgumentException("Invalid Uri path:" + uri); 808 } 809 } 810 } 811 812 @Override openFile(Uri uri, String mode)813 public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 814 final int userId = getUserIdFromUri(uri, UserHandle.getCallingUserId()); 815 if (userId != UserHandle.getCallingUserId()) { 816 getContext().enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS, 817 "Access files from the settings of another user"); 818 } 819 final String callingPackage = getCallingPackage(); 820 if (mode.contains("w") && !Settings.checkAndNoteWriteSettingsOperation(getContext(), 821 Binder.getCallingUid(), callingPackage, getCallingAttributionTag(), 822 true /* throwException */)) { 823 Slog.e(LOG_TAG, "Package: " + callingPackage + " is not allowed to modify " 824 + "system settings files."); 825 } 826 uri = ContentProvider.getUriWithoutUserId(uri); 827 828 final String cacheRingtoneSetting; 829 if (Settings.System.RINGTONE_CACHE_URI.equals(uri)) { 830 cacheRingtoneSetting = Settings.System.RINGTONE; 831 } else if (Settings.System.NOTIFICATION_SOUND_CACHE_URI.equals(uri)) { 832 cacheRingtoneSetting = Settings.System.NOTIFICATION_SOUND; 833 } else if (Settings.System.ALARM_ALERT_CACHE_URI.equals(uri)) { 834 cacheRingtoneSetting = Settings.System.ALARM_ALERT; 835 } else { 836 throw new FileNotFoundException("Direct file access no longer supported; " 837 + "ringtone playback is available through android.media.Ringtone"); 838 } 839 840 final File cacheFile = getCacheFile(cacheRingtoneSetting, userId); 841 return ParcelFileDescriptor.open(cacheFile, ParcelFileDescriptor.parseMode(mode)); 842 } 843 844 @Nullable getCacheName(String setting)845 private String getCacheName(String setting) { 846 if (Settings.System.RINGTONE.equals(setting)) { 847 return Settings.System.RINGTONE_CACHE; 848 } else if (Settings.System.NOTIFICATION_SOUND.equals(setting)) { 849 return Settings.System.NOTIFICATION_SOUND_CACHE; 850 } else if (Settings.System.ALARM_ALERT.equals(setting)) { 851 return Settings.System.ALARM_ALERT_CACHE; 852 } 853 return null; 854 } 855 856 @Nullable getCacheFile(String setting, int userId)857 private File getCacheFile(String setting, int userId) { 858 int actualCacheOwner; 859 // Redirect cache to parent if ringtone setting is owned by profile parent 860 synchronized (mLock) { 861 actualCacheOwner = resolveOwningUserIdForSystemSettingLocked(userId, setting); 862 } 863 final String cacheName = getCacheName(setting); 864 if (cacheName == null) { 865 return null; 866 } 867 final File cacheFile = new File(getRingtoneCacheDir(actualCacheOwner), cacheName); 868 return cacheFile; 869 } 870 871 872 /** 873 * Try opening the given ringtone locally first, but failover to 874 * {@link IRingtonePlayer} if we can't access it directly. Typically, happens 875 * when process doesn't hold {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}. 876 */ openRingtone(Context context, Uri uri)877 private static InputStream openRingtone(Context context, Uri uri) throws IOException { 878 final ContentResolver resolver = context.getContentResolver(); 879 try { 880 return resolver.openInputStream(uri); 881 } catch (SecurityException | IOException e) { 882 Log.w(LOG_TAG, "Failed to open directly; attempting failover: " + e); 883 final IRingtonePlayer player = context.getSystemService(AudioManager.class) 884 .getRingtonePlayer(); 885 try { 886 return new ParcelFileDescriptor.AutoCloseInputStream(player.openRingtone(uri)); 887 } catch (Exception e2) { 888 throw new IOException(e2); 889 } 890 } 891 } 892 getRingtoneCacheDir(int userId)893 private File getRingtoneCacheDir(int userId) { 894 final File cacheDir = new File(Environment.getDataSystemDeDirectory(userId), "ringtones"); 895 cacheDir.mkdir(); 896 SELinux.restorecon(cacheDir); 897 return cacheDir; 898 } 899 900 /** 901 * Dump all settings as a proto buf. 902 * 903 * @param fd The file to dump to 904 */ dumpProto(@onNull FileDescriptor fd)905 void dumpProto(@NonNull FileDescriptor fd) { 906 ProtoOutputStream proto = new ProtoOutputStream(fd); 907 908 synchronized (mLock) { 909 SettingsProtoDumpUtil.dumpProtoLocked(mSettingsRegistry, proto); 910 } 911 912 proto.flush(); 913 } 914 dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args)915 public void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) { 916 synchronized (mLock) { 917 final long identity = Binder.clearCallingIdentity(); 918 try { 919 SparseBooleanArray users = mSettingsRegistry.getKnownUsersLocked(); 920 final int userCount = users.size(); 921 for (int i = 0; i < userCount; i++) { 922 dumpForUserLocked(users.keyAt(i), pw); 923 } 924 } finally { 925 Binder.restoreCallingIdentity(identity); 926 } 927 mSettingsRegistry.mGenerationRegistry.dump(pw); 928 } 929 } 930 931 @GuardedBy("mLock") dumpForUserLocked(int userId, PrintWriter pw)932 private void dumpForUserLocked(int userId, PrintWriter pw) { 933 if (userId == UserHandle.USER_SYSTEM) { 934 pw.println("CONFIG SETTINGS (user " + userId + ")"); 935 SettingsState configSettings = mSettingsRegistry.getSettingsLocked( 936 SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM); 937 if (configSettings != null) { 938 dumpSettingsLocked(configSettings, pw); 939 pw.println(); 940 configSettings.dumpHistoricalOperations(pw); 941 } 942 943 pw.println("GLOBAL SETTINGS (user " + userId + ")"); 944 SettingsState globalSettings = mSettingsRegistry.getSettingsLocked( 945 SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); 946 if (globalSettings != null) { 947 dumpSettingsLocked(globalSettings, pw); 948 pw.println(); 949 globalSettings.dumpHistoricalOperations(pw); 950 } 951 } 952 953 pw.println("SECURE SETTINGS (user " + userId + ")"); 954 SettingsState secureSettings = mSettingsRegistry.getSettingsLocked( 955 SETTINGS_TYPE_SECURE, userId); 956 if (secureSettings != null) { 957 dumpSettingsLocked(secureSettings, pw); 958 pw.println(); 959 secureSettings.dumpHistoricalOperations(pw); 960 } 961 962 pw.println("SYSTEM SETTINGS (user " + userId + ")"); 963 SettingsState systemSettings = mSettingsRegistry.getSettingsLocked( 964 SETTINGS_TYPE_SYSTEM, userId); 965 if (systemSettings != null) { 966 dumpSettingsLocked(systemSettings, pw); 967 pw.println(); 968 systemSettings.dumpHistoricalOperations(pw); 969 } 970 } 971 972 @SuppressWarnings("GuardedBy") dumpSettingsLocked(SettingsState settingsState, PrintWriter pw)973 private void dumpSettingsLocked(SettingsState settingsState, PrintWriter pw) { 974 List<String> names = settingsState.getSettingNamesLocked(); 975 pw.println("version: " + settingsState.getVersionLocked()); 976 final int nameCount = names.size(); 977 978 for (int i = 0; i < nameCount; i++) { 979 String name = names.get(i); 980 Setting setting = settingsState.getSettingLocked(name); 981 pw.print("_id:"); pw.print(toDumpString(String.valueOf(setting.getId()))); 982 pw.print(" name:"); pw.print(toDumpString(name)); 983 if (setting.getPackageName() != null) { 984 pw.print(" pkg:"); pw.print(setting.getPackageName()); 985 } 986 pw.print(" value:"); pw.print(toDumpString(setting.getValue())); 987 if (setting.getDefaultValue() != null) { 988 pw.print(" default:"); pw.print(setting.getDefaultValue()); 989 pw.print(" defaultSystemSet:"); pw.print(setting.isDefaultFromSystem()); 990 } 991 if (setting.getTag() != null) { 992 pw.print(" tag:"); pw.print(setting.getTag()); 993 } 994 // The majority of settings are preserved in restore, so we're just dumping those that 995 // are not (to save space). 996 if (!setting.isValuePreservedInRestore()) { 997 pw.println(" notPreservedInRestore"); 998 } 999 pw.println(); 1000 } 1001 } 1002 toDumpString(String s)1003 private static String toDumpString(String s) { 1004 if (s != null) { 1005 return s; 1006 } 1007 return "{null}"; 1008 } 1009 registerBroadcastReceivers()1010 private void registerBroadcastReceivers() { 1011 IntentFilter userFilter = new IntentFilter(); 1012 userFilter.addAction(Intent.ACTION_USER_ADDED); 1013 userFilter.addAction(Intent.ACTION_USER_REMOVED); 1014 1015 getContext().registerReceiver(new BroadcastReceiver() { 1016 @Override 1017 public void onReceive(Context context, Intent intent) { 1018 if (intent.getAction() == null) { 1019 return; 1020 } 1021 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 1022 UserHandle.USER_NULL); 1023 if (userId == UserHandle.USER_NULL) { 1024 return; 1025 } 1026 1027 switch (intent.getAction()) { 1028 case Intent.ACTION_USER_ADDED -> { 1029 synchronized (mLock) { 1030 mSettingsRegistry.ensureSettingsForUserLocked(userId); 1031 } 1032 } 1033 case Intent.ACTION_USER_REMOVED -> { 1034 synchronized (mLock) { 1035 mSettingsRegistry.removeUserStateLocked(userId, true); 1036 } 1037 } 1038 } 1039 } 1040 }, userFilter); 1041 1042 mPackageMonitor = new PackageMonitor() { 1043 @Override 1044 public void onPackageRemoved(String packageName, int uid) { 1045 synchronized (mLock) { 1046 mSettingsRegistry.removeSettingsForPackageLocked(packageName, 1047 UserHandle.getUserId(uid)); 1048 } 1049 } 1050 1051 @Override 1052 public void onUidRemoved(int uid) { 1053 synchronized (mLock) { 1054 mSettingsRegistry.onUidRemovedLocked(uid); 1055 } 1056 } 1057 1058 @Override 1059 public void onPackageDataCleared(String packageName, int uid) { 1060 synchronized (mLock) { 1061 mSettingsRegistry.removeSettingsForPackageLocked(packageName, 1062 UserHandle.getUserId(uid)); 1063 } 1064 } 1065 }; 1066 1067 // package changes 1068 mPackageMonitor.register(getContext(), BackgroundThread.getHandler().getLooper(), 1069 UserHandle.ALL, true); 1070 } 1071 startWatchingUserRestrictionChanges()1072 private void startWatchingUserRestrictionChanges() { 1073 // TODO: The current design of settings looking different based on user restrictions 1074 // should be reworked to keep them separate and system code should check the setting 1075 // first followed by checking the user restriction before performing an operation. 1076 IUserRestrictionsListener listener = new IUserRestrictionsListener.Stub() { 1077 @Override 1078 public void onUserRestrictionsChanged(int userId, 1079 Bundle newRestrictions, Bundle prevRestrictions) { 1080 Set<String> changedRestrictions = 1081 getRestrictionDiff(prevRestrictions, newRestrictions); 1082 // We are changing the settings affected by restrictions to their current 1083 // value with a forced update to ensure that all cross profile dependencies 1084 // are taken into account. Also make sure the settings update to.. the same 1085 // value passes the security checks, so clear binder calling id. 1086 if (changedRestrictions.contains(UserManager.DISALLOW_SHARE_LOCATION)) { 1087 final long identity = Binder.clearCallingIdentity(); 1088 try { 1089 synchronized (mLock) { 1090 Setting setting = getSecureSetting( 1091 Settings.Secure.LOCATION_MODE, userId); 1092 updateSecureSetting(Settings.Secure.LOCATION_MODE, 1093 setting != null ? setting.getValue() : null, null, 1094 true, userId, true); 1095 } 1096 } finally { 1097 Binder.restoreCallingIdentity(identity); 1098 } 1099 } 1100 if (changedRestrictions.contains(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES) 1101 || changedRestrictions.contains( 1102 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY)) { 1103 final long identity = Binder.clearCallingIdentity(); 1104 try { 1105 synchronized (mLock) { 1106 Setting setting = getGlobalSetting( 1107 Settings.Global.INSTALL_NON_MARKET_APPS); 1108 String value = setting != null ? setting.getValue() : null; 1109 updateGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS, 1110 value, null, true, userId, true); 1111 } 1112 } finally { 1113 Binder.restoreCallingIdentity(identity); 1114 } 1115 } 1116 if (changedRestrictions.contains(UserManager.DISALLOW_DEBUGGING_FEATURES)) { 1117 final long identity = Binder.clearCallingIdentity(); 1118 try { 1119 synchronized (mLock) { 1120 Setting setting = getGlobalSetting(Settings.Global.ADB_ENABLED); 1121 String value = setting != null ? setting.getValue() : null; 1122 updateGlobalSetting(Settings.Global.ADB_ENABLED, 1123 value, null, true, userId, true); 1124 1125 setting = getGlobalSetting(Settings.Global.ADB_WIFI_ENABLED); 1126 value = setting != null ? setting.getValue() : null; 1127 updateGlobalSetting(Settings.Global.ADB_WIFI_ENABLED, 1128 value, null, true, userId, true); 1129 } 1130 } finally { 1131 Binder.restoreCallingIdentity(identity); 1132 } 1133 } 1134 if (changedRestrictions.contains(UserManager.ENSURE_VERIFY_APPS)) { 1135 final long identity = Binder.clearCallingIdentity(); 1136 try { 1137 synchronized (mLock) { 1138 Setting include = getGlobalSetting( 1139 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB); 1140 String includeValue = include != null ? include.getValue() : null; 1141 updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1142 includeValue, null, true, userId, true); 1143 } 1144 } finally { 1145 Binder.restoreCallingIdentity(identity); 1146 } 1147 } 1148 if (changedRestrictions.contains(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) { 1149 final long identity = Binder.clearCallingIdentity(); 1150 try { 1151 synchronized (mLock) { 1152 Setting setting = getGlobalSetting( 1153 Settings.Global.PREFERRED_NETWORK_MODE); 1154 String value = setting != null ? setting.getValue() : null; 1155 updateGlobalSetting(Settings.Global.PREFERRED_NETWORK_MODE, 1156 value, null, true, userId, true); 1157 } 1158 } finally { 1159 Binder.restoreCallingIdentity(identity); 1160 } 1161 } 1162 } 1163 }; 1164 mUserManager.addUserRestrictionsListener(listener); 1165 } 1166 getRestrictionDiff(Bundle prevRestrictions, Bundle newRestrictions)1167 private static Set<String> getRestrictionDiff(Bundle prevRestrictions, Bundle newRestrictions) { 1168 Set<String> restrictionNames = Sets.newArraySet(); 1169 restrictionNames.addAll(prevRestrictions.keySet()); 1170 restrictionNames.addAll(newRestrictions.keySet()); 1171 Set<String> diff = Sets.newArraySet(); 1172 for (String restrictionName : restrictionNames) { 1173 if (prevRestrictions.getBoolean(restrictionName) != newRestrictions.getBoolean( 1174 restrictionName)) { 1175 diff.add(restrictionName); 1176 } 1177 } 1178 return diff; 1179 } 1180 getConfigSetting(String name)1181 private Setting getConfigSetting(String name) { 1182 if (DEBUG) { 1183 Slog.v(LOG_TAG, "getConfigSetting(" + name + ")"); 1184 } 1185 1186 // Get the value. 1187 synchronized (mLock) { 1188 return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_CONFIG, 1189 UserHandle.USER_SYSTEM, name); 1190 } 1191 } 1192 insertConfigSetting(String name, String value, boolean makeDefault)1193 private boolean insertConfigSetting(String name, String value, boolean makeDefault) { 1194 if (DEBUG) { 1195 Slog.v(LOG_TAG, "insertConfigSetting(" + name + ", " + value + ", " 1196 + makeDefault + ")"); 1197 } 1198 return mutateConfigSetting(name, value, null, makeDefault, 1199 MUTATION_OPERATION_INSERT, 0); 1200 } 1201 1202 setAllConfigSettings(String prefix, Map<String, String> keyValues)1203 private @SetAllResult int setAllConfigSettings(String prefix, Map<String, String> keyValues) { 1204 if (DEBUG) { 1205 Slog.v(LOG_TAG, "setAllConfigSettings for prefix: " + prefix); 1206 } 1207 1208 enforceDeviceConfigWritePermission(getContext(), keyValues.keySet()); 1209 final String callingPackage = resolveCallingPackage(); 1210 1211 synchronized (mLock) { 1212 if (getSyncDisabledModeConfigLocked() != SYNC_DISABLED_MODE_NONE) { 1213 Slog.v(LOG_TAG, "did not write settings for prefix '" 1214 + prefix + "' because sync is disabled"); 1215 return SET_ALL_RESULT_DISABLED; 1216 } 1217 final int key = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM); 1218 boolean success = mSettingsRegistry.setConfigSettingsLocked(key, prefix, keyValues, 1219 callingPackage); 1220 return success ? SET_ALL_RESULT_SUCCESS : SET_ALL_RESULT_FAILURE; 1221 } 1222 } 1223 setSyncDisabledModeConfig(@yncDisabledMode int syncDisabledMode)1224 private void setSyncDisabledModeConfig(@SyncDisabledMode int syncDisabledMode) { 1225 if (DEBUG) { 1226 Slog.v(LOG_TAG, "setSyncDisabledModeConfig(" + syncDisabledMode + ")"); 1227 } 1228 1229 enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG, 1230 Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG); 1231 1232 synchronized (mLock) { 1233 setSyncDisabledModeConfigLocked(syncDisabledMode); 1234 } 1235 } 1236 getSyncDisabledModeConfig()1237 private int getSyncDisabledModeConfig() { 1238 if (DEBUG) { 1239 Slog.v(LOG_TAG, "getSyncDisabledModeConfig"); 1240 } 1241 1242 enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG, 1243 Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG); 1244 1245 synchronized (mLock) { 1246 return getSyncDisabledModeConfigLocked(); 1247 } 1248 } 1249 1250 @GuardedBy("mLock") setSyncDisabledModeConfigLocked(@yncDisabledMode int syncDisabledMode)1251 private void setSyncDisabledModeConfigLocked(@SyncDisabledMode int syncDisabledMode) { 1252 boolean persistentValue; 1253 boolean inMemoryValue; 1254 if (syncDisabledMode == SYNC_DISABLED_MODE_NONE) { 1255 persistentValue = false; 1256 inMemoryValue = false; 1257 } else if (syncDisabledMode == SYNC_DISABLED_MODE_PERSISTENT) { 1258 persistentValue = true; 1259 inMemoryValue = false; 1260 } else if (syncDisabledMode == SYNC_DISABLED_MODE_UNTIL_REBOOT) { 1261 persistentValue = false; 1262 inMemoryValue = true; 1263 } else { 1264 throw new IllegalArgumentException(Integer.toString(syncDisabledMode)); 1265 } 1266 1267 mSyncConfigDisabledUntilReboot = inMemoryValue; 1268 1269 CallingIdentity callingIdentity = clearCallingIdentity(); 1270 try { 1271 String globalSettingValue = persistentValue ? "1" : "0"; 1272 mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL, 1273 UserHandle.USER_SYSTEM, Settings.Global.DEVICE_CONFIG_SYNC_DISABLED, 1274 globalSettingValue, /*tag=*/null, /*makeDefault=*/false, 1275 SettingsState.SYSTEM_PACKAGE_NAME, /*forceNotify=*/false, 1276 /*criticalSettings=*/null, Settings.DEFAULT_OVERRIDEABLE_BY_RESTORE); 1277 } finally { 1278 restoreCallingIdentity(callingIdentity); 1279 } 1280 } 1281 1282 @GuardedBy("mLock") getSyncDisabledModeConfigLocked()1283 private int getSyncDisabledModeConfigLocked() { 1284 // Check the values used for both SYNC_DISABLED_MODE_PERSISTENT and 1285 // SYNC_DISABLED_MODE_UNTIL_REBOOT. 1286 1287 // The SYNC_DISABLED_MODE_UNTIL_REBOOT value is cheap to check first. 1288 if (mSyncConfigDisabledUntilReboot) { 1289 return SYNC_DISABLED_MODE_UNTIL_REBOOT; 1290 } 1291 1292 // Now check the global setting used to implement SYNC_DISABLED_MODE_PERSISTENT. 1293 CallingIdentity callingIdentity = clearCallingIdentity(); 1294 try { 1295 Setting settingLocked = mSettingsRegistry.getSettingLocked( 1296 SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM, 1297 Global.DEVICE_CONFIG_SYNC_DISABLED); 1298 String settingValue = settingLocked == null ? null : settingLocked.getValue(); 1299 if (settingValue == null) { 1300 // Disable sync by default in test harness mode. 1301 return ActivityManager.isRunningInUserTestHarness() 1302 ? SYNC_DISABLED_MODE_PERSISTENT : SYNC_DISABLED_MODE_NONE; 1303 } 1304 boolean isSyncDisabledPersistent = !"0".equals(settingValue); 1305 return isSyncDisabledPersistent 1306 ? SYNC_DISABLED_MODE_PERSISTENT : SYNC_DISABLED_MODE_NONE; 1307 } finally { 1308 restoreCallingIdentity(callingIdentity); 1309 } 1310 } 1311 deleteConfigSetting(String name)1312 private boolean deleteConfigSetting(String name) { 1313 if (DEBUG) { 1314 Slog.v(LOG_TAG, "deleteConfigSetting(" + name + ")"); 1315 } 1316 return mutateConfigSetting(name, null, null, false, 1317 MUTATION_OPERATION_DELETE, 0); 1318 } 1319 resetConfigSetting(int mode, String prefix)1320 private void resetConfigSetting(int mode, String prefix) { 1321 if (DEBUG) { 1322 Slog.v(LOG_TAG, "resetConfigSetting(" + mode + ", " + prefix + ")"); 1323 } 1324 mutateConfigSetting(null, null, prefix, false, 1325 MUTATION_OPERATION_RESET, mode); 1326 } 1327 mutateConfigSetting(String name, String value, String prefix, boolean makeDefault, int operation, int mode)1328 private boolean mutateConfigSetting(String name, String value, String prefix, 1329 boolean makeDefault, int operation, int mode) { 1330 final String callingPackage = resolveCallingPackage(); 1331 1332 // Perform the mutation. 1333 synchronized (mLock) { 1334 switch (operation) { 1335 case MUTATION_OPERATION_INSERT -> { 1336 enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name)); 1337 return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG, 1338 UserHandle.USER_SYSTEM, name, value, null, makeDefault, true, 1339 callingPackage, false, null, 1340 /* overrideableByRestore */ false); 1341 } 1342 case MUTATION_OPERATION_DELETE -> { 1343 enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name)); 1344 return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_CONFIG, 1345 UserHandle.USER_SYSTEM, name, false, null); 1346 } 1347 case MUTATION_OPERATION_RESET -> { 1348 enforceDeviceConfigWritePermission(getContext(), 1349 getAllConfigFlags(prefix).keySet()); 1350 return mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG, 1351 UserHandle.USER_SYSTEM, callingPackage, mode, null, prefix); 1352 } 1353 } 1354 } 1355 1356 return false; 1357 } 1358 1359 @NonNull getAllConfigFlagNamespaces()1360 private HashSet<String> getAllConfigFlagNamespaces() { 1361 Set<String> flagNames = getAllConfigFlags(null).keySet(); 1362 HashSet<String> namespaces = new HashSet(); 1363 for (String name : flagNames) { 1364 int slashIndex = name.indexOf("/"); 1365 boolean validSlashIndex = slashIndex != -1 1366 && slashIndex != 0 1367 && slashIndex != name.length(); 1368 if (validSlashIndex) { 1369 String namespace = name.substring(0, slashIndex); 1370 namespaces.add(namespace); 1371 } 1372 } 1373 return namespaces; 1374 } 1375 1376 @NonNull getAllConfigFlags(@ullable String prefix)1377 private HashMap<String, String> getAllConfigFlags(@Nullable String prefix) { 1378 if (DEBUG) { 1379 Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix); 1380 } 1381 1382 synchronized (mLock) { 1383 // Get the settings. 1384 SettingsState settingsState = mSettingsRegistry.getSettingsLocked( 1385 SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM); 1386 List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_CONFIG, 1387 UserHandle.USER_SYSTEM); 1388 1389 final int nameCount = names.size(); 1390 HashMap<String, String> flagsToValues = new HashMap<>(names.size()); 1391 1392 if (Flags.loadAconfigDefaults()) { 1393 Map<String, Map<String, String>> allDefaults = 1394 settingsState.getAconfigDefaultValues(); 1395 1396 if (allDefaults != null) { 1397 if (prefix != null) { 1398 String namespace = prefix.substring(0, prefix.length() - 1); 1399 1400 Map<String, String> namespaceDefaults = allDefaults.get(namespace); 1401 if (namespaceDefaults != null) { 1402 flagsToValues.putAll(namespaceDefaults); 1403 } 1404 } else { 1405 for (Map<String, String> namespaceDefaults : allDefaults.values()) { 1406 flagsToValues.putAll(namespaceDefaults); 1407 } 1408 } 1409 } 1410 } 1411 1412 Map<String, AconfigdFlagInfo> aconfigFlagInfos = 1413 settingsState.getAconfigDefaultFlags(); 1414 1415 for (int i = 0; i < nameCount; i++) { 1416 String name = names.get(i); 1417 Setting setting = settingsState.getSettingLocked(name); 1418 if (prefix == null || name.startsWith(prefix)) { 1419 if (Flags.ignoreXmlForReadOnlyFlags()) { 1420 int slashIndex = name.indexOf("/"); 1421 boolean validSlashIndex = slashIndex != -1 1422 && slashIndex != 0 1423 && slashIndex != name.length(); 1424 if (validSlashIndex) { 1425 String flagName = name.substring(slashIndex + 1); 1426 AconfigdFlagInfo flagInfo = aconfigFlagInfos.get(flagName); 1427 if (flagInfo != null && !flagInfo.getIsReadWrite()) { 1428 continue; 1429 } 1430 } 1431 } 1432 1433 flagsToValues.put(setting.getName(), setting.getValue()); 1434 } 1435 } 1436 1437 return flagsToValues; 1438 } 1439 } 1440 getAllGlobalSettings(String[] projection)1441 private Cursor getAllGlobalSettings(String[] projection) { 1442 if (DEBUG) { 1443 Slog.v(LOG_TAG, "getAllGlobalSettings()"); 1444 } 1445 1446 synchronized (mLock) { 1447 // Get the settings. 1448 SettingsState settingsState = mSettingsRegistry.getSettingsLocked( 1449 SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); 1450 1451 List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_GLOBAL, 1452 UserHandle.USER_SYSTEM); 1453 1454 final int nameCount = names.size(); 1455 1456 String[] normalizedProjection = normalizeProjection(projection); 1457 MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); 1458 1459 // Anyone can get the global settings, so no security checks. 1460 for (int i = 0; i < nameCount; i++) { 1461 String name = names.get(i); 1462 try { 1463 enforceSettingReadable(name, SETTINGS_TYPE_GLOBAL, 1464 UserHandle.getCallingUserId()); 1465 } catch (SecurityException e) { 1466 // Caller doesn't have permission to read this setting 1467 continue; 1468 } 1469 Setting setting = settingsState.getSettingLocked(name); 1470 appendSettingToCursor(result, setting); 1471 } 1472 1473 return result; 1474 } 1475 } 1476 getGlobalSetting(String name)1477 private Setting getGlobalSetting(String name) { 1478 if (DEBUG) { 1479 Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")"); 1480 } 1481 1482 // Ensure the caller can access the setting. 1483 enforceSettingReadable(name, SETTINGS_TYPE_GLOBAL, UserHandle.getCallingUserId()); 1484 1485 // Get the value. 1486 synchronized (mLock) { 1487 return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_GLOBAL, 1488 UserHandle.USER_SYSTEM, name); 1489 } 1490 } 1491 updateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, boolean forceNotify)1492 private boolean updateGlobalSetting(String name, String value, String tag, 1493 boolean makeDefault, int requestingUserId, boolean forceNotify) { 1494 if (DEBUG) { 1495 Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ", " 1496 + ", " + tag + ", " + makeDefault + ", " + requestingUserId 1497 + ", " + forceNotify + ")"); 1498 } 1499 return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId, 1500 MUTATION_OPERATION_UPDATE, forceNotify, 0); 1501 } 1502 insertGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, boolean forceNotify, boolean overrideableByRestore)1503 private boolean insertGlobalSetting(String name, String value, String tag, 1504 boolean makeDefault, int requestingUserId, boolean forceNotify, 1505 boolean overrideableByRestore) { 1506 if (DEBUG) { 1507 Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value + ", " 1508 + ", " + tag + ", " + makeDefault + ", " + requestingUserId 1509 + ", " + forceNotify + ", " + overrideableByRestore + ")"); 1510 } 1511 return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId, 1512 MUTATION_OPERATION_INSERT, forceNotify, 0, overrideableByRestore); 1513 } 1514 deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify)1515 private boolean deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify) { 1516 if (DEBUG) { 1517 Slog.v(LOG_TAG, "deleteGlobalSetting(" + name + ", " + requestingUserId 1518 + ", " + forceNotify + ")"); 1519 } 1520 return mutateGlobalSetting(name, null, null, false, requestingUserId, 1521 MUTATION_OPERATION_DELETE, forceNotify, 0); 1522 } 1523 resetGlobalSetting(int requestingUserId, int mode, String tag)1524 private void resetGlobalSetting(int requestingUserId, int mode, String tag) { 1525 if (DEBUG) { 1526 Slog.v(LOG_TAG, "resetGlobalSetting(" + requestingUserId + ", " 1527 + mode + ", " + tag + ")"); 1528 } 1529 mutateGlobalSetting(null, null, tag, false, requestingUserId, 1530 MUTATION_OPERATION_RESET, false, mode); 1531 } 1532 isSettingRestrictedForUser(String name, int userId, String value, int callerUid)1533 private boolean isSettingRestrictedForUser(String name, int userId, 1534 String value, int callerUid) { 1535 final long oldId = Binder.clearCallingIdentity(); 1536 try { 1537 return (name != null 1538 && mUserManager.isSettingRestrictedForUser(name, userId, value, callerUid)); 1539 } finally { 1540 Binder.restoreCallingIdentity(oldId); 1541 } 1542 } 1543 mutateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode)1544 private boolean mutateGlobalSetting(String name, String value, String tag, 1545 boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, 1546 int mode) { 1547 // overrideableByRestore = false as by default settings values shouldn't be overrideable by 1548 // restore. 1549 return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId, operation, 1550 forceNotify, mode, /* overrideableByRestore */ false); 1551 } 1552 mutateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode, boolean overrideableByRestore)1553 private boolean mutateGlobalSetting(String name, String value, String tag, 1554 boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, 1555 int mode, boolean overrideableByRestore) { 1556 // Make sure the caller can change the settings - treated as secure. 1557 enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS); 1558 1559 // Resolve the userId on whose behalf the call is made. 1560 final int callingUserId = resolveCallingUserIdEnforcingPermissions(requestingUserId); 1561 1562 // If this is a setting that is currently restricted for this user, do not allow 1563 // unrestricting changes. 1564 if (isSettingRestrictedForUser(name, callingUserId, value, Binder.getCallingUid())) { 1565 return false; 1566 } 1567 1568 final String callingPackage = getCallingPackage(); 1569 1570 // Perform the mutation. 1571 synchronized (mLock) { 1572 switch (operation) { 1573 case MUTATION_OPERATION_INSERT -> { 1574 return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL, 1575 UserHandle.USER_SYSTEM, name, value, tag, makeDefault, 1576 callingPackage, forceNotify, 1577 CRITICAL_GLOBAL_SETTINGS, overrideableByRestore); 1578 } 1579 case MUTATION_OPERATION_DELETE -> { 1580 return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_GLOBAL, 1581 UserHandle.USER_SYSTEM, name, forceNotify, CRITICAL_GLOBAL_SETTINGS); 1582 } 1583 case MUTATION_OPERATION_UPDATE -> { 1584 return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_GLOBAL, 1585 UserHandle.USER_SYSTEM, name, value, tag, makeDefault, 1586 callingPackage, forceNotify, CRITICAL_GLOBAL_SETTINGS); 1587 } 1588 case MUTATION_OPERATION_RESET -> { 1589 return mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_GLOBAL, 1590 UserHandle.USER_SYSTEM, callingPackage, mode, tag); 1591 } 1592 } 1593 } 1594 1595 return false; 1596 } 1597 getCallingPackageInfo(int userId)1598 private PackageInfo getCallingPackageInfo(int userId) { 1599 final String callingPackage = getCallingPackage(); 1600 try { 1601 return mPackageManager.getPackageInfo(callingPackage, 1602 PackageManager.GET_SIGNATURES, userId); 1603 } catch (RemoteException e) { 1604 throw new IllegalStateException("Package " + callingPackage + " doesn't exist"); 1605 } 1606 } 1607 getAllSecureSettings(int userId, String[] projection)1608 private Cursor getAllSecureSettings(int userId, String[] projection) { 1609 if (DEBUG) { 1610 Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")"); 1611 } 1612 1613 // Resolve the userId on whose behalf the call is made. 1614 final int callingUserId = resolveCallingUserIdEnforcingPermissions(userId); 1615 1616 // The relevant "calling package" userId will be the owning userId for some 1617 // profiles, and we can't do the lookup inside our [lock held] loop, so work out 1618 // up front who the effective "new SSAID" user ID for that settings name will be. 1619 final int ssaidUserId = resolveOwningUserIdForSecureSetting(callingUserId, 1620 Settings.Secure.ANDROID_ID); 1621 final PackageInfo ssaidCallingPkg = getCallingPackageInfo(ssaidUserId); 1622 1623 synchronized (mLock) { 1624 List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SECURE, callingUserId); 1625 1626 final int nameCount = names.size(); 1627 1628 String[] normalizedProjection = normalizeProjection(projection); 1629 MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); 1630 1631 for (int i = 0; i < nameCount; i++) { 1632 String name = names.get(i); 1633 // Determine the owning user as some profile settings are cloned from the parent. 1634 final int owningUserId = resolveOwningUserIdForSecureSetting(callingUserId, 1635 name); 1636 1637 if (!isSecureSettingAccessible(name)) { 1638 // This caller is not permitted to access this setting. Pretend the setting 1639 // doesn't exist. 1640 continue; 1641 } 1642 1643 try { 1644 enforceSettingReadable(name, SETTINGS_TYPE_SECURE, callingUserId); 1645 } catch (SecurityException e) { 1646 // Caller doesn't have permission to read this setting 1647 continue; 1648 } 1649 1650 // As of Android O, the SSAID is read from an app-specific entry in table 1651 // SETTINGS_FILE_SSAID, unless accessed by a system process. 1652 final Setting setting; 1653 if (isNewSsaidSetting(name)) { 1654 setting = getSsaidSettingLocked(ssaidCallingPkg, owningUserId); 1655 } else { 1656 setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE, owningUserId, 1657 name); 1658 } 1659 appendSettingToCursor(result, setting); 1660 } 1661 1662 return result; 1663 } 1664 } 1665 getSecureSetting(String name, int requestingUserId)1666 private Setting getSecureSetting(String name, int requestingUserId) { 1667 if (DEBUG) { 1668 Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")"); 1669 } 1670 1671 // Resolve the userId on whose behalf the call is made. 1672 final int callingUserId = resolveCallingUserIdEnforcingPermissions(requestingUserId); 1673 1674 // Ensure the caller can access the setting. 1675 enforceSettingReadable(name, SETTINGS_TYPE_SECURE, UserHandle.getCallingUserId()); 1676 1677 // Determine the owning user as some profile settings are cloned from the parent. 1678 final int owningUserId = resolveOwningUserIdForSecureSetting(callingUserId, name); 1679 1680 if (!isSecureSettingAccessible(name)) { 1681 // This caller is not permitted to access this setting. Pretend the setting doesn't 1682 // exist. 1683 SettingsState settings = mSettingsRegistry.getSettingsLocked(SETTINGS_TYPE_SECURE, 1684 owningUserId); 1685 return settings != null ? settings.getNullSetting() : null; 1686 } 1687 1688 // As of Android O, the SSAID is read from an app-specific entry in table 1689 // SETTINGS_FILE_SSAID, unless accessed by a system process. 1690 if (isNewSsaidSetting(name)) { 1691 PackageInfo callingPkg = getCallingPackageInfo(owningUserId); 1692 synchronized (mLock) { 1693 return getSsaidSettingLocked(callingPkg, owningUserId); 1694 } 1695 } 1696 1697 // Not the SSAID; do a straight lookup 1698 synchronized (mLock) { 1699 return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE, 1700 owningUserId, name); 1701 } 1702 } 1703 isNewSsaidSetting(String name)1704 private boolean isNewSsaidSetting(String name) { 1705 return Settings.Secure.ANDROID_ID.equals(name) 1706 && UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID; 1707 } 1708 1709 @GuardedBy("mLock") getSsaidSettingLocked(PackageInfo callingPkg, int owningUserId)1710 private Setting getSsaidSettingLocked(PackageInfo callingPkg, int owningUserId) { 1711 // Get uid of caller (key) used to store ssaid value 1712 String name = Integer.toString( 1713 UserHandle.getUid(owningUserId, UserHandle.getAppId(Binder.getCallingUid()))); 1714 1715 if (DEBUG) { 1716 Slog.v(LOG_TAG, "getSsaidSettingLocked(" + name + "," + owningUserId + ")"); 1717 } 1718 1719 // Retrieve the ssaid from the table if present. 1720 final Setting ssaid = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId, 1721 name); 1722 // If the app is an Instant App use its stored SSAID instead of our own. 1723 final String instantSsaid; 1724 final long token = Binder.clearCallingIdentity(); 1725 try { 1726 instantSsaid = mPackageManager.getInstantAppAndroidId(callingPkg.packageName, 1727 owningUserId); 1728 } catch (RemoteException e) { 1729 Slog.e(LOG_TAG, "Failed to get Instant App Android ID", e); 1730 return null; 1731 } finally { 1732 Binder.restoreCallingIdentity(token); 1733 } 1734 1735 final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked( 1736 SETTINGS_TYPE_SSAID, owningUserId); 1737 1738 if (instantSsaid != null) { 1739 // Use the stored value if it is still valid. 1740 if (ssaid != null && instantSsaid.equals(ssaid.getValue())) { 1741 return mascaradeSsaidSetting(ssaidSettings, ssaid); 1742 } 1743 // The value has changed, update the stored value. 1744 final boolean success = ssaidSettings.insertSettingLocked(name, instantSsaid, null, 1745 true, callingPkg.packageName); 1746 if (!success) { 1747 throw new IllegalStateException("Failed to update instant app android id"); 1748 } 1749 Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, 1750 owningUserId, name); 1751 return mascaradeSsaidSetting(ssaidSettings, setting); 1752 } 1753 1754 // Lazy initialize ssaid if not yet present in ssaid table. 1755 if (ssaid == null || ssaid.isNull() || ssaid.getValue() == null) { 1756 Setting setting = mSettingsRegistry.generateSsaidLocked(callingPkg, owningUserId); 1757 return mascaradeSsaidSetting(ssaidSettings, setting); 1758 } 1759 1760 return mascaradeSsaidSetting(ssaidSettings, ssaid); 1761 } 1762 mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting)1763 private Setting mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting) { 1764 // SSAID settings are located in a dedicated table for internal bookkeeping 1765 // but for the world they reside in the secure table, so adjust the key here. 1766 // We have a special name when looking it up but want the world to see it as 1767 // "android_id". 1768 if (ssaidSetting != null) { 1769 return settingsState.new Setting(ssaidSetting) { 1770 @Override 1771 public int getKey() { 1772 final int userId = getUserIdFromKey(super.getKey()); 1773 return makeKey(SETTINGS_TYPE_SECURE, userId); 1774 } 1775 1776 @Override 1777 public String getName() { 1778 return Settings.Secure.ANDROID_ID; 1779 } 1780 }; 1781 } 1782 return null; 1783 } 1784 1785 private boolean insertSecureSetting(String name, String value, String tag, 1786 boolean makeDefault, int requestingUserId, boolean forceNotify, 1787 boolean overrideableByRestore) { 1788 if (DEBUG) { 1789 Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", " 1790 + ", " + tag + ", " + makeDefault + ", " + requestingUserId 1791 + ", " + forceNotify + ", " + overrideableByRestore + ")"); 1792 } 1793 return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId, 1794 MUTATION_OPERATION_INSERT, forceNotify, 0, overrideableByRestore); 1795 } 1796 1797 private boolean deleteSecureSetting(String name, int requestingUserId, boolean forceNotify) { 1798 if (DEBUG) { 1799 Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId 1800 + ", " + forceNotify + ")"); 1801 } 1802 1803 return mutateSecureSetting(name, null, null, false, requestingUserId, 1804 MUTATION_OPERATION_DELETE, forceNotify, 0); 1805 } 1806 1807 private boolean updateSecureSetting(String name, String value, String tag, 1808 boolean makeDefault, int requestingUserId, boolean forceNotify) { 1809 if (DEBUG) { 1810 Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", " 1811 + ", " + tag + ", " + makeDefault + ", " + requestingUserId 1812 + ", " + forceNotify +")"); 1813 } 1814 1815 return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId, 1816 MUTATION_OPERATION_UPDATE, forceNotify, 0); 1817 } 1818 1819 private void resetSecureSetting(int requestingUserId, int mode, String tag) { 1820 if (DEBUG) { 1821 Slog.v(LOG_TAG, "resetSecureSetting(" + requestingUserId + ", " 1822 + mode + ", " + tag + ")"); 1823 } 1824 1825 mutateSecureSetting(null, null, tag, false, requestingUserId, 1826 MUTATION_OPERATION_RESET, false, mode); 1827 } 1828 1829 private boolean mutateSecureSetting(String name, String value, String tag, 1830 boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, 1831 int mode) { 1832 // overrideableByRestore = false as by default settings values shouldn't be overrideable by 1833 // restore. 1834 return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId, operation, 1835 forceNotify, mode, /* overrideableByRestore */ false); 1836 } 1837 1838 private boolean mutateSecureSetting(String name, String value, String tag, 1839 boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, 1840 int mode, boolean overrideableByRestore) { 1841 // Make sure the caller can change the settings. 1842 enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS); 1843 1844 // Resolve the userId on whose behalf the call is made. 1845 final int callingUserId = resolveCallingUserIdEnforcingPermissions(requestingUserId); 1846 1847 // If this is a setting that is currently restricted for this user, do not allow 1848 // unrestricting changes. 1849 if (isSettingRestrictedForUser(name, callingUserId, value, Binder.getCallingUid())) { 1850 return false; 1851 } 1852 1853 // Determine the owning user as some profile settings are cloned from the parent. 1854 final int owningUserId = resolveOwningUserIdForSecureSetting(callingUserId, name); 1855 1856 // Only the owning user can change the setting. 1857 if (owningUserId != callingUserId) { 1858 return false; 1859 } 1860 1861 final String callingPackage = getCallingPackage(); 1862 1863 // Mutate the value. 1864 synchronized (mLock) { 1865 switch (operation) { 1866 case MUTATION_OPERATION_INSERT -> { 1867 return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE, 1868 owningUserId, name, value, tag, makeDefault, 1869 callingPackage, forceNotify, CRITICAL_SECURE_SETTINGS, 1870 overrideableByRestore); 1871 } 1872 case MUTATION_OPERATION_DELETE -> { 1873 return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SECURE, 1874 owningUserId, name, forceNotify, CRITICAL_SECURE_SETTINGS); 1875 } 1876 case MUTATION_OPERATION_UPDATE -> { 1877 return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SECURE, 1878 owningUserId, name, value, tag, makeDefault, 1879 callingPackage, forceNotify, CRITICAL_SECURE_SETTINGS); 1880 } 1881 case MUTATION_OPERATION_RESET -> { 1882 return mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_SECURE, 1883 owningUserId, callingPackage, mode, tag); 1884 } 1885 } 1886 } 1887 1888 return false; 1889 } 1890 1891 private Cursor getAllSystemSettings(int userId, String[] projection) { 1892 if (DEBUG) { 1893 Slog.v(LOG_TAG, "getAllSecureSystem(" + userId + ")"); 1894 } 1895 1896 // Resolve the userId on whose behalf the call is made. 1897 final int callingUserId = resolveCallingUserIdEnforcingPermissions(userId); 1898 1899 synchronized (mLock) { 1900 List<String> names = getSettingsNamesLocked(SETTINGS_TYPE_SYSTEM, callingUserId); 1901 1902 final int nameCount = names.size(); 1903 1904 String[] normalizedProjection = normalizeProjection(projection); 1905 MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); 1906 1907 for (int i = 0; i < nameCount; i++) { 1908 String name = names.get(i); 1909 try { 1910 enforceSettingReadable(name, SETTINGS_TYPE_SYSTEM, callingUserId); 1911 } catch (SecurityException e) { 1912 // Caller doesn't have permission to read this setting 1913 continue; 1914 } 1915 // Determine the owning user as some profile settings are cloned from the parent. 1916 final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, 1917 name); 1918 1919 Setting setting = mSettingsRegistry.getSettingLocked( 1920 SETTINGS_TYPE_SYSTEM, owningUserId, name); 1921 appendSettingToCursor(result, setting); 1922 } 1923 1924 return result; 1925 } 1926 } 1927 1928 private Setting getSystemSetting(String name, int requestingUserId) { 1929 if (DEBUG) { 1930 Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")"); 1931 } 1932 1933 // Resolve the userId on whose behalf the call is made. 1934 final int callingUserId = resolveCallingUserIdEnforcingPermissions(requestingUserId); 1935 1936 // Ensure the caller can access the setting. 1937 enforceSettingReadable(name, SETTINGS_TYPE_SYSTEM, UserHandle.getCallingUserId()); 1938 1939 // Determine the owning user as some profile settings are cloned from the parent. 1940 final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name); 1941 1942 // Get the value. 1943 synchronized (mLock) { 1944 return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SYSTEM, owningUserId, name); 1945 } 1946 } 1947 1948 private boolean insertSystemSetting(String name, String value, int requestingUserId, 1949 boolean overrideableByRestore) { 1950 if (DEBUG) { 1951 Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", " 1952 + requestingUserId + ", " + overrideableByRestore + ")"); 1953 } 1954 1955 return mutateSystemSetting(name, value, /* tag= */ null, requestingUserId, 1956 MUTATION_OPERATION_INSERT, /* mode= */ 0, overrideableByRestore); 1957 } 1958 1959 private boolean deleteSystemSetting(String name, int requestingUserId) { 1960 if (DEBUG) { 1961 Slog.v(LOG_TAG, "deleteSystemSetting(" + name + ", " + requestingUserId + ")"); 1962 } 1963 1964 return mutateSystemSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE); 1965 } 1966 1967 private boolean updateSystemSetting(String name, String value, int requestingUserId) { 1968 if (DEBUG) { 1969 Slog.v(LOG_TAG, "updateSystemSetting(" + name + ", " + value + ", " 1970 + requestingUserId + ")"); 1971 } 1972 1973 return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); 1974 } 1975 1976 private void resetSystemSetting(int requestingUserId, int mode, String tag) { 1977 if (DEBUG) { 1978 Slog.v(LOG_TAG, "resetSystemSetting(" + requestingUserId + ", " 1979 + mode + ", " + tag + ")"); 1980 } 1981 1982 mutateSystemSetting(null, null, tag, requestingUserId, MUTATION_OPERATION_RESET, mode, 1983 false); 1984 } 1985 1986 private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation) { 1987 // overrideableByRestore = false as by default settings values shouldn't be overrideable by 1988 // restore. 1989 return mutateSystemSetting(name, value, /* tag= */ null, runAsUserId, operation, 1990 /* mode= */ 0, /* overrideableByRestore */ false); 1991 } 1992 1993 private boolean mutateSystemSetting(String name, String value, String tag, int runAsUserId, 1994 int operation, int mode, boolean overrideableByRestore) { 1995 final String callingPackage = getCallingPackage(); 1996 if (!hasWriteSecureSettingsPermission()) { 1997 // If the caller doesn't hold WRITE_SECURE_SETTINGS, we verify whether this 1998 // operation is allowed for the calling package through appops. 1999 if (!Settings.checkAndNoteWriteSettingsOperation(getContext(), 2000 Binder.getCallingUid(), callingPackage, getCallingAttributionTag(), 2001 true)) { 2002 Slog.e(LOG_TAG, "Calling package: " + callingPackage + " is not allowed to " 2003 + "write system settings: " + name); 2004 return false; 2005 } 2006 } 2007 2008 // Resolve the userId on whose behalf the call is made. 2009 final int callingUserId = resolveCallingUserIdEnforcingPermissions(runAsUserId); 2010 2011 if (isSettingRestrictedForUser(name, callingUserId, value, Binder.getCallingUid())) { 2012 Slog.e(LOG_TAG, "UserId: " + callingUserId + " is disallowed to change system " 2013 + "setting: " + name); 2014 return false; 2015 } 2016 2017 // Enforce what the calling package can mutate the system settings. 2018 enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name, callingUserId); 2019 2020 // Determine the owning user as some profile settings are cloned from the parent. 2021 final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name); 2022 2023 // Only the owning user id can change the setting. 2024 if (owningUserId != callingUserId) { 2025 Slog.e(LOG_TAG, "UserId: " + callingUserId + " is not the owning userId: " 2026 + owningUserId); 2027 return false; 2028 } 2029 2030 File cacheFile = getCacheFile(name, callingUserId); 2031 if (cacheFile != null) { 2032 if (!isValidMediaUri(name, value)) { 2033 return false; 2034 } 2035 } 2036 2037 final boolean success; 2038 // Mutate the value. 2039 synchronized (mLock) { 2040 switch (operation) { 2041 case MUTATION_OPERATION_INSERT -> { 2042 validateSystemSettingValue(name, value); 2043 success = mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SYSTEM, 2044 owningUserId, name, value, null, false, callingPackage, 2045 false, null, overrideableByRestore); 2046 } 2047 case MUTATION_OPERATION_DELETE -> { 2048 success = mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_SYSTEM, 2049 owningUserId, name, false, null); 2050 } 2051 case MUTATION_OPERATION_UPDATE -> { 2052 validateSystemSettingValue(name, value); 2053 success = mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SYSTEM, 2054 owningUserId, name, value, null, false, callingPackage, 2055 false, null); 2056 } 2057 case MUTATION_OPERATION_RESET -> { 2058 success = mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_SYSTEM, 2059 runAsUserId, callingPackage, mode, tag); 2060 } 2061 default -> { 2062 success = false; 2063 Slog.e(LOG_TAG, "Unknown operation code: " + operation); 2064 } 2065 } 2066 } 2067 2068 if (!success) { 2069 return false; 2070 } 2071 2072 if (cacheFile != null) { 2073 // Invalidate any relevant cache files 2074 cacheFile.delete(); 2075 } 2076 2077 if ((operation == MUTATION_OPERATION_INSERT || operation == MUTATION_OPERATION_UPDATE) 2078 && cacheFile != null && value != null) { 2079 final Uri ringtoneUri = Uri.parse(value); 2080 // Stream selected ringtone into cache, so it's available for playback 2081 // when CE storage is still locked 2082 Binder.withCleanCallingIdentity(() -> { 2083 try (InputStream in = openRingtone(getContext(), ringtoneUri); 2084 OutputStream out = new FileOutputStream(cacheFile)) { 2085 FileUtils.copy(in, out); 2086 } catch (IOException e) { 2087 Slog.w(LOG_TAG, "Failed to cache ringtone: " + e); 2088 } 2089 }); 2090 } 2091 return true; 2092 } 2093 2094 private boolean isValidMediaUri(String name, String uri) { 2095 if (uri != null) { 2096 Uri audioUri = Uri.parse(uri); 2097 if (Settings.AUTHORITY.equals( 2098 ContentProvider.getAuthorityWithoutUserId(audioUri.getAuthority()))) { 2099 // Don't accept setting the default uri to self-referential URIs like 2100 // Settings.System.DEFAULT_RINGTONE_URI, which is an alias to the value of this 2101 // setting. 2102 return false; 2103 } 2104 2105 // If the audioUri comes from FileProvider, the security check will fail. Currently, it 2106 // should not have too many FileProvider Uri usage, using a workaround fix here. 2107 // Only allow for caller is privileged apps 2108 ApplicationInfo aInfo = null; 2109 try { 2110 aInfo = getCallingApplicationInfoOrThrow(); 2111 } catch (IllegalStateException ignored) { 2112 Slog.w(LOG_TAG, "isValidMediaUri: cannot get calling app info for setting: " 2113 + name + " URI: " + audioUri); 2114 return false; 2115 } 2116 final boolean isPrivilegedApp = aInfo != null ? aInfo.isPrivilegedApp() : false; 2117 String mimeType = null; 2118 if (isPrivilegedApp) { 2119 final long identity = Binder.clearCallingIdentity(); 2120 try { 2121 mimeType = getContext().getContentResolver().getType(audioUri); 2122 } finally { 2123 Binder.restoreCallingIdentity(identity); 2124 } 2125 } else { 2126 mimeType = getContext().getContentResolver().getType(audioUri); 2127 } 2128 if (DEBUG) { 2129 Slog.v(LOG_TAG, "isValidMediaUri mimeType: " + mimeType); 2130 } 2131 if (mimeType == null) { 2132 Slog.e(LOG_TAG, 2133 "mutateSystemSetting for setting: " + name + " URI: " + audioUri 2134 + " ignored: failure to find mimeType (no access from this context?)"); 2135 return false; 2136 } 2137 if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg") 2138 || mimeType.equals("application/x-flac") 2139 // also check for video ringtones 2140 || mimeType.startsWith("video/") || mimeType.equals("application/mp4"))) { 2141 Slog.e(LOG_TAG, 2142 "mutateSystemSetting for setting: " + name + " URI: " + audioUri 2143 + " ignored: associated MIME type:" + mimeType 2144 + " is not a recognized audio or video type"); 2145 return false; 2146 } 2147 } 2148 return true; 2149 } 2150 2151 private boolean hasWriteSecureSettingsPermission() { 2152 // Write secure settings is a more protected permission. If caller has it we are good. 2153 return getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) 2154 == PackageManager.PERMISSION_GRANTED; 2155 } 2156 2157 private void validateSystemSettingValue(String name, String value) { 2158 Validator validator = SystemSettingsValidators.VALIDATORS.get(name); 2159 if (validator != null && !validator.validate(value)) { 2160 throw new IllegalArgumentException("Invalid value: " + value 2161 + " for setting: " + name); 2162 } 2163 } 2164 2165 /** 2166 * Returns {@code true} if the specified secure setting should be accessible to the caller. 2167 */ 2168 private boolean isSecureSettingAccessible(String name) { 2169 return switch (name) { 2170 case "bluetooth_address" -> 2171 // BluetoothManagerService for some reason stores the Android's Bluetooth MAC 2172 // address in this secure setting. Secure settings can normally be read by any app, 2173 // which thus enables them to bypass the recently introduced restrictions on access 2174 // to device identifiers. 2175 // To mitigate this we make this setting available only to callers privileged to see 2176 // this device's MAC addresses, same as through public API 2177 // BluetoothAdapter.getAddress() (see BluetoothManagerService for details). 2178 getContext().checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS) 2179 == PackageManager.PERMISSION_GRANTED; 2180 default -> true; 2181 }; 2182 } 2183 2184 private int resolveOwningUserIdForSecureSetting(int userId, String setting) { 2185 // no need to lock because sSecureCloneToManagedSettings is never modified 2186 return resolveOwningUserId(userId, sSecureCloneToManagedSettings, setting); 2187 } 2188 2189 @GuardedBy("mLock") 2190 private int resolveOwningUserIdForSystemSettingLocked(int userId, String setting) { 2191 final int parentId; 2192 // Resolves dependency if setting has a dependency and the calling user has a parent 2193 if (sSystemCloneFromParentOnDependency.containsKey(setting) 2194 && (parentId = getGroupParent(userId)) != userId) { 2195 // The setting has a dependency and the profile has a parent 2196 String dependency = sSystemCloneFromParentOnDependency.get(setting); 2197 // Lookup the dependency setting as ourselves, some callers may not have access to it. 2198 final long token = Binder.clearCallingIdentity(); 2199 try { 2200 Setting settingObj = getSecureSetting(dependency, userId); 2201 if (settingObj != null && settingObj.getValue().equals("1")) { 2202 return parentId; 2203 } 2204 } finally { 2205 Binder.restoreCallingIdentity(token); 2206 } 2207 } 2208 return resolveOwningUserId(userId, sSystemCloneToManagedSettings, setting); 2209 } 2210 2211 private int resolveOwningUserId(int userId, Set<String> keys, String name) { 2212 final int parentId = getGroupParent(userId); 2213 if (parentId != userId && keys.contains(name)) { 2214 return parentId; 2215 } 2216 return userId; 2217 } 2218 2219 private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation, 2220 String name, int userId) { 2221 // System/root/shell can mutate whatever secure settings they want. 2222 final int callingUid = Binder.getCallingUid(); 2223 final int appId = UserHandle.getAppId(callingUid); 2224 if (appId == android.os.Process.SYSTEM_UID 2225 || appId == Process.SHELL_UID 2226 || appId == Process.ROOT_UID) { 2227 return; 2228 } 2229 2230 switch (operation) { 2231 // Insert updates. 2232 case MUTATION_OPERATION_INSERT, MUTATION_OPERATION_UPDATE -> { 2233 if (Settings.System.PUBLIC_SETTINGS.contains(name)) { 2234 return; 2235 } 2236 2237 // The calling package is already verified. 2238 PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId); 2239 2240 // Privileged apps can do whatever they want. 2241 if ((packageInfo.applicationInfo.privateFlags 2242 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 2243 return; 2244 } 2245 2246 warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk( 2247 packageInfo.applicationInfo.targetSdkVersion, name); 2248 } 2249 case MUTATION_OPERATION_DELETE -> { 2250 if (Settings.System.PUBLIC_SETTINGS.contains(name) 2251 || Settings.System.PRIVATE_SETTINGS.contains(name)) { 2252 throw new IllegalArgumentException("You cannot delete system defined" 2253 + " secure settings."); 2254 } 2255 2256 // The calling package is already verified. 2257 PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId); 2258 2259 // Privileged apps can do whatever they want. 2260 if ((packageInfo.applicationInfo.privateFlags & 2261 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 2262 return; 2263 } 2264 2265 warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk( 2266 packageInfo.applicationInfo.targetSdkVersion, name); 2267 } 2268 } 2269 } 2270 2271 private static Set<String> getInstantAppAccessibleSettings(int settingsType) { 2272 return switch (settingsType) { 2273 case SETTINGS_TYPE_GLOBAL -> Global.INSTANT_APP_SETTINGS; 2274 case SETTINGS_TYPE_SECURE -> Secure.INSTANT_APP_SETTINGS; 2275 case SETTINGS_TYPE_SYSTEM -> Settings.System.INSTANT_APP_SETTINGS; 2276 default -> throw new IllegalArgumentException("Invalid settings type: " + settingsType); 2277 }; 2278 } 2279 2280 private static Set<String> getOverlayInstantAppAccessibleSettings(int settingsType) { 2281 return switch (settingsType) { 2282 case SETTINGS_TYPE_GLOBAL -> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS; 2283 case SETTINGS_TYPE_SYSTEM -> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS; 2284 case SETTINGS_TYPE_SECURE -> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS; 2285 default -> throw new IllegalArgumentException("Invalid settings type: " + settingsType); 2286 }; 2287 } 2288 2289 @GuardedBy("mLock") 2290 private List<String> getSettingsNamesLocked(int settingsType, int userId) { 2291 // Don't enforce the instant app allowlist for now -- its too prone to unintended breakage 2292 // in the current form. 2293 return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId); 2294 } 2295 2296 private void enforceSettingReadable(String settingName, int settingsType, int userId) { 2297 if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) { 2298 return; 2299 } 2300 ApplicationInfo ai = getCallingApplicationInfoOrThrow(); 2301 if (ai.isSystemApp() || ai.isSignedWithPlatformKey()) { 2302 return; 2303 } 2304 if ((ai.flags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { 2305 // Skip checking readable annotations for test_only apps 2306 checkReadableAnnotation(settingsType, settingName, ai.targetSdkVersion); 2307 } 2308 /** 2309 * some settings need additional permission check, this is to have a matching security 2310 * control from other API alternatives returning the same settings values. 2311 * note, the permission enforcement should be based on app's targetSDKlevel to better handle 2312 * app-compat. 2313 */ 2314 switch (settingName) { 2315 // missing READ_PRIVILEGED_PHONE_STATE permission protection 2316 // see alternative API {@link SubscriptionManager#getPreferredDataSubscriptionId() 2317 case Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION -> { 2318 // app-compat handling, not break apps targeting on previous SDKs. 2319 if (CompatChanges.isChangeEnabled( 2320 ENFORCE_READ_PERMISSION_FOR_MULTI_SIM_DATA_CALL)) { 2321 getContext().enforceCallingOrSelfPermission( 2322 Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 2323 "access global settings MULTI_SIM_DATA_CALL_SUBSCRIPTION"); 2324 } 2325 } 2326 } 2327 if (!ai.isInstantApp()) { 2328 return; 2329 } 2330 if (!getInstantAppAccessibleSettings(settingsType).contains(settingName) 2331 && !getOverlayInstantAppAccessibleSettings(settingsType).contains(settingName)) { 2332 // Don't enforce the instant app allowlist for now -- its too prone to unintended 2333 // breakage in the current form. 2334 Slog.w(LOG_TAG, "Instant App " + ai.packageName 2335 + " trying to access unexposed setting, this will be an error in the future."); 2336 } 2337 } 2338 2339 /** 2340 * Check if the target settings key is readable. Reject if the caller app is trying to access a 2341 * settings key defined in the Settings.Secure, Settings.System or Settings.Global and is not 2342 * annotated as @Readable. Reject if the caller app is targeting an SDK level that is higher 2343 * than the maxTargetSdk specified in the @Readable annotation. 2344 * Notice that a key string that is not defined in any of the Settings.* classes will still be 2345 * regarded as readable. 2346 */ 2347 private void checkReadableAnnotation(int settingsType, String settingName, 2348 int targetSdkVersion) { 2349 final Set<String> allFields; 2350 final Set<String> readableFields; 2351 final ArrayMap<String, Integer> readableFieldsWithMaxTargetSdk; 2352 switch (settingsType) { 2353 case SETTINGS_TYPE_GLOBAL -> { 2354 allFields = sAllGlobalSettings; 2355 readableFields = sReadableGlobalSettings; 2356 readableFieldsWithMaxTargetSdk = sReadableGlobalSettingsWithMaxTargetSdk; 2357 } 2358 case SETTINGS_TYPE_SYSTEM -> { 2359 allFields = sAllSystemSettings; 2360 readableFields = sReadableSystemSettings; 2361 readableFieldsWithMaxTargetSdk = sReadableSystemSettingsWithMaxTargetSdk; 2362 } 2363 case SETTINGS_TYPE_SECURE -> { 2364 allFields = sAllSecureSettings; 2365 readableFields = sReadableSecureSettings; 2366 readableFieldsWithMaxTargetSdk = sReadableSecureSettingsWithMaxTargetSdk; 2367 } 2368 default -> throw new IllegalArgumentException("Invalid settings type: " + settingsType); 2369 } 2370 2371 if (allFields.contains(settingName)) { 2372 if (!readableFields.contains(settingName)) { 2373 throw new SecurityException( 2374 "Settings key: <" + settingName + "> is not readable. From S+, settings " 2375 + "keys annotated with @hide are restricted to system_server and " 2376 + "system apps only, unless they are annotated with @Readable." 2377 ); 2378 } else { 2379 if (readableFieldsWithMaxTargetSdk.containsKey(settingName)) { 2380 final int maxTargetSdk = readableFieldsWithMaxTargetSdk.get(settingName); 2381 if (targetSdkVersion > maxTargetSdk) { 2382 throw new SecurityException( 2383 "Settings key: <" + settingName + "> is only readable to apps with " 2384 + "targetSdkVersion lower than or equal to: " 2385 + maxTargetSdk 2386 ); 2387 } 2388 } 2389 } 2390 } 2391 } 2392 2393 private ApplicationInfo getCallingApplicationInfoOrThrow() { 2394 // We always use the callingUid for this lookup. This means that if hypothetically an 2395 // app was installed in user A with cross user and in user B as an Instant App 2396 // the app in A would be able to see all the settings in user B. However since cross 2397 // user is a system permission and the app must be uninstalled in B and then installed as 2398 // an Instant App that situation is not realistic or supported. 2399 ApplicationInfo ai = null; 2400 final String callingPackage = getCallingPackage(); 2401 try { 2402 ai = mPackageManager.getApplicationInfo(callingPackage, 0 2403 , UserHandle.getCallingUserId()); 2404 } catch (RemoteException ignored) { 2405 } 2406 if (ai == null) { 2407 throw new IllegalStateException("Failed to lookup info for package " 2408 + callingPackage); 2409 } 2410 return ai; 2411 } 2412 2413 private PackageInfo getCallingPackageInfoOrThrow(int userId) { 2414 try { 2415 PackageInfo packageInfo = mPackageManager.getPackageInfo( 2416 getCallingPackage(), 0, userId); 2417 if (packageInfo != null) { 2418 return packageInfo; 2419 } 2420 } catch (RemoteException e) { 2421 /* ignore */ 2422 } 2423 throw new IllegalStateException("Calling package doesn't exist"); 2424 } 2425 2426 private int getGroupParent(int userId) { 2427 // Most frequent use case. 2428 if (userId == UserHandle.USER_SYSTEM) { 2429 return userId; 2430 } 2431 // We are in the same process with the user manager and the returned 2432 // user info is a cached instance, so just look up instead of cache. 2433 final long identity = Binder.clearCallingIdentity(); 2434 try { 2435 // Just a lookup and not reentrant, so holding a lock is fine. 2436 UserInfo userInfo = mUserManager.getProfileParent(userId); 2437 return (userInfo != null) ? userInfo.id : userId; 2438 } finally { 2439 Binder.restoreCallingIdentity(identity); 2440 } 2441 } 2442 2443 private void enforceHasAtLeastOnePermission(String ...permissions) { 2444 for (String permission : permissions) { 2445 if (getContext().checkCallingOrSelfPermission(permission) 2446 == PackageManager.PERMISSION_GRANTED) { 2447 return; 2448 } 2449 } 2450 throw new SecurityException("Permission denial, must have one of: " 2451 + Arrays.toString(permissions)); 2452 } 2453 2454 /** 2455 * Throws an exception if write permissions are not granted for {@code flags}. 2456 * <p> 2457 * Write permissions are granted if the calling UID is root, or the 2458 * WRITE_DEVICE_CONFIG permission is granted, or the WRITE_DEVICE_CONFIG_ALLOWLIST 2459 * permission is granted and each flag in {@code flags} is allowlisted in {@code 2460 * WRITABLE_FLAG_ALLOWLIST_FLAG}. 2461 * 2462 * @param context the {@link Context} this is called in 2463 * @param flags a list of flags to check, each one of the form 'namespace/flagName' 2464 * 2465 * @throws SecurityException if the above criteria are not met. 2466 * @hide 2467 */ 2468 private void enforceDeviceConfigWritePermission( 2469 @NonNull Context context, 2470 @NonNull Set<String> flags) { 2471 boolean hasAllowlistPermission = 2472 context.checkCallingOrSelfPermission( 2473 Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG) 2474 == PackageManager.PERMISSION_GRANTED; 2475 boolean hasWritePermission = 2476 context.checkCallingOrSelfPermission( 2477 Manifest.permission.WRITE_DEVICE_CONFIG) 2478 == PackageManager.PERMISSION_GRANTED; 2479 // Only the shell user and tests request the allowlist permission; this is used to force 2480 // the WRITE_ALLOWLISTED_DEVICE_CONFIG path to log any flags that need to be allowlisted. 2481 boolean isRestrictedShell = android.security.Flags.protectDeviceConfigFlags() 2482 && hasAllowlistPermission; 2483 2484 if (hasWritePermission) { 2485 assertCallingUserDenyList(flags); 2486 } else if (hasAllowlistPermission) { 2487 Set<String> allowlistedDeviceConfigNamespaces = null; 2488 if (isRestrictedShell) { 2489 allowlistedDeviceConfigNamespaces = getAllowlistedDeviceConfigNamespaces(); 2490 } 2491 for (String flag : flags) { 2492 boolean namespaceAllowed = false; 2493 if (isRestrictedShell) { 2494 String flagNamespace = getFlagNamespace(flag); 2495 // If the namespace indicates this is a flag override, then the actual 2496 // namespace and flag name should be used for the allowlist verification. 2497 if (DEVICE_CONFIG_OVERRIDES_NAMESPACE.equals(flagNamespace)) { 2498 // Override flags are in the following form: 2499 // device_config_overrides/namespace:flagName 2500 int slashIndex = flag.indexOf("/"); 2501 int colonIndex = flag.indexOf(":", slashIndex); 2502 if (slashIndex != -1 && colonIndex != -1 && (slashIndex + 1) < flag.length() 2503 && (colonIndex + 1) < flag.length()) { 2504 flagNamespace = flag.substring(slashIndex + 1, colonIndex); 2505 StringBuilder flagBuilder = new StringBuilder(flagNamespace); 2506 flagBuilder.append("/").append(flag.substring(colonIndex + 1)); 2507 flag = flagBuilder.toString(); 2508 } 2509 } 2510 if (allowlistedDeviceConfigNamespaces.contains(flagNamespace)) { 2511 namespaceAllowed = true; 2512 } 2513 } else { 2514 for (String allowlistedPrefix : WritableNamespacePrefixes.ALLOWLIST) { 2515 if (flag.startsWith(allowlistedPrefix)) { 2516 namespaceAllowed = true; 2517 break; 2518 } 2519 } 2520 } 2521 2522 if (!namespaceAllowed && !DeviceConfig.getAdbWritableFlags().contains(flag)) { 2523 throw new SecurityException("Permission denial for flag '" + flag 2524 + "'; allowlist permission granted, but must add flag to the " 2525 + "allowlist"); 2526 } 2527 } 2528 assertCallingUserDenyList(flags); 2529 } else { 2530 throw new SecurityException("Permission denial to mutate flag, must have root, " 2531 + "WRITE_DEVICE_CONFIG, or WRITE_ALLOWLISTED_DEVICE_CONFIG"); 2532 } 2533 } 2534 2535 /** 2536 * Returns the namespace for the provided {@code flag}. 2537 * <p> 2538 * Flags are expected to be in the form namespace/flagName; if the '/' delimiter does 2539 * not exist, then the provided flag is returned as the namespace. 2540 */ 2541 private static String getFlagNamespace(String flag) { 2542 int delimiterIndex = flag.indexOf("/"); 2543 String flagNamespace; 2544 if (delimiterIndex != -1) { 2545 flagNamespace = flag.substring(0, delimiterIndex); 2546 } else { 2547 flagNamespace = flag; 2548 } 2549 return flagNamespace; 2550 } 2551 2552 // The check is added mainly for auto devices. On auto devices, it is possible that 2553 // multiple users are visible simultaneously using visible background users. 2554 // In such cases, it is desired that Non-current user (ex. visible background users) can 2555 // only change settings for certain namespaces. 2556 private void assertCallingUserDenyList(@NonNull Set<String> flags) { 2557 if (!UserManager.isVisibleBackgroundUsersEnabled()) { 2558 // enforce the deny list only on devices supporting visible background user. 2559 return; 2560 } 2561 2562 int callingUser = UserHandle.getCallingUserId(); 2563 final long identity = Binder.clearCallingIdentity(); 2564 try { 2565 int currentUser = ActivityManager.getCurrentUser(); 2566 if (callingUser == currentUser || callingUser == UserHandle.USER_SYSTEM) { 2567 // enforce the deny list only if the caller is not current user or not a system 2568 // user. Currently only auto uses background visible user, and auto doesn't 2569 // support profiles so profiles of current users is not checked here. 2570 return; 2571 } 2572 } finally { 2573 Binder.restoreCallingIdentity(identity); 2574 } 2575 2576 for (String flag : flags) { 2577 for (String denylistedPrefix : 2578 NonWritableNamespacesForBackgroundUserPrefixes.DENYLIST) { 2579 if (flag.startsWith(denylistedPrefix)) { 2580 throw new SecurityException("Permission denial for flag '" + flag 2581 + "' for background user " + callingUser + ". Namespace is added to " 2582 + "denylist."); 2583 } 2584 } 2585 } 2586 } 2587 2588 /** 2589 * Returns a Set of DeviceConfig allowlisted namespaces in which all flags can be modified 2590 * by a caller with the {@code WRITE_ALLOWLISTED_DEVICE_CONFIG} permission. 2591 * <p> 2592 * This method also supports mainline modules that introduce their own allowlisted 2593 * namespaces within the {@code etc/writable_namespaces} file under their directory. 2594 */ 2595 private Set<String> getAllowlistedDeviceConfigNamespaces() { 2596 synchronized (sDeviceConfigAllowlistedNamespaces) { 2597 if (!sDeviceConfigAllowlistedNamespaces.isEmpty()) { 2598 return sDeviceConfigAllowlistedNamespaces; 2599 } 2600 if (android.provider.flags.Flags.deviceConfigWritableNamespacesApi()) { 2601 sDeviceConfigAllowlistedNamespaces.addAll(DeviceConfig.getAdbWritableNamespaces()); 2602 } else { 2603 sDeviceConfigAllowlistedNamespaces.addAll(WritableNamespaces.ALLOWLIST); 2604 } 2605 final long identity = Binder.clearCallingIdentity(); 2606 try { 2607 List<String> apexDirectories; 2608 try { 2609 apexDirectories = mPackageManager.getAllApexDirectories(); 2610 } catch (RemoteException e) { 2611 Slog.e(LOG_TAG, "Caught a RemoteException obtaining APEX directories: ", e); 2612 return sDeviceConfigAllowlistedNamespaces; 2613 } 2614 for (int i = 0; i < apexDirectories.size(); i++) { 2615 String apexDirectory = apexDirectories.get(i); 2616 File namespaceFile = Environment.buildPath(new File(apexDirectory), "etc", 2617 "writable_namespaces"); 2618 if (namespaceFile.exists() && namespaceFile.isFile()) { 2619 try (BufferedReader reader = new BufferedReader( 2620 new FileReader(namespaceFile))) { 2621 String namespace; 2622 while ((namespace = reader.readLine()) != null) { 2623 namespace = namespace.trim(); 2624 // Support comments by ignoring any lines that start with '#'. 2625 if (!namespace.isEmpty() && !namespace.startsWith("#")) { 2626 sDeviceConfigAllowlistedNamespaces.add(namespace); 2627 } 2628 } 2629 } catch (IOException e) { 2630 Slog.e(LOG_TAG, "Caught an exception parsing file: " + namespaceFile, 2631 e); 2632 } 2633 } 2634 } 2635 } finally { 2636 Binder.restoreCallingIdentity(identity); 2637 } 2638 return sDeviceConfigAllowlistedNamespaces; 2639 } 2640 } 2641 2642 private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk( 2643 int targetSdkVersion, String name) { 2644 // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash. 2645 if (targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) { 2646 if (Settings.System.PRIVATE_SETTINGS.contains(name)) { 2647 Slog.w(LOG_TAG, "You shouldn't not change private system settings." 2648 + " This will soon become an error."); 2649 } else { 2650 Slog.w(LOG_TAG, "You shouldn't keep your settings in the secure settings." 2651 + " This will soon become an error."); 2652 } 2653 } else { 2654 if (Settings.System.PRIVATE_SETTINGS.contains(name)) { 2655 throw new IllegalArgumentException("You cannot change private secure settings."); 2656 } else { 2657 throw new IllegalArgumentException("You cannot keep your settings in" 2658 + " the secure settings."); 2659 } 2660 } 2661 } 2662 2663 private static int resolveCallingUserIdEnforcingPermissions(int requestingUserId) { 2664 if (requestingUserId == UserHandle.getCallingUserId()) { 2665 return requestingUserId; 2666 } 2667 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), 2668 Binder.getCallingUid(), requestingUserId, false, true, 2669 "get/set setting for user", null); 2670 } 2671 2672 private Bundle packageValueForCallResult(int type, @NonNull String name, int userId, 2673 @Nullable Setting setting, boolean trackingGeneration) { 2674 if (!trackingGeneration) { 2675 if (setting == null || setting.isNull()) { 2676 return NULL_SETTING_BUNDLE; 2677 } 2678 return Bundle.forPair(Settings.NameValueTable.VALUE, setting.getValue()); 2679 } 2680 Bundle result = new Bundle(); 2681 result.putString(Settings.NameValueTable.VALUE, 2682 (setting != null && !setting.isNull()) ? setting.getValue() : null); 2683 2684 synchronized (mLock) { 2685 if ((setting != null && !setting.isNull()) || isSettingPreDefined(name, type)) { 2686 // Individual generation tracking for predefined settings even if they are unset 2687 mSettingsRegistry.mGenerationRegistry.addGenerationData(result, 2688 SettingsState.makeKey(type, userId), name); 2689 } else { 2690 // All non-predefined, unset settings are tracked using the same generation number 2691 mSettingsRegistry.mGenerationRegistry.addGenerationDataForUnsetSettings(result, 2692 SettingsState.makeKey(type, userId)); 2693 } 2694 } 2695 return result; 2696 } 2697 2698 private boolean isSettingPreDefined(String name, int type) { 2699 if (type == SETTINGS_TYPE_GLOBAL) { 2700 return sAllGlobalSettings.contains(name); 2701 } else if (type == SETTINGS_TYPE_SECURE) { 2702 return sAllSecureSettings.contains(name); 2703 } else if (type == SETTINGS_TYPE_SYSTEM) { 2704 return sAllSystemSettings.contains(name); 2705 } else { 2706 // Consider all config settings predefined because they are used by system apps only 2707 return type == SETTINGS_TYPE_CONFIG; 2708 } 2709 } 2710 2711 private Bundle packageValuesForCallResult(String prefix, 2712 @NonNull HashMap<String, String> keyValues, boolean trackingGeneration) { 2713 Bundle result = new Bundle(); 2714 result.putSerializable(Settings.NameValueTable.VALUE, keyValues); 2715 if (trackingGeneration) { 2716 synchronized (mLock) { 2717 // Track generation even if namespace is empty because this is for system apps only 2718 mSettingsRegistry.mGenerationRegistry.addGenerationData(result, 2719 SettingsState.makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM), 2720 prefix); 2721 } 2722 } 2723 return result; 2724 } 2725 2726 private Bundle packageNamespacesForCallResult(@NonNull HashSet<String> namespaces) { 2727 Bundle result = new Bundle(); 2728 result.putSerializable(Settings.NameValueTable.VALUE, namespaces); 2729 return result; 2730 } 2731 2732 private void setMonitorCallback(RemoteCallback callback) { 2733 if (callback == null) { 2734 return; 2735 } 2736 getContext().enforceCallingOrSelfPermission( 2737 Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS, 2738 "Permission denial: registering for config access requires: " 2739 + Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS); 2740 synchronized (mLock) { 2741 mConfigMonitorCallback = callback; 2742 } 2743 } 2744 2745 private void clearMonitorCallback() { 2746 getContext().enforceCallingOrSelfPermission( 2747 Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS, 2748 "Permission denial: registering for config access requires: " 2749 + Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS); 2750 synchronized (mLock) { 2751 mConfigMonitorCallback = null; 2752 } 2753 } 2754 2755 private void reportDeviceConfigAccess(@Nullable String prefix) { 2756 if (prefix == null) { 2757 return; 2758 } 2759 String callingPackage = resolveCallingPackage(); 2760 String namespace = prefix.replace("/", ""); 2761 if (DeviceConfig.getPublicNamespaces().contains(namespace)) { 2762 return; 2763 } 2764 synchronized (mLock) { 2765 if (mConfigMonitorCallback != null) { 2766 Bundle callbackResult = new Bundle(); 2767 callbackResult.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE, 2768 Settings.EXTRA_ACCESS_CALLBACK); 2769 callbackResult.putString(Settings.EXTRA_CALLING_PACKAGE, callingPackage); 2770 callbackResult.putString(Settings.EXTRA_NAMESPACE, namespace); 2771 mConfigMonitorCallback.sendResult(callbackResult); 2772 } 2773 } 2774 } 2775 2776 private void reportDeviceConfigUpdate(@Nullable String prefix) { 2777 if (prefix == null) { 2778 return; 2779 } 2780 String namespace = prefix.replace("/", ""); 2781 if (DeviceConfig.getPublicNamespaces().contains(namespace)) { 2782 return; 2783 } 2784 synchronized (mLock) { 2785 if (mConfigMonitorCallback != null) { 2786 Bundle callbackResult = new Bundle(); 2787 callbackResult.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE, 2788 Settings.EXTRA_NAMESPACE_UPDATED_CALLBACK); 2789 callbackResult.putString(Settings.EXTRA_NAMESPACE, namespace); 2790 mConfigMonitorCallback.sendResult(callbackResult); 2791 } 2792 } 2793 } 2794 2795 private static int getRequestingUserId(Bundle args) { 2796 final int callingUserId = UserHandle.getCallingUserId(); 2797 return (args != null) ? args.getInt(Settings.CALL_METHOD_USER_KEY, callingUserId) 2798 : callingUserId; 2799 } 2800 2801 private boolean isTrackingGeneration(Bundle args) { 2802 return args != null && args.containsKey(Settings.CALL_METHOD_TRACK_GENERATION_KEY); 2803 } 2804 2805 private static String getSettingValue(Bundle args) { 2806 return (args != null) ? args.getString(Settings.NameValueTable.VALUE) : null; 2807 } 2808 2809 private static String getSettingTag(Bundle args) { 2810 return (args != null) ? args.getString(Settings.CALL_METHOD_TAG_KEY) : null; 2811 } 2812 2813 private static String getSettingPrefix(Bundle args) { 2814 return (args != null) ? args.getString(Settings.CALL_METHOD_PREFIX_KEY) : null; 2815 } 2816 2817 private static Map<String, String> getSettingFlags(Bundle args) { 2818 return (args != null) ? (HashMap) args.getSerializable(Settings.CALL_METHOD_FLAGS_KEY) 2819 : Collections.emptyMap(); 2820 } 2821 2822 private static boolean getSettingMakeDefault(Bundle args) { 2823 return (args != null) && args.getBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY); 2824 } 2825 2826 private static boolean getSettingOverrideableByRestore(Bundle args) { 2827 return (args != null) && args.getBoolean(Settings.CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY); 2828 } 2829 2830 private static int getSyncDisabledMode(Bundle args) { 2831 final int mode = (args != null) 2832 ? args.getInt(Settings.CALL_METHOD_SYNC_DISABLED_MODE_KEY) : -1; 2833 if (mode == SYNC_DISABLED_MODE_NONE || mode == SYNC_DISABLED_MODE_UNTIL_REBOOT 2834 || mode == SYNC_DISABLED_MODE_PERSISTENT) { 2835 return mode; 2836 } 2837 throw new IllegalArgumentException("Invalid sync disabled mode: " + mode); 2838 } 2839 2840 private static int getResetModeEnforcingPermission(Bundle args) { 2841 final int mode = (args != null) ? args.getInt(Settings.CALL_METHOD_RESET_MODE_KEY) : 0; 2842 switch (mode) { 2843 case Settings.RESET_MODE_UNTRUSTED_DEFAULTS -> { 2844 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) { 2845 throw new SecurityException("Only system, shell/root on a " 2846 + "debuggable build can reset to untrusted defaults"); 2847 } 2848 return mode; 2849 } 2850 case Settings.RESET_MODE_UNTRUSTED_CHANGES -> { 2851 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) { 2852 throw new SecurityException("Only system, shell/root on a " 2853 + "debuggable build can reset untrusted changes"); 2854 } 2855 return mode; 2856 } 2857 case Settings.RESET_MODE_TRUSTED_DEFAULTS -> { 2858 if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) { 2859 throw new SecurityException("Only system, shell/root on a " 2860 + "debuggable build can reset to trusted defaults"); 2861 } 2862 return mode; 2863 } 2864 case Settings.RESET_MODE_PACKAGE_DEFAULTS -> { 2865 return mode; 2866 } 2867 } 2868 throw new IllegalArgumentException("Invalid reset mode: " + mode); 2869 } 2870 2871 private static boolean isCallerSystemOrShellOrRootOnDebuggableBuild() { 2872 final int appId = UserHandle.getAppId(Binder.getCallingUid()); 2873 return appId == SYSTEM_UID || (Build.IS_DEBUGGABLE 2874 && (appId == SHELL_UID || appId == ROOT_UID)); 2875 } 2876 2877 private static String getValidTableOrThrow(Uri uri) { 2878 if (uri.getPathSegments().size() > 0) { 2879 String table = uri.getPathSegments().get(0); 2880 if (DatabaseHelper.isValidTable(table)) { 2881 return table; 2882 } 2883 throw new IllegalArgumentException("Bad root path: " + table); 2884 } 2885 throw new IllegalArgumentException("Invalid URI:" + uri); 2886 } 2887 2888 private static MatrixCursor packageSettingForQuery(Setting setting, String[] projection) { 2889 if (setting.isNull()) { 2890 return new MatrixCursor(projection, 0); 2891 } 2892 MatrixCursor cursor = new MatrixCursor(projection, 1); 2893 appendSettingToCursor(cursor, setting); 2894 return cursor; 2895 } 2896 2897 private static String[] normalizeProjection(String[] projection) { 2898 if (projection == null) { 2899 return ALL_COLUMNS; 2900 } 2901 2902 final int columnCount = projection.length; 2903 for (int i = 0; i < columnCount; i++) { 2904 String column = projection[i]; 2905 if (!ArrayUtils.contains(ALL_COLUMNS, column)) { 2906 throw new IllegalArgumentException("Invalid column: " + column); 2907 } 2908 } 2909 2910 return projection; 2911 } 2912 2913 private static void appendSettingToCursor(MatrixCursor cursor, Setting setting) { 2914 if (setting == null || setting.isNull()) { 2915 return; 2916 } 2917 final int columnCount = cursor.getColumnCount(); 2918 2919 String[] values = new String[columnCount]; 2920 2921 for (int i = 0; i < columnCount; i++) { 2922 String column = cursor.getColumnName(i); 2923 2924 switch (column) { 2925 case Settings.NameValueTable._ID -> { 2926 values[i] = String.valueOf(setting.getId()); 2927 } 2928 case Settings.NameValueTable.NAME -> { 2929 values[i] = setting.getName(); 2930 } 2931 case Settings.NameValueTable.VALUE -> { 2932 values[i] = setting.getValue(); 2933 } 2934 case Settings.NameValueTable.IS_PRESERVED_IN_RESTORE -> { 2935 values[i] = String.valueOf(setting.isValuePreservedInRestore()); 2936 } 2937 } 2938 } 2939 2940 cursor.addRow(values); 2941 } 2942 2943 private static boolean isKeyValid(String key) { 2944 return !(TextUtils.isEmpty(key) || SettingsState.isBinary(key)); 2945 } 2946 2947 private String resolveCallingPackage() { 2948 return switch (Binder.getCallingUid()) { 2949 case Process.ROOT_UID -> "root"; 2950 case Process.SHELL_UID -> "com.android.shell"; 2951 default -> getCallingPackage(); 2952 }; 2953 } 2954 2955 @VisibleForTesting 2956 void injectServices(UserManager userManager, IPackageManager packageManager, 2957 SystemConfigManager sysConfigManager) { 2958 mUserManager = userManager; 2959 mPackageManager = packageManager; 2960 mSysConfigManager = sysConfigManager; 2961 } 2962 2963 private static final class Arguments { 2964 private static final Pattern WHERE_PATTERN_WITH_PARAM_NO_BRACKETS = 2965 Pattern.compile("[\\s]*name[\\s]*=[\\s]*\\?[\\s]*"); 2966 2967 private static final Pattern WHERE_PATTERN_WITH_PARAM_IN_BRACKETS = 2968 Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*\\?[\\s]*\\)[\\s]*"); 2969 2970 private static final Pattern WHERE_PATTERN_NO_PARAM_IN_BRACKETS = 2971 Pattern.compile("[\\s]*\\([\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*\\)[\\s]*"); 2972 2973 private static final Pattern WHERE_PATTERN_NO_PARAM_NO_BRACKETS = 2974 Pattern.compile("[\\s]*name[\\s]*=[\\s]*['\"].*['\"][\\s]*"); 2975 2976 public final String table; 2977 public final String name; 2978 2979 public Arguments(Uri uri, String where, String[] whereArgs, boolean supportAll) { 2980 final int segmentSize = uri.getPathSegments().size(); 2981 switch (segmentSize) { 2982 case 1 -> { 2983 if (where != null 2984 && (WHERE_PATTERN_WITH_PARAM_NO_BRACKETS.matcher(where).matches() 2985 || WHERE_PATTERN_WITH_PARAM_IN_BRACKETS.matcher(where).matches()) 2986 && whereArgs.length == 1) { 2987 name = whereArgs[0]; 2988 table = computeTableForSetting(uri, name); 2989 return; 2990 } else if (where != null 2991 && (WHERE_PATTERN_NO_PARAM_NO_BRACKETS.matcher(where).matches() 2992 || WHERE_PATTERN_NO_PARAM_IN_BRACKETS.matcher(where).matches())) { 2993 final int startIndex = Math.max(where.indexOf("'"), 2994 where.indexOf("\"")) + 1; 2995 final int endIndex = Math.max(where.lastIndexOf("'"), 2996 where.lastIndexOf("\"")); 2997 name = where.substring(startIndex, endIndex); 2998 table = computeTableForSetting(uri, name); 2999 return; 3000 } else if (supportAll && where == null && whereArgs == null) { 3001 name = null; 3002 table = computeTableForSetting(uri, null); 3003 return; 3004 } 3005 } 3006 case 2 -> { 3007 if (where == null && whereArgs == null) { 3008 name = uri.getPathSegments().get(1); 3009 table = computeTableForSetting(uri, name); 3010 return; 3011 } 3012 } 3013 } 3014 3015 EventLogTags.writeUnsupportedSettingsQuery( 3016 uri.toSafeString(), where, Arrays.toString(whereArgs)); 3017 String message = String.format( "Supported SQL:\n" 3018 + " uri content://some_table/some_property with null where and where args\n" 3019 + " uri content://some_table with query name=? and single name as arg\n" 3020 + " uri content://some_table with query name=some_name and null args\n" 3021 + " but got - uri:%1s, where:%2s whereArgs:%3s", uri, where, 3022 Arrays.toString(whereArgs)); 3023 throw new IllegalArgumentException(message); 3024 } 3025 3026 private static String computeTableForSetting(Uri uri, String name) { 3027 String table = getValidTableOrThrow(uri); 3028 3029 if (name != null) { 3030 if (sSystemMovedToSecureSettings.contains(name)) { 3031 table = TABLE_SECURE; 3032 } 3033 3034 if (sSystemMovedToGlobalSettings.contains(name)) { 3035 table = TABLE_GLOBAL; 3036 } 3037 3038 if (sSecureMovedToGlobalSettings.contains(name)) { 3039 table = TABLE_GLOBAL; 3040 } 3041 3042 if (sGlobalMovedToSecureSettings.contains(name)) { 3043 table = TABLE_SECURE; 3044 } 3045 3046 if (sGlobalMovedToSystemSettings.contains(name)) { 3047 table = TABLE_SYSTEM; 3048 } 3049 } 3050 3051 return table; 3052 } 3053 } 3054 3055 /** 3056 * Schedule the job service to make a copy of all the settings files. 3057 */ 3058 public void scheduleWriteFallbackFilesJob() { 3059 final Context context = getContext(); 3060 JobScheduler jobScheduler = 3061 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); 3062 if (jobScheduler == null) { 3063 // Might happen: SettingsProvider is created before JobSchedulerService in system server 3064 return; 3065 } 3066 jobScheduler = jobScheduler.forNamespace(SETTINGS_PROVIDER_JOBS_NS); 3067 // Check if the job is already scheduled. If so, skip scheduling another one 3068 if (jobScheduler.getPendingJob(WRITE_FALLBACK_SETTINGS_FILES_JOB_ID) != null) { 3069 return; 3070 } 3071 // Back up all settings files 3072 final PersistableBundle bundle = new PersistableBundle(); 3073 final File globalSettingsFile = mSettingsRegistry.getSettingsFile( 3074 makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM)); 3075 final File systemSettingsFile = mSettingsRegistry.getSettingsFile( 3076 makeKey(SETTINGS_TYPE_SYSTEM, UserHandle.USER_SYSTEM)); 3077 final File secureSettingsFile = mSettingsRegistry.getSettingsFile( 3078 makeKey(SETTINGS_TYPE_SECURE, UserHandle.USER_SYSTEM)); 3079 final File ssaidSettingsFile = mSettingsRegistry.getSettingsFile( 3080 makeKey(SETTINGS_TYPE_SSAID, UserHandle.USER_SYSTEM)); 3081 final File configSettingsFile = mSettingsRegistry.getSettingsFile( 3082 makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM)); 3083 bundle.putString(TABLE_GLOBAL, globalSettingsFile.getAbsolutePath()); 3084 bundle.putString(TABLE_SYSTEM, systemSettingsFile.getAbsolutePath()); 3085 bundle.putString(TABLE_SECURE, secureSettingsFile.getAbsolutePath()); 3086 bundle.putString(TABLE_SSAID, ssaidSettingsFile.getAbsolutePath()); 3087 bundle.putString(TABLE_CONFIG, configSettingsFile.getAbsolutePath()); 3088 // Schedule the job to write the fallback files, once daily when phone is charging 3089 jobScheduler.schedule(new JobInfo.Builder(WRITE_FALLBACK_SETTINGS_FILES_JOB_ID, 3090 new ComponentName(context, WriteFallbackSettingsFilesJobService.class)) 3091 .setExtras(bundle) 3092 .setPeriodic(ONE_DAY_INTERVAL_MILLIS) 3093 .setRequiresCharging(true) 3094 .setPersisted(true) 3095 .build()); 3096 } 3097 3098 /** 3099 * For each file in the given list, if it exists, copy it to a back up file. Ignore failures. 3100 * @param filePaths List of paths of files that need to be backed up 3101 */ 3102 public static void writeFallBackSettingsFiles(List<String> filePaths) { 3103 final int numFiles = filePaths.size(); 3104 for (int i = 0; i < numFiles; i++) { 3105 final String filePath = filePaths.get(i); 3106 final File originalFile = new File(filePath); 3107 if (SettingsState.stateFileExists(originalFile)) { 3108 final File fallBackFile = new File(filePath + FALLBACK_FILE_SUFFIX); 3109 try { 3110 FileUtils.copy(originalFile, fallBackFile); 3111 } catch (IOException ex) { 3112 Slog.w(LOG_TAG, "Failed to write fallback file for: " + filePath); 3113 } 3114 } 3115 } 3116 } 3117 3118 final class SettingsRegistry { 3119 private static final String DROPBOX_TAG_USERLOG = "restricted_profile_ssaid"; 3120 3121 private static final String SETTINGS_FILE_GLOBAL = "settings_global.xml"; 3122 private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml"; 3123 private static final String SETTINGS_FILE_SECURE = "settings_secure.xml"; 3124 private static final String SETTINGS_FILE_SSAID = "settings_ssaid.xml"; 3125 private static final String SETTINGS_FILE_CONFIG = "settings_config.xml"; 3126 3127 private static final String SSAID_USER_KEY = "userkey"; 3128 3129 @GuardedBy("mLock") 3130 private final SparseArray<SettingsState> mSettingsStates = new SparseArray<>(); 3131 3132 private GenerationRegistry mGenerationRegistry; 3133 3134 private final Handler mHandler; 3135 3136 private final BackupManager mBackupManager; 3137 3138 private String mSettingsCreationBuildId; 3139 3140 SettingsRegistry(Looper looper) { 3141 mHandler = new MyHandler(looper); 3142 mGenerationRegistry = new GenerationRegistry(UserManager.getMaxSupportedUsers()); 3143 mBackupManager = new BackupManager(getContext()); 3144 } 3145 3146 @GuardedBy("mLock") 3147 private void generateUserKeyLocked(int userId) { 3148 // Generate a random key for each user used for creating a new ssaid. 3149 final byte[] keyBytes = new byte[32]; 3150 final SecureRandom rand = new SecureRandom(); 3151 rand.nextBytes(keyBytes); 3152 3153 // Convert to string for storage in settings table. 3154 final String userKey = HexEncoding.encodeToString(keyBytes, true /* upperCase */); 3155 3156 // Store the key in the ssaid table. 3157 final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId); 3158 final boolean success = ssaidSettings.insertSettingLocked(SSAID_USER_KEY, userKey, null, 3159 true, SettingsState.SYSTEM_PACKAGE_NAME); 3160 3161 if (!success) { 3162 throw new IllegalStateException("Ssaid settings not accessible"); 3163 } 3164 } 3165 3166 private byte[] getLengthPrefix(byte[] data) { 3167 return ByteBuffer.allocate(4).putInt(data.length).array(); 3168 } 3169 3170 @GuardedBy("mLock") 3171 public Setting generateSsaidLocked(PackageInfo callingPkg, int userId) { 3172 // Read the user's key from the ssaid table. 3173 Setting userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY); 3174 if (userKeySetting == null || userKeySetting.isNull() 3175 || userKeySetting.getValue() == null) { 3176 // Lazy initialize and store the user key. 3177 generateUserKeyLocked(userId); 3178 userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY); 3179 if (userKeySetting == null || userKeySetting.isNull() 3180 || userKeySetting.getValue() == null) { 3181 throw new IllegalStateException("User key not accessible"); 3182 } 3183 } 3184 final String userKey = userKeySetting.getValue(); 3185 if (userKey == null || userKey.length() % 2 != 0) { 3186 throw new IllegalStateException("User key invalid"); 3187 } 3188 3189 // Convert the user's key back to a byte array. 3190 final byte[] keyBytes = HexEncoding.decode(userKey); 3191 3192 // Validate that the key is of expected length. 3193 // Keys are currently 32 bytes, but were once 16 bytes during Android O development. 3194 if (keyBytes.length != 16 && keyBytes.length != 32) { 3195 throw new IllegalStateException("User key invalid"); 3196 } 3197 3198 final Mac m; 3199 try { 3200 m = Mac.getInstance("HmacSHA256"); 3201 m.init(new SecretKeySpec(keyBytes, m.getAlgorithm())); 3202 } catch (NoSuchAlgorithmException e) { 3203 throw new IllegalStateException("HmacSHA256 is not available", e); 3204 } catch (InvalidKeyException e) { 3205 throw new IllegalStateException("Key is corrupted", e); 3206 } 3207 3208 // Mac each of the developer signatures. 3209 for (int i = 0; i < callingPkg.signatures.length; i++) { 3210 byte[] sig = callingPkg.signatures[i].toByteArray(); 3211 m.update(getLengthPrefix(sig), 0, 4); 3212 m.update(sig); 3213 } 3214 3215 // Convert result to a string for storage in settings table. Only want first 64 bits. 3216 final String ssaid = HexEncoding.encodeToString(m.doFinal(), false /* upperCase */) 3217 .substring(0, 16); 3218 3219 // Save the ssaid in the ssaid table. 3220 final String uid = Integer.toString(callingPkg.applicationInfo.uid); 3221 final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId); 3222 final boolean success = ssaidSettings.insertSettingLocked(uid, ssaid, null, true, 3223 callingPkg.packageName); 3224 3225 if (!success) { 3226 throw new IllegalStateException("Ssaid settings not accessible"); 3227 } 3228 3229 return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid); 3230 } 3231 3232 @GuardedBy("mLock") 3233 private void syncSsaidTableOnStartLocked() { 3234 // Verify that each user's packages and ssaid's are in sync. 3235 for (UserInfo user : mUserManager.getAliveUsers()) { 3236 // Get all uids for the user's packages. 3237 final List<PackageInfo> packages; 3238 try { 3239 packages = mPackageManager.getInstalledPackages( 3240 PackageManager.MATCH_UNINSTALLED_PACKAGES, 3241 user.id).getList(); 3242 } catch (RemoteException e) { 3243 throw new IllegalStateException("Package manager not available"); 3244 } 3245 final Set<String> appUids = new HashSet<>(); 3246 for (PackageInfo info : packages) { 3247 appUids.add(Integer.toString(info.applicationInfo.uid)); 3248 } 3249 3250 // Get all uids currently stored in the user's ssaid table. 3251 final Set<String> ssaidUids = new HashSet<>( 3252 getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id)); 3253 ssaidUids.remove(SSAID_USER_KEY); 3254 3255 // Perform a set difference for the appUids and ssaidUids. 3256 ssaidUids.removeAll(appUids); 3257 3258 // If there are ssaidUids left over they need to be removed from the table. 3259 final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, 3260 user.id); 3261 for (String uid : ssaidUids) { 3262 ssaidSettings.deleteSettingLocked(uid); 3263 } 3264 } 3265 } 3266 3267 @GuardedBy("mLock") 3268 public List<String> getSettingsNamesLocked(int type, int userId) { 3269 final int key = makeKey(type, userId); 3270 SettingsState settingsState = mSettingsStates.get(key); 3271 if (settingsState == null) { 3272 return new ArrayList<>(); 3273 } 3274 return settingsState.getSettingNamesLocked(); 3275 } 3276 3277 @GuardedBy("mLock") 3278 public SparseBooleanArray getKnownUsersLocked() { 3279 SparseBooleanArray users = new SparseBooleanArray(); 3280 for (int i = mSettingsStates.size()-1; i >= 0; i--) { 3281 users.put(getUserIdFromKey(mSettingsStates.keyAt(i)), true); 3282 } 3283 return users; 3284 } 3285 3286 @GuardedBy("mLock") 3287 @Nullable 3288 public SettingsState getSettingsLocked(int type, int userId) { 3289 final int key = makeKey(type, userId); 3290 return mSettingsStates.get(key); 3291 } 3292 3293 @GuardedBy("mLock") 3294 @Nullable 3295 private SettingsState getOrCreateSettingsStateLocked(int key) { 3296 SettingsState settingsState = mSettingsStates.get(key); 3297 if (settingsState != null) { 3298 return settingsState; 3299 } 3300 3301 if (!ensureSettingsForUserLocked(getUserIdFromKey(key))) { 3302 return null; 3303 } 3304 return mSettingsStates.get(key); 3305 } 3306 3307 @GuardedBy("mLock") 3308 public boolean ensureSettingsForUserLocked(int userId) { 3309 // First make sure this user actually exists. 3310 if (mUserManager.getUserInfo(userId) == null) { 3311 Slog.wtf(LOG_TAG, "Requested user " + userId + " does not exist"); 3312 return false; 3313 } 3314 3315 // Migrate the setting for this user if needed. 3316 migrateLegacySettingsForUserIfNeededLocked(userId); 3317 3318 // Ensure config settings loaded if owner. 3319 if (userId == UserHandle.USER_SYSTEM) { 3320 final int configKey 3321 = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM); 3322 ensureSettingsStateLocked(configKey); 3323 } 3324 3325 // Ensure global settings loaded if owner. 3326 if (userId == UserHandle.USER_SYSTEM) { 3327 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); 3328 ensureSettingsStateLocked(globalKey); 3329 } 3330 3331 // Ensure secure settings loaded. 3332 final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId); 3333 ensureSettingsStateLocked(secureKey); 3334 3335 // Make sure the secure settings have an Android id set. 3336 SettingsState secureSettings = getSettingsLocked(SETTINGS_TYPE_SECURE, userId); 3337 ensureSecureSettingAndroidIdSetLocked(secureSettings); 3338 3339 // Ensure system settings loaded. 3340 final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId); 3341 ensureSettingsStateLocked(systemKey); 3342 3343 // Ensure secure settings loaded. 3344 final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId); 3345 ensureSettingsStateLocked(ssaidKey); 3346 3347 // Upgrade the settings to the latest version. 3348 UpgradeController upgrader = new UpgradeController(userId); 3349 upgrader.upgradeIfNeededLocked(); 3350 return true; 3351 } 3352 3353 @GuardedBy("mLock") 3354 private void ensureSettingsStateLocked(int key) { 3355 if (mSettingsStates.get(key) == null) { 3356 final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key)); 3357 SettingsState settingsState = new SettingsState(getContext(), mLock, 3358 getSettingsFile(key), key, maxBytesPerPackage, mHandlerThread.getLooper()); 3359 mSettingsStates.put(key, settingsState); 3360 } 3361 } 3362 3363 @GuardedBy("mLock") 3364 public void removeUserStateLocked(int userId, boolean permanently) { 3365 // We always keep the global settings in memory. 3366 3367 // Nuke system settings. 3368 final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId); 3369 final SettingsState systemSettingsState = mSettingsStates.get(systemKey); 3370 if (systemSettingsState != null) { 3371 if (permanently) { 3372 mSettingsStates.remove(systemKey); 3373 systemSettingsState.destroyLocked(null); 3374 } else { 3375 systemSettingsState.destroyLocked(() -> mSettingsStates.remove(systemKey)); 3376 } 3377 } 3378 3379 // Nuke secure settings. 3380 final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId); 3381 final SettingsState secureSettingsState = mSettingsStates.get(secureKey); 3382 if (secureSettingsState != null) { 3383 if (permanently) { 3384 mSettingsStates.remove(secureKey); 3385 secureSettingsState.destroyLocked(null); 3386 } else { 3387 secureSettingsState.destroyLocked(() -> mSettingsStates.remove(secureKey)); 3388 } 3389 } 3390 3391 // Nuke ssaid settings. 3392 final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId); 3393 final SettingsState ssaidSettingsState = mSettingsStates.get(ssaidKey); 3394 if (ssaidSettingsState != null) { 3395 if (permanently) { 3396 mSettingsStates.remove(ssaidKey); 3397 ssaidSettingsState.destroyLocked(null); 3398 } else { 3399 ssaidSettingsState.destroyLocked(() -> mSettingsStates.remove(ssaidKey)); 3400 } 3401 } 3402 3403 // Nuke generation tracking data 3404 mGenerationRegistry.onUserRemoved(userId); 3405 } 3406 3407 @GuardedBy("mLock") 3408 public boolean insertSettingLocked(int type, int userId, String name, String value, 3409 String tag, boolean makeDefault, String packageName, boolean forceNotify, 3410 Set<String> criticalSettings, boolean overrideableByRestore) { 3411 return insertSettingLocked(type, userId, name, value, tag, makeDefault, false, 3412 packageName, forceNotify, criticalSettings, overrideableByRestore); 3413 } 3414 3415 @GuardedBy("mLock") 3416 public boolean insertSettingLocked(int type, int userId, String name, String value, 3417 String tag, boolean makeDefault, boolean forceNonSystemPackage, String packageName, 3418 boolean forceNotify, Set<String> criticalSettings, boolean overrideableByRestore) { 3419 if (overrideableByRestore != Settings.DEFAULT_OVERRIDEABLE_BY_RESTORE) { 3420 getContext().enforceCallingOrSelfPermission( 3421 Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE, 3422 "Caller is not allowed to modify settings overrideable by restore"); 3423 } 3424 final int key = makeKey(type, userId); 3425 3426 boolean success = false; 3427 boolean wasUnsetNonPredefinedSetting = false; 3428 SettingsState settingsState = getOrCreateSettingsStateLocked(key); 3429 if (settingsState != null) { 3430 if (!isSettingPreDefined(name, type) && !settingsState.hasSetting(name)) { 3431 wasUnsetNonPredefinedSetting = true; 3432 } 3433 success = settingsState.insertSettingLocked(name, value, 3434 tag, makeDefault, forceNonSystemPackage, packageName, 3435 overrideableByRestore); 3436 } 3437 3438 if (success && criticalSettings != null && criticalSettings.contains(name)) { 3439 settingsState.persistSettingsLocked(); 3440 } 3441 3442 if (forceNotify || success) { 3443 notifyForSettingsChange(key, name); 3444 3445 // If this is an aconfig flag, it will be written as a staged flag. 3446 // Notify that its staged flag value will be updated. 3447 if (Flags.notifyIndividualAconfigSyspropChanged() && type == SETTINGS_TYPE_CONFIG) { 3448 int slashIndex = name.indexOf('/'); 3449 boolean validSlashIndex = slashIndex != -1 3450 && slashIndex != 0 3451 && slashIndex != name.length(); 3452 if (validSlashIndex) { 3453 String namespace = name.substring(0, slashIndex); 3454 String flagName = name.substring(slashIndex + 1); 3455 if (settingsState.getAconfigDefaultFlags().containsKey(flagName)) { 3456 String stagedName = "staged/" + namespace + "*" + flagName; 3457 notifyForSettingsChange(key, stagedName); 3458 } 3459 } 3460 } 3461 3462 if (wasUnsetNonPredefinedSetting) { 3463 // Increment the generation number for all non-predefined, unset settings, 3464 // because a new non-predefined setting has been inserted 3465 mGenerationRegistry.incrementGenerationForUnsetSettings(key); 3466 } 3467 } 3468 if (success) { 3469 logSettingChanged(userId, name, type, CHANGE_TYPE_INSERT); 3470 } 3471 return success; 3472 } 3473 3474 /** 3475 * Set Config Settings using consumed keyValues, returns true if the keyValues can be set, 3476 * false otherwise. 3477 */ 3478 @GuardedBy("mLock") 3479 public boolean setConfigSettingsLocked(int key, String prefix, 3480 Map<String, String> keyValues, String packageName) { 3481 SettingsState settingsState = getOrCreateSettingsStateLocked(key); 3482 if (settingsState != null) { 3483 if (settingsState.isNewConfigBannedLocked(prefix, keyValues)) { 3484 return false; 3485 } 3486 settingsState.unbanAllConfigIfBannedConfigUpdatedLocked(prefix); 3487 List<String> changedSettings = 3488 settingsState.setSettingsLocked(prefix, keyValues, packageName); 3489 if (!changedSettings.isEmpty()) { 3490 reportDeviceConfigUpdate(prefix); 3491 notifyForConfigSettingsChangeLocked(key, prefix, changedSettings); 3492 } 3493 } 3494 // keyValues aren't banned and can be set 3495 return true; 3496 } 3497 3498 @GuardedBy("mLock") 3499 public boolean deleteSettingLocked(int type, int userId, String name, boolean forceNotify, 3500 Set<String> criticalSettings) { 3501 final int key = makeKey(type, userId); 3502 3503 boolean success = false; 3504 SettingsState settingsState = getOrCreateSettingsStateLocked(key); 3505 if (settingsState != null) { 3506 success = settingsState.deleteSettingLocked(name); 3507 } 3508 3509 if (success && criticalSettings != null && criticalSettings.contains(name)) { 3510 settingsState.persistSettingsLocked(); 3511 } 3512 3513 if (forceNotify || success) { 3514 notifyForSettingsChange(key, name); 3515 } 3516 if (success) { 3517 logSettingChanged(userId, name, type, CHANGE_TYPE_DELETE); 3518 } 3519 return success; 3520 } 3521 3522 @GuardedBy("mLock") 3523 public boolean updateSettingLocked(int type, int userId, String name, String value, 3524 String tag, boolean makeDefault, String packageName, boolean forceNotify, 3525 Set<String> criticalSettings) { 3526 final int key = makeKey(type, userId); 3527 3528 boolean success = false; 3529 SettingsState settingsState = getOrCreateSettingsStateLocked(key); 3530 if (settingsState != null) { 3531 success = settingsState.updateSettingLocked(name, value, tag, 3532 makeDefault, packageName); 3533 } 3534 3535 if (success && criticalSettings != null && criticalSettings.contains(name)) { 3536 settingsState.persistSettingsLocked(); 3537 } 3538 3539 if (forceNotify || success) { 3540 notifyForSettingsChange(key, name); 3541 } 3542 if (success) { 3543 logSettingChanged(userId, name, type, CHANGE_TYPE_UPDATE); 3544 } 3545 return success; 3546 } 3547 3548 @GuardedBy("mLock") 3549 public Setting getSettingLocked(int type, int userId, String name) { 3550 final int key = makeKey(type, userId); 3551 3552 SettingsState settingsState = mSettingsStates.get(key); 3553 if (settingsState == null) { 3554 return null; 3555 } 3556 3557 // getSettingLocked will return non-null result 3558 return settingsState.getSettingLocked(name); 3559 } 3560 3561 private static boolean shouldExcludeSettingFromReset(Setting setting, String prefix) { 3562 // If a prefix was specified, exclude settings whose names don't start with it. 3563 if (prefix != null && !setting.getName().startsWith(prefix)) { 3564 return true; 3565 } 3566 // Never reset SECURE_FRP_MODE, as it could be abused to bypass FRP via RescueParty. 3567 return Global.SECURE_FRP_MODE.equals(setting.getName()); 3568 } 3569 3570 @GuardedBy("mLock") 3571 public boolean resetSettingsLocked(int type, int userId, String packageName, int mode, 3572 String tag) { 3573 return resetSettingsLocked(type, userId, packageName, mode, tag, /*prefix=*/ 3574 null); 3575 } 3576 3577 @GuardedBy("mLock") 3578 public boolean resetSettingsLocked(int type, int userId, String packageName, int mode, 3579 String tag, @Nullable String prefix) { 3580 final int key = makeKey(type, userId); 3581 SettingsState settingsState = getOrCreateSettingsStateLocked(key); 3582 if (settingsState == null) { 3583 return false; 3584 } 3585 3586 boolean success = false; 3587 banConfigurationIfNecessary(type, prefix, settingsState); 3588 switch (mode) { 3589 case Settings.RESET_MODE_PACKAGE_DEFAULTS -> { 3590 for (String name : settingsState.getSettingNamesLocked()) { 3591 boolean someSettingChanged = false; 3592 Setting setting = settingsState.getSettingLocked(name); 3593 if (packageName.equals(setting.getPackageName())) { 3594 if ((tag != null && !tag.equals(setting.getTag())) 3595 || shouldExcludeSettingFromReset(setting, prefix)) { 3596 continue; 3597 } 3598 if (settingsState.resetSettingLocked(name)) { 3599 someSettingChanged = true; 3600 notifyForSettingsChange(key, name); 3601 logSettingChanged(userId, name, type, CHANGE_TYPE_RESET); 3602 } 3603 } 3604 if (someSettingChanged) { 3605 settingsState.persistSettingsLocked(); 3606 success = true; 3607 } 3608 } 3609 } 3610 case Settings.RESET_MODE_UNTRUSTED_DEFAULTS -> { 3611 for (String name : settingsState.getSettingNamesLocked()) { 3612 boolean someSettingChanged = false; 3613 Setting setting = settingsState.getSettingLocked(name); 3614 if (!SettingsState.isSystemPackage(getContext(), 3615 setting.getPackageName())) { 3616 if (shouldExcludeSettingFromReset(setting, prefix)) { 3617 continue; 3618 } 3619 if (settingsState.resetSettingLocked(name)) { 3620 someSettingChanged = true; 3621 notifyForSettingsChange(key, name); 3622 logSettingChanged(userId, name, type, CHANGE_TYPE_RESET); 3623 } 3624 } 3625 if (someSettingChanged) { 3626 settingsState.persistSettingsLocked(); 3627 success = true; 3628 } 3629 } 3630 } 3631 case Settings.RESET_MODE_UNTRUSTED_CHANGES -> { 3632 for (String name : settingsState.getSettingNamesLocked()) { 3633 boolean someSettingChanged = false; 3634 Setting setting = settingsState.getSettingLocked(name); 3635 if (!SettingsState.isSystemPackage(getContext(), 3636 setting.getPackageName())) { 3637 if (shouldExcludeSettingFromReset(setting, prefix)) { 3638 continue; 3639 } 3640 if (setting.isDefaultFromSystem()) { 3641 if (settingsState.resetSettingLocked(name)) { 3642 someSettingChanged = true; 3643 notifyForSettingsChange(key, name); 3644 logSettingChanged(userId, name, type, CHANGE_TYPE_RESET); 3645 } 3646 } else if (settingsState.deleteSettingLocked(name)) { 3647 someSettingChanged = true; 3648 notifyForSettingsChange(key, name); 3649 logSettingChanged(userId, name, type, CHANGE_TYPE_DELETE); 3650 } 3651 } 3652 if (someSettingChanged) { 3653 settingsState.persistSettingsLocked(); 3654 success = true; 3655 } 3656 } 3657 } 3658 case Settings.RESET_MODE_TRUSTED_DEFAULTS -> { 3659 for (String name : settingsState.getSettingNamesLocked()) { 3660 Setting setting = settingsState.getSettingLocked(name); 3661 boolean someSettingChanged = false; 3662 if (shouldExcludeSettingFromReset(setting, prefix)) { 3663 continue; 3664 } 3665 if (setting.isDefaultFromSystem()) { 3666 if (settingsState.resetSettingLocked(name)) { 3667 someSettingChanged = true; 3668 notifyForSettingsChange(key, name); 3669 logSettingChanged(userId, name, type, CHANGE_TYPE_RESET); 3670 } 3671 } else if (settingsState.deleteSettingLocked(name)) { 3672 someSettingChanged = true; 3673 notifyForSettingsChange(key, name); 3674 logSettingChanged(userId, name, type, CHANGE_TYPE_DELETE); 3675 } 3676 if (someSettingChanged) { 3677 settingsState.persistSettingsLocked(); 3678 success = true; 3679 } 3680 } 3681 } 3682 } 3683 return success; 3684 } 3685 3686 @GuardedBy("mLock") 3687 public void removeSettingsForPackageLocked(String packageName, int userId) { 3688 // Global and secure settings are signature protected. Apps signed 3689 // by the platform certificate are generally not uninstalled and 3690 // the main exception is tests. We trust components signed 3691 // by the platform certificate and do not do a clean up after them. 3692 3693 final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId); 3694 SettingsState systemSettings = mSettingsStates.get(systemKey); 3695 if (systemSettings != null) { 3696 systemSettings.removeSettingsForPackageLocked(packageName); 3697 } 3698 } 3699 3700 @GuardedBy("mLock") 3701 public void onUidRemovedLocked(int uid) { 3702 final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, 3703 UserHandle.getUserId(uid)); 3704 if (ssaidSettings != null) { 3705 ssaidSettings.deleteSettingLocked(Integer.toString(uid)); 3706 } 3707 } 3708 3709 @GuardedBy("mLock") 3710 private void migrateAllLegacySettingsIfNeededLocked() { 3711 final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); 3712 File globalFile = getSettingsFile(key); 3713 if (SettingsState.stateFileExists(globalFile)) { 3714 return; 3715 } 3716 3717 mSettingsCreationBuildId = Build.ID; 3718 3719 final long identity = Binder.clearCallingIdentity(); 3720 try { 3721 List<UserInfo> users = mUserManager.getAliveUsers(); 3722 3723 final int userCount = users.size(); 3724 for (int i = 0; i < userCount; i++) { 3725 final int userId = users.get(i).id; 3726 3727 DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId); 3728 SQLiteDatabase database = dbHelper.getWritableDatabase(); 3729 migrateLegacySettingsForUserLocked(dbHelper, database, userId); 3730 3731 // Upgrade to the latest version. 3732 UpgradeController upgrader = new UpgradeController(userId); 3733 upgrader.upgradeIfNeededLocked(); 3734 3735 // Drop from memory if not a running user. 3736 if (!mUserManager.isUserRunning(new UserHandle(userId))) { 3737 removeUserStateLocked(userId, false); 3738 } 3739 } 3740 } finally { 3741 Binder.restoreCallingIdentity(identity); 3742 } 3743 } 3744 3745 @GuardedBy("mLock") 3746 private void migrateLegacySettingsForUserIfNeededLocked(int userId) { 3747 // Every user has secure settings and if no file we need to migrate. 3748 final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId); 3749 File secureFile = getSettingsFile(secureKey); 3750 if (SettingsState.stateFileExists(secureFile)) { 3751 return; 3752 } 3753 3754 DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId); 3755 SQLiteDatabase database = dbHelper.getWritableDatabase(); 3756 3757 migrateLegacySettingsForUserLocked(dbHelper, database, userId); 3758 } 3759 3760 @GuardedBy("mLock") 3761 private void migrateLegacySettingsForUserLocked(DatabaseHelper dbHelper, 3762 SQLiteDatabase database, int userId) { 3763 // Move over the system settings. 3764 final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId); 3765 ensureSettingsStateLocked(systemKey); 3766 SettingsState systemSettings = mSettingsStates.get(systemKey); 3767 migrateLegacySettingsLocked(systemSettings, database, TABLE_SYSTEM); 3768 systemSettings.persistSettingsLocked(); 3769 3770 // Move over the secure settings. 3771 // Do this after System settings, since this is the first thing we check when deciding 3772 // to skip over migration from db to xml for a secondary user. 3773 final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId); 3774 ensureSettingsStateLocked(secureKey); 3775 SettingsState secureSettings = mSettingsStates.get(secureKey); 3776 migrateLegacySettingsLocked(secureSettings, database, TABLE_SECURE); 3777 ensureSecureSettingAndroidIdSetLocked(secureSettings); 3778 secureSettings.persistSettingsLocked(); 3779 3780 // Move over the global settings if owner. 3781 // Do this last, since this is the first thing we check when deciding 3782 // to skip over migration from db to xml for owner user. 3783 if (userId == UserHandle.USER_SYSTEM) { 3784 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, userId); 3785 ensureSettingsStateLocked(globalKey); 3786 SettingsState globalSettings = mSettingsStates.get(globalKey); 3787 migrateLegacySettingsLocked(globalSettings, database, TABLE_GLOBAL); 3788 // If this was just created 3789 if (mSettingsCreationBuildId != null) { 3790 globalSettings.insertSettingLocked(Settings.Global.DATABASE_CREATION_BUILDID, 3791 mSettingsCreationBuildId, null, true, 3792 SettingsState.SYSTEM_PACKAGE_NAME); 3793 } 3794 globalSettings.persistSettingsLocked(); 3795 } 3796 3797 // Drop the database as now all is moved and persisted. 3798 if (DROP_DATABASE_ON_MIGRATION) { 3799 dbHelper.dropDatabase(); 3800 } else { 3801 dbHelper.backupDatabase(); 3802 } 3803 } 3804 3805 @GuardedBy("mLock") 3806 private void migrateLegacySettingsLocked(SettingsState settingsState, 3807 SQLiteDatabase database, String table) { 3808 SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 3809 queryBuilder.setTables(table); 3810 3811 Cursor cursor = queryBuilder.query(database, LEGACY_SQL_COLUMNS, 3812 null, null, null, null, null); 3813 3814 if (cursor == null) { 3815 return; 3816 } 3817 3818 try { 3819 if (!cursor.moveToFirst()) { 3820 return; 3821 } 3822 3823 final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME); 3824 final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE); 3825 3826 settingsState.setVersionLocked(database.getVersion()); 3827 3828 while (!cursor.isAfterLast()) { 3829 String name = cursor.getString(nameColumnIdx); 3830 String value = cursor.getString(valueColumnIdx); 3831 settingsState.insertSettingLocked(name, value, null, true, 3832 SettingsState.SYSTEM_PACKAGE_NAME); 3833 cursor.moveToNext(); 3834 } 3835 } finally { 3836 cursor.close(); 3837 } 3838 } 3839 3840 @GuardedBy("mLock") 3841 private void ensureSecureSettingAndroidIdSetLocked(SettingsState secureSettings) { 3842 Setting value = secureSettings.getSettingLocked(Settings.Secure.ANDROID_ID); 3843 3844 if (!value.isNull()) { 3845 return; 3846 } 3847 3848 final int userId = getUserIdFromKey(secureSettings.mKey); 3849 3850 final UserInfo user; 3851 final long identity = Binder.clearCallingIdentity(); 3852 try { 3853 user = mUserManager.getUserInfo(userId); 3854 } finally { 3855 Binder.restoreCallingIdentity(identity); 3856 } 3857 if (user == null) { 3858 // Can happen due to races when deleting users - treat as benign. 3859 return; 3860 } 3861 3862 String androidId = Long.toHexString(new SecureRandom().nextLong()); 3863 secureSettings.insertSettingLocked(Settings.Secure.ANDROID_ID, androidId, 3864 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 3865 3866 Slog.d(LOG_TAG, "Generated and saved new ANDROID_ID [" + androidId 3867 + "] for user " + userId); 3868 3869 // Write a drop box entry if it's a restricted profile 3870 if (user.isRestricted()) { 3871 DropBoxManager dbm = (DropBoxManager) getContext().getSystemService( 3872 Context.DROPBOX_SERVICE); 3873 if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) { 3874 dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis() 3875 + "," + DROPBOX_TAG_USERLOG + "," + androidId + "\n"); 3876 } 3877 } 3878 } 3879 3880 private void notifyForSettingsChange(int key, String name) { 3881 // Increment the generation first, so observers always see the new value 3882 mGenerationRegistry.incrementGeneration(key, name); 3883 3884 if (isGlobalSettingsKey(key) || isConfigSettingsKey(key)) { 3885 final long token = Binder.clearCallingIdentity(); 3886 try { 3887 notifySettingChangeForRunningUsers(key, name); 3888 } finally { 3889 Binder.restoreCallingIdentity(token); 3890 } 3891 } else { 3892 final int userId = getUserIdFromKey(key); 3893 final Uri uri = getNotificationUriFor(key, name); 3894 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, 3895 userId, 0, uri).sendToTarget(); 3896 if (isSecureSettingsKey(key)) { 3897 maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name, 3898 sSecureCloneToManagedSettings); 3899 } else if (isSystemSettingsKey(key)) { 3900 maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name, 3901 sSystemCloneToManagedSettings); 3902 maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name, 3903 sSystemCloneFromParentOnDependency.keySet()); 3904 } 3905 } 3906 3907 // Always notify that our data changed 3908 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget(); 3909 } 3910 3911 private void logSettingChanged(int userId, String name, int type, int changeType) { 3912 FrameworkStatsLog.write(FrameworkStatsLog.SETTINGS_PROVIDER_SETTING_CHANGED, userId, 3913 name, type, changeType); 3914 } 3915 3916 @GuardedBy("mLock") 3917 private void notifyForConfigSettingsChangeLocked(int key, String prefix, 3918 List<String> changedSettings) { 3919 3920 // Increment the generation first, so observers always see the new value 3921 mGenerationRegistry.incrementGeneration(key, prefix); 3922 3923 StringBuilder stringBuilder = new StringBuilder(prefix); 3924 for (int i = 0; i < changedSettings.size(); ++i) { 3925 stringBuilder.append(changedSettings.get(i).split("/")[1]).append("/"); 3926 } 3927 3928 final long token = Binder.clearCallingIdentity(); 3929 try { 3930 notifySettingChangeForRunningUsers(key, stringBuilder.toString()); 3931 } finally { 3932 Binder.restoreCallingIdentity(token); 3933 } 3934 3935 // Always notify that our data changed 3936 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget(); 3937 } 3938 3939 private void maybeNotifyProfiles(int type, int userId, Uri uri, String name, 3940 Collection<String> keysCloned) { 3941 if (keysCloned.contains(name)) { 3942 for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) { 3943 // the notification for userId has already been sent. 3944 if (profileId != userId) { 3945 final int key = makeKey(type, profileId); 3946 // Increment the generation first, so observers always see the new value 3947 mGenerationRegistry.incrementGeneration(key, name); 3948 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, 3949 profileId, 0, uri).sendToTarget(); 3950 } 3951 } 3952 } 3953 } 3954 3955 private void notifySettingChangeForRunningUsers(int key, String name) { 3956 // Important: No need to update generation for each user as there 3957 // is a singleton generation entry for the global settings which 3958 // is already incremented be the caller. 3959 final Uri uri = getNotificationUriFor(key, name); 3960 final List<UserInfo> users = mUserManager.getAliveUsers(); 3961 for (int i = 0; i < users.size(); i++) { 3962 final int userId = users.get(i).id; 3963 if (mUserManager.isUserRunning(UserHandle.of(userId))) { 3964 mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, 3965 userId, 0, uri).sendToTarget(); 3966 } 3967 } 3968 } 3969 3970 private boolean shouldBan(int type) { 3971 if (SETTINGS_TYPE_CONFIG != type) { 3972 return false; 3973 } 3974 final int callingUid = Binder.getCallingUid(); 3975 final int appId = UserHandle.getAppId(callingUid); 3976 3977 // Only non-shell resets should result in namespace banning 3978 return appId != SHELL_UID; 3979 } 3980 3981 private void banConfigurationIfNecessary(int type, @Nullable String prefix, 3982 SettingsState settingsState) { 3983 // Banning should be performed only for Settings.Config and for non-shell reset calls 3984 if (!shouldBan(type)) { 3985 return; 3986 } 3987 if (prefix != null) { 3988 settingsState.banConfigurationLocked(prefix, getAllConfigFlags(prefix)); 3989 } else { 3990 Set<String> configPrefixes = settingsState.getAllConfigPrefixesLocked(); 3991 for (String configPrefix : configPrefixes) { 3992 settingsState.banConfigurationLocked(configPrefix, 3993 getAllConfigFlags(configPrefix)); 3994 } 3995 } 3996 } 3997 3998 private static File getSettingsFile(int key) { 3999 final int userId = getUserIdFromKey(key); 4000 final int type = getTypeFromKey(key); 4001 final File userSystemDirectory = Environment.getUserSystemDirectory(userId); 4002 return switch (type) { 4003 case SETTINGS_TYPE_CONFIG -> new File(userSystemDirectory, SETTINGS_FILE_CONFIG); 4004 case SETTINGS_TYPE_GLOBAL -> new File(userSystemDirectory, SETTINGS_FILE_GLOBAL); 4005 case SETTINGS_TYPE_SYSTEM -> new File(userSystemDirectory, SETTINGS_FILE_SYSTEM); 4006 case SETTINGS_TYPE_SECURE -> new File(userSystemDirectory, SETTINGS_FILE_SECURE); 4007 case SETTINGS_TYPE_SSAID -> new File(userSystemDirectory, SETTINGS_FILE_SSAID); 4008 default -> throw new IllegalArgumentException("Invalid settings key:" + key); 4009 }; 4010 } 4011 4012 private Uri getNotificationUriFor(int key, String name) { 4013 if (isConfigSettingsKey(key)) { 4014 return (name != null) ? Uri.withAppendedPath(Settings.Config.CONTENT_URI, name) 4015 : Settings.Config.CONTENT_URI; 4016 } else if (isGlobalSettingsKey(key)) { 4017 return (name != null) ? Uri.withAppendedPath(Settings.Global.CONTENT_URI, name) 4018 : Settings.Global.CONTENT_URI; 4019 } else if (isSecureSettingsKey(key)) { 4020 return (name != null) ? Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name) 4021 : Settings.Secure.CONTENT_URI; 4022 } else if (isSystemSettingsKey(key)) { 4023 return (name != null) ? Uri.withAppendedPath(Settings.System.CONTENT_URI, name) 4024 : Settings.System.CONTENT_URI; 4025 } else { 4026 throw new IllegalArgumentException("Invalid settings key:" + key); 4027 } 4028 } 4029 4030 private int getMaxBytesPerPackageForType(int type) { 4031 switch (type) { 4032 case SETTINGS_TYPE_CONFIG, SETTINGS_TYPE_GLOBAL, SETTINGS_TYPE_SECURE, 4033 SETTINGS_TYPE_SSAID -> { 4034 return SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED; 4035 } 4036 default -> { 4037 return SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED; 4038 } 4039 } 4040 } 4041 4042 @VisibleForTesting 4043 void injectSettings(SettingsState settings, int type, int userId) { 4044 int key = makeKey(type, userId); 4045 synchronized (mLock) { 4046 mSettingsStates.put(key, settings); 4047 } 4048 } 4049 4050 private final class MyHandler extends Handler { 4051 private static final int MSG_NOTIFY_URI_CHANGED = 1; 4052 private static final int MSG_NOTIFY_DATA_CHANGED = 2; 4053 4054 public MyHandler(Looper looper) { 4055 super(looper); 4056 } 4057 4058 @Override 4059 public void handleMessage(Message msg) { 4060 switch (msg.what) { 4061 case MSG_NOTIFY_URI_CHANGED -> { 4062 final int userId = msg.arg1; 4063 Uri uri = (Uri) msg.obj; 4064 try { 4065 getContext().getContentResolver().notifyChange(uri, null, true, userId); 4066 } catch (SecurityException e) { 4067 Slog.w(LOG_TAG, "Failed to notify for " + userId + ": " + uri, e); 4068 } 4069 if (DEBUG) { 4070 Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri); 4071 } 4072 } 4073 case MSG_NOTIFY_DATA_CHANGED -> { 4074 mBackupManager.dataChanged(); 4075 scheduleWriteFallbackFilesJob(); 4076 } 4077 } 4078 } 4079 } 4080 4081 @VisibleForTesting 4082 final class UpgradeController { 4083 private static final int SETTINGS_VERSION = 229; 4084 4085 private final int mUserId; 4086 4087 private final Injector mInjector; 4088 4089 public UpgradeController(int userId) { 4090 this(/* injector= */ null, userId); 4091 } 4092 4093 @VisibleForTesting 4094 UpgradeController(Injector injector, int userId) { 4095 mInjector = injector == null ? new Injector() : injector; 4096 mUserId = userId; 4097 } 4098 4099 @GuardedBy("mLock") 4100 public void upgradeIfNeededLocked() { 4101 // The version of all settings for a user is the same (all users have secure). 4102 SettingsState secureSettings = getSettingsLocked( 4103 SETTINGS_TYPE_SECURE, mUserId); 4104 4105 // Try an update from the current state. 4106 final int oldVersion = secureSettings.getVersionLocked(); 4107 final int newVersion = SETTINGS_VERSION; 4108 4109 // If up do date - done. 4110 if (oldVersion == newVersion) { 4111 return; 4112 } 4113 4114 // Try to upgrade. 4115 final int curVersion = onUpgradeLocked(mUserId, oldVersion, newVersion); 4116 4117 // If upgrade failed start from scratch and upgrade. 4118 if (curVersion != newVersion) { 4119 // Drop state we have for this user. 4120 removeUserStateLocked(mUserId, true); 4121 4122 // Recreate the database. 4123 DatabaseHelper dbHelper = new DatabaseHelper(getContext(), mUserId); 4124 SQLiteDatabase database = dbHelper.getWritableDatabase(); 4125 dbHelper.recreateDatabase(database, newVersion, curVersion, oldVersion); 4126 4127 // Migrate the settings for this user. 4128 migrateLegacySettingsForUserLocked(dbHelper, database, mUserId); 4129 4130 // Now upgrade should work fine. 4131 onUpgradeLocked(mUserId, oldVersion, newVersion); 4132 4133 // Make a note what happened, so we don't wonder why data was lost 4134 String reason = "Settings rebuilt! Current version: " 4135 + curVersion + " while expected: " + newVersion; 4136 getGlobalSettingsLocked().insertSettingLocked( 4137 Settings.Global.DATABASE_DOWNGRADE_REASON, 4138 reason, null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4139 } 4140 4141 // Set the global settings version if owner. 4142 if (mUserId == UserHandle.USER_SYSTEM) { 4143 SettingsState globalSettings = getSettingsLocked( 4144 SETTINGS_TYPE_GLOBAL, mUserId); 4145 globalSettings.setVersionLocked(newVersion); 4146 } 4147 4148 // Set the secure settings version. 4149 secureSettings.setVersionLocked(newVersion); 4150 4151 // Set the system settings version. 4152 SettingsState systemSettings = getSettingsLocked( 4153 SETTINGS_TYPE_SYSTEM, mUserId); 4154 systemSettings.setVersionLocked(newVersion); 4155 } 4156 4157 @GuardedBy("mLock") 4158 private SettingsState getGlobalSettingsLocked() { 4159 return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); 4160 } 4161 4162 @GuardedBy("mLock") 4163 private SettingsState getSecureSettingsLocked(int userId) { 4164 return getSettingsLocked(SETTINGS_TYPE_SECURE, userId); 4165 } 4166 4167 @GuardedBy("mLock") 4168 private SettingsState getSsaidSettingsLocked(int userId) { 4169 return getSettingsLocked(SETTINGS_TYPE_SSAID, userId); 4170 } 4171 4172 @GuardedBy("mLock") 4173 private SettingsState getSystemSettingsLocked(int userId) { 4174 return getSettingsLocked(SETTINGS_TYPE_SYSTEM, userId); 4175 } 4176 4177 /** 4178 * You must perform all necessary mutations to bring the settings 4179 * for this user from the old to the new version. When you add a new 4180 * upgrade step you *must* update SETTINGS_VERSION. 4181 * 4182 * All settings modifications should be made through 4183 * {@link SettingsState#insertSettingOverrideableByRestoreLocked(String, String, String, 4184 * boolean, String)} so that restore can override those values if needed. 4185 * 4186 * This is an example of moving a setting from secure to global. 4187 * 4188 * // v119: Example settings changes. 4189 * if (currentVersion == 118) { 4190 * if (userId == UserHandle.USER_OWNER) { 4191 * // Remove from the secure settings. 4192 * SettingsState secureSettings = getSecureSettingsLocked(userId); 4193 * String name = "example_setting_to_move"; 4194 * String value = secureSettings.getSetting(name); 4195 * secureSettings.deleteSetting(name); 4196 * 4197 * // Add to the global settings. 4198 * SettingsState globalSettings = getGlobalSettingsLocked(); 4199 * globalSettings.insertSetting(name, value, SettingsState.SYSTEM_PACKAGE_NAME); 4200 * } 4201 * 4202 * // Update the current version. 4203 * currentVersion = 119; 4204 * } 4205 */ 4206 @GuardedBy("mLock") 4207 private int onUpgradeLocked(int userId, int oldVersion, int newVersion) { 4208 if (DEBUG) { 4209 Slog.w(LOG_TAG, "Upgrading settings for user: " + userId + " from version: " 4210 + oldVersion + " to version: " + newVersion); 4211 } 4212 4213 int currentVersion = oldVersion; 4214 4215 // v119: Reset zen + ringer mode. 4216 if (currentVersion == 118) { 4217 if (userId == UserHandle.USER_SYSTEM) { 4218 final SettingsState globalSettings = getGlobalSettingsLocked(); 4219 globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE, 4220 Integer.toString(Settings.Global.ZEN_MODE_OFF), null, 4221 true, SettingsState.SYSTEM_PACKAGE_NAME); 4222 final int defaultRingerMode = 4223 getContext().getResources().getInteger(R.integer.def_ringer_mode); 4224 globalSettings.updateSettingLocked(Settings.Global.MODE_RINGER, 4225 Integer.toString(defaultRingerMode), null, 4226 true, SettingsState.SYSTEM_PACKAGE_NAME); 4227 } 4228 currentVersion = 119; 4229 } 4230 4231 // v120: Add double tap to wake setting. 4232 if (currentVersion == 119) { 4233 SettingsState secureSettings = getSecureSettingsLocked(userId); 4234 secureSettings.insertSettingOverrideableByRestoreLocked( 4235 Settings.Secure.DOUBLE_TAP_TO_WAKE, 4236 getContext().getResources().getBoolean( 4237 R.bool.def_double_tap_to_wake) ? "1" : "0", null, true, 4238 SettingsState.SYSTEM_PACKAGE_NAME); 4239 4240 currentVersion = 120; 4241 } 4242 4243 if (currentVersion == 120) { 4244 // Before 121, we used a different string encoding logic. We just bump the 4245 // version here; SettingsState knows how to handle pre-version 120 files. 4246 currentVersion = 121; 4247 } 4248 4249 if (currentVersion == 121) { 4250 // Version 122: allow OEMs to set a default payment component in resources. 4251 // Note that we only write the default if no default has been set; 4252 // if there is, we just leave the default at whatever it currently is. 4253 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4254 String defaultComponent = (getContext().getResources().getString( 4255 R.string.def_nfc_payment_component)); 4256 Setting currentSetting = secureSettings.getSettingLocked( 4257 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT); 4258 if (defaultComponent != null && !defaultComponent.isEmpty() && 4259 currentSetting.isNull()) { 4260 secureSettings.insertSettingOverrideableByRestoreLocked( 4261 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT, 4262 defaultComponent, null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4263 } 4264 currentVersion = 122; 4265 } 4266 4267 if (currentVersion == 122) { 4268 // Version 123: Adding a default value for the ability to add a user from 4269 // the lock screen. 4270 if (userId == UserHandle.USER_SYSTEM) { 4271 final SettingsState globalSettings = getGlobalSettingsLocked(); 4272 Setting currentSetting = globalSettings.getSettingLocked( 4273 Settings.Global.ADD_USERS_WHEN_LOCKED); 4274 if (currentSetting.isNull()) { 4275 globalSettings.insertSettingOverrideableByRestoreLocked( 4276 Settings.Global.ADD_USERS_WHEN_LOCKED, 4277 getContext().getResources().getBoolean( 4278 R.bool.def_add_users_from_lockscreen) ? "1" : "0", 4279 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4280 } 4281 } 4282 currentVersion = 123; 4283 } 4284 4285 if (currentVersion == 123) { 4286 final SettingsState globalSettings = getGlobalSettingsLocked(); 4287 String defaultDisabledProfiles = (getContext().getResources().getString( 4288 R.string.def_bluetooth_disabled_profiles)); 4289 globalSettings.insertSettingOverrideableByRestoreLocked( 4290 Settings.Global.BLUETOOTH_DISABLED_PROFILES, defaultDisabledProfiles, 4291 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4292 currentVersion = 124; 4293 } 4294 4295 if (currentVersion == 124) { 4296 // Version 124: allow OEMs to set a default value for whether IME should be 4297 // shown when a physical keyboard is connected. 4298 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4299 Setting currentSetting = secureSettings.getSettingLocked( 4300 Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD); 4301 if (currentSetting.isNull()) { 4302 secureSettings.insertSettingOverrideableByRestoreLocked( 4303 Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 4304 getContext().getResources().getBoolean( 4305 R.bool.def_show_ime_with_hard_keyboard) ? "1" : "0", 4306 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4307 } 4308 currentVersion = 125; 4309 } 4310 4311 if (currentVersion == 125) { 4312 // Version 125: Allow OEMs to set the default VR service. 4313 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4314 4315 Setting currentSetting = secureSettings.getSettingLocked( 4316 Settings.Secure.ENABLED_VR_LISTENERS); 4317 if (currentSetting.isNull()) { 4318 List<ComponentName> l = mSysConfigManager.getDefaultVrComponents(); 4319 4320 if (l != null && !l.isEmpty()) { 4321 StringBuilder b = new StringBuilder(); 4322 boolean start = true; 4323 for (ComponentName c : l) { 4324 if (!start) { 4325 b.append(':'); 4326 } 4327 b.append(c.flattenToString()); 4328 start = false; 4329 } 4330 secureSettings.insertSettingOverrideableByRestoreLocked( 4331 Settings.Secure.ENABLED_VR_LISTENERS, b.toString(), 4332 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4333 } 4334 4335 } 4336 currentVersion = 126; 4337 } 4338 4339 if (currentVersion == 126) { 4340 // Version 126: copy the primary values of LOCK_SCREEN_SHOW_NOTIFICATIONS and 4341 // LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS into managed profile. 4342 if (mUserManager.isManagedProfile(userId)) { 4343 final SettingsState systemSecureSettings = 4344 getSecureSettingsLocked(UserHandle.USER_SYSTEM); 4345 4346 final Setting showNotifications = systemSecureSettings.getSettingLocked( 4347 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); 4348 if (!showNotifications.isNull()) { 4349 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4350 secureSettings.insertSettingOverrideableByRestoreLocked( 4351 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 4352 showNotifications.getValue(), null, true, 4353 SettingsState.SYSTEM_PACKAGE_NAME); 4354 } 4355 4356 final Setting allowPrivate = systemSecureSettings.getSettingLocked( 4357 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); 4358 if (!allowPrivate.isNull()) { 4359 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4360 secureSettings.insertSettingOverrideableByRestoreLocked( 4361 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 4362 allowPrivate.getValue(), null, true, 4363 SettingsState.SYSTEM_PACKAGE_NAME); 4364 } 4365 } 4366 currentVersion = 127; 4367 } 4368 4369 if (currentVersion == 127) { 4370 // version 127 is no longer used. 4371 currentVersion = 128; 4372 } 4373 4374 if (currentVersion == 128) { 4375 // Version 128: Removed 4376 currentVersion = 129; 4377 } 4378 4379 if (currentVersion == 129) { 4380 // default longpress timeout changed from 500 to 400. If unchanged from the old 4381 // default, update to the new default. 4382 final SettingsState systemSecureSettings = 4383 getSecureSettingsLocked(userId); 4384 final String oldValue = systemSecureSettings.getSettingLocked( 4385 Settings.Secure.LONG_PRESS_TIMEOUT).getValue(); 4386 if (TextUtils.equals("500", oldValue)) { 4387 systemSecureSettings.insertSettingOverrideableByRestoreLocked( 4388 Settings.Secure.LONG_PRESS_TIMEOUT, 4389 String.valueOf(getContext().getResources().getInteger( 4390 R.integer.def_long_press_timeout_millis)), 4391 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4392 } 4393 currentVersion = 130; 4394 } 4395 4396 if (currentVersion == 130) { 4397 // Split Ambient settings 4398 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4399 boolean dozeExplicitlyDisabled = "0".equals(secureSettings. 4400 getSettingLocked(Settings.Secure.DOZE_ENABLED).getValue()); 4401 4402 if (dozeExplicitlyDisabled) { 4403 secureSettings.insertSettingOverrideableByRestoreLocked( 4404 Settings.Secure.DOZE_PICK_UP_GESTURE, "0", null, true, 4405 SettingsState.SYSTEM_PACKAGE_NAME); 4406 secureSettings.insertSettingOverrideableByRestoreLocked( 4407 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, "0", null, true, 4408 SettingsState.SYSTEM_PACKAGE_NAME); 4409 } 4410 currentVersion = 131; 4411 } 4412 4413 if (currentVersion == 131) { 4414 // Initialize new multi-press timeout to default value 4415 final SettingsState systemSecureSettings = getSecureSettingsLocked(userId); 4416 final String oldValue = systemSecureSettings.getSettingLocked( 4417 Settings.Secure.MULTI_PRESS_TIMEOUT).getValue(); 4418 if (TextUtils.equals(null, oldValue)) { 4419 systemSecureSettings.insertSettingOverrideableByRestoreLocked( 4420 Settings.Secure.MULTI_PRESS_TIMEOUT, 4421 String.valueOf(getContext().getResources().getInteger( 4422 R.integer.def_multi_press_timeout_millis)), 4423 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4424 } 4425 4426 currentVersion = 132; 4427 } 4428 4429 if (currentVersion == 132) { 4430 // Version 132: Allow managed profile to optionally use the parent's ringtones 4431 final SettingsState systemSecureSettings = getSecureSettingsLocked(userId); 4432 String defaultSyncParentSounds = (getContext().getResources() 4433 .getBoolean(R.bool.def_sync_parent_sounds) ? "1" : "0"); 4434 systemSecureSettings.insertSettingOverrideableByRestoreLocked( 4435 Settings.Secure.SYNC_PARENT_SOUNDS, defaultSyncParentSounds, 4436 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4437 currentVersion = 133; 4438 } 4439 4440 if (currentVersion == 133) { 4441 // Version 133: Add default end button behavior 4442 final SettingsState systemSettings = getSystemSettingsLocked(userId); 4443 if (systemSettings.getSettingLocked(Settings.System.END_BUTTON_BEHAVIOR) 4444 .isNull()) { 4445 String defaultEndButtonBehavior = Integer.toString(getContext() 4446 .getResources().getInteger(R.integer.def_end_button_behavior)); 4447 systemSettings.insertSettingOverrideableByRestoreLocked( 4448 Settings.System.END_BUTTON_BEHAVIOR, defaultEndButtonBehavior, null, 4449 true, SettingsState.SYSTEM_PACKAGE_NAME); 4450 } 4451 currentVersion = 134; 4452 } 4453 4454 if (currentVersion == 134) { 4455 // Remove setting that specifies if magnification values should be preserved. 4456 // This setting defaulted to true and never has a UI. 4457 getSecureSettingsLocked(userId).deleteSettingLocked( 4458 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE); 4459 currentVersion = 135; 4460 } 4461 4462 if (currentVersion == 135) { 4463 // Version 135 no longer used. 4464 currentVersion = 136; 4465 } 4466 4467 if (currentVersion == 136) { 4468 // Version 136: Store legacy SSAID for all apps currently installed on the 4469 // device as first step in migrating SSAID to be unique per application. 4470 4471 final boolean isUpgrade; 4472 try { 4473 isUpgrade = mPackageManager.isDeviceUpgrading(); 4474 } catch (RemoteException e) { 4475 throw new IllegalStateException("Package manager not available"); 4476 } 4477 // Only retain legacy ssaid if the device is performing an OTA. After wiping 4478 // user data or first boot on a new device should use new ssaid generation. 4479 if (isUpgrade) { 4480 // Retrieve the legacy ssaid from the secure settings table. 4481 final Setting legacySsaidSetting = getSettingLocked(SETTINGS_TYPE_SECURE, 4482 userId, Settings.Secure.ANDROID_ID); 4483 if (legacySsaidSetting == null || legacySsaidSetting.isNull() 4484 || legacySsaidSetting.getValue() == null) { 4485 throw new IllegalStateException("Legacy ssaid not accessible"); 4486 } 4487 final String legacySsaid = legacySsaidSetting.getValue(); 4488 4489 // Fill each uid with the legacy ssaid to be backwards compatible. 4490 final List<PackageInfo> packages; 4491 try { 4492 packages = mPackageManager.getInstalledPackages( 4493 PackageManager.MATCH_UNINSTALLED_PACKAGES, 4494 userId).getList(); 4495 } catch (RemoteException e) { 4496 throw new IllegalStateException("Package manager not available"); 4497 } 4498 4499 final SettingsState ssaidSettings = getSsaidSettingsLocked(userId); 4500 for (PackageInfo info : packages) { 4501 // Check if the UID already has an entry in the table. 4502 final String uid = Integer.toString(info.applicationInfo.uid); 4503 final Setting ssaid = ssaidSettings.getSettingLocked(uid); 4504 4505 if (ssaid.isNull() || ssaid.getValue() == null) { 4506 // Android Id doesn't exist for this package so create it. 4507 ssaidSettings.insertSettingOverrideableByRestoreLocked(uid, 4508 legacySsaid, null, true, info.packageName); 4509 if (DEBUG) { 4510 Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid); 4511 } 4512 } 4513 } 4514 } 4515 4516 currentVersion = 137; 4517 } 4518 if (currentVersion == 137) { 4519 // Version 138: Settings.Secure#INSTALL_NON_MARKET_APPS is deprecated and its 4520 // default value set to 1. The user can no longer change the value of this 4521 // setting through the UI. 4522 final SettingsState secureSetting = getSecureSettingsLocked(userId); 4523 if (!mUserManager.hasUserRestriction( 4524 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, UserHandle.of(userId)) 4525 && secureSetting.getSettingLocked( 4526 Settings.Secure.INSTALL_NON_MARKET_APPS).getValue().equals("0")) { 4527 4528 secureSetting.insertSettingOverrideableByRestoreLocked( 4529 Settings.Secure.INSTALL_NON_MARKET_APPS, "1", null, true, 4530 SettingsState.SYSTEM_PACKAGE_NAME); 4531 // For managed profiles with profile owners, DevicePolicyManagerService 4532 // may want to set the user restriction in this case 4533 secureSetting.insertSettingOverrideableByRestoreLocked( 4534 Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, "1", null, 4535 true, SettingsState.SYSTEM_PACKAGE_NAME); 4536 } 4537 currentVersion = 138; 4538 } 4539 4540 if (currentVersion == 138) { 4541 // Version 139: Removed. 4542 currentVersion = 139; 4543 } 4544 4545 if (currentVersion == 139) { 4546 // Version 140: Settings.Secure#ACCESSIBILITY_SPEAK_PASSWORD is deprecated and 4547 // the user can no longer change the value of this setting through the UI. 4548 // Force to true. 4549 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4550 secureSettings.updateSettingLocked(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 4551 "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4552 currentVersion = 140; 4553 } 4554 4555 if (currentVersion == 140) { 4556 // Version 141: Removed 4557 currentVersion = 141; 4558 } 4559 4560 if (currentVersion == 141) { 4561 // This implementation was incorrectly setting the current value of 4562 // settings changed by non-system packages as the default which default 4563 // is set by the system. We add a new upgrade step at the end to properly 4564 // handle this case which would also fix incorrect changes made by the 4565 // old implementation of this step. 4566 currentVersion = 142; 4567 } 4568 4569 if (currentVersion == 142) { 4570 // Version 143: Set a default value for Wi-Fi wakeup feature. 4571 if (userId == UserHandle.USER_SYSTEM) { 4572 final SettingsState globalSettings = getGlobalSettingsLocked(); 4573 Setting currentSetting = globalSettings.getSettingLocked( 4574 Settings.Global.WIFI_WAKEUP_ENABLED); 4575 if (currentSetting.isNull()) { 4576 globalSettings.insertSettingOverrideableByRestoreLocked( 4577 Settings.Global.WIFI_WAKEUP_ENABLED, 4578 getContext().getResources().getBoolean( 4579 R.bool.def_wifi_wakeup_enabled) ? "1" : "0", 4580 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4581 } 4582 } 4583 4584 currentVersion = 143; 4585 } 4586 4587 if (currentVersion == 143) { 4588 // Version 144: Set a default value for Autofill service. 4589 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4590 final Setting currentSetting = secureSettings 4591 .getSettingLocked(Settings.Secure.AUTOFILL_SERVICE); 4592 if (currentSetting.isNull()) { 4593 final String defaultValue = getContext().getResources().getString( 4594 com.android.internal.R.string.config_defaultAutofillService); 4595 if (defaultValue != null) { 4596 Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as Autofill Service " 4597 + "for user " + userId); 4598 secureSettings.insertSettingOverrideableByRestoreLocked( 4599 Settings.Secure.AUTOFILL_SERVICE, defaultValue, null, true, 4600 SettingsState.SYSTEM_PACKAGE_NAME); 4601 } 4602 } 4603 4604 currentVersion = 144; 4605 } 4606 4607 if (currentVersion == 144) { 4608 // Version 145: Removed 4609 currentVersion = 145; 4610 } 4611 4612 if (currentVersion == 145) { 4613 // Version 146: In step 142 we had a bug where incorrectly 4614 // some settings were considered system set and as a result 4615 // made the default and marked as the default being set by 4616 // the system. Here reevaluate the default and default system 4617 // set flags. This would both fix corruption by the old impl 4618 // of step 142 and also properly handle devices which never 4619 // run 142. 4620 if (userId == UserHandle.USER_SYSTEM) { 4621 SettingsState globalSettings = getGlobalSettingsLocked(); 4622 ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings, userId); 4623 globalSettings.persistSettingsLocked(); 4624 } 4625 4626 SettingsState secureSettings = getSecureSettingsLocked(mUserId); 4627 ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings, userId); 4628 secureSettings.persistSettingsLocked(); 4629 4630 SettingsState systemSettings = getSystemSettingsLocked(mUserId); 4631 ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings, userId); 4632 systemSettings.persistSettingsLocked(); 4633 4634 currentVersion = 146; 4635 } 4636 4637 if (currentVersion == 146) { 4638 // Version 147: Removed. (This version previously allowed showing the 4639 // "wifi_wakeup_available" setting). 4640 // The setting that was added here is deleted in 153. 4641 currentVersion = 147; 4642 } 4643 4644 if (currentVersion == 147) { 4645 // Version 148: Set the default value for DEFAULT_RESTRICT_BACKGROUND_DATA. 4646 if (userId == UserHandle.USER_SYSTEM) { 4647 final SettingsState globalSettings = getGlobalSettingsLocked(); 4648 final Setting currentSetting = globalSettings.getSettingLocked( 4649 Global.DEFAULT_RESTRICT_BACKGROUND_DATA); 4650 if (currentSetting.isNull()) { 4651 globalSettings.insertSettingOverrideableByRestoreLocked( 4652 Global.DEFAULT_RESTRICT_BACKGROUND_DATA, 4653 getContext().getResources().getBoolean( 4654 R.bool.def_restrict_background_data) ? "1" : "0", 4655 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4656 } 4657 } 4658 currentVersion = 148; 4659 } 4660 4661 if (currentVersion == 148) { 4662 // Version 149: Set the default value for BACKUP_MANAGER_CONSTANTS. 4663 final SettingsState systemSecureSettings = getSecureSettingsLocked(userId); 4664 final String oldValue = systemSecureSettings.getSettingLocked( 4665 Settings.Secure.BACKUP_MANAGER_CONSTANTS).getValue(); 4666 if (TextUtils.equals(null, oldValue)) { 4667 final String defaultValue = getContext().getResources().getString( 4668 R.string.def_backup_manager_constants); 4669 if (!TextUtils.isEmpty(defaultValue)) { 4670 systemSecureSettings.insertSettingOverrideableByRestoreLocked( 4671 Settings.Secure.BACKUP_MANAGER_CONSTANTS, defaultValue, null, 4672 true, SettingsState.SYSTEM_PACKAGE_NAME); 4673 } 4674 } 4675 currentVersion = 149; 4676 } 4677 4678 if (currentVersion == 149) { 4679 // Version 150: Set a default value for mobile data always on 4680 final SettingsState globalSettings = getGlobalSettingsLocked(); 4681 final Setting currentSetting = globalSettings.getSettingLocked( 4682 Settings.Global.MOBILE_DATA_ALWAYS_ON); 4683 if (currentSetting.isNull()) { 4684 globalSettings.insertSettingOverrideableByRestoreLocked( 4685 Settings.Global.MOBILE_DATA_ALWAYS_ON, 4686 getContext().getResources().getBoolean( 4687 R.bool.def_mobile_data_always_on) ? "1" : "0", 4688 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4689 } 4690 4691 currentVersion = 150; 4692 } 4693 4694 if (currentVersion == 150) { 4695 // Version 151: Removed. 4696 currentVersion = 151; 4697 } 4698 4699 if (currentVersion == 151) { 4700 // Version 152: Removed. (This version made the setting for wifi_wakeup enabled 4701 // by default but it is now no longer configurable). 4702 // The setting updated here is deleted in 153. 4703 currentVersion = 152; 4704 } 4705 4706 if (currentVersion == 152) { 4707 getGlobalSettingsLocked().deleteSettingLocked("wifi_wakeup_available"); 4708 currentVersion = 153; 4709 } 4710 4711 if (currentVersion == 153) { 4712 // Version 154: Read notification badge configuration from config. 4713 // If user has already set the value, don't do anything. 4714 final SettingsState systemSecureSettings = getSecureSettingsLocked(userId); 4715 final Setting showNotificationBadges = systemSecureSettings.getSettingLocked( 4716 Settings.Secure.NOTIFICATION_BADGING); 4717 if (showNotificationBadges.isNull()) { 4718 final boolean defaultValue = getContext().getResources().getBoolean( 4719 com.android.internal.R.bool.config_notificationBadging); 4720 systemSecureSettings.insertSettingOverrideableByRestoreLocked( 4721 Secure.NOTIFICATION_BADGING, 4722 defaultValue ? "1" : "0", 4723 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4724 } 4725 currentVersion = 154; 4726 } 4727 4728 if (currentVersion == 154) { 4729 // Version 155: Set the default value for BACKUP_LOCAL_TRANSPORT_PARAMETERS. 4730 final SettingsState systemSecureSettings = getSecureSettingsLocked(userId); 4731 final String oldValue = systemSecureSettings.getSettingLocked( 4732 Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS).getValue(); 4733 if (TextUtils.equals(null, oldValue)) { 4734 final String defaultValue = getContext().getResources().getString( 4735 R.string.def_backup_local_transport_parameters); 4736 if (!TextUtils.isEmpty(defaultValue)) { 4737 systemSecureSettings.insertSettingOverrideableByRestoreLocked( 4738 Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS, defaultValue, 4739 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4740 } 4741 4742 } 4743 currentVersion = 155; 4744 } 4745 4746 if (currentVersion == 155) { 4747 // Version 156: migrated to version 184 4748 currentVersion = 156; 4749 } 4750 4751 if (currentVersion == 156) { 4752 // Version 157: Set a default value for zen duration, 4753 // in version 169, zen duration is moved to secure settings 4754 final SettingsState globalSettings = getGlobalSettingsLocked(); 4755 final Setting currentSetting = globalSettings.getSettingLocked( 4756 Global.ZEN_DURATION); 4757 if (currentSetting.isNull()) { 4758 String defaultZenDuration = Integer.toString(getContext() 4759 .getResources().getInteger(R.integer.def_zen_duration)); 4760 globalSettings.insertSettingOverrideableByRestoreLocked( 4761 Global.ZEN_DURATION, defaultZenDuration, 4762 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4763 } 4764 currentVersion = 157; 4765 } 4766 4767 if (currentVersion == 157) { 4768 // Version 158: Set default value for BACKUP_AGENT_TIMEOUT_PARAMETERS. 4769 final SettingsState globalSettings = getGlobalSettingsLocked(); 4770 final String oldValue = globalSettings.getSettingLocked( 4771 Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS).getValue(); 4772 if (TextUtils.equals(null, oldValue)) { 4773 final String defaultValue = getContext().getResources().getString( 4774 R.string.def_backup_agent_timeout_parameters); 4775 if (!TextUtils.isEmpty(defaultValue)) { 4776 globalSettings.insertSettingOverrideableByRestoreLocked( 4777 Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS, defaultValue, 4778 null, true, 4779 SettingsState.SYSTEM_PACKAGE_NAME); 4780 } 4781 } 4782 currentVersion = 158; 4783 } 4784 4785 if (currentVersion == 158) { 4786 // Remove setting that specifies wifi bgscan throttling params 4787 getGlobalSettingsLocked().deleteSettingLocked( 4788 "wifi_scan_background_throttle_interval_ms"); 4789 getGlobalSettingsLocked().deleteSettingLocked( 4790 "wifi_scan_background_throttle_package_whitelist"); 4791 currentVersion = 159; 4792 } 4793 4794 if (currentVersion == 159) { 4795 // Version 160: Hiding notifications from the lockscreen is only available as 4796 // primary user option, profiles can only make them redacted. If a profile was 4797 // configured to not show lockscreen notifications, ensure that at the very 4798 // least these will be come hidden. 4799 if (mUserManager.isManagedProfile(userId)) { 4800 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4801 Setting showNotifications = secureSettings.getSettingLocked( 4802 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); 4803 // The default value is "1", check if user has turned it off. 4804 if ("0".equals(showNotifications.getValue())) { 4805 secureSettings.insertSettingOverrideableByRestoreLocked( 4806 Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, "0", 4807 null /* tag */, false /* makeDefault */, 4808 SettingsState.SYSTEM_PACKAGE_NAME); 4809 } 4810 // The setting is no longer valid for managed profiles, it should be 4811 // treated as if it was set to "1". 4812 secureSettings.deleteSettingLocked(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); 4813 } 4814 currentVersion = 160; 4815 } 4816 4817 if (currentVersion == 160) { 4818 // Version 161: Set the default value for 4819 // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY and 4820 // SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT 4821 final SettingsState globalSettings = getGlobalSettingsLocked(); 4822 4823 String oldValue = globalSettings.getSettingLocked( 4824 Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY).getValue(); 4825 if (TextUtils.equals(null, oldValue)) { 4826 globalSettings.insertSettingOverrideableByRestoreLocked( 4827 Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY, 4828 Integer.toString(getContext().getResources().getInteger( 4829 R.integer.def_max_sound_trigger_detection_service_ops_per_day)), 4830 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4831 } 4832 4833 oldValue = globalSettings.getSettingLocked( 4834 Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT).getValue(); 4835 if (TextUtils.equals(null, oldValue)) { 4836 globalSettings.insertSettingOverrideableByRestoreLocked( 4837 Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT, 4838 Integer.toString(getContext().getResources().getInteger( 4839 R.integer.def_sound_trigger_detection_service_op_timeout)), 4840 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4841 } 4842 currentVersion = 161; 4843 } 4844 4845 if (currentVersion == 161) { 4846 // Version 161: Add a gesture for silencing phones 4847 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4848 final Setting currentSetting = secureSettings.getSettingLocked( 4849 Secure.VOLUME_HUSH_GESTURE); 4850 if (currentSetting.isNull()) { 4851 secureSettings.insertSettingOverrideableByRestoreLocked( 4852 Secure.VOLUME_HUSH_GESTURE, 4853 Integer.toString(Secure.VOLUME_HUSH_VIBRATE), 4854 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4855 } 4856 4857 currentVersion = 162; 4858 } 4859 4860 if (currentVersion == 162) { 4861 // Version 162: REMOVED: Add a gesture for silencing phones 4862 currentVersion = 163; 4863 } 4864 4865 if (currentVersion == 163) { 4866 // Version 163: Update default value of 4867 // MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY from old to new default 4868 final SettingsState settings = getGlobalSettingsLocked(); 4869 final Setting currentSetting = settings.getSettingLocked( 4870 Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY); 4871 if (currentSetting.isDefaultFromSystem()) { 4872 settings.insertSettingOverrideableByRestoreLocked( 4873 Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY, 4874 Integer.toString(getContext().getResources().getInteger( 4875 R.integer 4876 .def_max_sound_trigger_detection_service_ops_per_day)), 4877 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4878 } 4879 4880 currentVersion = 164; 4881 } 4882 4883 if (currentVersion == 164) { 4884 // Version 164: REMOVED: show zen upgrade notification 4885 currentVersion = 165; 4886 } 4887 4888 if (currentVersion == 165) { 4889 // Version 165: MOVED: Show zen settings suggestion and zen updated settings 4890 // moved to secure settings and are set in version 169 4891 currentVersion = 166; 4892 } 4893 4894 if (currentVersion == 166) { 4895 // Version 166: add default values for hush gesture used and manual ringer 4896 // toggle 4897 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4898 Setting currentHushUsedSetting = secureSettings.getSettingLocked( 4899 Secure.HUSH_GESTURE_USED); 4900 if (currentHushUsedSetting.isNull()) { 4901 secureSettings.insertSettingOverrideableByRestoreLocked( 4902 Settings.Secure.HUSH_GESTURE_USED, "0", null, true, 4903 SettingsState.SYSTEM_PACKAGE_NAME); 4904 } 4905 4906 Setting currentRingerToggleCountSetting = secureSettings.getSettingLocked( 4907 Secure.MANUAL_RINGER_TOGGLE_COUNT); 4908 if (currentRingerToggleCountSetting.isNull()) { 4909 secureSettings.insertSettingOverrideableByRestoreLocked( 4910 Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, "0", null, true, 4911 SettingsState.SYSTEM_PACKAGE_NAME); 4912 } 4913 currentVersion = 167; 4914 } 4915 4916 if (currentVersion == 167) { 4917 // Version 167: MOVED - Settings.Global.CHARGING_VIBRATION_ENABLED moved to 4918 // Settings.Secure.CHARGING_VIBRATION_ENABLED, set in version 170 4919 currentVersion = 168; 4920 } 4921 4922 if (currentVersion == 168) { 4923 // Version 168: by default, vibrate for phone calls 4924 final SettingsState systemSettings = getSystemSettingsLocked(userId); 4925 final Setting currentSetting = systemSettings.getSettingLocked( 4926 Settings.System.VIBRATE_WHEN_RINGING); 4927 if (currentSetting.isNull()) { 4928 systemSettings.insertSettingOverrideableByRestoreLocked( 4929 Settings.System.VIBRATE_WHEN_RINGING, 4930 getContext().getResources().getBoolean( 4931 R.bool.def_vibrate_when_ringing) ? "1" : "0", 4932 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 4933 } 4934 currentVersion = 169; 4935 } 4936 4937 if (currentVersion == 169) { 4938 // Version 169: Set the default value for Secure Settings ZEN_DURATION. 4939 // Also used to update SHOW_ZEN_SETTINGS_SUGGESTION, ZEN_SETTINGS_UPDATE and 4940 // ZEN_SETTINGS_SUGGESTION_VIEWED, but those properties are gone now. 4941 4942 final SettingsState globalSettings = getGlobalSettingsLocked(); 4943 final Setting globalZenDuration = globalSettings.getSettingLocked( 4944 Global.ZEN_DURATION); 4945 4946 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4947 final Setting secureZenDuration = secureSettings.getSettingLocked( 4948 Secure.ZEN_DURATION); 4949 4950 // ZEN_DURATION 4951 if (!globalZenDuration.isNull()) { 4952 secureSettings.insertSettingOverrideableByRestoreLocked( 4953 Secure.ZEN_DURATION, globalZenDuration.getValue(), null, false, 4954 SettingsState.SYSTEM_PACKAGE_NAME); 4955 4956 // set global zen duration setting to null since it's deprecated 4957 globalSettings.insertSettingOverrideableByRestoreLocked( 4958 Global.ZEN_DURATION, null, null, true, 4959 SettingsState.SYSTEM_PACKAGE_NAME); 4960 } else if (secureZenDuration.isNull()) { 4961 String defaultZenDuration = Integer.toString(getContext() 4962 .getResources().getInteger(R.integer.def_zen_duration)); 4963 secureSettings.insertSettingOverrideableByRestoreLocked( 4964 Secure.ZEN_DURATION, defaultZenDuration, null, true, 4965 SettingsState.SYSTEM_PACKAGE_NAME); 4966 } 4967 4968 currentVersion = 170; 4969 } 4970 4971 if (currentVersion == 170) { 4972 // Version 170: Set the default value for Secure Settings: 4973 // CHARGING_SOUNDS_ENABLED and CHARGING_VIBRATION_ENABLED 4974 4975 final SettingsState globalSettings = getGlobalSettingsLocked(); 4976 final SettingsState secureSettings = getSecureSettingsLocked(userId); 4977 4978 // CHARGING_SOUNDS_ENABLED 4979 final Setting globalChargingSoundEnabled = globalSettings.getSettingLocked( 4980 Global.CHARGING_SOUNDS_ENABLED); 4981 final Setting secureChargingSoundsEnabled = secureSettings.getSettingLocked( 4982 Secure.CHARGING_SOUNDS_ENABLED); 4983 4984 if (!globalChargingSoundEnabled.isNull()) { 4985 if (secureChargingSoundsEnabled.isNull()) { 4986 secureSettings.insertSettingOverrideableByRestoreLocked( 4987 Secure.CHARGING_SOUNDS_ENABLED, 4988 globalChargingSoundEnabled.getValue(), null, false, 4989 SettingsState.SYSTEM_PACKAGE_NAME); 4990 } 4991 4992 // set global charging_sounds_enabled setting to null since it's deprecated 4993 globalSettings.insertSettingOverrideableByRestoreLocked( 4994 Global.CHARGING_SOUNDS_ENABLED, null, null, true, 4995 SettingsState.SYSTEM_PACKAGE_NAME); 4996 } else if (secureChargingSoundsEnabled.isNull()) { 4997 String defChargingSoundsEnabled = getContext().getResources() 4998 .getBoolean(R.bool.def_charging_sounds_enabled) ? "1" : "0"; 4999 secureSettings.insertSettingOverrideableByRestoreLocked( 5000 Secure.CHARGING_SOUNDS_ENABLED, defChargingSoundsEnabled, null, 5001 true, SettingsState.SYSTEM_PACKAGE_NAME); 5002 } 5003 5004 // CHARGING_VIBRATION_ENABLED 5005 final Setting secureChargingVibrationEnabled = secureSettings.getSettingLocked( 5006 Secure.CHARGING_VIBRATION_ENABLED); 5007 5008 if (secureChargingVibrationEnabled.isNull()) { 5009 String defChargingVibrationEnabled = getContext().getResources() 5010 .getBoolean(R.bool.def_charging_vibration_enabled) ? "1" : "0"; 5011 secureSettings.insertSettingOverrideableByRestoreLocked( 5012 Secure.CHARGING_VIBRATION_ENABLED, defChargingVibrationEnabled, 5013 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5014 } 5015 5016 currentVersion = 171; 5017 } 5018 5019 if (currentVersion == 171) { 5020 // Version 171: by default, add STREAM_VOICE_CALL to list of streams that can 5021 // be muted. 5022 final SettingsState systemSettings = getSystemSettingsLocked(userId); 5023 final Setting currentSetting = systemSettings.getSettingLocked( 5024 Settings.System.MUTE_STREAMS_AFFECTED); 5025 if (!currentSetting.isNull()) { 5026 try { 5027 int currentSettingIntegerValue = Integer.parseInt( 5028 currentSetting.getValue()); 5029 if ((currentSettingIntegerValue 5030 & (1 << AudioManager.STREAM_VOICE_CALL)) == 0) { 5031 systemSettings.insertSettingOverrideableByRestoreLocked( 5032 Settings.System.MUTE_STREAMS_AFFECTED, 5033 Integer.toString( 5034 currentSettingIntegerValue 5035 | (1 << AudioManager.STREAM_VOICE_CALL)), 5036 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5037 } 5038 } catch (NumberFormatException e) { 5039 // remove the setting in case it is not a valid integer 5040 Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED" 5041 + "setting, removing setting", e); 5042 systemSettings.deleteSettingLocked( 5043 Settings.System.MUTE_STREAMS_AFFECTED); 5044 } 5045 5046 } 5047 currentVersion = 172; 5048 } 5049 5050 if (currentVersion == 172) { 5051 // Version 172: Set the default value for Secure Settings: LOCATION_MODE 5052 5053 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5054 5055 final Setting locationMode = secureSettings.getSettingLocked( 5056 Secure.LOCATION_MODE); 5057 5058 if (locationMode.isNull()) { 5059 final Setting locationProvidersAllowed = secureSettings.getSettingLocked( 5060 Secure.LOCATION_PROVIDERS_ALLOWED); 5061 5062 final int defLocationMode; 5063 if (locationProvidersAllowed.isNull()) { 5064 defLocationMode = getContext().getResources().getInteger( 5065 R.integer.def_location_mode); 5066 } else { 5067 defLocationMode = 5068 !TextUtils.isEmpty(locationProvidersAllowed.getValue()) 5069 ? Secure.LOCATION_MODE_ON 5070 : Secure.LOCATION_MODE_OFF; 5071 } 5072 secureSettings.insertSettingOverrideableByRestoreLocked( 5073 Secure.LOCATION_MODE, Integer.toString(defLocationMode), 5074 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5075 } 5076 5077 currentVersion = 173; 5078 } 5079 5080 if (currentVersion == 173) { 5081 // Version 173: Set the default value for Secure Settings: NOTIFICATION_BUBBLES 5082 // Removed. Moved NOTIFICATION_BUBBLES to Global Settings. 5083 currentVersion = 174; 5084 } 5085 5086 if (currentVersion == 174) { 5087 // Version 174: Set the default value for Global Settings: APPLY_RAMPING_RINGER 5088 // Removed. Moved APPLY_RAMPING_RINGER to System Settings, set in version 206. 5089 5090 currentVersion = 175; 5091 } 5092 5093 if (currentVersion == 175) { 5094 // Version 175: Set the default value for System Settings: 5095 // RING_VIBRATION_INTENSITY. If the notification vibration intensity has been 5096 // set and ring vibration intensity hasn't, the ring vibration intensity should 5097 // followed notification vibration intensity. 5098 5099 final SettingsState systemSettings = getSystemSettingsLocked(userId); 5100 5101 Setting notificationVibrationIntensity = systemSettings.getSettingLocked( 5102 Settings.System.NOTIFICATION_VIBRATION_INTENSITY); 5103 5104 Setting ringVibrationIntensity = systemSettings.getSettingLocked( 5105 Settings.System.RING_VIBRATION_INTENSITY); 5106 5107 if (!notificationVibrationIntensity.isNull() 5108 && ringVibrationIntensity.isNull()) { 5109 systemSettings.insertSettingOverrideableByRestoreLocked( 5110 Settings.System.RING_VIBRATION_INTENSITY, 5111 notificationVibrationIntensity.getValue(), 5112 null , true, SettingsState.SYSTEM_PACKAGE_NAME); 5113 } 5114 5115 currentVersion = 176; 5116 } 5117 5118 if (currentVersion == 176) { 5119 // Version 176: Migrate the existing swipe up setting into the resource overlay 5120 // for the navigation bar interaction mode. We do so only if the 5121 // setting is set. 5122 5123 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5124 final Setting swipeUpSetting = secureSettings.getSettingLocked( 5125 "swipe_up_to_switch_apps_enabled"); 5126 if (swipeUpSetting != null && !swipeUpSetting.isNull() 5127 && swipeUpSetting.getValue().equals("1")) { 5128 final IOverlayManager overlayManager = IOverlayManager.Stub.asInterface( 5129 ServiceManager.getService(Context.OVERLAY_SERVICE)); 5130 try { 5131 overlayManager.setEnabledExclusiveInCategory( 5132 NAV_BAR_MODE_2BUTTON_OVERLAY, UserHandle.USER_CURRENT); 5133 } catch (SecurityException | IllegalStateException | RemoteException e) { 5134 throw new IllegalStateException( 5135 "Failed to set nav bar interaction mode overlay"); 5136 } 5137 } 5138 5139 currentVersion = 177; 5140 } 5141 5142 if (currentVersion == 177) { 5143 // Version 177: Set the default value for Secure Settings: AWARE_ENABLED 5144 5145 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5146 5147 final Setting awareEnabled = secureSettings.getSettingLocked( 5148 Secure.AWARE_ENABLED); 5149 5150 if (awareEnabled.isNull()) { 5151 final boolean defAwareEnabled = getContext().getResources().getBoolean( 5152 R.bool.def_aware_enabled); 5153 secureSettings.insertSettingOverrideableByRestoreLocked( 5154 Secure.AWARE_ENABLED, defAwareEnabled ? "1" : "0", 5155 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5156 } 5157 5158 currentVersion = 178; 5159 } 5160 5161 if (currentVersion == 178) { 5162 // Version 178: Set the default value for Secure Settings: 5163 // SKIP_GESTURE & SILENCE_GESTURE 5164 5165 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5166 5167 final Setting skipGesture = secureSettings.getSettingLocked( 5168 Secure.SKIP_GESTURE); 5169 5170 if (skipGesture.isNull()) { 5171 final boolean defSkipGesture = getContext().getResources().getBoolean( 5172 R.bool.def_skip_gesture); 5173 secureSettings.insertSettingOverrideableByRestoreLocked( 5174 Secure.SKIP_GESTURE, defSkipGesture ? "1" : "0", 5175 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5176 } 5177 5178 final Setting silenceGesture = secureSettings.getSettingLocked( 5179 Secure.SILENCE_GESTURE); 5180 5181 if (silenceGesture.isNull()) { 5182 final boolean defSilenceGesture = getContext().getResources().getBoolean( 5183 R.bool.def_silence_gesture); 5184 secureSettings.insertSettingOverrideableByRestoreLocked( 5185 Secure.SILENCE_GESTURE, defSilenceGesture ? "1" : "0", 5186 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5187 } 5188 5189 currentVersion = 179; 5190 } 5191 5192 if (currentVersion == 179) { 5193 // Version 178: Reset the default for Secure Settings: NOTIFICATION_BUBBLES 5194 // This is originally set in version 173, however, the default value changed 5195 // so this step is to ensure the value is updated to the correct default. 5196 5197 // Removed. Moved NOTIFICATION_BUBBLES to Global Settings. 5198 currentVersion = 180; 5199 } 5200 5201 if (currentVersion == 180) { 5202 // Version 180: Set the default value for Secure Settings: AWARE_LOCK_ENABLED 5203 5204 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5205 5206 final Setting awareLockEnabled = secureSettings.getSettingLocked( 5207 Secure.AWARE_LOCK_ENABLED); 5208 5209 if (awareLockEnabled.isNull()) { 5210 final boolean defAwareLockEnabled = getContext().getResources().getBoolean( 5211 R.bool.def_aware_lock_enabled); 5212 secureSettings.insertSettingOverrideableByRestoreLocked( 5213 Secure.AWARE_LOCK_ENABLED, defAwareLockEnabled ? "1" : "0", 5214 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5215 } 5216 5217 currentVersion = 181; 5218 } 5219 5220 if (currentVersion == 181) { 5221 // Version cd : by default, add STREAM_BLUETOOTH_SCO to list of streams that can 5222 // be muted. 5223 final SettingsState systemSettings = getSystemSettingsLocked(userId); 5224 final Setting currentSetting = systemSettings.getSettingLocked( 5225 Settings.System.MUTE_STREAMS_AFFECTED); 5226 if (!currentSetting.isNull()) { 5227 try { 5228 int currentSettingIntegerValue = Integer.parseInt( 5229 currentSetting.getValue()); 5230 if ((currentSettingIntegerValue 5231 & (1 << AudioManager.STREAM_BLUETOOTH_SCO)) == 0) { 5232 systemSettings.insertSettingOverrideableByRestoreLocked( 5233 Settings.System.MUTE_STREAMS_AFFECTED, 5234 Integer.toString( 5235 currentSettingIntegerValue 5236 | (1 << AudioManager.STREAM_BLUETOOTH_SCO)), 5237 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5238 } 5239 } catch (NumberFormatException e) { 5240 // remove the setting in case it is not a valid integer 5241 Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED" 5242 + "setting, removing setting", e); 5243 systemSettings.deleteSettingLocked( 5244 Settings.System.MUTE_STREAMS_AFFECTED); 5245 } 5246 5247 } 5248 currentVersion = 182; 5249 } 5250 5251 if (currentVersion == 182) { 5252 // Remove secure bubble settings; it's in global now. 5253 getSecureSettingsLocked(userId).deleteSettingLocked("notification_bubbles"); 5254 5255 // Removed. Updated NOTIFICATION_BUBBLES to be true by default, see 184. 5256 currentVersion = 183; 5257 } 5258 5259 if (currentVersion == 183) { 5260 // Version 183: Set default values for WIRELESS_CHARGING_STARTED_SOUND 5261 // and CHARGING_STARTED_SOUND 5262 final SettingsState globalSettings = getGlobalSettingsLocked(); 5263 5264 final String oldValueWireless = globalSettings.getSettingLocked( 5265 Global.WIRELESS_CHARGING_STARTED_SOUND).getValue(); 5266 final String oldValueWired = globalSettings.getSettingLocked( 5267 Global.CHARGING_STARTED_SOUND).getValue(); 5268 5269 final String defaultValueWireless = getContext().getResources().getString( 5270 R.string.def_wireless_charging_started_sound); 5271 final String defaultValueWired = getContext().getResources().getString( 5272 R.string.def_charging_started_sound); 5273 5274 // wireless charging sound 5275 if (oldValueWireless == null 5276 || TextUtils.equals(oldValueWireless, defaultValueWired)) { 5277 if (!TextUtils.isEmpty(defaultValueWireless)) { 5278 globalSettings.insertSettingOverrideableByRestoreLocked( 5279 Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWireless, 5280 null /* tag */, true /* makeDefault */, 5281 SettingsState.SYSTEM_PACKAGE_NAME); 5282 } else if (!TextUtils.isEmpty(defaultValueWired)) { 5283 // if the wireless sound is empty, use the wired charging sound 5284 globalSettings.insertSettingOverrideableByRestoreLocked( 5285 Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWired, 5286 null /* tag */, true /* makeDefault */, 5287 SettingsState.SYSTEM_PACKAGE_NAME); 5288 } 5289 } 5290 5291 // wired charging sound 5292 if (oldValueWired == null && !TextUtils.isEmpty(defaultValueWired)) { 5293 globalSettings.insertSettingOverrideableByRestoreLocked( 5294 Global.CHARGING_STARTED_SOUND, defaultValueWired, 5295 null /* tag */, true /* makeDefault */, 5296 SettingsState.SYSTEM_PACKAGE_NAME); 5297 } 5298 currentVersion = 184; 5299 } 5300 5301 if (currentVersion == 184) { 5302 // Version 184: Reset the default for Global Settings: NOTIFICATION_BUBBLES 5303 // This is originally set in version 182, however, the default value changed 5304 // so this step is to ensure the value is updated to the correct default. 5305 5306 // Removed. Bubbles moved to secure settings. See version 197. 5307 currentVersion = 185; 5308 } 5309 5310 if (currentVersion == 185) { 5311 // Deprecate ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, and migrate it 5312 // to ACCESSIBILITY_BUTTON_TARGETS. 5313 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5314 final Setting magnifyNavbarEnabled = secureSettings.getSettingLocked( 5315 Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED); 5316 if ("1".equals(magnifyNavbarEnabled.getValue())) { 5317 secureSettings.insertSettingLocked( 5318 Secure.ACCESSIBILITY_BUTTON_TARGETS, 5319 ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER, 5320 null /* tag */, false /* makeDefault */, 5321 SettingsState.SYSTEM_PACKAGE_NAME); 5322 } 5323 secureSettings.deleteSettingLocked( 5324 Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED); 5325 currentVersion = 186; 5326 } 5327 5328 if (currentVersion == 186) { 5329 // Remove unused wifi settings 5330 getGlobalSettingsLocked().deleteSettingLocked( 5331 "wifi_rtt_background_exec_gap_ms"); 5332 getGlobalSettingsLocked().deleteSettingLocked( 5333 "network_recommendation_request_timeout_ms"); 5334 getGlobalSettingsLocked().deleteSettingLocked( 5335 "wifi_suspend_optimizations_enabled"); 5336 getGlobalSettingsLocked().deleteSettingLocked( 5337 "wifi_is_unusable_event_metrics_enabled"); 5338 getGlobalSettingsLocked().deleteSettingLocked( 5339 "wifi_data_stall_min_tx_bad"); 5340 getGlobalSettingsLocked().deleteSettingLocked( 5341 "wifi_data_stall_min_tx_success_without_rx"); 5342 getGlobalSettingsLocked().deleteSettingLocked( 5343 "wifi_link_speed_metrics_enabled"); 5344 getGlobalSettingsLocked().deleteSettingLocked( 5345 "wifi_pno_frequency_culling_enabled"); 5346 getGlobalSettingsLocked().deleteSettingLocked( 5347 "wifi_pno_recency_sorting_enabled"); 5348 getGlobalSettingsLocked().deleteSettingLocked( 5349 "wifi_link_probing_enabled"); 5350 getGlobalSettingsLocked().deleteSettingLocked( 5351 "wifi_saved_state"); 5352 currentVersion = 187; 5353 } 5354 5355 if (currentVersion == 187) { 5356 // Migrate adaptive sleep setting from System to Secure. 5357 if (userId == UserHandle.USER_OWNER) { 5358 // Remove from the system settings. 5359 SettingsState systemSettings = getSystemSettingsLocked(userId); 5360 String name = Settings.System.ADAPTIVE_SLEEP; 5361 Setting setting = systemSettings.getSettingLocked(name); 5362 systemSettings.deleteSettingLocked(name); 5363 5364 // Add to the secure settings. 5365 SettingsState secureSettings = getSecureSettingsLocked(userId); 5366 secureSettings.insertSettingLocked(name, setting.getValue(), null /* tag */, 5367 false /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); 5368 } 5369 currentVersion = 188; 5370 } 5371 5372 if (currentVersion == 188) { 5373 // Deprecate ACCESSIBILITY_SHORTCUT_ENABLED, and migrate it 5374 // to ACCESSIBILITY_SHORTCUT_TARGET_SERVICE. 5375 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5376 final Setting shortcutEnabled = secureSettings.getSettingLocked( 5377 "accessibility_shortcut_enabled"); 5378 if ("0".equals(shortcutEnabled.getValue())) { 5379 // Clear shortcut key targets list setting. 5380 secureSettings.insertSettingLocked( 5381 Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, 5382 "", null /* tag */, false /* makeDefault */, 5383 SettingsState.SYSTEM_PACKAGE_NAME); 5384 } 5385 secureSettings.deleteSettingLocked("accessibility_shortcut_enabled"); 5386 currentVersion = 189; 5387 } 5388 5389 if (currentVersion == 189) { 5390 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5391 final Setting showNotifications = secureSettings.getSettingLocked( 5392 Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); 5393 final Setting allowPrivateNotifications = secureSettings.getSettingLocked( 5394 Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); 5395 if ("1".equals(showNotifications.getValue()) 5396 && "1".equals(allowPrivateNotifications.getValue())) { 5397 secureSettings.insertSettingLocked( 5398 Secure.POWER_MENU_LOCKED_SHOW_CONTENT, 5399 "1", null /* tag */, false /* makeDefault */, 5400 SettingsState.SYSTEM_PACKAGE_NAME); 5401 } else if ("0".equals(showNotifications.getValue()) 5402 || "0".equals(allowPrivateNotifications.getValue())) { 5403 secureSettings.insertSettingLocked( 5404 Secure.POWER_MENU_LOCKED_SHOW_CONTENT, 5405 "0", null /* tag */, false /* makeDefault */, 5406 SettingsState.SYSTEM_PACKAGE_NAME); 5407 } 5408 currentVersion = 190; 5409 } 5410 5411 if (currentVersion == 190) { 5412 // Version 190: get HDMI auto device off from overlay 5413 // HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED settings option was removed 5414 currentVersion = 191; 5415 } 5416 5417 if (currentVersion == 191) { 5418 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5419 int mode = getContext().getResources().getInteger( 5420 com.android.internal.R.integer.config_navBarInteractionMode); 5421 if (mode == NAV_BAR_MODE_GESTURAL) { 5422 switchToDefaultGestureNavBackInset(userId, secureSettings); 5423 } 5424 migrateBackGestureSensitivity(Secure.BACK_GESTURE_INSET_SCALE_LEFT, userId, 5425 secureSettings); 5426 migrateBackGestureSensitivity(Secure.BACK_GESTURE_INSET_SCALE_RIGHT, userId, 5427 secureSettings); 5428 currentVersion = 192; 5429 } 5430 5431 if (currentVersion == 192) { 5432 // Version 192: set the default value for magnification capabilities. 5433 // If the device supports magnification area and magnification is enabled 5434 // by the user, set it to full-screen, and set a value to show a prompt 5435 // when using the magnification first time after upgrading. 5436 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5437 final Setting magnificationCapabilities = secureSettings.getSettingLocked( 5438 Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY); 5439 final boolean supportMagnificationArea = getContext().getResources().getBoolean( 5440 com.android.internal.R.bool.config_magnification_area); 5441 final String supportShowPrompt = supportMagnificationArea ? "1" : "0"; 5442 if (magnificationCapabilities.isNull()) { 5443 final int capability = supportMagnificationArea 5444 ? getContext().getResources().getInteger( 5445 R.integer.def_accessibility_magnification_capabilities) 5446 : Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; 5447 secureSettings.insertSettingLocked( 5448 Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY, 5449 String.valueOf(capability), 5450 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5451 5452 if (isMagnificationSettingsOn(secureSettings)) { 5453 secureSettings.insertSettingLocked( 5454 Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY, String.valueOf( 5455 Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN), 5456 null, false /* makeDefault */, 5457 SettingsState.SYSTEM_PACKAGE_NAME); 5458 secureSettings.insertSettingLocked( 5459 Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT, 5460 supportShowPrompt, 5461 null, false /* makeDefault */, 5462 SettingsState.SYSTEM_PACKAGE_NAME); 5463 } 5464 } 5465 currentVersion = 193; 5466 } 5467 5468 if (currentVersion == 193) { 5469 // Version 193: remove obsolete LOCATION_PROVIDERS_ALLOWED settings 5470 getSecureSettingsLocked(userId).deleteSettingLocked( 5471 Secure.LOCATION_PROVIDERS_ALLOWED); 5472 currentVersion = 194; 5473 } 5474 5475 if (currentVersion == 194) { 5476 // Version 194: migrate the GNSS_SATELLITE_BLOCKLIST setting 5477 final SettingsState globalSettings = getGlobalSettingsLocked(); 5478 final Setting newSetting = globalSettings.getSettingLocked( 5479 Global.GNSS_SATELLITE_BLOCKLIST); 5480 final String oldName = "gnss_satellite_blacklist"; 5481 final Setting oldSetting = globalSettings.getSettingLocked(oldName); 5482 if (newSetting.isNull() && !oldSetting.isNull()) { 5483 globalSettings.insertSettingLocked( 5484 Global.GNSS_SATELLITE_BLOCKLIST, oldSetting.getValue(), null, true, 5485 SettingsState.SYSTEM_PACKAGE_NAME); 5486 globalSettings.deleteSettingLocked(oldName); 5487 } 5488 currentVersion = 195; 5489 } 5490 5491 if (currentVersion == 195) { 5492 // Version 195: delete obsolete manged services settings 5493 getSecureSettingsLocked(userId).deleteSettingLocked( 5494 Secure.ENABLED_NOTIFICATION_ASSISTANT); 5495 getSecureSettingsLocked(userId).deleteSettingLocked( 5496 Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES); 5497 currentVersion = 196; 5498 } 5499 5500 if (currentVersion == 196) { 5501 // Version 196: Set the default value for Secure Settings: 5502 // SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED & ONE_HANDED_MODE_ENABLED 5503 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5504 final Setting swipeNotification = secureSettings.getSettingLocked( 5505 Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED); 5506 if (swipeNotification.isNull()) { 5507 final boolean defSwipeNotification = getContext().getResources() 5508 .getBoolean(R.bool.def_swipe_bottom_to_notification_enabled); 5509 secureSettings.insertSettingLocked( 5510 Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 5511 defSwipeNotification ? "1" : "0", null, true, 5512 SettingsState.SYSTEM_PACKAGE_NAME); 5513 } 5514 5515 final Setting oneHandedModeEnabled = secureSettings.getSettingLocked( 5516 Secure.ONE_HANDED_MODE_ENABLED); 5517 if (oneHandedModeEnabled.isNull()) { 5518 final boolean defOneHandedModeEnabled = getContext().getResources() 5519 .getBoolean(R.bool.def_one_handed_mode_enabled); 5520 secureSettings.insertSettingLocked( 5521 Secure.ONE_HANDED_MODE_ENABLED, 5522 defOneHandedModeEnabled ? "1" : "0", null, true, 5523 SettingsState.SYSTEM_PACKAGE_NAME); 5524 } 5525 5526 currentVersion = 197; 5527 } 5528 5529 if (currentVersion == 197) { 5530 // Version 197: Set the default value for Global Settings: 5531 // DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW 5532 final SettingsState globalSettings = getGlobalSettingsLocked(); 5533 final Setting enableNonResizableMultiWindow = globalSettings.getSettingLocked( 5534 Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW); 5535 if (enableNonResizableMultiWindow.isNull()) { 5536 final boolean defEnableNonResizableMultiWindow = getContext().getResources() 5537 .getBoolean(R.bool.def_enable_non_resizable_multi_window); 5538 globalSettings.insertSettingLocked( 5539 Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 5540 defEnableNonResizableMultiWindow ? "1" : "0", null, true, 5541 SettingsState.SYSTEM_PACKAGE_NAME); 5542 } 5543 currentVersion = 198; 5544 } 5545 5546 if (currentVersion == 198) { 5547 // Version 198: Set the default value for accessibility button. If the user 5548 // uses accessibility button in the navigation bar to trigger their 5549 // accessibility features (check if ACCESSIBILITY_BUTTON_TARGETS has value) 5550 // then leave accessibility button mode in the navigation bar, otherwise, set it 5551 // to the floating menu. 5552 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5553 final Setting accessibilityButtonMode = secureSettings.getSettingLocked( 5554 Secure.ACCESSIBILITY_BUTTON_MODE); 5555 if (accessibilityButtonMode.isNull()) { 5556 if (isAccessibilityButtonInNavigationBarOn(secureSettings)) { 5557 secureSettings.insertSettingLocked(Secure.ACCESSIBILITY_BUTTON_MODE, 5558 String.valueOf( 5559 Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR), 5560 /*tag= */ null, /* makeDefault= */ false, 5561 SettingsState.SYSTEM_PACKAGE_NAME); 5562 } else { 5563 final int defAccessibilityButtonMode = 5564 getContext().getResources().getInteger( 5565 R.integer.def_accessibility_button_mode); 5566 secureSettings.insertSettingLocked(Secure.ACCESSIBILITY_BUTTON_MODE, 5567 String.valueOf(defAccessibilityButtonMode), /* tag= */ 5568 null, /* makeDefault= */ true, 5569 SettingsState.SYSTEM_PACKAGE_NAME); 5570 5571 if (hasValueInA11yButtonTargets(secureSettings)) { 5572 secureSettings.insertSettingLocked( 5573 Secure.ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT, 5574 /* enabled */ "1", 5575 /* tag= */ null, 5576 /* makeDefault= */ false, 5577 SettingsState.SYSTEM_PACKAGE_NAME); 5578 } 5579 } 5580 } 5581 5582 currentVersion = 199; 5583 } 5584 5585 if (currentVersion == 199) { 5586 // Version 199: Bubbles moved to secure settings. Use the global value for 5587 // the newly inserted secure setting; we'll delete the global value in the 5588 // next version step. 5589 // If this is a new profile, check if a secure setting exists for the 5590 // owner of the profile and use that value for the work profile. 5591 int owningId = resolveOwningUserIdForSecureSetting(userId, 5592 NOTIFICATION_BUBBLES); 5593 Setting previous = getGlobalSettingsLocked() 5594 .getSettingLocked("notification_bubbles"); 5595 Setting secureBubbles = getSecureSettingsLocked(owningId) 5596 .getSettingLocked(NOTIFICATION_BUBBLES); 5597 String oldValue = "1"; 5598 if (!previous.isNull()) { 5599 oldValue = previous.getValue(); 5600 } else if (!secureBubbles.isNull()) { 5601 oldValue = secureBubbles.getValue(); 5602 } 5603 if (secureBubbles.isNull()) { 5604 boolean isDefault = oldValue.equals("1"); 5605 getSecureSettingsLocked(userId).insertSettingLocked( 5606 Secure.NOTIFICATION_BUBBLES, oldValue, null /* tag */, 5607 isDefault, SettingsState.SYSTEM_PACKAGE_NAME); 5608 } 5609 currentVersion = 200; 5610 } 5611 5612 if (currentVersion == 200) { 5613 // Version 200: delete the global bubble setting which was moved to secure in 5614 // version 199. 5615 getGlobalSettingsLocked().deleteSettingLocked("notification_bubbles"); 5616 currentVersion = 201; 5617 } 5618 5619 if (currentVersion == 201) { 5620 // Version 201: Set the default value for Secure Settings: 5621 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5622 final Setting oneHandedModeActivated = secureSettings.getSettingLocked( 5623 Secure.ONE_HANDED_MODE_ACTIVATED); 5624 if (oneHandedModeActivated.isNull()) { 5625 final boolean defOneHandedModeActivated = getContext().getResources() 5626 .getBoolean(R.bool.def_one_handed_mode_activated); 5627 secureSettings.insertSettingLocked( 5628 Secure.ONE_HANDED_MODE_ACTIVATED, 5629 defOneHandedModeActivated ? "1" : "0", null, true, 5630 SettingsState.SYSTEM_PACKAGE_NAME); 5631 } 5632 currentVersion = 202; 5633 } 5634 5635 if (currentVersion == 202) { 5636 // Version 202: Power menu has been removed, and the privacy setting 5637 // has been split into two for wallet and controls 5638 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5639 final Setting showLockedContent = secureSettings.getSettingLocked( 5640 Secure.POWER_MENU_LOCKED_SHOW_CONTENT); 5641 if (!showLockedContent.isNull()) { 5642 String currentValue = showLockedContent.getValue(); 5643 5644 secureSettings.insertSettingOverrideableByRestoreLocked( 5645 Secure.LOCKSCREEN_SHOW_CONTROLS, 5646 currentValue, null /* tag */, false /* makeDefault */, 5647 SettingsState.SYSTEM_PACKAGE_NAME); 5648 secureSettings.insertSettingOverrideableByRestoreLocked( 5649 Secure.LOCKSCREEN_SHOW_WALLET, 5650 currentValue, null /* tag */, false /* makeDefault */, 5651 SettingsState.SYSTEM_PACKAGE_NAME); 5652 } 5653 currentVersion = 203; 5654 } 5655 5656 if (currentVersion == 203) { 5657 // Version 203: initialize entries migrated from wear settings provide. 5658 initGlobalSettingsDefaultValLocked( 5659 Global.Wearable.HAS_PAY_TOKENS, false); 5660 initGlobalSettingsDefaultValLocked( 5661 Global.Wearable.GMS_CHECKIN_TIMEOUT_MIN, 6); 5662 initGlobalSettingsDefaultValLocked( 5663 Global.Wearable.HOTWORD_DETECTION_ENABLED, 5664 getContext() 5665 .getResources() 5666 .getBoolean(R.bool.def_wearable_hotwordDetectionEnabled)); 5667 initGlobalSettingsDefaultValLocked( 5668 Global.Wearable.SMART_REPLIES_ENABLED, true); 5669 Setting locationMode = 5670 getSecureSettingsLocked(userId).getSettingLocked(Secure.LOCATION_MODE); 5671 initGlobalSettingsDefaultValLocked( 5672 Global.Wearable.OBTAIN_PAIRED_DEVICE_LOCATION, 5673 !locationMode.isNull() 5674 && !Integer.toString(Secure.LOCATION_MODE_OFF) 5675 .equals(locationMode.getValue())); 5676 initGlobalSettingsDefaultValLocked( 5677 Global.Wearable.PHONE_PLAY_STORE_AVAILABILITY, 5678 Global.Wearable.PHONE_PLAY_STORE_AVAILABILITY_UNKNOWN); 5679 initGlobalSettingsDefaultValLocked( 5680 Global.Wearable.BUG_REPORT, 5681 "user".equals(Build.TYPE) // is user build? 5682 ? Global.Wearable.BUG_REPORT_DISABLED 5683 : Global.Wearable.BUG_REPORT_ENABLED); 5684 initGlobalSettingsDefaultValLocked( 5685 Global.Wearable.SMART_ILLUMINATE_ENABLED, 5686 getContext() 5687 .getResources() 5688 .getBoolean(R.bool.def_wearable_smartIlluminateEnabled)); 5689 initGlobalSettingsDefaultValLocked( 5690 Global.Wearable.CLOCKWORK_AUTO_TIME, 5691 Global.Wearable.SYNC_TIME_FROM_PHONE); 5692 initGlobalSettingsDefaultValLocked( 5693 Global.Wearable.CLOCKWORK_AUTO_TIME_ZONE, 5694 Global.Wearable.SYNC_TIME_ZONE_FROM_PHONE); 5695 initGlobalSettingsDefaultValLocked( 5696 Global.Wearable.CLOCKWORK_24HR_TIME, false); 5697 initGlobalSettingsDefaultValLocked(Global.Wearable.AUTO_WIFI, true); 5698 initGlobalSettingsDefaultValLocked( 5699 Global.Wearable.WIFI_POWER_SAVE, 5700 getContext() 5701 .getResources() 5702 .getInteger( 5703 R.integer 5704 .def_wearable_offChargerWifiUsageLimitMinutes)); 5705 initGlobalSettingsDefaultValLocked( 5706 Global.Wearable.ALT_BYPASS_WIFI_REQUIREMENT_TIME_MILLIS, 0L); 5707 initGlobalSettingsDefaultValLocked( 5708 Global.Wearable.SETUP_SKIPPED, Global.Wearable.SETUP_SKIPPED_UNKNOWN); 5709 initGlobalSettingsDefaultValLocked( 5710 Global.Wearable.LAST_CALL_FORWARD_ACTION, 5711 Global.Wearable.CALL_FORWARD_NO_LAST_ACTION); 5712 initGlobalSettingsDefaultValLocked( 5713 Global.Wearable.MUTE_WHEN_OFF_BODY_ENABLED, 5714 getContext() 5715 .getResources() 5716 .getBoolean(R.bool.def_wearable_muteWhenOffBodyEnabled)); 5717 initGlobalSettingsDefaultValLocked( 5718 Global.Wearable.WEAR_OS_VERSION_STRING, ""); 5719 initGlobalSettingsDefaultValLocked( 5720 Global.Wearable.SIDE_BUTTON, 5721 getContext() 5722 .getResources() 5723 .getBoolean(R.bool.def_wearable_sideButtonPresent)); 5724 initGlobalSettingsDefaultValLocked( 5725 Global.Wearable.ANDROID_WEAR_VERSION, 5726 Long.parseLong( 5727 getContext() 5728 .getResources() 5729 .getString(R.string.def_wearable_androidWearVersion))); 5730 final int editionGlobal = 1; 5731 final int editionLocal = 2; 5732 boolean isLe = getContext().getPackageManager().hasSystemFeature("cn.google"); 5733 initGlobalSettingsDefaultValLocked( 5734 Global.Wearable.SYSTEM_EDITION, isLe ? editionLocal : editionGlobal); 5735 initGlobalSettingsDefaultValLocked( 5736 Global.Wearable.SYSTEM_CAPABILITIES, getWearSystemCapabilities(isLe)); 5737 initGlobalSettingsDefaultValLocked( 5738 Global.Wearable.WEAR_PLATFORM_MR_NUMBER, 5739 SystemProperties.getInt("ro.cw_build.platform_mr", 0)); 5740 initGlobalSettingsDefaultValLocked( 5741 Settings.Global.Wearable.MOBILE_SIGNAL_DETECTOR, 5742 getContext() 5743 .getResources() 5744 .getBoolean(R.bool.def_wearable_mobileSignalDetectorAllowed)); 5745 initGlobalSettingsDefaultValLocked( 5746 Global.Wearable.AMBIENT_ENABLED, 5747 getContext() 5748 .getResources() 5749 .getBoolean(R.bool.def_wearable_ambientEnabled)); 5750 initGlobalSettingsDefaultValLocked( 5751 Global.Wearable.AMBIENT_TILT_TO_WAKE, 5752 getContext() 5753 .getResources() 5754 .getBoolean(R.bool.def_wearable_tiltToWakeEnabled)); 5755 initGlobalSettingsDefaultValLocked( 5756 Global.Wearable.AMBIENT_LOW_BIT_ENABLED_DEV, false); 5757 initGlobalSettingsDefaultValLocked( 5758 Global.Wearable.AMBIENT_TOUCH_TO_WAKE, 5759 getContext() 5760 .getResources() 5761 .getBoolean(R.bool.def_wearable_touchToWakeEnabled)); 5762 initGlobalSettingsDefaultValLocked( 5763 Global.Wearable.AMBIENT_TILT_TO_BRIGHT, 5764 getContext() 5765 .getResources() 5766 .getBoolean(R.bool.def_wearable_tiltToBrightEnabled)); 5767 initGlobalSettingsDefaultValLocked( 5768 Global.Wearable.DECOMPOSABLE_WATCHFACE, false); 5769 initGlobalSettingsDefaultValLocked( 5770 Settings.Global.Wearable.AMBIENT_FORCE_WHEN_DOCKED, 5771 SystemProperties.getBoolean("ro.ambient.force_when_docked", false)); 5772 initGlobalSettingsDefaultValLocked( 5773 Settings.Global.Wearable.AMBIENT_LOW_BIT_ENABLED, 5774 SystemProperties.getBoolean("ro.ambient.low_bit_enabled", false)); 5775 initGlobalSettingsDefaultValLocked( 5776 Settings.Global.Wearable.AMBIENT_PLUGGED_TIMEOUT_MIN, 5777 SystemProperties.getInt("ro.ambient.plugged_timeout_min", -1)); 5778 initGlobalSettingsDefaultValLocked( 5779 Settings.Global.Wearable.PAIRED_DEVICE_OS_TYPE, 5780 Settings.Global.Wearable.PAIRED_DEVICE_OS_TYPE_UNKNOWN); 5781 initGlobalSettingsDefaultValLocked( 5782 Settings.Global.Wearable.USER_HFP_CLIENT_SETTING, 5783 Settings.Global.Wearable.HFP_CLIENT_UNSET); 5784 Setting disabledProfileSetting = 5785 getGlobalSettingsLocked() 5786 .getSettingLocked(Settings.Global.BLUETOOTH_DISABLED_PROFILES); 5787 final long disabledProfileSettingValue = 5788 disabledProfileSetting.isNull() 5789 ? 0 5790 : Long.parseLong(disabledProfileSetting.getValue()); 5791 initGlobalSettingsDefaultValLocked( 5792 Settings.Global.Wearable.COMPANION_OS_VERSION, 5793 Settings.Global.Wearable.COMPANION_OS_VERSION_UNDEFINED); 5794 final boolean defaultBurnInProtectionEnabled = 5795 getContext() 5796 .getResources() 5797 .getBoolean( 5798 com.android 5799 .internal 5800 .R 5801 .bool 5802 .config_enableBurnInProtection); 5803 final boolean forceBurnInProtection = 5804 SystemProperties.getBoolean("persist.debug.force_burn_in", false); 5805 initGlobalSettingsDefaultValLocked( 5806 Settings.Global.Wearable.BURN_IN_PROTECTION_ENABLED, 5807 defaultBurnInProtectionEnabled || forceBurnInProtection); 5808 5809 initGlobalSettingsDefaultValLocked( 5810 Settings.Global.Wearable.CLOCKWORK_SYSUI_PACKAGE, 5811 getContext() 5812 .getResources() 5813 .getString( 5814 com.android.internal.R.string.config_wearSysUiPackage)); 5815 initGlobalSettingsDefaultValLocked( 5816 Settings.Global.Wearable.CLOCKWORK_SYSUI_MAIN_ACTIVITY, 5817 getContext() 5818 .getResources() 5819 .getString( 5820 com.android 5821 .internal 5822 .R 5823 .string 5824 .config_wearSysUiMainActivity)); 5825 5826 currentVersion = 204; 5827 } 5828 5829 if (currentVersion == 204) { 5830 // Version 204: Replace 'wifi' or 'cell' tiles with 'internet' if existed. 5831 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5832 final Setting currentValue = secureSettings.getSettingLocked(Secure.QS_TILES); 5833 if (!currentValue.isNull()) { 5834 String tileList = currentValue.getValue(); 5835 String[] tileSplit = tileList.split(","); 5836 final ArrayList<String> tiles = new ArrayList<String>(); 5837 boolean hasInternetTile = false; 5838 for (int i = 0; i < tileSplit.length; i++) { 5839 String tile = tileSplit[i].trim(); 5840 if (tile.isEmpty()) continue; 5841 tiles.add(tile); 5842 if (tile.equals("internet")) hasInternetTile = true; 5843 } 5844 if (!hasInternetTile) { 5845 if (tiles.contains("wifi")) { 5846 // Replace the WiFi with Internet, and remove the Cell 5847 tiles.set(tiles.indexOf("wifi"), "internet"); 5848 tiles.remove("cell"); 5849 } else if (tiles.contains("cell")) { 5850 // Replace the Cell with Internet 5851 tiles.set(tiles.indexOf("cell"), "internet"); 5852 } 5853 } else { 5854 tiles.remove("wifi"); 5855 tiles.remove("cell"); 5856 } 5857 secureSettings.insertSettingOverrideableByRestoreLocked( 5858 Secure.QS_TILES, 5859 TextUtils.join(",", tiles), 5860 null /* tag */, 5861 true /* makeDefault */, 5862 SettingsState.SYSTEM_PACKAGE_NAME); 5863 } 5864 currentVersion = 205; 5865 } 5866 5867 if (currentVersion == 205) { 5868 // Version 205: Set the default value for QR Code Scanner Setting: 5869 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5870 final Setting showQRCodeScannerOnLockScreen = secureSettings.getSettingLocked( 5871 Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER); 5872 if (showQRCodeScannerOnLockScreen.isNull()) { 5873 final boolean defLockScreenShowQrCodeScanner = getContext().getResources() 5874 .getBoolean(R.bool.def_lock_screen_show_qr_code_scanner); 5875 secureSettings.insertSettingOverrideableByRestoreLocked( 5876 Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 5877 defLockScreenShowQrCodeScanner ? "1" : "0", null, true, 5878 SettingsState.SYSTEM_PACKAGE_NAME); 5879 } 5880 currentVersion = 206; 5881 } 5882 5883 if (currentVersion == 206) { 5884 // Version 206: APPLY_RAMPING_RINGER moved to System settings. Use the old value 5885 // for the newly inserted system setting and keep it to be restored to other 5886 // users. Set default value if global value is not set. 5887 final SettingsState systemSettings = getSystemSettingsLocked(userId); 5888 Setting globalValue = getGlobalSettingsLocked() 5889 .getSettingLocked(Global.APPLY_RAMPING_RINGER); 5890 Setting currentValue = systemSettings 5891 .getSettingLocked(Settings.System.APPLY_RAMPING_RINGER); 5892 if (currentValue.isNull()) { 5893 if (!globalValue.isNull()) { 5894 // Recover settings from Global. 5895 systemSettings.insertSettingOverrideableByRestoreLocked( 5896 Settings.System.APPLY_RAMPING_RINGER, globalValue.getValue(), 5897 globalValue.getTag(), globalValue.isDefaultFromSystem(), 5898 SettingsState.SYSTEM_PACKAGE_NAME); 5899 } else { 5900 // Set default value. 5901 systemSettings.insertSettingOverrideableByRestoreLocked( 5902 Settings.System.APPLY_RAMPING_RINGER, 5903 getContext().getResources().getBoolean( 5904 R.bool.def_apply_ramping_ringer) ? "1" : "0", 5905 null /* tag */, true /* makeDefault */, 5906 SettingsState.SYSTEM_PACKAGE_NAME); 5907 } 5908 } 5909 currentVersion = 207; 5910 } 5911 5912 if (currentVersion == 207) { 5913 // Version 207: Reset the 5914 // Secure#ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT as enabled 5915 // status for showing the tooltips. 5916 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5917 final Setting accessibilityButtonMode = secureSettings.getSettingLocked( 5918 Secure.ACCESSIBILITY_BUTTON_MODE); 5919 if (!accessibilityButtonMode.isNull() 5920 && accessibilityButtonMode.getValue().equals( 5921 String.valueOf(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU))) { 5922 if (isGestureNavigateEnabled() 5923 && hasValueInA11yButtonTargets(secureSettings)) { 5924 secureSettings.insertSettingLocked( 5925 Secure.ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT, 5926 /* enabled */ "1", 5927 /* tag= */ null, 5928 /* makeDefault= */ false, 5929 SettingsState.SYSTEM_PACKAGE_NAME); 5930 } 5931 } 5932 5933 currentVersion = 208; 5934 } 5935 5936 if (currentVersion == 208) { 5937 // Unused 5938 currentVersion = 209; 5939 } 5940 if (currentVersion == 209) { 5941 // removed now that feature is enabled for everyone 5942 currentVersion = 210; 5943 } 5944 if (currentVersion == 210) { 5945 // Unused. Moved to version 217. 5946 currentVersion = 211; 5947 } 5948 if (currentVersion == 211) { 5949 // Unused. Moved to version 217. 5950 currentVersion = 212; 5951 } 5952 5953 if (currentVersion == 212) { 5954 // Unused. Moved to version 217. 5955 currentVersion = 213; 5956 } 5957 5958 if (currentVersion == 213) { 5959 final ComponentName accessibilityMenuToMigrate = 5960 AccessibilityUtils.getAccessibilityMenuComponentToMigrate( 5961 getContext().getPackageManager(), userId); 5962 if (accessibilityMenuToMigrate != null) { 5963 final SettingsState secureSettings = getSecureSettingsLocked(userId); 5964 final String toRemove = accessibilityMenuToMigrate.flattenToString(); 5965 final String toAdd = ACCESSIBILITY_MENU_IN_SYSTEM.flattenToString(); 5966 // Migrate the accessibility shortcuts and enabled state. 5967 migrateColonDelimitedStringSettingLocked(secureSettings, 5968 Secure.ACCESSIBILITY_BUTTON_TARGETS, toRemove, toAdd); 5969 migrateColonDelimitedStringSettingLocked(secureSettings, 5970 Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT, toRemove, toAdd); 5971 migrateColonDelimitedStringSettingLocked(secureSettings, 5972 Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, toRemove, toAdd); 5973 migrateColonDelimitedStringSettingLocked(secureSettings, 5974 Secure.ENABLED_ACCESSIBILITY_SERVICES, toRemove, toAdd); 5975 } 5976 currentVersion = 214; 5977 } 5978 5979 if (currentVersion == 214) { 5980 // Version 214: Removed, moved to version 216 5981 currentVersion = 215; 5982 } 5983 5984 if (currentVersion == 215) { 5985 // Version 215: default |def_airplane_mode_radios| and 5986 // |airplane_mode_toggleable_radios| changed to remove NFC & add UWB. 5987 final SettingsState globalSettings = getGlobalSettingsLocked(); 5988 final String oldApmRadiosValue = globalSettings.getSettingLocked( 5989 Settings.Global.AIRPLANE_MODE_RADIOS).getValue(); 5990 if (TextUtils.equals("cell,bluetooth,wifi,nfc,wimax", oldApmRadiosValue)) { 5991 globalSettings.insertSettingOverrideableByRestoreLocked( 5992 Settings.Global.AIRPLANE_MODE_RADIOS, 5993 getContext().getResources().getString( 5994 R.string.def_airplane_mode_radios), 5995 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 5996 } 5997 final String oldApmToggleableRadiosValue = globalSettings.getSettingLocked( 5998 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS).getValue(); 5999 if (TextUtils.equals("bluetooth,wifi,nfc", oldApmToggleableRadiosValue)) { 6000 globalSettings.insertSettingOverrideableByRestoreLocked( 6001 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS, 6002 getContext().getResources().getString( 6003 R.string.airplane_mode_toggleable_radios), 6004 null, true, SettingsState.SYSTEM_PACKAGE_NAME); 6005 } 6006 6007 currentVersion = 216; 6008 } 6009 6010 if (currentVersion == 216) { 6011 // Version 216: Set a default value for Credential Manager service. 6012 // We are doing this migration again because of an incorrect setting. 6013 6014 final SettingsState secureSettings = getSecureSettingsLocked(userId); 6015 final Setting currentSetting = secureSettings 6016 .getSettingLocked(Settings.Secure.CREDENTIAL_SERVICE); 6017 if (currentSetting.isNull()) { 6018 final int resourceId = 6019 com.android.internal.R.array.config_enabledCredentialProviderService; 6020 final Resources resources = getContext().getResources(); 6021 // If the config has not be defined we might get an exception. 6022 final List<String> providers = new ArrayList<>(); 6023 try { 6024 providers.addAll(Arrays.asList(resources.getStringArray(resourceId))); 6025 } catch (Resources.NotFoundException e) { 6026 Slog.w(LOG_TAG, 6027 "Get default array Cred Provider not found: " + e.toString()); 6028 } 6029 6030 if (!providers.isEmpty()) { 6031 final String defaultValue = String.join(":", providers); 6032 Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as CredMan Service " 6033 + "for user " + userId); 6034 secureSettings.insertSettingOverrideableByRestoreLocked( 6035 Settings.Secure.CREDENTIAL_SERVICE, defaultValue, null, true, 6036 SettingsState.SYSTEM_PACKAGE_NAME); 6037 } 6038 } 6039 6040 currentVersion = 217; 6041 } 6042 6043 if (currentVersion == 217) { 6044 // Version 217: merge and rebase wear settings init logic. 6045 6046 final SettingsState secureSettings = getSecureSettingsLocked(userId); 6047 final SettingsState globalSettings = getGlobalSettingsLocked(); 6048 6049 // Following init logic is moved from version 210 to this version in order to 6050 // resolve version conflict with wear branch. 6051 final Setting currentSetting = secureSettings.getSettingLocked( 6052 Secure.STATUS_BAR_SHOW_VIBRATE_ICON); 6053 if (currentSetting.isNull()) { 6054 final int defaultValueVibrateIconEnabled = getContext().getResources() 6055 .getInteger(R.integer.def_statusBarVibrateIconEnabled); 6056 secureSettings.insertSettingOverrideableByRestoreLocked( 6057 Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 6058 String.valueOf(defaultValueVibrateIconEnabled), 6059 null /* tag */, true /* makeDefault */, 6060 SettingsState.SYSTEM_PACKAGE_NAME); 6061 } 6062 6063 // Set default value for Secure#LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS 6064 // Following init logic is moved from version 211 to this version in order to 6065 // resolve version conflict with wear branch. 6066 final Setting lockScreenUnseenSetting = secureSettings 6067 .getSettingLocked(Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS); 6068 if (lockScreenUnseenSetting.isNull()) { 6069 final boolean defSetting = getContext().getResources() 6070 .getBoolean(R.bool.def_lock_screen_show_only_unseen_notifications); 6071 secureSettings.insertSettingOverrideableByRestoreLocked( 6072 Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, 6073 defSetting ? "1" : "0", 6074 null /* tag */, 6075 true /* makeDefault */, 6076 SettingsState.SYSTEM_PACKAGE_NAME); 6077 } 6078 6079 // Following init logic is moved from version 212 to this version in order to 6080 // resolve version conflict with wear branch. 6081 final Setting bugReportInPowerMenu = globalSettings.getSettingLocked( 6082 Global.BUGREPORT_IN_POWER_MENU); 6083 6084 if (!bugReportInPowerMenu.isNull()) { 6085 Slog.i(LOG_TAG, "Setting bugreport_in_power_menu to " 6086 + bugReportInPowerMenu.getValue() + " in Secure settings."); 6087 secureSettings.insertSettingLocked( 6088 Secure.BUGREPORT_IN_POWER_MENU, 6089 bugReportInPowerMenu.getValue(), null /* tag */, 6090 false /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); 6091 6092 // set global bug_report_in_power_menu setting to null since it's deprecated 6093 Slog.i(LOG_TAG, "Setting bugreport_in_power_menu to null" 6094 + " in Global settings since it's deprecated."); 6095 globalSettings.insertSettingLocked( 6096 Global.BUGREPORT_IN_POWER_MENU, null /* value */, null /* tag */, 6097 true /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); 6098 } 6099 6100 // Following init logic is rebased from wear OS branch. 6101 // Initialize default value of tether configuration to unknown. 6102 initGlobalSettingsDefaultValLocked( 6103 Settings.Global.Wearable.TETHER_CONFIG_STATE, 6104 Global.Wearable.TETHERED_CONFIG_UNKNOWN); 6105 // Init paired device location setting from resources. 6106 initGlobalSettingsDefaultValLocked( 6107 Global.Wearable.OBTAIN_PAIRED_DEVICE_LOCATION, 6108 getContext() 6109 .getResources() 6110 .getInteger(R.integer.def_paired_device_location_mode)); 6111 // Init media packages from resources. 6112 final String mediaControlsPackage = getContext().getResources().getString( 6113 com.android.internal.R.string.config_wearMediaControlsPackage); 6114 final String mediaSessionsPackage = getContext().getResources().getString( 6115 com.android.internal.R.string.config_wearMediaSessionsPackage); 6116 initGlobalSettingsDefaultValLocked( 6117 Global.Wearable.WEAR_MEDIA_CONTROLS_PACKAGE, 6118 mediaControlsPackage); 6119 initGlobalSettingsDefaultValLocked( 6120 Global.Wearable.WEAR_MEDIA_SESSIONS_PACKAGE, 6121 mediaSessionsPackage); 6122 6123 currentVersion = 218; 6124 } 6125 6126 if (currentVersion == 218) { 6127 // Version 219: Removed 6128 currentVersion = 219; 6129 } 6130 6131 if (currentVersion == 219) { 6132 6133 final SettingsState secureSettings = getSecureSettingsLocked(userId); 6134 final Setting currentSetting = secureSettings 6135 .getSettingLocked(Settings.Secure.CREDENTIAL_SERVICE_PRIMARY); 6136 if (currentSetting.isNull()) { 6137 final int resourceId = 6138 com.android.internal.R.array.config_primaryCredentialProviderService; 6139 final Resources resources = getContext().getResources(); 6140 // If the config has not be defined we might get an exception. 6141 final List<String> providers = new ArrayList<>(); 6142 try { 6143 providers.addAll(Arrays.asList(resources.getStringArray(resourceId))); 6144 } catch (Resources.NotFoundException e) { 6145 Slog.w(LOG_TAG, 6146 "Get default array Cred Provider not found: " + e.toString()); 6147 } 6148 6149 if (!providers.isEmpty()) { 6150 final String defaultValue = String.join(":", providers); 6151 Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as CredMan Service " 6152 + "for user " + userId); 6153 secureSettings.insertSettingOverrideableByRestoreLocked( 6154 Settings.Secure.CREDENTIAL_SERVICE_PRIMARY, defaultValue, null, 6155 true, SettingsState.SYSTEM_PACKAGE_NAME); 6156 } 6157 } 6158 currentVersion = 220; 6159 } 6160 6161 if (currentVersion == 220) { 6162 // Version 221: Removed 6163 currentVersion = 221; 6164 } 6165 6166 if (currentVersion == 221) { 6167 // Version 221: Set a default value for wifi always requested 6168 final SettingsState globalSettings = getGlobalSettingsLocked(); 6169 final Setting enableWifiAlwaysRequested = 6170 globalSettings.getSettingLocked(Global.WIFI_ALWAYS_REQUESTED); 6171 if (enableWifiAlwaysRequested.isNull()) { 6172 final boolean defEnableWifiAlwaysRequested = 6173 getContext() 6174 .getResources() 6175 .getBoolean(R.bool.def_enable_wifi_always_requested); 6176 initGlobalSettingsDefaultValLocked( 6177 Settings.Global.WIFI_ALWAYS_REQUESTED, 6178 defEnableWifiAlwaysRequested); 6179 } 6180 currentVersion = 222; 6181 } 6182 6183 // Version 222: Set peak refresh rate and min refresh rate to infinity if it's 6184 // meant to be the highest possible refresh rate. This is needed so that we can 6185 // back up and restore those settings on other devices. Other devices might have 6186 // different highest possible refresh rates. 6187 if (currentVersion == 222) { 6188 final SettingsState systemSettings = getSystemSettingsLocked(userId); 6189 final Setting peakRefreshRateSetting = 6190 systemSettings.getSettingLocked(Settings.System.PEAK_REFRESH_RATE); 6191 final Setting minRefreshRateSetting = 6192 systemSettings.getSettingLocked(Settings.System.MIN_REFRESH_RATE); 6193 float highestRefreshRate = 6194 mInjector.findHighestRefreshRateForDefaultDisplay(getContext()); 6195 6196 if (!peakRefreshRateSetting.isNull()) { 6197 try { 6198 float peakRefreshRate = 6199 Float.parseFloat(peakRefreshRateSetting.getValue()); 6200 if (Math.round(peakRefreshRate) == Math.round(highestRefreshRate)) { 6201 systemSettings.insertSettingLocked( 6202 Settings.System.PEAK_REFRESH_RATE, 6203 String.valueOf(Float.POSITIVE_INFINITY), 6204 /* tag= */ null, 6205 /* makeDefault= */ false, 6206 SettingsState.SYSTEM_PACKAGE_NAME); 6207 } 6208 } catch (NumberFormatException e) { 6209 // Do nothing. Leave the value as is. 6210 } 6211 } 6212 6213 if (!minRefreshRateSetting.isNull()) { 6214 try { 6215 float minRefreshRate = 6216 Float.parseFloat(minRefreshRateSetting.getValue()); 6217 if (Math.round(minRefreshRate) == Math.round(highestRefreshRate)) { 6218 systemSettings.insertSettingLocked( 6219 Settings.System.MIN_REFRESH_RATE, 6220 String.valueOf(Float.POSITIVE_INFINITY), 6221 /* tag= */ null, 6222 /* makeDefault= */ false, 6223 SettingsState.SYSTEM_PACKAGE_NAME); 6224 } 6225 } catch (NumberFormatException e) { 6226 // Do nothing. Leave the value as is. 6227 } 6228 } 6229 } 6230 6231 currentVersion = 223; 6232 6233 // Version 223: make charging constraint update criteria customizable. 6234 if (currentVersion == 223) { 6235 initGlobalSettingsDefaultValLocked( 6236 Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 6237 getContext().getResources().getInteger( 6238 R.integer.def_battery_charging_state_update_delay_ms)); 6239 6240 initGlobalSettingsDefaultValLocked( 6241 Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL, 6242 getContext().getResources().getInteger( 6243 R.integer.def_battery_charging_state_enforce_level) 6244 ); 6245 currentVersion = 224; 6246 } 6247 6248 // Version 224: Update the default font scale depending on the 6249 // R.dimen.def_device_font_scale configuration property. 6250 if (currentVersion == 224) { 6251 handleDefaultFontScale(getSystemSettingsLocked(userId)); 6252 currentVersion = 225; 6253 } 6254 6255 // Version 225: Set the System#KEYBOARD_VIBRATION_ENABLED based on touch 6256 // feedback enabled state. 6257 if (currentVersion == 225) { 6258 final SettingsState systemSettings = getSystemSettingsLocked(userId); 6259 final Setting touchFeedbackSettings = systemSettings 6260 .getSettingLocked(Settings.System.HAPTIC_FEEDBACK_ENABLED); 6261 final Setting keyboardVibrationSettings = systemSettings 6262 .getSettingLocked(Settings.System.KEYBOARD_VIBRATION_ENABLED); 6263 if (keyboardVibrationSettings.isNull()) { 6264 if (!touchFeedbackSettings.isNull()) { 6265 // Use touch feedback settings. 6266 systemSettings.insertSettingOverrideableByRestoreLocked( 6267 Settings.System.KEYBOARD_VIBRATION_ENABLED, 6268 touchFeedbackSettings.getValue(), 6269 touchFeedbackSettings.getTag(), 6270 touchFeedbackSettings.isDefaultFromSystem(), 6271 SettingsState.SYSTEM_PACKAGE_NAME); 6272 } 6273 } 6274 currentVersion = 226; 6275 } 6276 6277 // Version 226: Introduces dreaming while postured setting and migrates user from 6278 // docked dream trigger to postured dream trigger. 6279 if (currentVersion == 226) { 6280 final SettingsState secureSettings = getSecureSettingsLocked(userId); 6281 final Setting dreamOnDock = secureSettings.getSettingLocked( 6282 Secure.SCREENSAVER_ACTIVATE_ON_DOCK); 6283 final Setting dreamsEnabled = secureSettings.getSettingLocked( 6284 Secure.SCREENSAVER_ENABLED); 6285 final boolean dreamOnPosturedDefault = getContext().getResources().getBoolean( 6286 com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault); 6287 final boolean dreamsEnabledByDefault = getContext().getResources().getBoolean( 6288 com.android.internal.R.bool.config_dreamsEnabledByDefault); 6289 6290 if (dreamOnPosturedDefault && !dreamOnDock.isNull() 6291 && dreamOnDock.getValue().equals("1")) { 6292 // Disable dock activation and enable postured. 6293 secureSettings.insertSettingOverrideableByRestoreLocked( 6294 Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 6295 "0", 6296 null, 6297 true, 6298 SettingsState.SYSTEM_PACKAGE_NAME); 6299 secureSettings.insertSettingOverrideableByRestoreLocked( 6300 Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, 6301 "1", 6302 null, 6303 true, 6304 SettingsState.SYSTEM_PACKAGE_NAME); 6305 6306 // Disable dreams overall, so user doesn't start to unexpectedly see dreams 6307 // enabled when postured. 6308 if (!dreamsEnabledByDefault && !dreamsEnabled.isNull() 6309 && dreamsEnabled.getValue().equals("1")) { 6310 secureSettings.insertSettingOverrideableByRestoreLocked( 6311 Secure.SCREENSAVER_ENABLED, 6312 "0", 6313 null, 6314 true, 6315 SettingsState.SYSTEM_PACKAGE_NAME); 6316 } 6317 } 6318 6319 currentVersion = 227; 6320 } 6321 6322 // Version 227: Add default value for DOUBLE_TAP_TO_SLEEP. 6323 if (currentVersion == 227) { 6324 final SettingsState secureSettings = getSecureSettingsLocked(userId); 6325 final Setting doubleTapToSleep = secureSettings.getSettingLocked( 6326 Settings.Secure.DOUBLE_TAP_TO_SLEEP); 6327 if (doubleTapToSleep.isNull()) { 6328 secureSettings.insertSettingOverrideableByRestoreLocked( 6329 Settings.Secure.DOUBLE_TAP_TO_SLEEP, 6330 getContext().getResources().getBoolean( 6331 R.bool.def_double_tap_to_sleep) ? "1" : "0", 6332 null /* tag */, 6333 true /* makeDefault */, 6334 SettingsState.SYSTEM_PACKAGE_NAME); 6335 } 6336 currentVersion = 228; 6337 } 6338 6339 // Version 228: Migrate WearOS time settings 6340 if (currentVersion == 228) { 6341 if (getContext() 6342 .getPackageManager() 6343 .hasSystemFeature(PackageManager.FEATURE_WATCH)) { 6344 6345 SettingsState global = getGlobalSettingsLocked(); 6346 6347 Setting cwAutoTime = 6348 global.getSettingLocked(Global.Wearable.CLOCKWORK_AUTO_TIME); 6349 if (!cwAutoTime.isNull()) { 6350 boolean phone = 6351 String.valueOf(Global.Wearable.SYNC_TIME_FROM_PHONE) 6352 .equals(cwAutoTime.getValue()); 6353 boolean network = 6354 String.valueOf(Global.Wearable.SYNC_TIME_FROM_NETWORK) 6355 .equals(cwAutoTime.getValue()); 6356 global.insertSettingLocked( 6357 Global.AUTO_TIME, 6358 phone || network ? "1" : "0", 6359 null, 6360 true, 6361 SettingsState.SYSTEM_PACKAGE_NAME); 6362 } 6363 6364 Setting cwAutoTimeZone = 6365 global.getSettingLocked(Global.Wearable.CLOCKWORK_AUTO_TIME_ZONE); 6366 if (!cwAutoTimeZone.isNull()) { 6367 boolean phone = 6368 String.valueOf(Global.Wearable.SYNC_TIME_ZONE_FROM_PHONE) 6369 .equals(cwAutoTimeZone.getValue()); 6370 boolean network = 6371 String.valueOf(Global.Wearable.SYNC_TIME_ZONE_FROM_NETWORK) 6372 .equals(cwAutoTimeZone.getValue()); 6373 global.insertSettingLocked( 6374 Global.AUTO_TIME_ZONE, 6375 phone || network ? "1" : "0", 6376 null, 6377 true, 6378 SettingsState.SYSTEM_PACKAGE_NAME); 6379 } 6380 } 6381 6382 currentVersion = 229; 6383 } 6384 6385 // vXXX: Add new settings above this point. 6386 6387 if (currentVersion != newVersion) { 6388 Slog.wtf("SettingsProvider", "warning: upgrading settings database to version " 6389 + newVersion + " left it at " 6390 + currentVersion + 6391 " instead; this is probably a bug. Did you update SETTINGS_VERSION?", 6392 new Throwable()); 6393 if (DEBUG) { 6394 throw new RuntimeException("db upgrade error"); 6395 } 6396 } 6397 6398 // Return the current version. 6399 return currentVersion; 6400 } 6401 6402 @SuppressWarnings("GuardedBy") 6403 @GuardedBy("mLock") 6404 private void handleDefaultFontScale(@NonNull SettingsState systemSettings) { 6405 final float defaultFontScale = getContext().getResources() 6406 .getFloat(R.dimen.def_device_font_scale); 6407 // Persist the value for future use (e.g. Reset Settings option) 6408 systemSettings.insertSettingLocked( 6409 Settings.System.DEFAULT_DEVICE_FONT_SCALE, 6410 String.valueOf(defaultFontScale), 6411 /* tag= */ null, 6412 /* makeDefault= */ false, 6413 SettingsState.SYSTEM_PACKAGE_NAME); 6414 // We verify if there is a pre existing value for font_scale. 6415 final Setting existingFontScale = systemSettings.getSettingLocked( 6416 Settings.System.FONT_SCALE); 6417 if (existingFontScale == null || existingFontScale.isNull()) { 6418 // Set the default value only if it didn't exist before 6419 systemSettings.insertSettingLocked( 6420 Settings.System.FONT_SCALE, 6421 String.valueOf(defaultFontScale), 6422 /* tag= */ null, 6423 /* makeDefault= */ false, 6424 SettingsState.SYSTEM_PACKAGE_NAME); 6425 } 6426 } 6427 6428 @GuardedBy("mLock") 6429 private void initGlobalSettingsDefaultValLocked(String key, boolean val) { 6430 initGlobalSettingsDefaultValLocked(key, val ? "1" : "0"); 6431 } 6432 6433 @GuardedBy("mLock") 6434 private void initGlobalSettingsDefaultValLocked(String key, int val) { 6435 initGlobalSettingsDefaultValLocked(key, String.valueOf(val)); 6436 } 6437 6438 @GuardedBy("mLock") 6439 private void initGlobalSettingsDefaultValLocked(String key, long val) { 6440 initGlobalSettingsDefaultValLocked(key, String.valueOf(val)); 6441 } 6442 6443 @GuardedBy("mLock") 6444 private void initGlobalSettingsDefaultValLocked(String key, String val) { 6445 final SettingsState globalSettings = getGlobalSettingsLocked(); 6446 Setting currentSetting = globalSettings.getSettingLocked(key); 6447 if (currentSetting.isNull()) { 6448 globalSettings.insertSettingOverrideableByRestoreLocked( 6449 key, 6450 val, 6451 null /* tag */, 6452 true /* makeDefault */, 6453 SettingsState.SYSTEM_PACKAGE_NAME); 6454 } 6455 } 6456 6457 private long getWearSystemCapabilities(boolean isLe) { 6458 // Capability constants are imported from 6459 // com.google.android.clockwork.common.system.WearableConstants. 6460 final int capabilityCompanionLegacyCalling = 5; 6461 final int capabilitySpeaker = 6; 6462 final int capabilitySetupProtocommChannel = 7; 6463 long capabilities = 6464 Long.parseLong( 6465 getContext().getResources() 6466 .getString( 6467 isLe ? R.string.def_wearable_leSystemCapabilities 6468 : R.string.def_wearable_systemCapabilities)); 6469 PackageManager pm = getContext().getPackageManager(); 6470 if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 6471 capabilities |= getBitMask(capabilityCompanionLegacyCalling); 6472 } 6473 if (pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) { 6474 capabilities |= getBitMask(capabilitySpeaker); 6475 } 6476 capabilities |= getBitMask(capabilitySetupProtocommChannel); 6477 return capabilities; 6478 } 6479 6480 private long getBitMask(int capability) { 6481 return 1 << (capability - 1); 6482 } 6483 6484 @VisibleForTesting 6485 static class Injector { 6486 float findHighestRefreshRateForDefaultDisplay(Context context) { 6487 return RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay( 6488 context); 6489 } 6490 } 6491 } 6492 6493 /** 6494 * Previously, We were using separate overlay packages for different back inset sizes. Now, 6495 * we have a single overlay package for gesture navigation mode, and set the inset size via 6496 * a secure.settings field. 6497 * 6498 * If a non-default overlay package is enabled, then enable the default overlay exclusively, 6499 * and set the calculated inset size difference as a scale value in secure.settings. 6500 */ 6501 private void switchToDefaultGestureNavBackInset(int userId, SettingsState secureSettings) { 6502 try { 6503 final IOverlayManager om = IOverlayManager.Stub.asInterface( 6504 ServiceManager.getService(Context.OVERLAY_SERVICE)); 6505 final OverlayInfo info = om.getOverlayInfo(NAV_BAR_MODE_GESTURAL_OVERLAY, userId); 6506 if (info != null && !info.isEnabled()) { 6507 final int curInset = getContext().getResources().getDimensionPixelSize( 6508 com.android.internal.R.dimen.config_backGestureInset); 6509 om.setEnabledExclusiveInCategory(NAV_BAR_MODE_GESTURAL_OVERLAY, userId); 6510 final int defInset = getContext().getResources().getDimensionPixelSize( 6511 com.android.internal.R.dimen.config_backGestureInset); 6512 6513 final float scale = defInset == 0 ? 1.0f : ((float) curInset) / defInset; 6514 if (scale != 1.0f) { 6515 secureSettings.insertSettingLocked( 6516 Secure.BACK_GESTURE_INSET_SCALE_LEFT, 6517 Float.toString(scale), null /* tag */, false /* makeDefault */, 6518 SettingsState.SYSTEM_PACKAGE_NAME); 6519 secureSettings.insertSettingLocked( 6520 Secure.BACK_GESTURE_INSET_SCALE_RIGHT, 6521 Float.toString(scale), null /* tag */, false /* makeDefault */, 6522 SettingsState.SYSTEM_PACKAGE_NAME); 6523 if (DEBUG) { 6524 Slog.v(LOG_TAG, "Moved back sensitivity for user " + userId 6525 + " to scale " + scale); 6526 } 6527 } 6528 } 6529 } catch (SecurityException | IllegalStateException | RemoteException e) { 6530 Slog.e(LOG_TAG, "Failed to switch to default gesture nav overlay for user " 6531 + userId); 6532 } 6533 } 6534 6535 private void migrateBackGestureSensitivity(String side, int userId, 6536 SettingsState secureSettings) { 6537 final Setting currentScale = secureSettings.getSettingLocked(side); 6538 if (currentScale.isNull()) { 6539 return; 6540 } 6541 float current = 1.0f; 6542 try { 6543 current = Float.parseFloat(currentScale.getValue()); 6544 } catch (NumberFormatException e) { 6545 // Do nothing. Overwrite with default value. 6546 } 6547 6548 // Inset scale migration across all devices 6549 // Old(24dp): 0.66 0.75 0.83 1.00 1.08 1.33 1.66 6550 // New(30dp): 0.60 0.60 1.00 1.00 1.00 1.00 1.33 6551 final float low = 0.76f; // Values smaller than this will map to 0.6 6552 final float high = 1.65f; // Values larger than this will map to 1.33 6553 float newScale; 6554 if (current < low) { 6555 newScale = 0.6f; 6556 } else if (current < high) { 6557 newScale = 1.0f; 6558 } else { 6559 newScale = 1.33f; 6560 } 6561 secureSettings.insertSettingLocked(side, Float.toString(newScale), 6562 null /* tag */, false /* makeDefault */, 6563 SettingsState.SYSTEM_PACKAGE_NAME); 6564 if (DEBUG) { 6565 Slog.v(LOG_TAG, "Changed back sensitivity from " + current + " to " + newScale 6566 + " for user " + userId + " on " + side); 6567 } 6568 } 6569 6570 @GuardedBy("mLock") 6571 private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings, 6572 int userId) { 6573 List<String> names = settings.getSettingNamesLocked(); 6574 final int nameCount = names.size(); 6575 for (int i = 0; i < nameCount; i++) { 6576 String name = names.get(i); 6577 Setting setting = settings.getSettingLocked(name); 6578 6579 // In the upgrade case we pretend the call is made from the app 6580 // that made the last change to the setting to properly determine 6581 // whether the call has been made by a system component. 6582 try { 6583 final boolean systemSet = SettingsState.isSystemPackage( 6584 getContext(), setting.getPackageName()); 6585 if (systemSet) { 6586 settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(), 6587 setting.getTag(), true, setting.getPackageName()); 6588 } else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) { 6589 // We had a bug where changes by non-system packages were marked 6590 // as system made and as a result set as the default. Therefore, if 6591 // the package changed the setting last is not a system one but the 6592 // setting is marked as its default coming from the system we clear 6593 // the default and clear the system set flag. 6594 settings.resetSettingDefaultValueLocked(name); 6595 } 6596 } catch (IllegalStateException e) { 6597 // If the package goes over its quota during the upgrade, don't 6598 // crash but just log the error as the system does the upgrade. 6599 Slog.e(LOG_TAG, "Error upgrading setting: " + setting.getName(), e); 6600 6601 } 6602 } 6603 } 6604 6605 private boolean isMagnificationSettingsOn(SettingsState secureSettings) { 6606 if ("1".equals(secureSettings.getSettingLocked( 6607 Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED).getValue())) { 6608 return true; 6609 } 6610 6611 final Set<String> a11yButtonTargets = transformColonDelimitedStringToSet( 6612 secureSettings.getSettingLocked( 6613 Secure.ACCESSIBILITY_BUTTON_TARGETS).getValue()); 6614 if (a11yButtonTargets != null && a11yButtonTargets.contains( 6615 MAGNIFICATION_CONTROLLER_NAME)) { 6616 return true; 6617 } 6618 6619 final Set<String> a11yShortcutServices = transformColonDelimitedStringToSet( 6620 secureSettings.getSettingLocked( 6621 Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE).getValue()); 6622 if (a11yShortcutServices != null && a11yShortcutServices.contains( 6623 MAGNIFICATION_CONTROLLER_NAME)) { 6624 return true; 6625 } 6626 return false; 6627 } 6628 6629 @Nullable 6630 private Set<String> transformColonDelimitedStringToSet(String value) { 6631 if (TextUtils.isEmpty(value)) return null; 6632 final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(':'); 6633 splitter.setString(value); 6634 final Set<String> items = new HashSet<>(); 6635 while (splitter.hasNext()) { 6636 final String str = splitter.next(); 6637 if (TextUtils.isEmpty(str)) { 6638 continue; 6639 } 6640 items.add(str); 6641 } 6642 return items; 6643 } 6644 6645 @GuardedBy("mLock") 6646 private void migrateColonDelimitedStringSettingLocked(SettingsState settingsState, 6647 String setting, String toRemove, String toAdd) { 6648 final Set<String> componentNames = transformColonDelimitedStringToSet( 6649 settingsState.getSettingLocked(setting).getValue()); 6650 if (componentNames != null && componentNames.contains(toRemove)) { 6651 componentNames.remove(toRemove); 6652 componentNames.add(toAdd); 6653 settingsState.insertSettingLocked( 6654 setting, 6655 TextUtils.join(":", componentNames), 6656 null /* tag */, false /* makeDefault */, 6657 SettingsState.SYSTEM_PACKAGE_NAME); 6658 } 6659 } 6660 6661 private boolean isAccessibilityButtonInNavigationBarOn(SettingsState secureSettings) { 6662 return hasValueInA11yButtonTargets(secureSettings) && !isGestureNavigateEnabled(); 6663 } 6664 6665 private boolean isGestureNavigateEnabled() { 6666 final int navigationMode = getContext().getResources().getInteger( 6667 com.android.internal.R.integer.config_navBarInteractionMode); 6668 return navigationMode == NAV_BAR_MODE_GESTURAL; 6669 } 6670 6671 private boolean hasValueInA11yButtonTargets(SettingsState secureSettings) { 6672 final Setting a11yButtonTargetsSettings = 6673 secureSettings.getSettingLocked(Secure.ACCESSIBILITY_BUTTON_TARGETS); 6674 6675 return !a11yButtonTargetsSettings.isNull() 6676 && !TextUtils.isEmpty(a11yButtonTargetsSettings.getValue()); 6677 } 6678 6679 @NonNull 6680 public GenerationRegistry getGenerationRegistry() { 6681 return mGenerationRegistry; 6682 } 6683 } 6684 } 6685