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