1 /* 2 * Copyright (C) 2018 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 package com.android.server.infra; 17 18 import android.annotation.IntDef; 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.UserIdInt; 22 import android.app.ActivityManager; 23 import android.content.ComponentName; 24 import android.content.ContentResolver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.pm.UserInfo; 28 import android.credentials.flags.Flags; 29 import android.database.ContentObserver; 30 import android.net.Uri; 31 import android.os.Binder; 32 import android.os.Handler; 33 import android.os.UserHandle; 34 import android.os.UserManager; 35 import android.provider.Settings; 36 import android.util.Slog; 37 import android.util.SparseArray; 38 import android.util.SparseBooleanArray; 39 40 import com.android.internal.annotations.GuardedBy; 41 import com.android.internal.content.PackageMonitor; 42 import com.android.internal.infra.AbstractRemoteService; 43 import com.android.internal.os.BackgroundThread; 44 import com.android.server.LocalServices; 45 import com.android.server.SystemService; 46 import com.android.server.pm.UserManagerInternal; 47 48 import java.io.PrintWriter; 49 import java.lang.annotation.Retention; 50 import java.lang.annotation.RetentionPolicy; 51 import java.util.ArrayList; 52 import java.util.Arrays; 53 import java.util.List; 54 import java.util.Objects; 55 56 /** 57 * Base class for {@link SystemService SystemServices} that support multi user. 58 * 59 * <p>Subclasses of this service are just a facade for the service binder calls - the "real" work 60 * is done by the {@link AbstractPerUserSystemService} subclasses, which are automatically managed 61 * through an user -> service cache. 62 * 63 * <p>It also takes care of other plumbing tasks such as: 64 * 65 * <ul> 66 * <li>Disabling the service when {@link UserManager} restrictions change. 67 * <li>Refreshing the service when its underlying 68 * {@link #getServiceSettingsProperty() Settings property} changed. 69 * <li>Calling the service when other Settings properties changed. 70 * </ul> 71 * 72 * <p>See {@code com.android.server.autofill.AutofillManagerService} for a concrete 73 * (no pun intended) example of how to use it. 74 * 75 * @param <M> "main" service class. 76 * @param <S> "real" service class. 77 * 78 * @hide 79 */ 80 // TODO(b/117779333): improve javadoc above instead of using Autofill as an example 81 public abstract class AbstractMasterSystemService<M extends AbstractMasterSystemService<M, S>, 82 S extends AbstractPerUserSystemService<S, M>> extends SystemService { 83 84 /** On a package update, does not refresh the per-user service in the cache. */ 85 public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0x00000001; 86 87 /** 88 * On a package update, removes any existing per-user services in the cache. 89 * 90 * <p>This does not immediately recreate these services. It is assumed they will be recreated 91 * for the next user request. 92 */ 93 public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 0x00000002; 94 95 /** 96 * On a package update, removes and recreates any existing per-user services in the cache. 97 */ 98 public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 0x00000004; 99 100 /** On a package restart, does not refresh the per-user service in the cache. */ 101 public static final int PACKAGE_RESTART_POLICY_NO_REFRESH = 0x00000010; 102 103 /** 104 * On a package restart, removes any existing per-user services in the cache. 105 * 106 * <p>This does not immediately recreate these services. It is assumed they will be recreated 107 * for the next user request. 108 */ 109 public static final int PACKAGE_RESTART_POLICY_REFRESH_LAZY = 0x00000020; 110 111 /** 112 * On a package restart, removes and recreates any existing per-user services in the cache. 113 */ 114 public static final int PACKAGE_RESTART_POLICY_REFRESH_EAGER = 0x00000040; 115 116 @IntDef(flag = true, prefix = { "PACKAGE_" }, value = { 117 PACKAGE_UPDATE_POLICY_NO_REFRESH, 118 PACKAGE_UPDATE_POLICY_REFRESH_LAZY, 119 PACKAGE_UPDATE_POLICY_REFRESH_EAGER, 120 PACKAGE_RESTART_POLICY_NO_REFRESH, 121 PACKAGE_RESTART_POLICY_REFRESH_LAZY, 122 PACKAGE_RESTART_POLICY_REFRESH_EAGER 123 }) 124 125 @Retention(RetentionPolicy.SOURCE) 126 public @interface ServicePackagePolicyFlags {} 127 128 /** 129 * Log tag 130 */ 131 protected final String mTag = getClass().getSimpleName(); 132 133 /** 134 * Lock used to synchronize access to internal state; should be acquired before calling a 135 * method whose name ends with {@code locked}. 136 */ 137 protected final Object mLock = new Object(); 138 139 /** 140 * Object used to define the name of the service component used to create 141 * {@link com.android.internal.infra.AbstractRemoteService} instances. 142 */ 143 @Nullable 144 protected final ServiceNameResolver mServiceNameResolver; 145 146 /** 147 * Whether the service should log debug statements. 148 */ 149 //TODO(b/117779333): consider using constants for these guards 150 public boolean verbose = false; 151 152 /** 153 * Whether the service should log verbose statements. 154 */ 155 //TODO(b/117779333): consider using constants for these guards 156 public boolean debug = false; 157 158 /** 159 * Whether the service is allowed to bind to an instant-app. 160 */ 161 @GuardedBy("mLock") 162 protected boolean mAllowInstantService; 163 164 /** 165 * Users disabled due to {@link UserManager} restrictions, or {@code null} if the service cannot 166 * be disabled through {@link UserManager}. 167 */ 168 @GuardedBy("mLock") 169 @Nullable 170 private final SparseBooleanArray mDisabledByUserRestriction; 171 172 /** 173 * Cache of service list per user id. 174 */ 175 @GuardedBy("mLock") 176 private final SparseArray<List<S>> mServicesCacheList = new SparseArray<>(); 177 178 /** 179 * Value that determines whether the per-user service should be removed from the cache when its 180 * apk is updated or restarted. 181 */ 182 private final @ServicePackagePolicyFlags int mServicePackagePolicyFlags; 183 184 /** 185 * Name of the service packages whose APK are being updated, keyed by user id. 186 */ 187 @GuardedBy("mLock") 188 private SparseArray<String> mUpdatingPackageNames; 189 190 /** 191 * Lazy-loadable reference to {@link UserManagerInternal}. 192 */ 193 @Nullable 194 private UserManagerInternal mUm; 195 196 private final MyPackageMonitor mPackageMonitor; 197 198 /** 199 * Default constructor. 200 * 201 * <p>When using this constructor, the {@link AbstractPerUserSystemService} is removed from 202 * the cache (and re-added) when the service package is updated. 203 * 204 * @param context system context. 205 * @param serviceNameResolver resolver for 206 * {@link com.android.internal.infra.AbstractRemoteService} instances, or 207 * {@code null} when the service doesn't bind to remote services. 208 * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that 209 * disables the service. <b>NOTE: </b> you'll also need to add it to 210 * {@code UserRestrictionsUtils.USER_RESTRICTIONS}. 211 */ AbstractMasterSystemService(@onNull Context context, @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty)212 protected AbstractMasterSystemService(@NonNull Context context, 213 @Nullable ServiceNameResolver serviceNameResolver, 214 @Nullable String disallowProperty) { 215 this(context, serviceNameResolver, disallowProperty, 216 PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_LAZY); 217 } 218 219 /** 220 * Full Constructor. 221 * 222 * @param context system context. 223 * @param serviceNameResolver resolver for 224 * {@link com.android.internal.infra.AbstractRemoteService} instances, or 225 * {@code null} when the service doesn't bind to remote services. 226 * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that 227 * disables the service. <b>NOTE: </b> you'll also need to add it to 228 * {@code UserRestrictionsUtils.USER_RESTRICTIONS}. 229 * @param servicePackagePolicyFlags a combination of 230 * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, 231 * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, 232 * {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, 233 * {@link #PACKAGE_RESTART_POLICY_NO_REFRESH}, 234 * {@link #PACKAGE_RESTART_POLICY_REFRESH_LAZY} or 235 * {@link #PACKAGE_RESTART_POLICY_REFRESH_EAGER} 236 */ AbstractMasterSystemService(@onNull Context context, @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty, @ServicePackagePolicyFlags int servicePackagePolicyFlags)237 protected AbstractMasterSystemService(@NonNull Context context, 238 @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty, 239 @ServicePackagePolicyFlags int servicePackagePolicyFlags) { 240 super(context); 241 242 final int updatePolicyMask = PACKAGE_UPDATE_POLICY_NO_REFRESH 243 | PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_UPDATE_POLICY_REFRESH_EAGER; 244 if ((servicePackagePolicyFlags & updatePolicyMask) == 0) { 245 // If the package update policy is not set, add the default flag 246 servicePackagePolicyFlags |= PACKAGE_UPDATE_POLICY_REFRESH_LAZY; 247 } 248 final int restartPolicyMask = PACKAGE_RESTART_POLICY_NO_REFRESH 249 | PACKAGE_RESTART_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_EAGER; 250 if ((servicePackagePolicyFlags & restartPolicyMask) == 0) { 251 // If the package restart policy is not set, add the default flag 252 servicePackagePolicyFlags |= PACKAGE_RESTART_POLICY_REFRESH_LAZY; 253 } 254 mServicePackagePolicyFlags = servicePackagePolicyFlags; 255 256 mServiceNameResolver = serviceNameResolver; 257 if (mServiceNameResolver != null) { 258 mServiceNameResolver.setOnTemporaryServiceNameChangedCallback( 259 this::onServiceNameChanged); 260 } 261 if (disallowProperty == null) { 262 mDisabledByUserRestriction = null; 263 } else { 264 mDisabledByUserRestriction = new SparseBooleanArray(); 265 // Hookup with UserManager to disable service when necessary. 266 final UserManagerInternal umi = getUserManagerInternal(); 267 final List<UserInfo> users = getSupportedUsers(); 268 for (int i = 0; i < users.size(); i++) { 269 final int userId = users.get(i).id; 270 final boolean disabled = umi.getUserRestriction(userId, disallowProperty); 271 if (disabled) { 272 Slog.i(mTag, "Disabling by restrictions user " + userId); 273 mDisabledByUserRestriction.put(userId, disabled); 274 } 275 } 276 umi.addUserRestrictionsListener((userId, newRestrictions, prevRestrictions) -> { 277 final boolean disabledNow = 278 newRestrictions.getBoolean(disallowProperty, false); 279 synchronized (mLock) { 280 final boolean disabledBefore = mDisabledByUserRestriction.get(userId); 281 if (disabledBefore == disabledNow) { 282 // Nothing changed, do nothing. 283 if (debug) { 284 Slog.d(mTag, "Restriction did not change for user " + userId); 285 return; 286 } 287 } 288 Slog.i(mTag, "Updating for user " + userId + ": disabled=" + disabledNow); 289 mDisabledByUserRestriction.put(userId, disabledNow); 290 updateCachedServiceLocked(userId, disabledNow); 291 } 292 }); 293 } 294 mPackageMonitor = new MyPackageMonitor(/* supportsPackageRestartQuery */ true); 295 startTrackingPackageChanges(); 296 } 297 298 @Override // from SystemService onBootPhase(int phase)299 public void onBootPhase(int phase) { 300 if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 301 new SettingsObserver(BackgroundThread.getHandler()); 302 } 303 } 304 305 @Override // from SystemService onUserUnlocking(@onNull TargetUser user)306 public void onUserUnlocking(@NonNull TargetUser user) { 307 synchronized (mLock) { 308 updateCachedServiceLocked(user.getUserIdentifier()); 309 } 310 } 311 312 @Override // from SystemService onUserStopped(@onNull TargetUser user)313 public void onUserStopped(@NonNull TargetUser user) { 314 synchronized (mLock) { 315 removeCachedServiceListLocked(user.getUserIdentifier()); 316 } 317 } 318 319 /** 320 * Gets whether the service is allowed to bind to an instant-app. 321 * 322 * <p>Typically called by {@code ShellCommand} during CTS tests. 323 * 324 * @throws SecurityException if caller is not allowed to manage this service's settings. 325 */ getAllowInstantService()326 public final boolean getAllowInstantService() { 327 enforceCallingPermissionForManagement(); 328 synchronized (mLock) { 329 return mAllowInstantService; 330 } 331 } 332 333 /** 334 * Checks whether the service is allowed to bind to an instant-app. 335 * 336 * <p>Typically called by subclasses when creating {@link AbstractRemoteService} instances. 337 * 338 * <p><b>NOTE: </b>must not be called by {@code ShellCommand} as it does not check for 339 * permission. 340 */ isBindInstantServiceAllowed()341 public final boolean isBindInstantServiceAllowed() { 342 synchronized (mLock) { 343 return mAllowInstantService; 344 } 345 } 346 347 /** 348 * Sets whether the service is allowed to bind to an instant-app. 349 * 350 * <p>Typically called by {@code ShellCommand} during CTS tests. 351 * 352 * @throws SecurityException if caller is not allowed to manage this service's settings. 353 */ setAllowInstantService(boolean mode)354 public final void setAllowInstantService(boolean mode) { 355 Slog.i(mTag, "setAllowInstantService(): " + mode); 356 enforceCallingPermissionForManagement(); 357 synchronized (mLock) { 358 mAllowInstantService = mode; 359 } 360 } 361 362 /** 363 * Temporarily sets the service implementation. 364 * 365 * <p>Typically used by Shell command and/or CTS tests. 366 * 367 * @param componentName name of the new component 368 * @param durationMs how long the change will be valid (the service will be automatically reset 369 * to the default component after this timeout expires). 370 * @throws SecurityException if caller is not allowed to manage this service's settings. 371 * @throws IllegalArgumentException if value of {@code durationMs} is higher than 372 * {@link #getMaximumTemporaryServiceDurationMs()}. 373 */ setTemporaryService(@serIdInt int userId, @NonNull String componentName, int durationMs)374 public final void setTemporaryService(@UserIdInt int userId, @NonNull String componentName, 375 int durationMs) { 376 Slog.i(mTag, "setTemporaryService(" + userId + ") to " + componentName + " for " 377 + durationMs + "ms"); 378 if (mServiceNameResolver == null) { 379 return; 380 } 381 enforceCallingPermissionForManagement(); 382 383 Objects.requireNonNull(componentName); 384 final int maxDurationMs = getMaximumTemporaryServiceDurationMs(); 385 if (durationMs > maxDurationMs) { 386 throw new IllegalArgumentException( 387 "Max duration is " + maxDurationMs + " (called with " + durationMs + ")"); 388 } 389 390 synchronized (mLock) { 391 final S oldService = peekServiceForUserLocked(userId); 392 if (oldService != null) { 393 oldService.removeSelfFromCache(); 394 } 395 mServiceNameResolver.setTemporaryService(userId, componentName, durationMs); 396 } 397 } 398 399 /** 400 * Temporarily sets the service implementation. 401 * 402 * <p>Typically used by Shell command and/or CTS tests. 403 * 404 * @param componentNames list of the names of the new component 405 * @param durationMs how long the change will be valid (the service will be automatically 406 * reset 407 * to the default component after this timeout expires). 408 * @throws SecurityException if caller is not allowed to manage this service's settings. 409 * @throws IllegalArgumentException if value of {@code durationMs} is higher than 410 * {@link #getMaximumTemporaryServiceDurationMs()}. 411 */ setTemporaryServices(@serIdInt int userId, @NonNull String[] componentNames, int durationMs)412 public final void setTemporaryServices(@UserIdInt int userId, @NonNull String[] componentNames, 413 int durationMs) { 414 Slog.i(mTag, "setTemporaryService(" + userId + ") to " + Arrays.toString(componentNames) 415 + " for " + durationMs + "ms"); 416 if (mServiceNameResolver == null) { 417 return; 418 } 419 enforceCallingPermissionForManagement(); 420 421 Objects.requireNonNull(componentNames); 422 final int maxDurationMs = getMaximumTemporaryServiceDurationMs(); 423 if (durationMs > maxDurationMs) { 424 throw new IllegalArgumentException( 425 "Max duration is " + maxDurationMs + " (called with " + durationMs + ")"); 426 } 427 428 synchronized (mLock) { 429 final S oldService = peekServiceForUserLocked(userId); 430 if (oldService != null) { 431 oldService.removeSelfFromCache(); 432 } 433 mServiceNameResolver.setTemporaryServices(userId, componentNames, durationMs); 434 } 435 } 436 437 /** 438 * Sets whether the default service should be used. 439 * 440 * <p>Typically used during CTS tests to make sure only the default service doesn't interfere 441 * with the test results. 442 * 443 * @return whether the enabled state changed. 444 * @throws SecurityException if caller is not allowed to manage this service's settings. 445 */ setDefaultServiceEnabled(@serIdInt int userId, boolean enabled)446 public final boolean setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) { 447 Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled); 448 enforceCallingPermissionForManagement(); 449 450 synchronized (mLock) { 451 if (mServiceNameResolver == null) { 452 return false; 453 } 454 final boolean changed = mServiceNameResolver.setDefaultServiceEnabled(userId, enabled); 455 if (!changed) { 456 if (verbose) { 457 Slog.v(mTag, "setDefaultServiceEnabled(" + userId + "): already " + enabled); 458 } 459 return false; 460 } 461 462 final S oldService = peekServiceForUserLocked(userId); 463 if (oldService != null) { 464 oldService.removeSelfFromCache(); 465 } 466 467 // Must update the service on cache so its initialization code is triggered 468 updateCachedServiceLocked(userId); 469 } 470 return true; 471 } 472 473 /** 474 * Checks whether the default service should be used. 475 * 476 * <p>Typically used during CTS tests to make sure only the default service doesn't interfere 477 * with the test results. 478 * 479 * @throws SecurityException if caller is not allowed to manage this service's settings. 480 */ isDefaultServiceEnabled(@serIdInt int userId)481 public final boolean isDefaultServiceEnabled(@UserIdInt int userId) { 482 enforceCallingPermissionForManagement(); 483 484 if (mServiceNameResolver == null) { 485 return false; 486 } 487 488 synchronized (mLock) { 489 return mServiceNameResolver.isDefaultServiceEnabled(userId); 490 } 491 } 492 493 /** 494 * Gets the maximum time the service implementation can be changed. 495 * 496 * @throws UnsupportedOperationException if subclass doesn't override it. 497 */ getMaximumTemporaryServiceDurationMs()498 protected int getMaximumTemporaryServiceDurationMs() { 499 throw new UnsupportedOperationException("Not implemented by " + getClass()); 500 } 501 502 /** 503 * Resets the temporary service implementation to the default component. 504 * 505 * <p>Typically used by Shell command and/or CTS tests. 506 * 507 * @throws SecurityException if caller is not allowed to manage this service's settings. 508 */ resetTemporaryService(@serIdInt int userId)509 public final void resetTemporaryService(@UserIdInt int userId) { 510 Slog.i(mTag, "resetTemporaryService(): " + userId); 511 enforceCallingPermissionForManagement(); 512 synchronized (mLock) { 513 final S service = getServiceForUserLocked(userId); 514 if (service != null) { 515 service.resetTemporaryServiceLocked(); 516 } 517 } 518 } 519 520 /** 521 * Asserts that the caller has permissions to manage this service. 522 * 523 * <p>Typically called by {@code ShellCommand} implementations. 524 * 525 * @throws UnsupportedOperationException if subclass doesn't override it. 526 * @throws SecurityException if caller is not allowed to manage this service's settings. 527 */ enforceCallingPermissionForManagement()528 protected void enforceCallingPermissionForManagement() { 529 throw new UnsupportedOperationException("Not implemented by " + getClass()); 530 } 531 532 /** 533 * Creates a new service that will be added to the cache. 534 * 535 * @param resolvedUserId the resolved user id for the service. 536 * @param disabled whether the service is currently disabled (due to {@link UserManager} 537 * restrictions). 538 * 539 * @return a new instance. 540 */ 541 @Nullable newServiceLocked(@serIdInt int resolvedUserId, boolean disabled)542 protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled); 543 544 /** 545 * Creates a new service list that will be added to the cache. 546 * 547 * @param resolvedUserId the resolved user id for the service. 548 * @param disabled whether the service is currently disabled (due to {@link UserManager} 549 * restrictions). 550 * @return a new instance. 551 */ 552 @Nullable 553 @GuardedBy("mLock") newServiceListLocked(@serIdInt int resolvedUserId, boolean disabled, String[] serviceNames)554 protected List<S> newServiceListLocked(@UserIdInt int resolvedUserId, boolean disabled, 555 String[] serviceNames) { 556 throw new UnsupportedOperationException("newServiceListLocked not implemented. "); 557 } 558 559 /** 560 * Register the service for extra Settings changes (i.e., other than 561 * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or 562 * {@link #getServiceSettingsProperty()}, which are automatically handled). 563 * 564 * <p> Example: 565 * 566 * <pre><code> 567 * resolver.registerContentObserver(Settings.Global.getUriFor( 568 * Settings.Global.AUTOFILL_LOGGING_LEVEL), false, observer, 569 * UserHandle.USER_ALL); 570 * </code></pre> 571 * 572 * <p><b>NOTE: </p>it doesn't need to register for 573 * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or 574 * {@link #getServiceSettingsProperty()}. 575 */ 576 @SuppressWarnings("unused") registerForExtraSettingsChanges(@onNull ContentResolver resolver, @NonNull ContentObserver observer)577 protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver, 578 @NonNull ContentObserver observer) { 579 } 580 581 /** 582 * Callback for Settings changes that were registered though 583 * {@link #registerForExtraSettingsChanges(ContentResolver, ContentObserver)}. 584 * 585 * @param userId user associated with the change 586 * @param property Settings property changed. 587 */ onSettingsChanged(@serIdInt int userId, @NonNull String property)588 protected void onSettingsChanged(@UserIdInt int userId, @NonNull String property) { 589 } 590 591 /** 592 * Gets the service instance for an user, creating an instance if not present in the cache. 593 */ 594 @GuardedBy("mLock") 595 @NonNull getServiceForUserLocked(@serIdInt int userId)596 protected S getServiceForUserLocked(@UserIdInt int userId) { 597 List<S> services = getServiceListForUserLocked(userId); 598 return services == null || services.size() == 0 ? null : services.get(0); 599 } 600 601 /** 602 * Gets the service instance list for a user, creating instances if not present in the cache. 603 */ 604 @GuardedBy("mLock") getServiceListForUserLocked(@serIdInt int userId)605 protected List<S> getServiceListForUserLocked(@UserIdInt int userId) { 606 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 607 Binder.getCallingUid(), userId, false, false, null, null); 608 List<S> services = mServicesCacheList.get(resolvedUserId); 609 if (services == null || services.size() == 0) { 610 final boolean disabled = isDisabledLocked(userId); 611 if (mServiceNameResolver != null && mServiceNameResolver.isConfiguredInMultipleMode()) { 612 services = newServiceListLocked(resolvedUserId, disabled, 613 mServiceNameResolver.getServiceNameList(userId)); 614 } else { 615 services = new ArrayList<>(); 616 services.add(newServiceLocked(resolvedUserId, disabled)); 617 } 618 if (!disabled) { 619 for (int i = 0; i < services.size(); i++) { 620 onServiceEnabledLocked(services.get(i), resolvedUserId); 621 } 622 } 623 mServicesCacheList.put(userId, services); 624 } 625 return services; 626 } 627 628 /** 629 * Gets the <b>existing</b> service instance for a user, returning {@code null} if not already 630 * present in the cache. 631 */ 632 @GuardedBy("mLock") 633 @Nullable peekServiceForUserLocked(@serIdInt int userId)634 protected S peekServiceForUserLocked(@UserIdInt int userId) { 635 List<S> serviceList = peekServiceListForUserLocked(userId); 636 return serviceList == null || serviceList.size() == 0 ? null : serviceList.get(0); 637 } 638 639 /** 640 * Gets the <b>existing</b> service instance for a user, returning {@code null} if not already 641 * present in the cache. 642 */ 643 @GuardedBy("mLock") 644 @Nullable peekServiceListForUserLocked(@serIdInt int userId)645 protected List<S> peekServiceListForUserLocked(@UserIdInt int userId) { 646 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 647 Binder.getCallingUid(), userId, false, false, null, null); 648 return mServicesCacheList.get(resolvedUserId); 649 } 650 651 /** 652 * Updates a cached service for a given user. 653 */ 654 @GuardedBy("mLock") updateCachedServiceLocked(@serIdInt int userId)655 protected void updateCachedServiceLocked(@UserIdInt int userId) { 656 updateCachedServiceListLocked(userId, isDisabledLocked(userId)); 657 } 658 659 /** 660 * Checks whether the service is disabled (through {@link UserManager} restrictions) for the 661 * given user. 662 */ 663 @GuardedBy("mLock") isDisabledLocked(@serIdInt int userId)664 protected boolean isDisabledLocked(@UserIdInt int userId) { 665 return mDisabledByUserRestriction != null && mDisabledByUserRestriction.get(userId); 666 } 667 668 /** 669 * Updates a cached service for a given user. 670 * 671 * @param userId user handle. 672 * @param disabled whether the user is disabled. 673 * @return service for the user. 674 */ 675 @GuardedBy("mLock") updateCachedServiceLocked(@serIdInt int userId, boolean disabled)676 protected S updateCachedServiceLocked(@UserIdInt int userId, boolean disabled) { 677 final S service = getServiceForUserLocked(userId); 678 updateCachedServiceListLocked(userId, disabled); 679 return service; 680 } 681 682 /** 683 * Updates a cached service for a given user. 684 * 685 * @param userId user handle. 686 * @param disabled whether the user is disabled. 687 * @return service for the user. 688 */ 689 @GuardedBy("mLock") updateCachedServiceListLocked(@serIdInt int userId, boolean disabled)690 protected List<S> updateCachedServiceListLocked(@UserIdInt int userId, boolean disabled) { 691 if (mServiceNameResolver != null 692 && mServiceNameResolver.isConfiguredInMultipleMode()) { 693 // In multiple mode, we have multiple instances of AbstractPerUserSystemService, per 694 // user where each instance holds information needed to connect to a backend. An 695 // update operation in this mode needs to account for addition, deletion, change 696 // of backends and cannot be executed in the scope of a given 697 // AbstractPerUserSystemService. 698 return updateCachedServiceListMultiModeLocked(userId, disabled); 699 } 700 // isConfiguredInMultipleMode is false 701 final List<S> services = getServiceListForUserLocked(userId); 702 if (services == null) { 703 return null; 704 } 705 for (int i = 0; i < services.size(); i++) { 706 S service = services.get(i); 707 if (service != null) { 708 synchronized (service.mLock) { 709 service.updateLocked(disabled); 710 if (!service.isEnabledLocked()) { 711 removeCachedServiceListLocked(userId); 712 } else { 713 onServiceEnabledLocked(services.get(i), userId); 714 } 715 } 716 } 717 } 718 return services; 719 } 720 721 @GuardedBy("mLock") updateCachedServiceListMultiModeLocked(int userId, boolean disabled)722 private List<S> updateCachedServiceListMultiModeLocked(int userId, boolean disabled) { 723 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 724 Binder.getCallingUid(), userId, false, false, null, 725 null); 726 List<S> services = new ArrayList<>(); 727 synchronized (mLock) { 728 removeCachedServiceListLocked(resolvedUserId); 729 services = getServiceListForUserLocked(userId); 730 } 731 return services; 732 } 733 734 /** 735 * Gets the Settings property that defines the name of the component name used to bind this 736 * service to an external service, or {@code null} when the service is not defined by such 737 * property (for example, if it's a system service defined by framework resources). 738 */ 739 @Nullable getServiceSettingsProperty()740 protected String getServiceSettingsProperty() { 741 return null; 742 } 743 744 /** 745 * Callback called after a new service was added to the cache, or an existing service that was 746 * previously disabled gets enabled. 747 * 748 * <p>By default doesn't do anything, but can be overridden by subclasses. 749 */ 750 @SuppressWarnings("unused") 751 @GuardedBy("mLock") onServiceEnabledLocked(@onNull S service, @UserIdInt int userId)752 protected void onServiceEnabledLocked(@NonNull S service, @UserIdInt int userId) { 753 } 754 755 /** 756 * Removes a cached service list for a given user. 757 * 758 * @return the removed service. 759 */ 760 @GuardedBy("mLock") 761 @NonNull removeCachedServiceListLocked(@serIdInt int userId)762 protected final List<S> removeCachedServiceListLocked(@UserIdInt int userId) { 763 final List<S> services = peekServiceListForUserLocked(userId); 764 if (services != null) { 765 mServicesCacheList.delete(userId); 766 for (int i = 0; i < services.size(); i++) { 767 onServiceRemoved(services.get(i), userId); 768 } 769 } 770 return services; 771 } 772 773 /** 774 * Called before the package that provides the service for the given user is being updated. 775 */ 776 @GuardedBy("mLock") onServicePackageUpdatingLocked(@serIdInt int userId)777 protected void onServicePackageUpdatingLocked(@UserIdInt int userId) { 778 if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")"); 779 } 780 781 /** 782 * Called after the package that provides the service for the given user is being updated. 783 */ 784 @GuardedBy("mLock") onServicePackageUpdatedLocked(@serIdInt int userId)785 protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { 786 if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")"); 787 } 788 789 /** 790 * Called after the package data that provides the service for the given user is cleared. 791 */ 792 @GuardedBy("mLock") onServicePackageDataClearedLocked(@serIdInt int userId)793 protected void onServicePackageDataClearedLocked(@UserIdInt int userId) { 794 if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")"); 795 } 796 797 /** 798 * Called after the package that provides the service for the given user is restarted. 799 */ 800 @GuardedBy("mLock") onServicePackageRestartedLocked(@serIdInt int userId)801 protected void onServicePackageRestartedLocked(@UserIdInt int userId) { 802 if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")"); 803 } 804 805 /** 806 * Called after the service is removed from the cache. 807 */ 808 @SuppressWarnings("unused") onServiceRemoved(@onNull S service, @UserIdInt int userId)809 protected void onServiceRemoved(@NonNull S service, @UserIdInt int userId) { 810 } 811 812 /** 813 * Called when the service name changed (typically when using temporary services). 814 * 815 * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call 816 * that same method, or {@code super.onServiceNameChanged()}. 817 * 818 * @param userId user handle. 819 * @param serviceName the new service name. 820 * @param isTemporary whether the new service is temporary. 821 */ onServiceNameChanged(@serIdInt int userId, @Nullable String serviceName, boolean isTemporary)822 protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName, 823 boolean isTemporary) { 824 synchronized (mLock) { 825 updateCachedServiceListLocked(userId, isDisabledLocked(userId)); 826 } 827 } 828 829 /** 830 * Called when the service name list has changed (typically when using temporary services). 831 * 832 * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call 833 * that same method, or {@code super.onServiceNameChanged()}. 834 * 835 * @param userId user handle. 836 * @param serviceNames the new service name list. 837 * @param isTemporary whether the new service is temporary. 838 */ onServiceNameListChanged(@serIdInt int userId, @Nullable String[] serviceNames, boolean isTemporary)839 protected void onServiceNameListChanged(@UserIdInt int userId, @Nullable String[] serviceNames, 840 boolean isTemporary) { 841 synchronized (mLock) { 842 updateCachedServiceListLocked(userId, isDisabledLocked(userId)); 843 } 844 } 845 846 /** 847 * Visits all services in the cache. 848 */ 849 @GuardedBy("mLock") visitServicesLocked(@onNull Visitor<S> visitor)850 protected void visitServicesLocked(@NonNull Visitor<S> visitor) { 851 final int size = mServicesCacheList.size(); 852 for (int i = 0; i < size; i++) { 853 List<S> services = mServicesCacheList.valueAt(i); 854 for (int j = 0; j < services.size(); j++) { 855 visitor.visit(services.get(j)); 856 } 857 } 858 } 859 860 /** 861 * Clear the cache by removing all services. 862 */ 863 @GuardedBy("mLock") clearCacheLocked()864 protected void clearCacheLocked() { 865 mServicesCacheList.clear(); 866 } 867 868 /** 869 * Gets a cached reference to {@link UserManagerInternal}. 870 */ 871 @NonNull getUserManagerInternal()872 protected UserManagerInternal getUserManagerInternal() { 873 if (mUm == null) { 874 if (verbose) Slog.v(mTag, "lazy-loading UserManagerInternal"); 875 mUm = LocalServices.getService(UserManagerInternal.class); 876 } 877 return mUm; 878 } 879 880 /** 881 * Gets a list of all supported users (i.e., those that pass the 882 * {@link #isUserSupported(TargetUser)}check). 883 */ 884 @NonNull getSupportedUsers()885 protected List<UserInfo> getSupportedUsers() { 886 final UserInfo[] allUsers = getUserManagerInternal().getUserInfos(); 887 final int size = allUsers.length; 888 final List<UserInfo> supportedUsers = new ArrayList<>(size); 889 for (int i = 0; i < size; i++) { 890 final UserInfo userInfo = allUsers[i]; 891 if (isUserSupported(new TargetUser(userInfo))) { 892 supportedUsers.add(userInfo); 893 } 894 } 895 return supportedUsers; 896 } 897 898 /** 899 * Asserts that the given package name is owned by the UID making this call. 900 * 901 * @throws SecurityException when it's not... 902 */ assertCalledByPackageOwner(@onNull String packageName)903 protected void assertCalledByPackageOwner(@NonNull String packageName) { 904 Objects.requireNonNull(packageName); 905 final int uid = Binder.getCallingUid(); 906 final String[] packages = getContext().getPackageManager().getPackagesForUid(uid); 907 if (packages != null) { 908 for (String candidate : packages) { 909 if (packageName.equals(candidate)) return; // Found it 910 } 911 } 912 throw new SecurityException("UID " + uid + " does not own " + packageName); 913 } 914 915 // TODO(b/117779333): support proto 916 @GuardedBy("mLock") dumpLocked(@onNull String prefix, @NonNull PrintWriter pw)917 protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) { 918 boolean realDebug = debug; 919 boolean realVerbose = verbose; 920 final String prefix2 = " "; 921 922 try { 923 // Temporarily turn on full logging; 924 debug = verbose = true; 925 final int size = mServicesCacheList.size(); 926 pw.print(prefix); 927 pw.print("Debug: "); 928 pw.print(realDebug); 929 pw.print(" Verbose: "); 930 pw.println(realVerbose); 931 pw.print("Package policy flags: "); 932 pw.println(mServicePackagePolicyFlags); 933 if (mUpdatingPackageNames != null) { 934 pw.print("Packages being updated: "); 935 pw.println(mUpdatingPackageNames); 936 } 937 dumpSupportedUsers(pw, prefix); 938 if (mServiceNameResolver != null) { 939 pw.print(prefix); 940 pw.print("Name resolver: "); 941 mServiceNameResolver.dumpShort(pw); 942 pw.println(); 943 final List<UserInfo> users = getSupportedUsers(); 944 for (int i = 0; i < users.size(); i++) { 945 final int userId = users.get(i).id; 946 pw.print(prefix2); 947 pw.print(userId); 948 pw.print(": "); 949 mServiceNameResolver.dumpShort(pw, userId); 950 pw.println(); 951 } 952 } 953 pw.print(prefix); 954 pw.print("Users disabled by restriction: "); 955 pw.println(mDisabledByUserRestriction); 956 pw.print(prefix); 957 pw.print("Allow instant service: "); 958 pw.println(mAllowInstantService); 959 final String settingsProperty = getServiceSettingsProperty(); 960 if (settingsProperty != null) { 961 pw.print(prefix); 962 pw.print("Settings property: "); 963 pw.println(settingsProperty); 964 } 965 pw.print(prefix); 966 pw.print("Cached services: "); 967 if (size == 0) { 968 pw.println("none"); 969 } else { 970 pw.println(size); 971 for (int i = 0; i < size; i++) { 972 pw.print(prefix); 973 pw.print("Service at "); 974 pw.print(i); 975 pw.println(": "); 976 final List<S> services = mServicesCacheList.valueAt(i); 977 for (int j = 0; j < services.size(); j++) { 978 S service = services.get(j); 979 synchronized (service.mLock) { 980 service.dumpLocked(prefix2, pw); 981 } 982 } 983 pw.println(); 984 } 985 } 986 } finally { 987 debug = realDebug; 988 verbose = realVerbose; 989 } 990 } 991 992 private class MyPackageMonitor extends PackageMonitor { MyPackageMonitor(boolean supportsPackageRestartQuery)993 MyPackageMonitor(boolean supportsPackageRestartQuery) { 994 super(supportsPackageRestartQuery); 995 } 996 997 @Override onPackageUpdateStarted(@onNull String packageName, int uid)998 public void onPackageUpdateStarted(@NonNull String packageName, int uid) { 999 if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName); 1000 synchronized (mLock) { 1001 final String activePackageName = getActiveServicePackageNameLocked(); 1002 if (!packageName.equals(activePackageName)) return; 1003 1004 final int userId = getChangingUserId(); 1005 1006 if (mUpdatingPackageNames == null) { 1007 mUpdatingPackageNames = new SparseArray<String>(mServicesCacheList.size()); 1008 } 1009 mUpdatingPackageNames.put(userId, packageName); 1010 onServicePackageUpdatingLocked(userId); 1011 if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) { 1012 if (debug) { 1013 Slog.d(mTag, "Holding service for user " + userId + " while package " 1014 + activePackageName + " is being updated"); 1015 } 1016 } else { 1017 if (debug) { 1018 Slog.d(mTag, "Removing service for user " + userId 1019 + " because package " + activePackageName 1020 + " is being updated"); 1021 } 1022 removeCachedServiceListLocked(userId); 1023 1024 if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER) 1025 != 0) { 1026 if (debug) { 1027 Slog.d(mTag, "Eagerly recreating service for user " 1028 + userId); 1029 } 1030 getServiceForUserLocked(userId); 1031 } 1032 } 1033 } 1034 } 1035 1036 @Override onPackageUpdateFinished(@onNull String packageName, int uid)1037 public void onPackageUpdateFinished(@NonNull String packageName, int uid) { 1038 if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName); 1039 final int userId = getChangingUserId(); 1040 synchronized (mLock) { 1041 final String activePackageName = mUpdatingPackageNames == null ? null 1042 : mUpdatingPackageNames.get(userId); 1043 if (packageName.equals(activePackageName)) { 1044 if (mUpdatingPackageNames != null) { 1045 mUpdatingPackageNames.remove(userId); 1046 if (mUpdatingPackageNames.size() == 0) { 1047 mUpdatingPackageNames = null; 1048 } 1049 } 1050 onServicePackageUpdatedLocked(userId); 1051 } else { 1052 handlePackageUpdateLocked(packageName); 1053 } 1054 } 1055 } 1056 1057 @Override onPackageRemoved(String packageName, int uid)1058 public void onPackageRemoved(String packageName, int uid) { 1059 if (mServiceNameResolver != null 1060 && mServiceNameResolver.isConfiguredInMultipleMode()) { 1061 final int userId = getChangingUserId(); 1062 synchronized (mLock) { 1063 handlePackageRemovedMultiModeLocked(packageName, userId); 1064 } 1065 return; 1066 } 1067 1068 synchronized (mLock) { 1069 final int userId = getChangingUserId(); 1070 final S service = peekServiceForUserLocked(userId); 1071 if (service != null) { 1072 final ComponentName componentName = service.getServiceComponentName(); 1073 if (componentName != null) { 1074 if (packageName.equals(componentName.getPackageName())) { 1075 handleActiveServiceRemoved(userId); 1076 } 1077 } 1078 } 1079 } 1080 } 1081 1082 @Override onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit)1083 public boolean onHandleForceStop(Intent intent, String[] packages, 1084 int uid, boolean doit) { 1085 synchronized (mLock) { 1086 final String activePackageName = getActiveServicePackageNameLocked(); 1087 for (String pkg : packages) { 1088 if (pkg.equals(activePackageName)) { 1089 if (!doit) { 1090 return true; 1091 } 1092 final String action = intent.getAction(); 1093 final int userId = getChangingUserId(); 1094 if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) { 1095 handleActiveServiceRestartedLocked(activePackageName, userId); 1096 } else { 1097 removeCachedServiceListLocked(userId); 1098 } 1099 } else { 1100 handlePackageUpdateLocked(pkg); 1101 } 1102 } 1103 } 1104 return false; 1105 } 1106 1107 @Override onPackageDataCleared(String packageName, int uid)1108 public void onPackageDataCleared(String packageName, int uid) { 1109 if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName); 1110 final int userId = getChangingUserId(); 1111 1112 if (mServiceNameResolver != null 1113 && mServiceNameResolver.isConfiguredInMultipleMode()) { 1114 synchronized (mLock) { 1115 onServicePackageDataClearedMultiModeLocked(packageName, userId); 1116 } 1117 return; 1118 } 1119 1120 synchronized (mLock) { 1121 final S service = peekServiceForUserLocked(userId); 1122 if (service != null) { 1123 final ComponentName componentName = service.getServiceComponentName(); 1124 if (componentName != null) { 1125 if (packageName.equals(componentName.getPackageName())) { 1126 onServicePackageDataClearedLocked(userId); 1127 } 1128 } 1129 } 1130 } 1131 } 1132 handleActiveServiceRemoved(@serIdInt int userId)1133 private void handleActiveServiceRemoved(@UserIdInt int userId) { 1134 synchronized (mLock) { 1135 removeCachedServiceListLocked(userId); 1136 } 1137 final String serviceSettingsProperty = getServiceSettingsProperty(); 1138 if (serviceSettingsProperty != null) { 1139 Settings.Secure.putStringForUser(getContext().getContentResolver(), 1140 serviceSettingsProperty, null, userId); 1141 } 1142 } 1143 1144 @GuardedBy("mLock") handleActiveServiceRestartedLocked(String activePackageName, @UserIdInt int userId)1145 private void handleActiveServiceRestartedLocked(String activePackageName, 1146 @UserIdInt int userId) { 1147 if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) { 1148 if (debug) { 1149 Slog.d(mTag, "Holding service for user " + userId + " while package " 1150 + activePackageName + " is being restarted"); 1151 } 1152 } else { 1153 if (debug) { 1154 Slog.d(mTag, "Removing service for user " + userId 1155 + " because package " + activePackageName 1156 + " is being restarted"); 1157 } 1158 removeCachedServiceListLocked(userId); 1159 1160 if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) { 1161 if (debug) { 1162 Slog.d(mTag, "Eagerly recreating service for user " + userId); 1163 } 1164 updateCachedServiceLocked(userId); 1165 } 1166 } 1167 onServicePackageRestartedLocked(userId); 1168 } 1169 1170 @Override onPackageModified(String packageName)1171 public void onPackageModified(String packageName) { 1172 synchronized (mLock) { 1173 if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName); 1174 1175 if (mServiceNameResolver == null) { 1176 return; 1177 } 1178 1179 final int userId = getChangingUserId(); 1180 final String[] serviceNames = mServiceNameResolver.getDefaultServiceNameList( 1181 userId); 1182 if (serviceNames != null) { 1183 if (Flags.packageUpdateFixEnabled()) { 1184 if (mServiceNameResolver.isConfiguredInMultipleMode()) { 1185 // Remove any service that is in the cache but is no longer valid 1186 // after this modification for this particular package 1187 removeInvalidCachedServicesLocked(serviceNames, packageName, 1188 userId); 1189 } 1190 } 1191 1192 // Update services that are still valid 1193 for (int i = 0; i < serviceNames.length; i++) { 1194 peekAndUpdateCachedServiceLocked(packageName, userId, 1195 serviceNames[i]); 1196 } 1197 } 1198 } 1199 } 1200 1201 @GuardedBy("mLock") peekAndUpdateCachedServiceLocked(String packageName, int userId, String serviceName)1202 private void peekAndUpdateCachedServiceLocked(String packageName, int userId, 1203 String serviceName) { 1204 if (serviceName == null) { 1205 return; 1206 } 1207 1208 final ComponentName serviceComponentName = 1209 ComponentName.unflattenFromString(serviceName); 1210 if (serviceComponentName == null 1211 || !serviceComponentName.getPackageName().equals(packageName)) { 1212 return; 1213 } 1214 1215 // The default service package has changed, update the cached if the service 1216 // exists but no active component. 1217 final S service = peekServiceForUserLocked(userId); 1218 if (service != null) { 1219 final ComponentName componentName = service.getServiceComponentName(); 1220 if (componentName == null) { 1221 if (verbose) Slog.v(mTag, "update cached"); 1222 updateCachedServiceLocked(userId); 1223 } 1224 } 1225 } 1226 1227 @GuardedBy("mLock") getActiveServicePackageNameLocked()1228 private String getActiveServicePackageNameLocked() { 1229 final int userId = getChangingUserId(); 1230 final S service = peekServiceForUserLocked(userId); 1231 if (service == null) { 1232 return null; 1233 } 1234 final ComponentName serviceComponent = service.getServiceComponentName(); 1235 if (serviceComponent == null) { 1236 return null; 1237 } 1238 return serviceComponent.getPackageName(); 1239 } 1240 1241 @GuardedBy("mLock") handlePackageUpdateLocked(String packageName)1242 private void handlePackageUpdateLocked(String packageName) { 1243 visitServicesLocked((s) -> s.handlePackageUpdateLocked(packageName)); 1244 } 1245 } 1246 startTrackingPackageChanges()1247 private void startTrackingPackageChanges() { 1248 // package changes 1249 mPackageMonitor.register(getContext(), null, UserHandle.ALL, true); 1250 } 1251 1252 @GuardedBy("mLock") 1253 @SuppressWarnings("GuardedBy") // ErrorProne requires this.mLock for 1254 // handleServiceRemovedMultiModeLocked which is the same removeInvalidCachedServicesLocked(String[] validServices, String packageName, int userId)1255 private void removeInvalidCachedServicesLocked(String[] validServices, 1256 String packageName, int userId) { 1257 visitServicesLocked((s) -> { 1258 ComponentName serviceComponentName = s 1259 .getServiceComponentName(); 1260 if (serviceComponentName != null && serviceComponentName 1261 .getPackageName().equals(packageName)) { 1262 if (!serviceInValidServiceList(serviceComponentName, 1263 validServices)) { 1264 handleServiceRemovedMultiModeLocked( 1265 serviceComponentName, userId); 1266 } 1267 } 1268 }); 1269 } 1270 serviceInValidServiceList(ComponentName serviceComponentName, String[] serviceNames)1271 private boolean serviceInValidServiceList(ComponentName serviceComponentName, 1272 String[] serviceNames) { 1273 for (String service: serviceNames) { 1274 ComponentName componentName = ComponentName.unflattenFromString(service); 1275 if (componentName != null && componentName.equals(serviceComponentName)) { 1276 return true; 1277 } 1278 } 1279 return false; 1280 } 1281 1282 @GuardedBy("mLock") 1283 @SuppressWarnings("unused") onServicePackageDataClearedMultiModeLocked(String packageName, int userId)1284 protected void onServicePackageDataClearedMultiModeLocked(String packageName, int userId) { 1285 if (verbose) { 1286 Slog.v(mTag, "onServicePackageDataClearedMultiModeLocked(" 1287 + userId + ")"); 1288 } 1289 } 1290 1291 @GuardedBy("mLock") 1292 @SuppressWarnings("unused") handlePackageRemovedMultiModeLocked(String packageName, int userId)1293 protected void handlePackageRemovedMultiModeLocked(String packageName, int userId) { 1294 if (verbose) Slog.v(mTag, "handlePackageRemovedMultiModeLocked(" + userId + ")"); 1295 } 1296 1297 @GuardedBy("mLock") handleServiceRemovedMultiModeLocked(ComponentName serviceComponentName, int userId)1298 protected void handleServiceRemovedMultiModeLocked(ComponentName serviceComponentName, 1299 int userId) { 1300 if (verbose) Slog.v(mTag, "handleServiceRemovedMultiModeLocked(" + userId + ")"); 1301 } 1302 1303 @GuardedBy("mLock") removeServiceFromCache(@onNull S service, int userId)1304 protected void removeServiceFromCache(@NonNull S service, int userId) { 1305 if (mServicesCacheList.get(userId) != null) { 1306 mServicesCacheList.get(userId).remove(service); 1307 } 1308 } 1309 1310 @GuardedBy("mLock") removeServiceFromMultiModeSettings(String serviceComponentName, int userId)1311 protected void removeServiceFromMultiModeSettings(String serviceComponentName, int userId) { 1312 final String serviceSettingsProperty = getServiceSettingsProperty(); 1313 if (serviceSettingsProperty == null || mServiceNameResolver == null 1314 || !mServiceNameResolver.isConfiguredInMultipleMode()) { 1315 if (verbose) { 1316 Slog.v(mTag, "removeServiceFromSettings not implemented " 1317 + " for single backend implementation"); 1318 } 1319 return; 1320 } 1321 String[] settingComponentNames = mServiceNameResolver.getServiceNameList(userId); 1322 List<String> remainingServices = new ArrayList<>(); 1323 for (String settingComponentName : settingComponentNames) { 1324 if (!settingComponentName.equals(serviceComponentName)) { 1325 remainingServices.add(settingComponentName); 1326 } 1327 } 1328 mServiceNameResolver.setServiceNameList(remainingServices, userId); 1329 } 1330 1331 /** 1332 * Visitor pattern. 1333 * 1334 * @param <S> visited class. 1335 */ 1336 public interface Visitor<S> { 1337 /** 1338 * Visits a service. 1339 * 1340 * @param service the service to be visited. 1341 */ visit(@onNull S service)1342 void visit(@NonNull S service); 1343 } 1344 1345 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)1346 SettingsObserver(Handler handler) { 1347 super(handler); 1348 ContentResolver resolver = getContext().getContentResolver(); 1349 final String serviceProperty = getServiceSettingsProperty(); 1350 if (serviceProperty != null) { 1351 resolver.registerContentObserver(Settings.Secure.getUriFor( 1352 serviceProperty), false, this, UserHandle.USER_ALL); 1353 } 1354 resolver.registerContentObserver(Settings.Secure.getUriFor( 1355 Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL); 1356 registerForExtraSettingsChanges(resolver, this); 1357 } 1358 1359 @Override onChange(boolean selfChange, Uri uri, @UserIdInt int userId)1360 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { 1361 if (verbose) Slog.v(mTag, "onChange(): uri=" + uri + ", userId=" + userId); 1362 final String property = uri.getLastPathSegment(); 1363 if (property == null) { 1364 return; 1365 } 1366 if (property.equals(getServiceSettingsProperty()) 1367 || property.equals(Settings.Secure.USER_SETUP_COMPLETE)) { 1368 synchronized (mLock) { 1369 updateCachedServiceLocked(userId); 1370 } 1371 } else { 1372 onSettingsChanged(userId, property); 1373 } 1374 } 1375 } 1376 } 1377