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