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