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