• 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.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