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.database.ContentObserver; 29 import android.net.Uri; 30 import android.os.Binder; 31 import android.os.Handler; 32 import android.os.UserHandle; 33 import android.os.UserManager; 34 import android.os.UserManagerInternal; 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.internal.util.Preconditions; 45 import com.android.server.LocalServices; 46 import com.android.server.SystemService; 47 48 import java.io.PrintWriter; 49 import java.lang.annotation.Retention; 50 import java.lang.annotation.RetentionPolicy; 51 import java.util.List; 52 53 /** 54 * Base class for {@link SystemService SystemServices} that support multi user. 55 * 56 * <p>Subclasses of this service are just a facade for the service binder calls - the "real" work 57 * is done by the {@link AbstractPerUserSystemService} subclasses, which are automatically managed 58 * through an user -> service cache. 59 * 60 * <p>It also takes care of other plumbing tasks such as: 61 * 62 * <ul> 63 * <li>Disabling the service when {@link UserManager} restrictions change. 64 * <li>Refreshing the service when its underlying 65 * {@link #getServiceSettingsProperty() Settings property} changed. 66 * <li>Calling the service when other Settings properties changed. 67 * </ul> 68 * 69 * <p>See {@code com.android.server.autofill.AutofillManagerService} for a concrete 70 * (no pun intended) example of how to use it. 71 * 72 * @param <M> "master" service class. 73 * @param <S> "real" service class. 74 * 75 * @hide 76 */ 77 // TODO(b/117779333): improve javadoc above instead of using Autofill as an example 78 public abstract class AbstractMasterSystemService<M extends AbstractMasterSystemService<M, S>, 79 S extends AbstractPerUserSystemService<S, M>> extends SystemService { 80 81 /** On a package update, does not refresh the per-user service in the cache. */ 82 public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0; 83 84 /** 85 * On a package update, removes any existing per-user services in the cache. 86 * 87 * <p>This does not immediately recreate these services. It is assumed they will be recreated 88 * for the next user request. 89 */ 90 public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1; 91 92 /** 93 * On a package update, removes and recreates any existing per-user services in the cache. 94 */ 95 public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2; 96 97 @IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = { 98 PACKAGE_UPDATE_POLICY_NO_REFRESH, 99 PACKAGE_UPDATE_POLICY_REFRESH_LAZY, 100 PACKAGE_UPDATE_POLICY_REFRESH_EAGER 101 }) 102 @Retention(RetentionPolicy.SOURCE) 103 public @interface PackageUpdatePolicy {} 104 105 /** 106 * Log tag 107 */ 108 protected final String mTag = getClass().getSimpleName(); 109 110 /** 111 * Lock used to synchronize access to internal state; should be acquired before calling a 112 * method whose name ends with {@code locked}. 113 */ 114 protected final Object mLock = new Object(); 115 116 /** 117 * Object used to define the name of the service component used to create 118 * {@link com.android.internal.infra.AbstractRemoteService} instances. 119 */ 120 @Nullable 121 protected final ServiceNameResolver mServiceNameResolver; 122 123 /** 124 * Whether the service should log debug statements. 125 */ 126 //TODO(b/117779333): consider using constants for these guards 127 public boolean verbose = false; 128 129 /** 130 * Whether the service should log verbose statements. 131 */ 132 //TODO(b/117779333): consider using constants for these guards 133 public boolean debug = false; 134 135 /** 136 * Whether the service is allowed to bind to an instant-app. 137 */ 138 @GuardedBy("mLock") 139 protected boolean mAllowInstantService; 140 141 /** 142 * Users disabled due to {@link UserManager} restrictions, or {@code null} if the service cannot 143 * be disabled through {@link UserManager}. 144 */ 145 @GuardedBy("mLock") 146 @Nullable 147 private final SparseBooleanArray mDisabledByUserRestriction; 148 149 /** 150 * Cache of services per user id. 151 */ 152 @GuardedBy("mLock") 153 private final SparseArray<S> mServicesCache = new SparseArray<>(); 154 155 /** 156 * Whether the per-user service should be removed from the cache when its apk is updated. 157 * 158 * <p>One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, 159 * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}. 160 */ 161 private final @PackageUpdatePolicy int mPackageUpdatePolicy; 162 163 /** 164 * Name of the service packages whose APK are being updated, keyed by user id. 165 */ 166 @GuardedBy("mLock") 167 private SparseArray<String> mUpdatingPackageNames; 168 169 /** 170 * Default constructor. 171 * 172 * <p>When using this constructor, the {@link AbstractPerUserSystemService} is removed from 173 * the cache (and re-added) when the service package is updated. 174 * 175 * @param context system context. 176 * @param serviceNameResolver resolver for 177 * {@link com.android.internal.infra.AbstractRemoteService} instances, or 178 * {@code null} when the service doesn't bind to remote services. 179 * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that 180 * disables the service. <b>NOTE: </b> you'll also need to add it to 181 * {@code UserRestrictionsUtils.USER_RESTRICTIONS}. 182 */ AbstractMasterSystemService(@onNull Context context, @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty)183 protected AbstractMasterSystemService(@NonNull Context context, 184 @Nullable ServiceNameResolver serviceNameResolver, 185 @Nullable String disallowProperty) { 186 this(context, serviceNameResolver, disallowProperty, 187 /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY); 188 } 189 190 /** 191 * Full constructor. 192 * 193 * @param context system context. 194 * @param serviceNameResolver resolver for 195 * {@link com.android.internal.infra.AbstractRemoteService} instances, or 196 * {@code null} when the service doesn't bind to remote services. 197 * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that 198 * disables the service. <b>NOTE: </b> you'll also need to add it to 199 * {@code UserRestrictionsUtils.USER_RESTRICTIONS}. 200 * @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the 201 * {@link AbstractPerUserSystemService} is removed from the cache when the service 202 * package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the 203 * {@link AbstractPerUserSystemService} is removed from the cache and immediately 204 * re-added when the service package is updated; when 205 * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update. 206 */ AbstractMasterSystemService(@onNull Context context, @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy)207 protected AbstractMasterSystemService(@NonNull Context context, 208 @Nullable ServiceNameResolver serviceNameResolver, 209 @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) { 210 super(context); 211 212 mPackageUpdatePolicy = packageUpdatePolicy; 213 214 mServiceNameResolver = serviceNameResolver; 215 if (mServiceNameResolver != null) { 216 mServiceNameResolver.setOnTemporaryServiceNameChangedCallback( 217 (u, s, t) -> onServiceNameChanged(u, s, t)); 218 219 } 220 if (disallowProperty == null) { 221 mDisabledByUserRestriction = null; 222 } else { 223 mDisabledByUserRestriction = new SparseBooleanArray(); 224 // Hookup with UserManager to disable service when necessary. 225 final UserManager um = context.getSystemService(UserManager.class); 226 final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); 227 final List<UserInfo> users = um.getUsers(); 228 for (int i = 0; i < users.size(); i++) { 229 final int userId = users.get(i).id; 230 final boolean disabled = umi.getUserRestriction(userId, disallowProperty); 231 if (disabled) { 232 Slog.i(mTag, "Disabling by restrictions user " + userId); 233 mDisabledByUserRestriction.put(userId, disabled); 234 } 235 } 236 umi.addUserRestrictionsListener((userId, newRestrictions, prevRestrictions) -> { 237 final boolean disabledNow = 238 newRestrictions.getBoolean(disallowProperty, false); 239 synchronized (mLock) { 240 final boolean disabledBefore = mDisabledByUserRestriction.get(userId); 241 if (disabledBefore == disabledNow) { 242 // Nothing changed, do nothing. 243 if (debug) { 244 Slog.d(mTag, "Restriction did not change for user " + userId); 245 return; 246 } 247 } 248 Slog.i(mTag, "Updating for user " + userId + ": disabled=" + disabledNow); 249 mDisabledByUserRestriction.put(userId, disabledNow); 250 updateCachedServiceLocked(userId, disabledNow); 251 } 252 }); 253 } 254 startTrackingPackageChanges(); 255 } 256 257 @Override // from SystemService onBootPhase(int phase)258 public void onBootPhase(int phase) { 259 if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 260 new SettingsObserver(BackgroundThread.getHandler()); 261 } 262 } 263 264 @Override // from SystemService onUnlockUser(int userId)265 public void onUnlockUser(int userId) { 266 synchronized (mLock) { 267 updateCachedServiceLocked(userId); 268 } 269 } 270 271 @Override // from SystemService onCleanupUser(int userId)272 public void onCleanupUser(int userId) { 273 synchronized (mLock) { 274 removeCachedServiceLocked(userId); 275 } 276 } 277 278 /** 279 * Gets whether the service is allowed to bind to an instant-app. 280 * 281 * <p>Typically called by {@code ShellCommand} during CTS tests. 282 * 283 * @throws SecurityException if caller is not allowed to manage this service's settings. 284 */ getAllowInstantService()285 public final boolean getAllowInstantService() { 286 enforceCallingPermissionForManagement(); 287 synchronized (mLock) { 288 return mAllowInstantService; 289 } 290 } 291 292 /** 293 * Checks whether the service is allowed to bind to an instant-app. 294 * 295 * <p>Typically called by subclasses when creating {@link AbstractRemoteService} instances. 296 * 297 * <p><b>NOTE: </b>must not be called by {@code ShellCommand} as it does not check for 298 * permission. 299 */ isBindInstantServiceAllowed()300 public final boolean isBindInstantServiceAllowed() { 301 synchronized (mLock) { 302 return mAllowInstantService; 303 } 304 } 305 306 /** 307 * Sets whether the service is allowed to bind to an instant-app. 308 * 309 * <p>Typically called by {@code ShellCommand} during CTS tests. 310 * 311 * @throws SecurityException if caller is not allowed to manage this service's settings. 312 */ setAllowInstantService(boolean mode)313 public final void setAllowInstantService(boolean mode) { 314 Slog.i(mTag, "setAllowInstantService(): " + mode); 315 enforceCallingPermissionForManagement(); 316 synchronized (mLock) { 317 mAllowInstantService = mode; 318 } 319 } 320 321 /** 322 * Temporarily sets the service implementation. 323 * 324 * <p>Typically used by Shell command and/or CTS tests. 325 * 326 * @param componentName name of the new component 327 * @param durationMs how long the change will be valid (the service will be automatically reset 328 * to the default component after this timeout expires). 329 * @throws SecurityException if caller is not allowed to manage this service's settings. 330 * @throws IllegalArgumentException if value of {@code durationMs} is higher than 331 * {@link #getMaximumTemporaryServiceDurationMs()}. 332 */ setTemporaryService(@serIdInt int userId, @NonNull String componentName, int durationMs)333 public final void setTemporaryService(@UserIdInt int userId, @NonNull String componentName, 334 int durationMs) { 335 Slog.i(mTag, "setTemporaryService(" + userId + ") to " + componentName + " for " 336 + durationMs + "ms"); 337 enforceCallingPermissionForManagement(); 338 339 Preconditions.checkNotNull(componentName); 340 final int maxDurationMs = getMaximumTemporaryServiceDurationMs(); 341 if (durationMs > maxDurationMs) { 342 throw new IllegalArgumentException( 343 "Max duration is " + maxDurationMs + " (called with " + durationMs + ")"); 344 } 345 346 synchronized (mLock) { 347 final S oldService = peekServiceForUserLocked(userId); 348 if (oldService != null) { 349 oldService.removeSelfFromCacheLocked(); 350 } 351 mServiceNameResolver.setTemporaryService(userId, componentName, durationMs); 352 } 353 } 354 355 /** 356 * Sets whether the default service should be used. 357 * 358 * <p>Typically used during CTS tests to make sure only the default service doesn't interfere 359 * with the test results. 360 * 361 * @throws SecurityException if caller is not allowed to manage this service's settings. 362 * 363 * @return whether the enabled state changed. 364 */ setDefaultServiceEnabled(@serIdInt int userId, boolean enabled)365 public final boolean setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) { 366 Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled); 367 enforceCallingPermissionForManagement(); 368 369 synchronized (mLock) { 370 final boolean changed = mServiceNameResolver.setDefaultServiceEnabled(userId, enabled); 371 if (!changed) { 372 if (verbose) { 373 Slog.v(mTag, "setDefaultServiceEnabled(" + userId + "): already " + enabled); 374 } 375 return false; 376 } 377 378 final S oldService = peekServiceForUserLocked(userId); 379 if (oldService != null) { 380 oldService.removeSelfFromCacheLocked(); 381 } 382 383 // Must update the service on cache so its initialization code is triggered 384 updateCachedServiceLocked(userId); 385 } 386 return true; 387 } 388 389 /** 390 * Checks whether the default service should be used. 391 * 392 * <p>Typically used during CTS tests to make sure only the default service doesn't interfere 393 * with the test results. 394 * 395 * @throws SecurityException if caller is not allowed to manage this service's settings. 396 */ isDefaultServiceEnabled(@serIdInt int userId)397 public final boolean isDefaultServiceEnabled(@UserIdInt int userId) { 398 enforceCallingPermissionForManagement(); 399 400 synchronized (mLock) { 401 return mServiceNameResolver.isDefaultServiceEnabled(userId); 402 } 403 } 404 405 /** 406 * Gets the maximum time the service implementation can be changed. 407 * 408 * @throws UnsupportedOperationException if subclass doesn't override it. 409 */ getMaximumTemporaryServiceDurationMs()410 protected int getMaximumTemporaryServiceDurationMs() { 411 throw new UnsupportedOperationException("Not implemented by " + getClass()); 412 } 413 414 /** 415 * Resets the temporary service implementation to the default component. 416 * 417 * <p>Typically used by Shell command and/or CTS tests. 418 * 419 * @throws SecurityException if caller is not allowed to manage this service's settings. 420 */ resetTemporaryService(@serIdInt int userId)421 public final void resetTemporaryService(@UserIdInt int userId) { 422 Slog.i(mTag, "resetTemporaryService(): " + userId); 423 enforceCallingPermissionForManagement(); 424 synchronized (mLock) { 425 final S service = getServiceForUserLocked(userId); 426 if (service != null) { 427 service.resetTemporaryServiceLocked(); 428 } 429 } 430 } 431 432 /** 433 * Asserts that the caller has permissions to manage this service. 434 * 435 * <p>Typically called by {@code ShellCommand} implementations. 436 * 437 * @throws UnsupportedOperationException if subclass doesn't override it. 438 * @throws SecurityException if caller is not allowed to manage this service's settings. 439 */ enforceCallingPermissionForManagement()440 protected void enforceCallingPermissionForManagement() { 441 throw new UnsupportedOperationException("Not implemented by " + getClass()); 442 } 443 444 /** 445 * Creates a new service that will be added to the cache. 446 * 447 * @param resolvedUserId the resolved user id for the service. 448 * @param disabled whether the service is currently disabled (due to {@link UserManager} 449 * restrictions). 450 * 451 * @return a new instance. 452 */ 453 @Nullable newServiceLocked(@serIdInt int resolvedUserId, boolean disabled)454 protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled); 455 456 /** 457 * Register the service for extra Settings changes (i.e., other than 458 * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or 459 * {@link #getServiceSettingsProperty()}, which are automatically handled). 460 * 461 * <p> Example: 462 * 463 * <pre><code> 464 * resolver.registerContentObserver(Settings.Global.getUriFor( 465 * Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES), false, observer, 466 * UserHandle.USER_ALL); 467 * </code></pre> 468 * 469 * <p><b>NOTE: </p>it doesn't need to register for 470 * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or 471 * {@link #getServiceSettingsProperty()}. 472 * 473 */ 474 @SuppressWarnings("unused") registerForExtraSettingsChanges(@onNull ContentResolver resolver, @NonNull ContentObserver observer)475 protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver, 476 @NonNull ContentObserver observer) { 477 } 478 479 /** 480 * Callback for Settings changes that were registered though 481 * {@link #registerForExtraSettingsChanges(ContentResolver, ContentObserver)}. 482 * 483 * @param userId user associated with the change 484 * @param property Settings property changed. 485 */ onSettingsChanged(@serIdInt int userId, @NonNull String property)486 protected void onSettingsChanged(@UserIdInt int userId, @NonNull String property) { 487 } 488 489 /** 490 * Gets the service instance for an user, creating an instance if not present in the cache. 491 */ 492 @GuardedBy("mLock") 493 @NonNull getServiceForUserLocked(@serIdInt int userId)494 protected S getServiceForUserLocked(@UserIdInt int userId) { 495 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 496 Binder.getCallingUid(), userId, false, false, null, null); 497 S service = mServicesCache.get(resolvedUserId); 498 if (service == null) { 499 final boolean disabled = isDisabledLocked(userId); 500 service = newServiceLocked(resolvedUserId, disabled); 501 if (!disabled) { 502 onServiceEnabledLocked(service, resolvedUserId); 503 } 504 mServicesCache.put(userId, service); 505 } 506 return service; 507 } 508 509 /** 510 * Gets the <b>existing</b> service instance for a user, returning {@code null} if not already 511 * present in the cache. 512 */ 513 @GuardedBy("mLock") 514 @Nullable peekServiceForUserLocked(@serIdInt int userId)515 protected S peekServiceForUserLocked(@UserIdInt int userId) { 516 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 517 Binder.getCallingUid(), userId, false, false, null, null); 518 return mServicesCache.get(resolvedUserId); 519 } 520 521 /** 522 * Updates a cached service for a given user. 523 */ 524 @GuardedBy("mLock") updateCachedServiceLocked(@serIdInt int userId)525 protected void updateCachedServiceLocked(@UserIdInt int userId) { 526 updateCachedServiceLocked(userId, isDisabledLocked(userId)); 527 } 528 529 /** 530 * Checks whether the service is disabled (through {@link UserManager} restrictions) for the 531 * given user. 532 */ isDisabledLocked(@serIdInt int userId)533 protected boolean isDisabledLocked(@UserIdInt int userId) { 534 return mDisabledByUserRestriction == null ? false : mDisabledByUserRestriction.get(userId); 535 } 536 537 /** 538 * Updates a cached service for a given user. 539 * 540 * @param userId user handle. 541 * @param disabled whether the user is disabled. 542 * @return service for the user. 543 */ 544 @GuardedBy("mLock") updateCachedServiceLocked(@serIdInt int userId, boolean disabled)545 protected S updateCachedServiceLocked(@UserIdInt int userId, boolean disabled) { 546 final S service = getServiceForUserLocked(userId); 547 if (service != null) { 548 service.updateLocked(disabled); 549 if (!service.isEnabledLocked()) { 550 removeCachedServiceLocked(userId); 551 } else { 552 onServiceEnabledLocked(service, userId); 553 } 554 } 555 return service; 556 } 557 558 /** 559 * Gets the Settings property that defines the name of the component name used to bind this 560 * service to an external service, or {@code null} when the service is not defined by such 561 * property (for example, if it's a system service defined by framework resources). 562 */ 563 @Nullable getServiceSettingsProperty()564 protected String getServiceSettingsProperty() { 565 return null; 566 } 567 568 /** 569 * Callback called after a new service was added to the cache, or an existing service that was 570 * previously disabled gets enabled. 571 * 572 * <p>By default doesn't do anything, but can be overridden by subclasses. 573 */ 574 @SuppressWarnings("unused") onServiceEnabledLocked(@onNull S service, @UserIdInt int userId)575 protected void onServiceEnabledLocked(@NonNull S service, @UserIdInt int userId) { 576 } 577 578 /** 579 * Removes a cached service for a given user. 580 * 581 * @return the removed service. 582 */ 583 @GuardedBy("mLock") 584 @NonNull removeCachedServiceLocked(@serIdInt int userId)585 protected final S removeCachedServiceLocked(@UserIdInt int userId) { 586 final S service = peekServiceForUserLocked(userId); 587 if (service != null) { 588 mServicesCache.delete(userId); 589 onServiceRemoved(service, userId); 590 } 591 return service; 592 } 593 594 /** 595 * Called before the package that provides the service for the given user is being updated. 596 */ onServicePackageUpdatingLocked(@serIdInt int userId)597 protected void onServicePackageUpdatingLocked(@UserIdInt int userId) { 598 if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")"); 599 } 600 601 /** 602 * Called after the package that provides the service for the given user is being updated. 603 */ onServicePackageUpdatedLocked(@serIdInt int userId)604 protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { 605 if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")"); 606 } 607 608 /** 609 * Called after the service is removed from the cache. 610 */ 611 @SuppressWarnings("unused") onServiceRemoved(@onNull S service, @UserIdInt int userId)612 protected void onServiceRemoved(@NonNull S service, @UserIdInt int userId) { 613 } 614 615 /** 616 * Called when the service name changed (typically when using temporary services). 617 * 618 * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call 619 * that same method, or {@code super.onServiceNameChanged()}. 620 * 621 * @param userId user handle. 622 * @param serviceName the new service name. 623 * @param isTemporary whether the new service is temporary. 624 */ onServiceNameChanged(@serIdInt int userId, @Nullable String serviceName, boolean isTemporary)625 protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName, 626 boolean isTemporary) { 627 synchronized (mLock) { 628 updateCachedServiceLocked(userId); 629 } 630 } 631 632 /** 633 * Visits all services in the cache. 634 */ 635 @GuardedBy("mLock") visitServicesLocked(@onNull Visitor<S> visitor)636 protected void visitServicesLocked(@NonNull Visitor<S> visitor) { 637 final int size = mServicesCache.size(); 638 for (int i = 0; i < size; i++) { 639 visitor.visit(mServicesCache.valueAt(i)); 640 } 641 } 642 643 /** 644 * Clear the cache by removing all services. 645 */ 646 @GuardedBy("mLock") clearCacheLocked()647 protected void clearCacheLocked() { 648 mServicesCache.clear(); 649 } 650 651 /** 652 * Asserts that the given package name is owned by the UID making this call. 653 * 654 * @throws SecurityException when it's not... 655 */ assertCalledByPackageOwner(@onNull String packageName)656 protected final void assertCalledByPackageOwner(@NonNull String packageName) { 657 Preconditions.checkNotNull(packageName); 658 final int uid = Binder.getCallingUid(); 659 final String[] packages = getContext().getPackageManager().getPackagesForUid(uid); 660 if (packages != null) { 661 for (String candidate : packages) { 662 if (packageName.equals(candidate)) return; // Found it 663 } 664 } 665 throw new SecurityException("UID " + uid + " does not own " + packageName); 666 } 667 668 // TODO(b/117779333): support proto dumpLocked(@onNull String prefix, @NonNull PrintWriter pw)669 protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) { 670 boolean realDebug = debug; 671 boolean realVerbose = verbose; 672 final String prefix2 = " "; 673 674 try { 675 // Temporarily turn on full logging; 676 debug = verbose = true; 677 final int size = mServicesCache.size(); 678 pw.print(prefix); pw.print("Debug: "); pw.print(realDebug); 679 pw.print(" Verbose: "); pw.println(realVerbose); 680 pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy); 681 if (mUpdatingPackageNames != null) { 682 pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames); 683 } 684 if (mServiceNameResolver != null) { 685 pw.print(prefix); pw.print("Name resolver: "); 686 mServiceNameResolver.dumpShort(pw); pw.println(); 687 final UserManager um = getContext().getSystemService(UserManager.class); 688 final List<UserInfo> users = um.getUsers(); 689 for (int i = 0; i < users.size(); i++) { 690 final int userId = users.get(i).id; 691 pw.print(prefix2); pw.print(userId); pw.print(": "); 692 mServiceNameResolver.dumpShort(pw, userId); pw.println(); 693 } 694 } 695 pw.print(prefix); pw.print("Users disabled by restriction: "); 696 pw.println(mDisabledByUserRestriction); 697 pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService); 698 final String settingsProperty = getServiceSettingsProperty(); 699 if (settingsProperty != null) { 700 pw.print(prefix); pw.print("Settings property: "); pw.println(settingsProperty); 701 } 702 pw.print(prefix); pw.print("Cached services: "); 703 if (size == 0) { 704 pw.println("none"); 705 } else { 706 pw.println(size); 707 for (int i = 0; i < size; i++) { 708 pw.print(prefix); pw.print("Service at "); pw.print(i); pw.println(": "); 709 final S service = mServicesCache.valueAt(i); 710 service.dumpLocked(prefix2, pw); 711 pw.println(); 712 } 713 } 714 } finally { 715 debug = realDebug; 716 verbose = realVerbose; 717 } 718 } 719 startTrackingPackageChanges()720 private void startTrackingPackageChanges() { 721 final PackageMonitor monitor = new PackageMonitor() { 722 723 @Override 724 public void onPackageUpdateStarted(@NonNull String packageName, int uid) { 725 if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName); 726 final String activePackageName = getActiveServicePackageNameLocked(); 727 if (!packageName.equals(activePackageName)) return; 728 729 final int userId = getChangingUserId(); 730 synchronized (mLock) { 731 if (mUpdatingPackageNames == null) { 732 mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size()); 733 } 734 mUpdatingPackageNames.put(userId, packageName); 735 onServicePackageUpdatingLocked(userId); 736 if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) { 737 if (debug) { 738 Slog.d(mTag, "Removing service for user " + userId 739 + " because package " + activePackageName 740 + " is being updated"); 741 } 742 removeCachedServiceLocked(userId); 743 744 if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) { 745 if (debug) { 746 Slog.d(mTag, "Eagerly recreating service for user " 747 + userId); 748 } 749 getServiceForUserLocked(userId); 750 } 751 } else { 752 if (debug) { 753 Slog.d(mTag, "Holding service for user " + userId + " while package " 754 + activePackageName + " is being updated"); 755 } 756 } 757 } 758 } 759 760 @Override 761 public void onPackageUpdateFinished(@NonNull String packageName, int uid) { 762 if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName); 763 final int userId = getChangingUserId(); 764 synchronized (mLock) { 765 final String activePackageName = mUpdatingPackageNames == null ? null 766 : mUpdatingPackageNames.get(userId); 767 if (packageName.equals(activePackageName)) { 768 if (mUpdatingPackageNames != null) { 769 mUpdatingPackageNames.remove(userId); 770 if (mUpdatingPackageNames.size() == 0) { 771 mUpdatingPackageNames = null; 772 } 773 } 774 onServicePackageUpdatedLocked(userId); 775 } else { 776 handlePackageUpdateLocked(packageName); 777 } 778 } 779 } 780 781 @Override 782 public void onPackageRemoved(String packageName, int uid) { 783 synchronized (mLock) { 784 final int userId = getChangingUserId(); 785 final S service = peekServiceForUserLocked(userId); 786 if (service != null) { 787 final ComponentName componentName = service.getServiceComponentName(); 788 if (componentName != null) { 789 if (packageName.equals(componentName.getPackageName())) { 790 handleActiveServiceRemoved(userId); 791 } 792 } 793 } 794 } 795 } 796 797 @Override 798 public boolean onHandleForceStop(Intent intent, String[] packages, 799 int uid, boolean doit) { 800 synchronized (mLock) { 801 final String activePackageName = getActiveServicePackageNameLocked(); 802 for (String pkg : packages) { 803 if (pkg.equals(activePackageName)) { 804 if (!doit) { 805 return true; 806 } 807 removeCachedServiceLocked(getChangingUserId()); 808 } else { 809 handlePackageUpdateLocked(pkg); 810 } 811 } 812 } 813 return false; 814 } 815 816 private void handleActiveServiceRemoved(@UserIdInt int userId) { 817 synchronized (mLock) { 818 removeCachedServiceLocked(userId); 819 } 820 final String serviceSettingsProperty = getServiceSettingsProperty(); 821 if (serviceSettingsProperty != null) { 822 Settings.Secure.putStringForUser(getContext().getContentResolver(), 823 serviceSettingsProperty, null, userId); 824 } 825 } 826 827 private String getActiveServicePackageNameLocked() { 828 final int userId = getChangingUserId(); 829 final S service = peekServiceForUserLocked(userId); 830 if (service == null) { 831 return null; 832 } 833 final ComponentName serviceComponent = service.getServiceComponentName(); 834 if (serviceComponent == null) { 835 return null; 836 } 837 return serviceComponent.getPackageName(); 838 } 839 840 @GuardedBy("mLock") 841 private void handlePackageUpdateLocked(String packageName) { 842 visitServicesLocked((s) -> s.handlePackageUpdateLocked(packageName)); 843 } 844 }; 845 846 // package changes 847 monitor.register(getContext(), null, UserHandle.ALL, true); 848 } 849 850 /** 851 * Visitor pattern. 852 * 853 * @param <S> visited class. 854 */ 855 public interface Visitor<S> { 856 /** 857 * Visits a service. 858 * 859 * @param service the service to be visited. 860 */ visit(@onNull S service)861 void visit(@NonNull S service); 862 } 863 864 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)865 SettingsObserver(Handler handler) { 866 super(handler); 867 ContentResolver resolver = getContext().getContentResolver(); 868 final String serviceProperty = getServiceSettingsProperty(); 869 if (serviceProperty != null) { 870 resolver.registerContentObserver(Settings.Secure.getUriFor( 871 serviceProperty), false, this, UserHandle.USER_ALL); 872 } 873 resolver.registerContentObserver(Settings.Secure.getUriFor( 874 Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL); 875 registerForExtraSettingsChanges(resolver, this); 876 } 877 878 @Override onChange(boolean selfChange, Uri uri, @UserIdInt int userId)879 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { 880 if (verbose) Slog.v(mTag, "onChange(): uri=" + uri + ", userId=" + userId); 881 final String property = uri.getLastPathSegment(); 882 if (property.equals(getServiceSettingsProperty()) 883 || property.equals(Settings.Secure.USER_SETUP_COMPLETE)) { 884 synchronized (mLock) { 885 updateCachedServiceLocked(userId); 886 } 887 } else { 888 onSettingsChanged(userId, property); 889 } 890 } 891 } 892 } 893