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