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.provider.Settings; 35 import android.util.Slog; 36 import android.util.SparseArray; 37 import android.util.SparseBooleanArray; 38 39 import com.android.internal.annotations.GuardedBy; 40 import com.android.internal.content.PackageMonitor; 41 import com.android.internal.infra.AbstractRemoteService; 42 import com.android.internal.os.BackgroundThread; 43 import com.android.server.LocalServices; 44 import com.android.server.SystemService; 45 import com.android.server.pm.UserManagerInternal; 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> "main" 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 onUserUnlocking(@onNull TargetUser user)302 public void onUserUnlocking(@NonNull TargetUser user) { 303 synchronized (mLock) { 304 updateCachedServiceLocked(user.getUserIdentifier()); 305 } 306 } 307 308 @Override // from SystemService onUserStopped(@onNull TargetUser user)309 public void onUserStopped(@NonNull TargetUser user) { 310 synchronized (mLock) { 311 removeCachedServiceLocked(user.getUserIdentifier()); 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 if (mServiceNameResolver == null) { 375 return; 376 } 377 enforceCallingPermissionForManagement(); 378 379 Objects.requireNonNull(componentName); 380 final int maxDurationMs = getMaximumTemporaryServiceDurationMs(); 381 if (durationMs > maxDurationMs) { 382 throw new IllegalArgumentException( 383 "Max duration is " + maxDurationMs + " (called with " + durationMs + ")"); 384 } 385 386 synchronized (mLock) { 387 final S oldService = peekServiceForUserLocked(userId); 388 if (oldService != null) { 389 oldService.removeSelfFromCacheLocked(); 390 } 391 mServiceNameResolver.setTemporaryService(userId, componentName, durationMs); 392 } 393 } 394 395 /** 396 * Sets whether the default service should be used. 397 * 398 * <p>Typically used during CTS tests to make sure only the default service doesn't interfere 399 * with the test results. 400 * 401 * @throws SecurityException if caller is not allowed to manage this service's settings. 402 * 403 * @return whether the enabled state changed. 404 */ setDefaultServiceEnabled(@serIdInt int userId, boolean enabled)405 public final boolean setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) { 406 Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled); 407 enforceCallingPermissionForManagement(); 408 409 synchronized (mLock) { 410 if (mServiceNameResolver == null) { 411 return false; 412 } 413 final boolean changed = mServiceNameResolver.setDefaultServiceEnabled(userId, enabled); 414 if (!changed) { 415 if (verbose) { 416 Slog.v(mTag, "setDefaultServiceEnabled(" + userId + "): already " + enabled); 417 } 418 return false; 419 } 420 421 final S oldService = peekServiceForUserLocked(userId); 422 if (oldService != null) { 423 oldService.removeSelfFromCacheLocked(); 424 } 425 426 // Must update the service on cache so its initialization code is triggered 427 updateCachedServiceLocked(userId); 428 } 429 return true; 430 } 431 432 /** 433 * Checks whether the default service should be used. 434 * 435 * <p>Typically used during CTS tests to make sure only the default service doesn't interfere 436 * with the test results. 437 * 438 * @throws SecurityException if caller is not allowed to manage this service's settings. 439 */ isDefaultServiceEnabled(@serIdInt int userId)440 public final boolean isDefaultServiceEnabled(@UserIdInt int userId) { 441 enforceCallingPermissionForManagement(); 442 443 if (mServiceNameResolver == null) { 444 return false; 445 } 446 447 synchronized (mLock) { 448 return mServiceNameResolver.isDefaultServiceEnabled(userId); 449 } 450 } 451 452 /** 453 * Gets the maximum time the service implementation can be changed. 454 * 455 * @throws UnsupportedOperationException if subclass doesn't override it. 456 */ getMaximumTemporaryServiceDurationMs()457 protected int getMaximumTemporaryServiceDurationMs() { 458 throw new UnsupportedOperationException("Not implemented by " + getClass()); 459 } 460 461 /** 462 * Resets the temporary service implementation to the default component. 463 * 464 * <p>Typically used by Shell command and/or CTS tests. 465 * 466 * @throws SecurityException if caller is not allowed to manage this service's settings. 467 */ resetTemporaryService(@serIdInt int userId)468 public final void resetTemporaryService(@UserIdInt int userId) { 469 Slog.i(mTag, "resetTemporaryService(): " + userId); 470 enforceCallingPermissionForManagement(); 471 synchronized (mLock) { 472 final S service = getServiceForUserLocked(userId); 473 if (service != null) { 474 service.resetTemporaryServiceLocked(); 475 } 476 } 477 } 478 479 /** 480 * Asserts that the caller has permissions to manage this service. 481 * 482 * <p>Typically called by {@code ShellCommand} implementations. 483 * 484 * @throws UnsupportedOperationException if subclass doesn't override it. 485 * @throws SecurityException if caller is not allowed to manage this service's settings. 486 */ enforceCallingPermissionForManagement()487 protected void enforceCallingPermissionForManagement() { 488 throw new UnsupportedOperationException("Not implemented by " + getClass()); 489 } 490 491 /** 492 * Creates a new service that will be added to the cache. 493 * 494 * @param resolvedUserId the resolved user id for the service. 495 * @param disabled whether the service is currently disabled (due to {@link UserManager} 496 * restrictions). 497 * 498 * @return a new instance. 499 */ 500 @Nullable newServiceLocked(@serIdInt int resolvedUserId, boolean disabled)501 protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled); 502 503 /** 504 * Register the service for extra Settings changes (i.e., other than 505 * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or 506 * {@link #getServiceSettingsProperty()}, which are automatically handled). 507 * 508 * <p> Example: 509 * 510 * <pre><code> 511 * resolver.registerContentObserver(Settings.Global.getUriFor( 512 * Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES), false, observer, 513 * UserHandle.USER_ALL); 514 * </code></pre> 515 * 516 * <p><b>NOTE: </p>it doesn't need to register for 517 * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or 518 * {@link #getServiceSettingsProperty()}. 519 * 520 */ 521 @SuppressWarnings("unused") registerForExtraSettingsChanges(@onNull ContentResolver resolver, @NonNull ContentObserver observer)522 protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver, 523 @NonNull ContentObserver observer) { 524 } 525 526 /** 527 * Callback for Settings changes that were registered though 528 * {@link #registerForExtraSettingsChanges(ContentResolver, ContentObserver)}. 529 * 530 * @param userId user associated with the change 531 * @param property Settings property changed. 532 */ onSettingsChanged(@serIdInt int userId, @NonNull String property)533 protected void onSettingsChanged(@UserIdInt int userId, @NonNull String property) { 534 } 535 536 /** 537 * Gets the service instance for an user, creating an instance if not present in the cache. 538 */ 539 @GuardedBy("mLock") 540 @NonNull getServiceForUserLocked(@serIdInt int userId)541 protected S getServiceForUserLocked(@UserIdInt int userId) { 542 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 543 Binder.getCallingUid(), userId, false, false, null, null); 544 S service = mServicesCache.get(resolvedUserId); 545 if (service == null) { 546 final boolean disabled = isDisabledLocked(userId); 547 service = newServiceLocked(resolvedUserId, disabled); 548 if (!disabled) { 549 onServiceEnabledLocked(service, resolvedUserId); 550 } 551 mServicesCache.put(userId, service); 552 } 553 return service; 554 } 555 556 /** 557 * Gets the <b>existing</b> service instance for a user, returning {@code null} if not already 558 * present in the cache. 559 */ 560 @GuardedBy("mLock") 561 @Nullable peekServiceForUserLocked(@serIdInt int userId)562 protected S peekServiceForUserLocked(@UserIdInt int userId) { 563 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 564 Binder.getCallingUid(), userId, false, false, null, null); 565 return mServicesCache.get(resolvedUserId); 566 } 567 568 /** 569 * Updates a cached service for a given user. 570 */ 571 @GuardedBy("mLock") updateCachedServiceLocked(@serIdInt int userId)572 protected void updateCachedServiceLocked(@UserIdInt int userId) { 573 updateCachedServiceLocked(userId, isDisabledLocked(userId)); 574 } 575 576 /** 577 * Checks whether the service is disabled (through {@link UserManager} restrictions) for the 578 * given user. 579 */ isDisabledLocked(@serIdInt int userId)580 protected boolean isDisabledLocked(@UserIdInt int userId) { 581 return mDisabledByUserRestriction == null ? false : mDisabledByUserRestriction.get(userId); 582 } 583 584 /** 585 * Updates a cached service for a given user. 586 * 587 * @param userId user handle. 588 * @param disabled whether the user is disabled. 589 * @return service for the user. 590 */ 591 @GuardedBy("mLock") updateCachedServiceLocked(@serIdInt int userId, boolean disabled)592 protected S updateCachedServiceLocked(@UserIdInt int userId, boolean disabled) { 593 final S service = getServiceForUserLocked(userId); 594 if (service != null) { 595 service.updateLocked(disabled); 596 if (!service.isEnabledLocked()) { 597 removeCachedServiceLocked(userId); 598 } else { 599 onServiceEnabledLocked(service, userId); 600 } 601 } 602 return service; 603 } 604 605 /** 606 * Gets the Settings property that defines the name of the component name used to bind this 607 * service to an external service, or {@code null} when the service is not defined by such 608 * property (for example, if it's a system service defined by framework resources). 609 */ 610 @Nullable getServiceSettingsProperty()611 protected String getServiceSettingsProperty() { 612 return null; 613 } 614 615 /** 616 * Callback called after a new service was added to the cache, or an existing service that was 617 * previously disabled gets enabled. 618 * 619 * <p>By default doesn't do anything, but can be overridden by subclasses. 620 */ 621 @SuppressWarnings("unused") onServiceEnabledLocked(@onNull S service, @UserIdInt int userId)622 protected void onServiceEnabledLocked(@NonNull S service, @UserIdInt int userId) { 623 } 624 625 /** 626 * Removes a cached service for a given user. 627 * 628 * @return the removed service. 629 */ 630 @GuardedBy("mLock") 631 @NonNull removeCachedServiceLocked(@serIdInt int userId)632 protected final S removeCachedServiceLocked(@UserIdInt int userId) { 633 final S service = peekServiceForUserLocked(userId); 634 if (service != null) { 635 mServicesCache.delete(userId); 636 onServiceRemoved(service, userId); 637 } 638 return service; 639 } 640 641 /** 642 * Called before the package that provides the service for the given user is being updated. 643 */ onServicePackageUpdatingLocked(@serIdInt int userId)644 protected void onServicePackageUpdatingLocked(@UserIdInt int userId) { 645 if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")"); 646 } 647 648 /** 649 * Called after the package that provides the service for the given user is being updated. 650 */ onServicePackageUpdatedLocked(@serIdInt int userId)651 protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { 652 if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")"); 653 } 654 655 /** 656 * Called after the package data that provides the service for the given user is cleared. 657 */ onServicePackageDataClearedLocked(@serIdInt int userId)658 protected void onServicePackageDataClearedLocked(@UserIdInt int userId) { 659 if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")"); 660 } 661 662 /** 663 * Called after the package that provides the service for the given user is restarted. 664 */ onServicePackageRestartedLocked(@serIdInt int userId)665 protected void onServicePackageRestartedLocked(@UserIdInt int userId) { 666 if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")"); 667 } 668 669 /** 670 * Called after the service is removed from the cache. 671 */ 672 @SuppressWarnings("unused") onServiceRemoved(@onNull S service, @UserIdInt int userId)673 protected void onServiceRemoved(@NonNull S service, @UserIdInt int userId) { 674 } 675 676 /** 677 * Called when the service name changed (typically when using temporary services). 678 * 679 * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call 680 * that same method, or {@code super.onServiceNameChanged()}. 681 * 682 * @param userId user handle. 683 * @param serviceName the new service name. 684 * @param isTemporary whether the new service is temporary. 685 */ onServiceNameChanged(@serIdInt int userId, @Nullable String serviceName, boolean isTemporary)686 protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName, 687 boolean isTemporary) { 688 synchronized (mLock) { 689 updateCachedServiceLocked(userId); 690 } 691 } 692 693 /** 694 * Visits all services in the cache. 695 */ 696 @GuardedBy("mLock") visitServicesLocked(@onNull Visitor<S> visitor)697 protected void visitServicesLocked(@NonNull Visitor<S> visitor) { 698 final int size = mServicesCache.size(); 699 for (int i = 0; i < size; i++) { 700 visitor.visit(mServicesCache.valueAt(i)); 701 } 702 } 703 704 /** 705 * Clear the cache by removing all services. 706 */ 707 @GuardedBy("mLock") clearCacheLocked()708 protected void clearCacheLocked() { 709 mServicesCache.clear(); 710 } 711 712 /** 713 * Gets a cached reference to {@link UserManagerInternal}. 714 */ 715 @NonNull getUserManagerInternal()716 protected UserManagerInternal getUserManagerInternal() { 717 if (mUm == null) { 718 if (verbose) Slog.v(mTag, "lazy-loading UserManagerInternal"); 719 mUm = LocalServices.getService(UserManagerInternal.class); 720 } 721 return mUm; 722 } 723 724 /** 725 * Gets a list of all supported users (i.e., those that pass the 726 * {@link #isUserSupported(TargetUser)}check). 727 */ 728 @NonNull getSupportedUsers()729 protected List<UserInfo> getSupportedUsers() { 730 final UserInfo[] allUsers = getUserManagerInternal().getUserInfos(); 731 final int size = allUsers.length; 732 final List<UserInfo> supportedUsers = new ArrayList<>(size); 733 for (int i = 0; i < size; i++) { 734 final UserInfo userInfo = allUsers[i]; 735 if (isUserSupported(new TargetUser(userInfo))) { 736 supportedUsers.add(userInfo); 737 } 738 } 739 return supportedUsers; 740 } 741 742 /** 743 * Asserts that the given package name is owned by the UID making this call. 744 * 745 * @throws SecurityException when it's not... 746 */ assertCalledByPackageOwner(@onNull String packageName)747 protected void assertCalledByPackageOwner(@NonNull String packageName) { 748 Objects.requireNonNull(packageName); 749 final int uid = Binder.getCallingUid(); 750 final String[] packages = getContext().getPackageManager().getPackagesForUid(uid); 751 if (packages != null) { 752 for (String candidate : packages) { 753 if (packageName.equals(candidate)) return; // Found it 754 } 755 } 756 throw new SecurityException("UID " + uid + " does not own " + packageName); 757 } 758 759 // TODO(b/117779333): support proto dumpLocked(@onNull String prefix, @NonNull PrintWriter pw)760 protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) { 761 boolean realDebug = debug; 762 boolean realVerbose = verbose; 763 final String prefix2 = " "; 764 765 try { 766 // Temporarily turn on full logging; 767 debug = verbose = true; 768 final int size = mServicesCache.size(); 769 pw.print(prefix); pw.print("Debug: "); pw.print(realDebug); 770 pw.print(" Verbose: "); pw.println(realVerbose); 771 pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags); 772 if (mUpdatingPackageNames != null) { 773 pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames); 774 } 775 dumpSupportedUsers(pw, prefix); 776 if (mServiceNameResolver != null) { 777 pw.print(prefix); pw.print("Name resolver: "); 778 mServiceNameResolver.dumpShort(pw); pw.println(); 779 final List<UserInfo> users = getSupportedUsers(); 780 for (int i = 0; i < users.size(); i++) { 781 final int userId = users.get(i).id; 782 pw.print(prefix2); pw.print(userId); pw.print(": "); 783 mServiceNameResolver.dumpShort(pw, userId); pw.println(); 784 } 785 } 786 pw.print(prefix); pw.print("Users disabled by restriction: "); 787 pw.println(mDisabledByUserRestriction); 788 pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService); 789 final String settingsProperty = getServiceSettingsProperty(); 790 if (settingsProperty != null) { 791 pw.print(prefix); pw.print("Settings property: "); pw.println(settingsProperty); 792 } 793 pw.print(prefix); pw.print("Cached services: "); 794 if (size == 0) { 795 pw.println("none"); 796 } else { 797 pw.println(size); 798 for (int i = 0; i < size; i++) { 799 pw.print(prefix); pw.print("Service at "); pw.print(i); pw.println(": "); 800 final S service = mServicesCache.valueAt(i); 801 service.dumpLocked(prefix2, pw); 802 pw.println(); 803 } 804 } 805 } finally { 806 debug = realDebug; 807 verbose = realVerbose; 808 } 809 } 810 startTrackingPackageChanges()811 private void startTrackingPackageChanges() { 812 final PackageMonitor monitor = new PackageMonitor() { 813 814 @Override 815 public void onPackageUpdateStarted(@NonNull String packageName, int uid) { 816 if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName); 817 final String activePackageName = getActiveServicePackageNameLocked(); 818 if (!packageName.equals(activePackageName)) return; 819 820 final int userId = getChangingUserId(); 821 synchronized (mLock) { 822 if (mUpdatingPackageNames == null) { 823 mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size()); 824 } 825 mUpdatingPackageNames.put(userId, packageName); 826 onServicePackageUpdatingLocked(userId); 827 if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) { 828 if (debug) { 829 Slog.d(mTag, "Holding service for user " + userId + " while package " 830 + activePackageName + " is being updated"); 831 } 832 } else { 833 if (debug) { 834 Slog.d(mTag, "Removing service for user " + userId 835 + " because package " + activePackageName 836 + " is being updated"); 837 } 838 removeCachedServiceLocked(userId); 839 840 if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER) 841 != 0) { 842 if (debug) { 843 Slog.d(mTag, "Eagerly recreating service for user " 844 + userId); 845 } 846 getServiceForUserLocked(userId); 847 } 848 } 849 } 850 } 851 852 @Override 853 public void onPackageUpdateFinished(@NonNull String packageName, int uid) { 854 if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName); 855 final int userId = getChangingUserId(); 856 synchronized (mLock) { 857 final String activePackageName = mUpdatingPackageNames == null ? null 858 : mUpdatingPackageNames.get(userId); 859 if (packageName.equals(activePackageName)) { 860 if (mUpdatingPackageNames != null) { 861 mUpdatingPackageNames.remove(userId); 862 if (mUpdatingPackageNames.size() == 0) { 863 mUpdatingPackageNames = null; 864 } 865 } 866 onServicePackageUpdatedLocked(userId); 867 } else { 868 handlePackageUpdateLocked(packageName); 869 } 870 } 871 } 872 873 @Override 874 public void onPackageRemoved(String packageName, int uid) { 875 synchronized (mLock) { 876 final int userId = getChangingUserId(); 877 final S service = peekServiceForUserLocked(userId); 878 if (service != null) { 879 final ComponentName componentName = service.getServiceComponentName(); 880 if (componentName != null) { 881 if (packageName.equals(componentName.getPackageName())) { 882 handleActiveServiceRemoved(userId); 883 } 884 } 885 } 886 } 887 } 888 889 @Override 890 public boolean onHandleForceStop(Intent intent, String[] packages, 891 int uid, boolean doit) { 892 synchronized (mLock) { 893 final String activePackageName = getActiveServicePackageNameLocked(); 894 for (String pkg : packages) { 895 if (pkg.equals(activePackageName)) { 896 if (!doit) { 897 return true; 898 } 899 final String action = intent.getAction(); 900 final int userId = getChangingUserId(); 901 if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) { 902 handleActiveServiceRestartedLocked(activePackageName, userId); 903 } else { 904 removeCachedServiceLocked(userId); 905 } 906 } else { 907 handlePackageUpdateLocked(pkg); 908 } 909 } 910 } 911 return false; 912 } 913 914 @Override 915 public void onPackageDataCleared(String packageName, int uid) { 916 if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName); 917 final int userId = getChangingUserId(); 918 synchronized (mLock) { 919 final S service = peekServiceForUserLocked(userId); 920 if (service != null) { 921 final ComponentName componentName = service.getServiceComponentName(); 922 if (componentName != null) { 923 if (packageName.equals(componentName.getPackageName())) { 924 onServicePackageDataClearedLocked(userId); 925 } 926 } 927 } 928 } 929 } 930 931 private void handleActiveServiceRemoved(@UserIdInt int userId) { 932 synchronized (mLock) { 933 removeCachedServiceLocked(userId); 934 } 935 final String serviceSettingsProperty = getServiceSettingsProperty(); 936 if (serviceSettingsProperty != null) { 937 Settings.Secure.putStringForUser(getContext().getContentResolver(), 938 serviceSettingsProperty, null, userId); 939 } 940 } 941 942 private void handleActiveServiceRestartedLocked(String activePackageName, 943 @UserIdInt int userId) { 944 if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) { 945 if (debug) { 946 Slog.d(mTag, "Holding service for user " + userId + " while package " 947 + activePackageName + " is being restarted"); 948 } 949 } else { 950 if (debug) { 951 Slog.d(mTag, "Removing service for user " + userId 952 + " because package " + activePackageName 953 + " is being restarted"); 954 } 955 removeCachedServiceLocked(userId); 956 957 if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) { 958 if (debug) { 959 Slog.d(mTag, "Eagerly recreating service for user " + userId); 960 } 961 updateCachedServiceLocked(userId); 962 } 963 } 964 onServicePackageRestartedLocked(userId); 965 } 966 967 @Override 968 public void onPackageModified(String packageName) { 969 if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName); 970 971 if (mServiceNameResolver == null) { 972 return; 973 } 974 975 final int userId = getChangingUserId(); 976 final String serviceName = mServiceNameResolver.getDefaultServiceName(userId); 977 if (serviceName == null) { 978 return; 979 } 980 981 final ComponentName serviceComponentName = 982 ComponentName.unflattenFromString(serviceName); 983 if (serviceComponentName == null 984 || !serviceComponentName.getPackageName().equals(packageName)) { 985 return; 986 } 987 988 // The default service package has changed, update the cached if the service 989 // exists but no active component. 990 final S service = peekServiceForUserLocked(userId); 991 if (service != null) { 992 final ComponentName componentName = service.getServiceComponentName(); 993 if (componentName == null) { 994 if (verbose) Slog.v(mTag, "update cached"); 995 updateCachedServiceLocked(userId); 996 } 997 } 998 } 999 1000 private String getActiveServicePackageNameLocked() { 1001 final int userId = getChangingUserId(); 1002 final S service = peekServiceForUserLocked(userId); 1003 if (service == null) { 1004 return null; 1005 } 1006 final ComponentName serviceComponent = service.getServiceComponentName(); 1007 if (serviceComponent == null) { 1008 return null; 1009 } 1010 return serviceComponent.getPackageName(); 1011 } 1012 1013 @GuardedBy("mLock") 1014 private void handlePackageUpdateLocked(String packageName) { 1015 visitServicesLocked((s) -> s.handlePackageUpdateLocked(packageName)); 1016 } 1017 }; 1018 1019 // package changes 1020 monitor.register(getContext(), null, UserHandle.ALL, true); 1021 } 1022 1023 /** 1024 * Visitor pattern. 1025 * 1026 * @param <S> visited class. 1027 */ 1028 public interface Visitor<S> { 1029 /** 1030 * Visits a service. 1031 * 1032 * @param service the service to be visited. 1033 */ visit(@onNull S service)1034 void visit(@NonNull S service); 1035 } 1036 1037 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)1038 SettingsObserver(Handler handler) { 1039 super(handler); 1040 ContentResolver resolver = getContext().getContentResolver(); 1041 final String serviceProperty = getServiceSettingsProperty(); 1042 if (serviceProperty != null) { 1043 resolver.registerContentObserver(Settings.Secure.getUriFor( 1044 serviceProperty), false, this, UserHandle.USER_ALL); 1045 } 1046 resolver.registerContentObserver(Settings.Secure.getUriFor( 1047 Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL); 1048 registerForExtraSettingsChanges(resolver, this); 1049 } 1050 1051 @Override onChange(boolean selfChange, Uri uri, @UserIdInt int userId)1052 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { 1053 if (verbose) Slog.v(mTag, "onChange(): uri=" + uri + ", userId=" + userId); 1054 final String property = uri.getLastPathSegment(); 1055 if (property == null) { 1056 return; 1057 } 1058 if (property.equals(getServiceSettingsProperty()) 1059 || property.equals(Settings.Secure.USER_SETUP_COMPLETE)) { 1060 synchronized (mLock) { 1061 updateCachedServiceLocked(userId); 1062 } 1063 } else { 1064 onSettingsChanged(userId, property); 1065 } 1066 } 1067 } 1068 } 1069