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