1 /**
2  * Copyright (c) 2014, 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 
17 package com.android.server.notification;
18 
19 import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR;
20 import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
21 import static android.content.Context.BIND_AUTO_CREATE;
22 import static android.content.Context.BIND_FOREGROUND_SERVICE;
23 import static android.content.Context.DEVICE_POLICY_SERVICE;
24 import static android.os.UserHandle.USER_ALL;
25 import static android.os.UserHandle.USER_SYSTEM;
26 import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_AUTOBIND;
27 
28 import static com.android.server.notification.NotificationManagerService.privateSpaceFlagsEnabled;
29 
30 import android.annotation.FlaggedApi;
31 import android.annotation.NonNull;
32 import android.app.ActivityManager;
33 import android.app.ActivityOptions;
34 import android.app.PendingIntent;
35 import android.app.admin.DevicePolicyManager;
36 import android.content.ComponentName;
37 import android.content.ContentResolver;
38 import android.content.Context;
39 import android.content.Intent;
40 import android.content.ServiceConnection;
41 import android.content.pm.ApplicationInfo;
42 import android.content.pm.IPackageManager;
43 import android.content.pm.PackageManager;
44 import android.content.pm.PackageManager.NameNotFoundException;
45 import android.content.pm.ResolveInfo;
46 import android.content.pm.ServiceInfo;
47 import android.content.pm.UserInfo;
48 import android.os.Binder;
49 import android.os.Build;
50 import android.os.Handler;
51 import android.os.IBinder;
52 import android.os.IInterface;
53 import android.os.Looper;
54 import android.os.RemoteException;
55 import android.os.UserHandle;
56 import android.os.UserManager;
57 import android.provider.Settings;
58 import android.service.notification.ManagedServiceInfoProto;
59 import android.service.notification.ManagedServicesProto;
60 import android.service.notification.ManagedServicesProto.ServiceProto;
61 import android.text.TextUtils;
62 import android.util.ArrayMap;
63 import android.util.ArraySet;
64 import android.util.IntArray;
65 import android.util.Log;
66 import android.util.Pair;
67 import android.util.Slog;
68 import android.util.SparseArray;
69 import android.util.SparseSetArray;
70 import android.util.proto.ProtoOutputStream;
71 
72 import com.android.internal.annotations.GuardedBy;
73 import com.android.internal.annotations.VisibleForTesting;
74 import com.android.internal.util.XmlUtils;
75 import com.android.internal.util.function.TriPredicate;
76 import com.android.modules.utils.TypedXmlPullParser;
77 import com.android.modules.utils.TypedXmlSerializer;
78 import com.android.server.notification.NotificationManagerService.DumpFilter;
79 import com.android.server.utils.TimingsTraceAndSlog;
80 
81 import org.xmlpull.v1.XmlPullParser;
82 import org.xmlpull.v1.XmlPullParserException;
83 
84 import java.io.IOException;
85 import java.io.PrintWriter;
86 import java.util.ArrayList;
87 import java.util.Arrays;
88 import java.util.HashSet;
89 import java.util.List;
90 import java.util.Objects;
91 import java.util.Set;
92 
93 /**
94  * Manages the lifecycle of application-provided services bound by system server.
95  *
96  * Services managed by this helper must have:
97  *  - An associated system settings value with a list of enabled component names.
98  *  - A well-known action for services to use in their intent-filter.
99  *  - A system permission for services to require in order to ensure system has exclusive binding.
100  *  - A settings page for user configuration of enabled services, and associated intent action.
101  *  - A remote interface definition (aidl) provided by the service used for communication.
102  */
103 abstract public class ManagedServices {
104     protected final String TAG = getClass().getSimpleName();
105     protected final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
106 
107     private static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
108     protected static final String ENABLED_SERVICES_SEPARATOR = ":";
109     private static final String DB_VERSION_1 = "1";
110     private static final String DB_VERSION_2 = "2";
111     private static final String DB_VERSION_3 = "3";
112 
113 
114     /**
115      * List of components and apps that can have running {@link ManagedServices}.
116      */
117     static final String TAG_MANAGED_SERVICES = "service_listing";
118     static final String ATT_APPROVED_LIST = "approved";
119     static final String ATT_USER_ID = "user";
120     static final String ATT_IS_PRIMARY = "primary";
121     static final String ATT_VERSION = "version";
122     static final String ATT_DEFAULTS = "defaults";
123     static final String ATT_USER_SET = "user_set_services";
124     static final String ATT_USER_SET_OLD = "user_set";
125     static final String ATT_USER_CHANGED = "user_changed";
126 
127     static final String DB_VERSION = "4";
128 
129     static final int APPROVAL_BY_PACKAGE = 0;
130     static final int APPROVAL_BY_COMPONENT = 1;
131 
132     protected final Context mContext;
133     protected final Object mMutex;
134     private final UserProfiles mUserProfiles;
135     protected final IPackageManager mPm;
136     protected final UserManager mUm;
137     private final Config mConfig;
138     private final Handler mHandler = new Handler(Looper.getMainLooper());
139 
140     // contains connections to all connected services, including app services
141     // and system services
142     @GuardedBy("mMutex")
143     private final ArrayList<ManagedServiceInfo> mServices = new ArrayList<>();
144     /**
145      * The services that have been bound by us. If the service is also connected, it will also
146      * be in {@link #mServices}.
147      */
148     @GuardedBy("mMutex")
149     private final ArrayList<Pair<ComponentName, Integer>> mServicesBound = new ArrayList<>();
150     @GuardedBy("mMutex")
151     private final ArraySet<Pair<ComponentName, Integer>> mServicesRebinding = new ArraySet<>();
152     // we need these packages to be protected because classes that inherit from it need to see it
153     protected final Object mDefaultsLock = new Object();
154     @GuardedBy("mDefaultsLock")
155     protected final ArraySet<ComponentName> mDefaultComponents = new ArraySet<>();
156     @GuardedBy("mDefaultsLock")
157     protected final ArraySet<String> mDefaultPackages = new ArraySet<>();
158 
159     // lists the component names of all enabled (and therefore potentially connected)
160     // app services for current profiles.
161     @GuardedBy("mMutex")
162     private final ArraySet<ComponentName> mEnabledServicesForCurrentProfiles = new ArraySet<>();
163     // Just the packages from mEnabledServicesForCurrentProfiles
164     @GuardedBy("mMutex")
165     private final ArraySet<String> mEnabledServicesPackageNames = new ArraySet<>();
166     // Per user id, list of enabled packages that have nevertheless asked not to be run
167     @GuardedBy("mSnoozing")
168     private final SparseSetArray<ComponentName> mSnoozing = new SparseSetArray<>();
169 
170     // List of approved packages or components (by user, then by primary/secondary) that are
171     // allowed to be bound as managed services. A package or component appearing in this list does
172     // not mean that we are currently bound to said package/component.
173     @GuardedBy("mApproved")
174     protected final ArrayMap<Integer, ArrayMap<Boolean, ArraySet<String>>> mApproved =
175             new ArrayMap<>();
176     // List of packages or components (by user) that are configured to be enabled/disabled
177     // explicitly by the user
178     @GuardedBy("mApproved")
179     protected ArrayMap<Integer, ArraySet<String>> mUserSetServices = new ArrayMap<>();
180     @GuardedBy("mApproved")
181     protected ArrayMap<Integer, Boolean> mIsUserChanged = new ArrayMap<>();
182 
183     // True if approved services are stored in xml, not settings.
184     private boolean mUseXml;
185 
186     // Whether managed services are approved individually or package wide
187     protected int mApprovalLevel;
188 
ManagedServices(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm)189     public ManagedServices(Context context, Object mutex, UserProfiles userProfiles,
190             IPackageManager pm) {
191         mContext = context;
192         mMutex = mutex;
193         mUserProfiles = userProfiles;
194         mPm = pm;
195         mConfig = getConfig();
196         mApprovalLevel = APPROVAL_BY_COMPONENT;
197         mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
198     }
199 
getConfig()200     abstract protected Config getConfig();
201 
getCaption()202     private String getCaption() {
203         return mConfig.caption;
204     }
205 
asInterface(IBinder binder)206     abstract protected IInterface asInterface(IBinder binder);
207 
checkType(IInterface service)208     abstract protected boolean checkType(IInterface service);
209 
onServiceAdded(ManagedServiceInfo info)210     abstract protected void onServiceAdded(ManagedServiceInfo info);
211 
ensureFilters(ServiceInfo si, int userId)212     abstract protected void ensureFilters(ServiceInfo si, int userId);
213 
getServices()214     protected List<ManagedServiceInfo> getServices() {
215         synchronized (mMutex) {
216             List<ManagedServiceInfo> services = new ArrayList<>(mServices);
217             return services;
218         }
219     }
220 
addDefaultComponentOrPackage(String packageOrComponent)221     protected void addDefaultComponentOrPackage(String packageOrComponent) {
222         if (!TextUtils.isEmpty(packageOrComponent)) {
223             synchronized (mDefaultsLock) {
224                 if (mApprovalLevel == APPROVAL_BY_PACKAGE) {
225                     mDefaultPackages.add(packageOrComponent);
226                     return;
227                 }
228                 ComponentName cn = ComponentName.unflattenFromString(packageOrComponent);
229                 if (cn != null  && mApprovalLevel == APPROVAL_BY_COMPONENT) {
230                     mDefaultPackages.add(cn.getPackageName());
231                     mDefaultComponents.add(cn);
232                     return;
233                 }
234             }
235         }
236     }
237 
loadDefaultsFromConfig()238     protected abstract void loadDefaultsFromConfig();
239 
isDefaultComponentOrPackage(String packageOrComponent)240     boolean isDefaultComponentOrPackage(String packageOrComponent) {
241         synchronized (mDefaultsLock) {
242             ComponentName cn = ComponentName.unflattenFromString(packageOrComponent);
243             if (cn == null) {
244                 return mDefaultPackages.contains(packageOrComponent);
245             } else {
246                 return mDefaultComponents.contains(cn);
247             }
248         }
249     }
250 
getDefaultComponents()251     ArraySet<ComponentName> getDefaultComponents() {
252         synchronized (mDefaultsLock) {
253             return new ArraySet<>(mDefaultComponents);
254         }
255     }
256 
getDefaultPackages()257     ArraySet<String> getDefaultPackages() {
258         synchronized (mDefaultsLock) {
259             return new ArraySet<>(mDefaultPackages);
260         }
261     }
262 
263     /**
264      * When resetting a package, we need to enable default components that belong to that packages
265      * we also need to disable components that are not default to return the managed service state
266      * to when a new android device is first turned on for that package.
267      *
268      * @param packageName package to reset.
269      * @param userId the android user id
270      * @return a list of components that were permitted
271      */
272     @NonNull
resetComponents(String packageName, int userId)273     ArrayMap<Boolean, ArrayList<ComponentName>> resetComponents(String packageName, int userId) {
274         // components that we want to enable
275         ArrayList<ComponentName> componentsToEnable;
276         // components that were removed
277         ArrayList<ComponentName> disabledComponents;
278         // all components that are enabled now
279         ArraySet<ComponentName> enabledComponents = new ArraySet<>(getAllowedComponents(userId));
280 
281         boolean changed = false;
282 
283         synchronized (mDefaultsLock) {
284             componentsToEnable = new ArrayList<>(mDefaultComponents.size());
285             disabledComponents = new ArrayList<>(mDefaultComponents.size());
286 
287             // record all components that are enabled but should not be by default
288             for (int i = 0; i < mDefaultComponents.size() && enabledComponents.size() > 0; i++) {
289                 ComponentName currentDefault = mDefaultComponents.valueAt(i);
290                 if (packageName.equals(currentDefault.getPackageName())
291                         && !enabledComponents.contains(currentDefault)) {
292                     componentsToEnable.add(currentDefault);
293                 }
294             }
295             synchronized (mApproved) {
296                 final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(
297                         userId);
298                 if (approvedByType != null) {
299                     final int M = approvedByType.size();
300                     for (int j = 0; j < M; j++) {
301                         final ArraySet<String> approved = approvedByType.valueAt(j);
302                         for (int i = 0; i < enabledComponents.size(); i++) {
303                             ComponentName currentComponent = enabledComponents.valueAt(i);
304                             if (packageName.equals(currentComponent.getPackageName())
305                                     && !mDefaultComponents.contains(currentComponent)) {
306                                 if (approved.remove(currentComponent.flattenToString())) {
307                                     disabledComponents.add(currentComponent);
308                                     clearUserSetFlagLocked(currentComponent, userId);
309                                     changed = true;
310                                 }
311                             }
312                         }
313                         for (int i = 0; i < componentsToEnable.size(); i++) {
314                             ComponentName candidate = componentsToEnable.get(i);
315                             changed |= approved.add(candidate.flattenToString());
316                         }
317                     }
318 
319                 }
320             }
321         }
322         if (changed) rebindServices(false, USER_ALL);
323 
324         ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>();
325         changes.put(true, componentsToEnable);
326         changes.put(false, disabledComponents);
327 
328         return changes;
329     }
330 
331     @GuardedBy("mApproved")
clearUserSetFlagLocked(ComponentName component, int userId)332     private boolean clearUserSetFlagLocked(ComponentName component, int userId) {
333         String approvedValue = getApprovedValue(component.flattenToString());
334         ArraySet<String> userSet = mUserSetServices.get(userId);
335         return userSet != null && userSet.remove(approvedValue);
336     }
337 
getBindFlags()338     protected int getBindFlags() {
339         return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT;
340     }
341 
onServiceRemovedLocked(ManagedServiceInfo removed)342     protected void onServiceRemovedLocked(ManagedServiceInfo removed) { }
343 
newServiceInfo(IInterface service, ComponentName component, int userId, boolean isSystem, ServiceConnection connection, int targetSdkVersion, int uid)344     private ManagedServiceInfo newServiceInfo(IInterface service,
345             ComponentName component, int userId, boolean isSystem, ServiceConnection connection,
346             int targetSdkVersion, int uid) {
347         return new ManagedServiceInfo(service, component, userId, isSystem, connection,
348                 targetSdkVersion, uid);
349     }
350 
onBootPhaseAppsCanStart()351     public void onBootPhaseAppsCanStart() {}
352 
dump(PrintWriter pw, DumpFilter filter)353     public void dump(PrintWriter pw, DumpFilter filter) {
354         pw.println("    Allowed " + getCaption() + "s:");
355         synchronized (mApproved) {
356             final int N = mApproved.size();
357             for (int i = 0; i < N; i++) {
358                 final int userId = mApproved.keyAt(i);
359                 final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
360                 final Boolean userChanged = mIsUserChanged.get(userId);
361                 if (approvedByType != null) {
362                     final int M = approvedByType.size();
363                     for (int j = 0; j < M; j++) {
364                         final boolean isPrimary = approvedByType.keyAt(j);
365                         final ArraySet<String> approved = approvedByType.valueAt(j);
366                         if (approvedByType != null && approvedByType.size() > 0) {
367                             pw.println("      " + String.join(ENABLED_SERVICES_SEPARATOR, approved)
368                                     + " (user: " + userId + " isPrimary: " + isPrimary
369                                     + (userChanged == null ? "" : " isUserChanged: "
370                                     + userChanged) + ")");
371                         }
372                     }
373                 }
374             }
375             pw.println("    Has user set:");
376             Set<Integer> userIds = mUserSetServices.keySet();
377             for (int userId : userIds) {
378                 if (mIsUserChanged.get(userId) == null) {
379                     pw.println("      userId=" + userId + " value="
380                             + (mUserSetServices.get(userId)));
381                 }
382             }
383         }
384 
385         synchronized (mMutex) {
386             pw.println("    All " + getCaption() + "s (" + mEnabledServicesForCurrentProfiles.size()
387                     + ") enabled for current profiles:");
388             for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
389                 if (filter != null && !filter.matches(cmpt)) continue;
390                 pw.println("      " + cmpt);
391             }
392 
393             pw.println("    Live " + getCaption() + "s (" + mServices.size() + "):");
394             for (ManagedServiceInfo info : mServices) {
395                 if (filter != null && !filter.matches(info.component)) continue;
396                 pw.println("      " + info.component
397                         + " (user " + info.userid + "): " + info.service
398                         + (info.isSystem ? " SYSTEM" : "")
399                         + (info.isGuest(this) ? " GUEST" : ""));
400             }
401         }
402 
403         final SparseSetArray<ComponentName> snoozingComponents;
404         synchronized (mSnoozing) {
405             snoozingComponents = new SparseSetArray<>(mSnoozing);
406         }
407         pw.println("    Snoozed " + getCaption() + "s ("
408                 + snoozingComponents.size() + "):");
409         for (int i = 0; i < snoozingComponents.size(); i++) {
410             pw.println("      User: " + snoozingComponents.keyAt(i));
411             for (ComponentName name : snoozingComponents.valuesAt(i)) {
412                 final ServiceInfo info = getServiceInfo(name, snoozingComponents.keyAt(i));
413                 pw.println("        " + name.flattenToShortString() + (isAutobindAllowed(info) ? ""
414                         : " (META_DATA_DEFAULT_AUTOBIND=false)"));
415             }
416         }
417     }
418 
dump(ProtoOutputStream proto, DumpFilter filter)419     public void dump(ProtoOutputStream proto, DumpFilter filter) {
420         proto.write(ManagedServicesProto.CAPTION, getCaption());
421         synchronized (mApproved) {
422             final int N = mApproved.size();
423             for (int i = 0; i < N; i++) {
424                 final int userId = mApproved.keyAt(i);
425                 final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
426                 if (approvedByType != null) {
427                     final int M = approvedByType.size();
428                     for (int j = 0; j < M; j++) {
429                         final boolean isPrimary = approvedByType.keyAt(j);
430                         final ArraySet<String> approved = approvedByType.valueAt(j);
431                         if (approvedByType != null && approvedByType.size() > 0) {
432                             final long sToken = proto.start(ManagedServicesProto.APPROVED);
433                             for (String s : approved) {
434                                 proto.write(ServiceProto.NAME, s);
435                             }
436                             proto.write(ServiceProto.USER_ID, userId);
437                             proto.write(ServiceProto.IS_PRIMARY, isPrimary);
438                             proto.end(sToken);
439                         }
440                     }
441                 }
442             }
443         }
444 
445 
446         synchronized (mMutex) {
447             for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
448                 if (filter != null && !filter.matches(cmpt)) continue;
449                 cmpt.dumpDebug(proto, ManagedServicesProto.ENABLED);
450             }
451             for (ManagedServiceInfo info : mServices) {
452                 if (filter != null && !filter.matches(info.component)) continue;
453                 info.dumpDebug(proto, ManagedServicesProto.LIVE_SERVICES, this);
454             }
455         }
456 
457         synchronized (mSnoozing) {
458             for (int i = 0; i < mSnoozing.size(); i++) {
459                 long token = proto.start(ManagedServicesProto.SNOOZED);
460                 proto.write(ManagedServicesProto.SnoozedServices.USER_ID,
461                         mSnoozing.keyAt(i));
462                 for (ComponentName name : mSnoozing.valuesAt(i)) {
463                     name.dumpDebug(proto, ManagedServicesProto.SnoozedServices.SNOOZED);
464                 }
465                 proto.end(token);
466             }
467         }
468     }
469 
onSettingRestored(String element, String value, int backupSdkInt, int userId)470     protected void onSettingRestored(String element, String value, int backupSdkInt, int userId) {
471         if (!mUseXml) {
472             Slog.d(TAG, "Restored managed service setting: " + element);
473             if (mConfig.secureSettingName.equals(element) ||
474                     (mConfig.secondarySettingName != null
475                             && mConfig.secondarySettingName.equals(element))) {
476                 if (backupSdkInt < Build.VERSION_CODES.O) {
477                     // automatic system grants were added in O, so append the approved apps
478                     // rather than wiping out the setting
479                     String currentSetting =
480                             getApproved(userId, mConfig.secureSettingName.equals(element));
481                     if (!TextUtils.isEmpty(currentSetting)) {
482                         if (!TextUtils.isEmpty(value)) {
483                             value = value + ENABLED_SERVICES_SEPARATOR + currentSetting;
484                         } else {
485                             value = currentSetting;
486                         }
487                     }
488                 }
489                 if (shouldReflectToSettings()) {
490                     Settings.Secure.putStringForUser(
491                             mContext.getContentResolver(), element, value, userId);
492                 }
493 
494                 for (UserInfo user : mUm.getUsers()) {
495                     addApprovedList(value, user.id, mConfig.secureSettingName.equals(element));
496                 }
497                 Slog.d(TAG, "Done loading approved values from settings");
498                 rebindServices(false, userId);
499             }
500         }
501     }
502 
writeDefaults(TypedXmlSerializer out)503     void writeDefaults(TypedXmlSerializer out) throws IOException {
504         synchronized (mDefaultsLock) {
505             List<String> componentStrings = new ArrayList<>(mDefaultComponents.size());
506             for (int i = 0; i < mDefaultComponents.size(); i++) {
507                 componentStrings.add(mDefaultComponents.valueAt(i).flattenToString());
508             }
509             String defaults = String.join(ENABLED_SERVICES_SEPARATOR, componentStrings);
510             out.attribute(null, ATT_DEFAULTS, defaults);
511         }
512     }
513 
writeXml(TypedXmlSerializer out, boolean forBackup, int userId)514     public void writeXml(TypedXmlSerializer out, boolean forBackup, int userId) throws IOException {
515         out.startTag(null, getConfig().xmlTag);
516 
517         out.attributeInt(null, ATT_VERSION, Integer.parseInt(DB_VERSION));
518 
519         writeDefaults(out);
520 
521         if (forBackup) {
522             trimApprovedListsAccordingToInstalledServices(userId);
523         }
524 
525         synchronized (mApproved) {
526             final int N = mApproved.size();
527             for (int i = 0; i < N; i++) {
528                 final int approvedUserId = mApproved.keyAt(i);
529                 if (forBackup && approvedUserId != userId) {
530                     continue;
531                 }
532                 final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
533                 final Boolean isUserChanged = mIsUserChanged.get(approvedUserId);
534                 if (approvedByType != null) {
535                     final int M = approvedByType.size();
536                     for (int j = 0; j < M; j++) {
537                         final boolean isPrimary = approvedByType.keyAt(j);
538                         final Set<String> approved = approvedByType.valueAt(j);
539                         final Set<String> userSet = mUserSetServices.get(approvedUserId);
540                         if (approved != null || userSet != null || isUserChanged != null) {
541                             String allowedItems = approved == null
542                                     ? ""
543                                     : String.join(ENABLED_SERVICES_SEPARATOR, approved);
544                             out.startTag(null, TAG_MANAGED_SERVICES);
545                             out.attribute(null, ATT_APPROVED_LIST, allowedItems);
546                             out.attributeInt(null, ATT_USER_ID, approvedUserId);
547                             out.attributeBoolean(null, ATT_IS_PRIMARY, isPrimary);
548                             if (isUserChanged != null) {
549                                 out.attributeBoolean(null, ATT_USER_CHANGED, isUserChanged);
550                             } else if (userSet != null) {
551                                 String userSetItems =
552                                         String.join(ENABLED_SERVICES_SEPARATOR, userSet);
553                                 out.attribute(null, ATT_USER_SET, userSetItems);
554                             }
555                             writeExtraAttributes(out, approvedUserId);
556                             out.endTag(null, TAG_MANAGED_SERVICES);
557 
558                             if (!forBackup && isPrimary) {
559                                 if (shouldReflectToSettings()) {
560                                     // Also write values to settings, for observers who haven't
561                                     // migrated yet
562                                     Settings.Secure.putStringForUser(mContext.getContentResolver(),
563                                             getConfig().secureSettingName, allowedItems,
564                                             approvedUserId);
565                                 }
566                             }
567 
568                         }
569                     }
570                 }
571             }
572         }
573 
574         writeExtraXmlTags(out);
575 
576         out.endTag(null, getConfig().xmlTag);
577     }
578 
579     /**
580      * Returns whether the approved list of services should also be written to the Settings db
581      */
shouldReflectToSettings()582     protected boolean shouldReflectToSettings() {
583         return false;
584     }
585 
586     /**
587      * Writes extra xml attributes to {@link #TAG_MANAGED_SERVICES} tag.
588      */
writeExtraAttributes(TypedXmlSerializer out, int userId)589     protected void writeExtraAttributes(TypedXmlSerializer out, int userId) throws IOException {}
590 
591     /**
592      * Writes extra xml tags within the parent tag specified in {@link Config#xmlTag}.
593      */
writeExtraXmlTags(TypedXmlSerializer out)594     protected void writeExtraXmlTags(TypedXmlSerializer out) throws IOException {}
595 
596     /**
597      * This is called to process tags other than {@link #TAG_MANAGED_SERVICES}.
598      */
readExtraTag(String tag, TypedXmlPullParser parser)599     protected void readExtraTag(String tag, TypedXmlPullParser parser)
600             throws IOException, XmlPullParserException {}
601 
migrateToXml()602     protected final void migrateToXml() {
603         for (UserInfo user : mUm.getUsers()) {
604             final ContentResolver cr = mContext.getContentResolver();
605             if (!TextUtils.isEmpty(getConfig().secureSettingName)) {
606                 addApprovedList(Settings.Secure.getStringForUser(
607                         cr,
608                         getConfig().secureSettingName,
609                         user.id), user.id, true);
610             }
611             if (!TextUtils.isEmpty(getConfig().secondarySettingName)) {
612                 addApprovedList(Settings.Secure.getStringForUser(
613                         cr,
614                         getConfig().secondarySettingName,
615                         user.id), user.id, false);
616             }
617         }
618     }
619 
readDefaults(TypedXmlPullParser parser)620     void readDefaults(TypedXmlPullParser parser) {
621         String defaultComponents = XmlUtils.readStringAttribute(parser, ATT_DEFAULTS);
622 
623         if (!TextUtils.isEmpty(defaultComponents)) {
624             String[] components = defaultComponents.split(ENABLED_SERVICES_SEPARATOR);
625             synchronized (mDefaultsLock) {
626                 for (int i = 0; i < components.length; i++) {
627                     if (!TextUtils.isEmpty(components[i])) {
628                         ComponentName cn = ComponentName.unflattenFromString(components[i]);
629                         if (cn != null) {
630                             mDefaultPackages.add(cn.getPackageName());
631                             mDefaultComponents.add(cn);
632                         } else {
633                             mDefaultPackages.add(components[i]);
634                         }
635                     }
636                 }
637             }
638         }
639     }
640 
readXml( TypedXmlPullParser parser, TriPredicate<String, Integer, String> allowedManagedServicePackages, boolean forRestore, int userId)641     public void readXml(
642             TypedXmlPullParser parser,
643             TriPredicate<String, Integer, String> allowedManagedServicePackages,
644             boolean forRestore,
645             int userId)
646             throws XmlPullParserException, IOException {
647         // read grants
648         int type;
649         String version = XmlUtils.readStringAttribute(parser, ATT_VERSION);
650         boolean needUpgradeUserset = false;
651         readDefaults(parser);
652         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
653             String tag = parser.getName();
654             if (type == XmlPullParser.END_TAG
655                     && getConfig().xmlTag.equals(tag)) {
656                 break;
657             }
658             if (type == XmlPullParser.START_TAG) {
659                 if (TAG_MANAGED_SERVICES.equals(tag)) {
660                     Slog.i(TAG, "Read " + mConfig.caption + " permissions from xml");
661 
662                     final String approved = XmlUtils.readStringAttribute(parser, ATT_APPROVED_LIST);
663                     // Ignore parser's user id for restore.
664                     final int resolvedUserId = forRestore
665                             ? userId : parser.getAttributeInt(null, ATT_USER_ID, 0);
666                     final boolean isPrimary =
667                             parser.getAttributeBoolean(null, ATT_IS_PRIMARY, true);
668 
669                     // Load three different userSet attributes from xml
670                     // user_changed, not null if version == 4 and is NAS setting
671                     final String isUserChanged = XmlUtils.readStringAttribute(parser,
672                             ATT_USER_CHANGED);
673                     // user_set, not null if version <= 3
674                     final String isUserChanged_Old = XmlUtils.readStringAttribute(parser,
675                             ATT_USER_SET_OLD);
676                     // user_set_services, not null if version >= 3 and is non-NAS setting
677                     String userSetComponent = XmlUtils.readStringAttribute(parser, ATT_USER_SET);
678 
679                     // since the same xml version may have different userSet attributes,
680                     // we need to check both xml version and userSet values to know how to set
681                     // the userSetComponent/mIsUserChanged to the correct value
682                     if (DB_VERSION.equals(version)) {
683                         // version 4, NAS contains user_changed and
684                         // NLS/others contain user_set_services
685                         if (isUserChanged == null) { //NLS
686                             userSetComponent = TextUtils.emptyIfNull(userSetComponent);
687                         } else { //NAS
688                             synchronized (mApproved) {
689                                 mIsUserChanged.put(resolvedUserId, Boolean.valueOf(isUserChanged));
690                             }
691                             userSetComponent = Boolean.valueOf(isUserChanged) ? approved : "";
692                         }
693                     } else {
694                         // version 3 may contain user_set (R) or user_set_services (S)
695                         // version 2 or older contain user_set or nothing
696                         needUpgradeUserset = true;
697                         if (userSetComponent == null) { //contains user_set
698                             if (isUserChanged_Old != null && Boolean.valueOf(isUserChanged_Old)) {
699                                 //user_set = true
700                                 userSetComponent = approved;
701                                 synchronized (mApproved) {
702                                     mIsUserChanged.put(resolvedUserId, true);
703                                 }
704                                 needUpgradeUserset = false;
705                             } else {
706                                 userSetComponent = "";
707                             }
708                         }
709                     }
710                     readExtraAttributes(tag, parser, resolvedUserId);
711                     if (allowedManagedServicePackages == null || allowedManagedServicePackages.test(
712                             getPackageName(approved), resolvedUserId, getRequiredPermission())
713                             || approved.isEmpty()) {
714                         if (mUm.getUserInfo(resolvedUserId) != null) {
715                             addApprovedList(approved, resolvedUserId, isPrimary, userSetComponent);
716                         }
717                         mUseXml = true;
718                     }
719                 } else {
720                     readExtraTag(tag, parser);
721                 }
722             }
723         }
724         boolean isOldVersion = TextUtils.isEmpty(version)
725                 || DB_VERSION_1.equals(version)
726                 || DB_VERSION_2.equals(version)
727                 || DB_VERSION_3.equals(version);
728         if (isOldVersion) {
729             upgradeDefaultsXmlVersion();
730         }
731         if (needUpgradeUserset) {
732             upgradeUserSet();
733         }
734 
735         rebindServices(false, USER_ALL);
736     }
737 
upgradeDefaultsXmlVersion()738     void upgradeDefaultsXmlVersion() {
739         int defaultsSize;
740         synchronized (mDefaultsLock) {
741             // check if any defaults are loaded
742             defaultsSize = mDefaultComponents.size() + mDefaultPackages.size();
743         }
744         if (defaultsSize == 0) {
745             // load defaults from current allowed
746             if (this.mApprovalLevel == APPROVAL_BY_COMPONENT) {
747                 List<ComponentName> approvedComponents = getAllowedComponents(USER_SYSTEM);
748                 for (int i = 0; i < approvedComponents.size(); i++) {
749                     addDefaultComponentOrPackage(approvedComponents.get(i).flattenToString());
750                 }
751             }
752             if (this.mApprovalLevel == APPROVAL_BY_PACKAGE) {
753                 List<String> approvedPkgs = getAllowedPackages(USER_SYSTEM);
754                 for (int i = 0; i < approvedPkgs.size(); i++) {
755                     addDefaultComponentOrPackage(approvedPkgs.get(i));
756                 }
757             }
758         }
759         synchronized (mDefaultsLock) {
760             defaultsSize = mDefaultComponents.size() + mDefaultPackages.size();
761         }
762         // if no defaults are loaded, then load from config
763         if (defaultsSize == 0) {
764             loadDefaultsFromConfig();
765         }
766     }
767 
upgradeUserSet()768     protected void upgradeUserSet() {};
769 
770     /**
771      * Read extra attributes in the {@link #TAG_MANAGED_SERVICES} tag.
772      */
readExtraAttributes(String tag, TypedXmlPullParser parser, int userId)773     protected void readExtraAttributes(String tag, TypedXmlPullParser parser, int userId)
774             throws IOException {}
775 
getRequiredPermission()776     protected abstract String getRequiredPermission();
777 
addApprovedList(String approved, int userId, boolean isPrimary)778     protected void addApprovedList(String approved, int userId, boolean isPrimary) {
779         addApprovedList(approved, userId, isPrimary, approved);
780     }
781 
addApprovedList(String approved, int userId, boolean isPrimary, String userSet)782     protected void addApprovedList(String approved, int userId, boolean isPrimary, String userSet) {
783         if (TextUtils.isEmpty(approved)) {
784             approved = "";
785         }
786         if (userSet == null) {
787             userSet = approved;
788         }
789         synchronized (mApproved) {
790             ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
791             if (approvedByType == null) {
792                 approvedByType = new ArrayMap<>();
793                 mApproved.put(userId, approvedByType);
794             }
795 
796             ArraySet<String> approvedList = approvedByType.get(isPrimary);
797             if (approvedList == null) {
798                 approvedList = new ArraySet<>();
799                 approvedByType.put(isPrimary, approvedList);
800             }
801 
802             String[] approvedArray = approved.split(ENABLED_SERVICES_SEPARATOR);
803             for (String pkgOrComponent : approvedArray) {
804                 String approvedItem = getApprovedValue(pkgOrComponent);
805                 if (approvedItem != null) {
806                     approvedList.add(approvedItem);
807                 }
808             }
809 
810             ArraySet<String> userSetList = mUserSetServices.get(userId);
811             if (userSetList == null) {
812                 userSetList = new ArraySet<>();
813                 mUserSetServices.put(userId, userSetList);
814             }
815             String[] userSetArray = userSet.split(ENABLED_SERVICES_SEPARATOR);
816             for (String pkgOrComponent : userSetArray) {
817                 String approvedItem = getApprovedValue(pkgOrComponent);
818                 if (approvedItem != null) {
819                     userSetList.add(approvedItem);
820                 }
821             }
822         }
823     }
824 
isComponentEnabledForPackage(String pkg)825     protected boolean isComponentEnabledForPackage(String pkg) {
826         synchronized (mMutex) {
827             return mEnabledServicesPackageNames.contains(pkg);
828         }
829     }
830 
setPackageOrComponentEnabled(String pkgOrComponent, int userId, boolean isPrimary, boolean enabled)831     protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
832             boolean isPrimary, boolean enabled) {
833         setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled, true);
834     }
835 
setPackageOrComponentEnabled(String pkgOrComponent, int userId, boolean isPrimary, boolean enabled, boolean userSet)836     protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
837             boolean isPrimary, boolean enabled, boolean userSet) {
838         Slog.i(TAG,
839                 (enabled ? " Allowing " : "Disallowing ") + mConfig.caption + " "
840                         + pkgOrComponent + " (userSet: " + userSet + ")");
841         synchronized (mApproved) {
842             ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId);
843             if (allowedByType == null) {
844                 allowedByType = new ArrayMap<>();
845                 mApproved.put(userId, allowedByType);
846             }
847             ArraySet<String> approved = allowedByType.get(isPrimary);
848             if (approved == null) {
849                 approved = new ArraySet<>();
850                 allowedByType.put(isPrimary, approved);
851             }
852             String approvedItem = getApprovedValue(pkgOrComponent);
853 
854             if (approvedItem != null) {
855                 if (enabled) {
856                     approved.add(approvedItem);
857                 } else {
858                     approved.remove(approvedItem);
859                 }
860             }
861             ArraySet<String> userSetServices = mUserSetServices.get(userId);
862             if (userSetServices == null) {
863                 userSetServices = new ArraySet<>();
864                 mUserSetServices.put(userId, userSetServices);
865             }
866             if (userSet) {
867                 userSetServices.add(pkgOrComponent);
868             } else {
869                 userSetServices.remove(pkgOrComponent);
870             }
871         }
872 
873         rebindServices(false, userId);
874     }
875 
getApprovedValue(String pkgOrComponent)876     private String getApprovedValue(String pkgOrComponent) {
877         if (mApprovalLevel == APPROVAL_BY_COMPONENT) {
878             if(ComponentName.unflattenFromString(pkgOrComponent) != null) {
879                 return pkgOrComponent;
880             }
881             return null;
882         } else {
883             return getPackageName(pkgOrComponent);
884         }
885     }
886 
getApproved(int userId, boolean primary)887     protected String getApproved(int userId, boolean primary) {
888         synchronized (mApproved) {
889             final ArrayMap<Boolean, ArraySet<String>> allowedByType =
890                     mApproved.getOrDefault(userId, new ArrayMap<>());
891             ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>());
892             return String.join(ENABLED_SERVICES_SEPARATOR, approved);
893         }
894     }
895 
getAllowedComponents(int userId)896     protected List<ComponentName> getAllowedComponents(int userId) {
897         final List<ComponentName> allowedComponents = new ArrayList<>();
898         synchronized (mApproved) {
899             final ArrayMap<Boolean, ArraySet<String>> allowedByType =
900                     mApproved.getOrDefault(userId, new ArrayMap<>());
901             for (int i = 0; i < allowedByType.size(); i++) {
902                 final ArraySet<String> allowed = allowedByType.valueAt(i);
903                 for (int j = 0; j < allowed.size(); j++) {
904                     ComponentName cn = ComponentName.unflattenFromString(allowed.valueAt(j));
905                     if (cn != null) {
906                         allowedComponents.add(cn);
907                     }
908                 }
909             }
910         }
911         return allowedComponents;
912     }
913 
914     @NonNull
getAllowedPackages(int userId)915     protected List<String> getAllowedPackages(int userId) {
916         final List<String> allowedPackages = new ArrayList<>();
917         synchronized (mApproved) {
918             final ArrayMap<Boolean, ArraySet<String>> allowedByType =
919                     mApproved.getOrDefault(userId, new ArrayMap<>());
920             for (int i = 0; i < allowedByType.size(); i++) {
921                 final ArraySet<String> allowed = allowedByType.valueAt(i);
922                 for (int j = 0; j < allowed.size(); j++) {
923                     String pkgName = getPackageName(allowed.valueAt(j));
924                     if (!TextUtils.isEmpty(pkgName)) {
925                         allowedPackages.add(pkgName);
926                     }
927                 }
928             }
929         }
930         return allowedPackages;
931     }
932 
isPackageOrComponentAllowed(String pkgOrComponent, int userId)933     protected boolean isPackageOrComponentAllowed(String pkgOrComponent, int userId) {
934         synchronized (mApproved) {
935             ArrayMap<Boolean, ArraySet<String>> allowedByType =
936                     mApproved.getOrDefault(userId, new ArrayMap<>());
937             for (int i = 0; i < allowedByType.size(); i++) {
938                 ArraySet<String> allowed = allowedByType.valueAt(i);
939                 if (allowed.contains(pkgOrComponent)) {
940                     return true;
941                 }
942             }
943         }
944         return false;
945     }
946 
isPackageOrComponentAllowedWithPermission(ComponentName component, int userId)947     protected boolean isPackageOrComponentAllowedWithPermission(ComponentName component,
948             int userId) {
949         if (!(isPackageOrComponentAllowed(component.flattenToString(), userId)
950                 || isPackageOrComponentAllowed(component.getPackageName(), userId))) {
951             return false;
952         }
953         return componentHasBindPermission(component, userId);
954     }
955 
componentHasBindPermission(ComponentName component, int userId)956     private boolean componentHasBindPermission(ComponentName component, int userId) {
957         ServiceInfo info = getServiceInfo(component, userId);
958         if (info == null) {
959             return false;
960         }
961         return mConfig.bindPermission.equals(info.permission);
962     }
963 
isPackageOrComponentUserSet(String pkgOrComponent, int userId)964     boolean isPackageOrComponentUserSet(String pkgOrComponent, int userId) {
965         synchronized (mApproved) {
966             ArraySet<String> services = mUserSetServices.get(userId);
967             return services != null && services.contains(pkgOrComponent);
968         }
969     }
970 
isPackageAllowed(String pkg, int userId)971     protected boolean isPackageAllowed(String pkg, int userId) {
972         if (pkg == null) {
973             return false;
974         }
975         synchronized (mApproved) {
976             ArrayMap<Boolean, ArraySet<String>> allowedByType =
977                     mApproved.getOrDefault(userId, new ArrayMap<>());
978             for (int i = 0; i < allowedByType.size(); i++) {
979                 ArraySet<String> allowed = allowedByType.valueAt(i);
980                 for (String allowedEntry : allowed) {
981                     ComponentName component = ComponentName.unflattenFromString(allowedEntry);
982                     if (component != null) {
983                         if (pkg.equals(component.getPackageName())) {
984                             return true;
985                         }
986                     } else {
987                         if (pkg.equals(allowedEntry)) {
988                             return true;
989                         }
990                     }
991                 }
992             }
993         }
994         return false;
995     }
996 
onPackagesChanged(boolean removingPackage, String[] pkgList, int[] uidList)997     public void onPackagesChanged(boolean removingPackage, String[] pkgList, int[] uidList) {
998         if (DEBUG) {
999             synchronized (mMutex) {
1000                 Slog.d(TAG, "onPackagesChanged removingPackage=" + removingPackage
1001                         + " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList))
1002                         + " mEnabledServicesPackageNames=" + mEnabledServicesPackageNames);
1003             }
1004         }
1005 
1006         if (pkgList != null && (pkgList.length > 0)) {
1007             boolean anyServicesInvolved = false;
1008             // Remove notification settings for uninstalled package
1009             if (removingPackage && uidList != null) {
1010                 int size = Math.min(pkgList.length, uidList.length);
1011                 for (int i = 0; i < size; i++) {
1012                     final String pkg = pkgList[i];
1013                     final int userId = UserHandle.getUserId(uidList[i]);
1014                     anyServicesInvolved = removeUninstalledItemsFromApprovedLists(userId, pkg);
1015                 }
1016             }
1017             for (String pkgName : pkgList) {
1018                 if (isComponentEnabledForPackage(pkgName)) {
1019                     anyServicesInvolved = true;
1020                 }
1021                 if (uidList != null && uidList.length > 0) {
1022                     for (int uid : uidList) {
1023                         if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) {
1024                             anyServicesInvolved = true;
1025                             trimApprovedListsForInvalidServices(pkgName, UserHandle.getUserId(uid));
1026                         }
1027                     }
1028                 }
1029             }
1030 
1031             if (anyServicesInvolved) {
1032                 // make sure we're still bound to any of our services who may have just upgraded
1033                 rebindServices(false, USER_ALL);
1034             }
1035         }
1036     }
1037 
onUserRemoved(int user)1038     public void onUserRemoved(int user) {
1039         Slog.i(TAG, "Removing approved services for removed user " + user);
1040         synchronized (mApproved) {
1041             mApproved.remove(user);
1042         }
1043         synchronized (mSnoozing) {
1044             mSnoozing.remove(user);
1045         }
1046         unbindUserServices(user);
1047     }
1048 
onUserSwitched(int user)1049     public void onUserSwitched(int user) {
1050         if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user);
1051         unbindOtherUserServices(user);
1052         rebindServices(true, user);
1053     }
1054 
onUserUnlocked(int user)1055     public void onUserUnlocked(int user) {
1056         if (DEBUG) Slog.d(TAG, "onUserUnlocked u=" + user);
1057         rebindServices(false, user);
1058     }
1059 
getServiceFromTokenLocked(IInterface service)1060     private ManagedServiceInfo getServiceFromTokenLocked(IInterface service) {
1061         if (service == null) {
1062             return null;
1063         }
1064         final IBinder token = service.asBinder();
1065         synchronized (mMutex) {
1066             final int nServices = mServices.size();
1067             for (int i = 0; i < nServices; i++) {
1068                 final ManagedServiceInfo info = mServices.get(i);
1069                 if (info.service.asBinder() == token) return info;
1070             }
1071         }
1072         return null;
1073     }
1074 
isServiceTokenValidLocked(IInterface service)1075     protected boolean isServiceTokenValidLocked(IInterface service) {
1076         if (service == null) {
1077             return false;
1078         }
1079         ManagedServiceInfo info = getServiceFromTokenLocked(service);
1080         if (info != null) {
1081             return true;
1082         }
1083         return false;
1084     }
1085 
checkServiceTokenLocked(IInterface service)1086     protected ManagedServiceInfo checkServiceTokenLocked(IInterface service) {
1087         checkNotNull(service);
1088         ManagedServiceInfo info = getServiceFromTokenLocked(service);
1089         if (info != null) {
1090             return info;
1091         }
1092         throw new SecurityException("Disallowed call from unknown " + getCaption() + ": "
1093                 + service + " " + service.getClass());
1094     }
1095 
isSameUser(IInterface service, int userId)1096     public boolean isSameUser(IInterface service, int userId) {
1097         checkNotNull(service);
1098         synchronized (mMutex) {
1099             ManagedServiceInfo info = getServiceFromTokenLocked(service);
1100             if (info != null) {
1101                 return info.isSameUser(userId);
1102             }
1103             return false;
1104         }
1105     }
1106 
unregisterService(IInterface service, int userid)1107     public void unregisterService(IInterface service, int userid) {
1108         checkNotNull(service);
1109         // no need to check permissions; if your service binder is in the list,
1110         // that's proof that you had permission to add it in the first place
1111         unregisterServiceImpl(service, userid);
1112     }
1113 
registerSystemService(IInterface service, ComponentName component, int userid, int uid)1114     public void registerSystemService(IInterface service, ComponentName component, int userid,
1115             int uid) {
1116         checkNotNull(service);
1117         ManagedServiceInfo info = registerServiceImpl(
1118                 service, component, userid, Build.VERSION_CODES.CUR_DEVELOPMENT, uid);
1119         if (info != null) {
1120             onServiceAdded(info);
1121         }
1122     }
1123 
1124     /**
1125      * Add a service to our callbacks. The lifecycle of this service is managed externally,
1126      * but unlike a system service, it should not be considered privileged.
1127      * */
registerGuestService(ManagedServiceInfo guest)1128     protected void registerGuestService(ManagedServiceInfo guest) {
1129         checkNotNull(guest.service);
1130         if (!checkType(guest.service)) {
1131             throw new IllegalArgumentException();
1132         }
1133         if (registerServiceImpl(guest) != null) {
1134             onServiceAdded(guest);
1135         }
1136     }
1137 
setComponentState(ComponentName component, int userId, boolean enabled)1138     protected void setComponentState(ComponentName component, int userId, boolean enabled) {
1139         synchronized (mSnoozing) {
1140             boolean previous = !mSnoozing.contains(userId, component);
1141             if (previous == enabled) {
1142                 return;
1143             }
1144 
1145             if (enabled) {
1146                 mSnoozing.remove(userId, component);
1147             } else {
1148                 mSnoozing.add(userId, component);
1149             }
1150         }
1151 
1152         // State changed
1153         Slog.d(TAG, ((enabled) ? "Enabling " : "Disabling ") + "component " +
1154                 component.flattenToShortString());
1155 
1156         synchronized (mMutex) {
1157             if (enabled) {
1158                 if (isPackageOrComponentAllowedWithPermission(component, userId)) {
1159                     registerServiceLocked(component, userId);
1160                 } else {
1161                     Slog.d(TAG, component + " no longer has permission to be bound");
1162                 }
1163             } else {
1164                 unregisterServiceLocked(component, userId);
1165             }
1166         }
1167     }
1168 
loadComponentNamesFromValues( ArraySet<String> approved, int userId)1169     private @NonNull ArraySet<ComponentName> loadComponentNamesFromValues(
1170             ArraySet<String> approved, int userId) {
1171         if (approved == null || approved.size() == 0)
1172             return new ArraySet<>();
1173         ArraySet<ComponentName> result = new ArraySet<>(approved.size());
1174         for (int i = 0; i < approved.size(); i++) {
1175             final String packageOrComponent = approved.valueAt(i);
1176             if (!TextUtils.isEmpty(packageOrComponent)) {
1177                 ComponentName component = ComponentName.unflattenFromString(packageOrComponent);
1178                 if (component != null) {
1179                     result.add(component);
1180                 } else {
1181                     result.addAll(queryPackageForServices(packageOrComponent, userId));
1182                 }
1183             }
1184         }
1185         return result;
1186     }
1187 
queryPackageForServices(String packageName, int userId)1188     protected Set<ComponentName> queryPackageForServices(String packageName, int userId) {
1189         return queryPackageForServices(packageName, 0, userId);
1190     }
1191 
queryPackageForServices(String packageName, int extraFlags, int userId)1192     protected ArraySet<ComponentName> queryPackageForServices(String packageName, int extraFlags,
1193             int userId) {
1194         ArraySet<ComponentName> installed = new ArraySet<>();
1195         final PackageManager pm = mContext.getPackageManager();
1196         Intent queryIntent = new Intent(mConfig.serviceInterface);
1197         if (!TextUtils.isEmpty(packageName)) {
1198             queryIntent.setPackage(packageName);
1199         }
1200         List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
1201                 queryIntent,
1202                 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA | extraFlags,
1203                 userId);
1204         if (DEBUG)
1205             Slog.v(TAG, mConfig.serviceInterface + " services: " + installedServices);
1206         if (installedServices != null) {
1207             for (int i = 0, count = installedServices.size(); i < count; i++) {
1208                 ResolveInfo resolveInfo = installedServices.get(i);
1209                 ServiceInfo info = resolveInfo.serviceInfo;
1210 
1211                 ComponentName component = new ComponentName(info.packageName, info.name);
1212                 if (!mConfig.bindPermission.equals(info.permission)) {
1213                     Slog.w(TAG, "Skipping " + getCaption() + " service "
1214                         + info.packageName + "/" + info.name
1215                         + ": it does not require the permission "
1216                         + mConfig.bindPermission);
1217                     continue;
1218                 }
1219                 installed.add(component);
1220             }
1221         }
1222         return installed;
1223     }
1224 
trimApprovedListsAccordingToInstalledServices(int userId)1225     private void trimApprovedListsAccordingToInstalledServices(int userId) {
1226         synchronized (mApproved) {
1227             final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
1228             if (approvedByType == null) {
1229                 return;
1230             }
1231             for (int i = 0; i < approvedByType.size(); i++) {
1232                 final ArraySet<String> approved = approvedByType.valueAt(i);
1233                 for (int j = approved.size() - 1; j >= 0; j--) {
1234                     final String approvedPackageOrComponent = approved.valueAt(j);
1235                     if (!isValidEntry(approvedPackageOrComponent, userId)) {
1236                         approved.removeAt(j);
1237                         Slog.v(TAG, "Removing " + approvedPackageOrComponent
1238                                 + " from approved list; no matching services found");
1239                     } else {
1240                         if (DEBUG) {
1241                             Slog.v(TAG, "Keeping " + approvedPackageOrComponent
1242                                     + " on approved list; matching services found");
1243                         }
1244                     }
1245                 }
1246             }
1247         }
1248     }
1249 
removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg)1250     private boolean removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg) {
1251         boolean removed = false;
1252         synchronized (mApproved) {
1253             final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(
1254                     uninstalledUserId);
1255             if (approvedByType != null) {
1256                 int M = approvedByType.size();
1257                 for (int j = 0; j < M; j++) {
1258                     final ArraySet<String> approved = approvedByType.valueAt(j);
1259                     int O = approved.size();
1260                     for (int k = O - 1; k >= 0; k--) {
1261                         final String packageOrComponent = approved.valueAt(k);
1262                         final String packageName = getPackageName(packageOrComponent);
1263                         if (TextUtils.equals(pkg, packageName)) {
1264                             approved.removeAt(k);
1265                             if (DEBUG) {
1266                                 Slog.v(TAG, "Removing " + packageOrComponent
1267                                         + " from approved list; uninstalled");
1268                             }
1269                         }
1270                     }
1271                 }
1272             }
1273             // Remove uninstalled components from user-set list
1274             final ArraySet<String> userSet = mUserSetServices.get(uninstalledUserId);
1275             if (userSet != null) {
1276                 int numServices = userSet.size();
1277                 for (int i = numServices - 1; i >= 0; i--) {
1278                     String pkgOrComponent = userSet.valueAt(i);
1279                     if (TextUtils.equals(pkg, getPackageName(pkgOrComponent))) {
1280                         userSet.removeAt(i);
1281                         if (DEBUG) {
1282                             Slog.v(TAG, "Removing " + pkgOrComponent
1283                                     + " from user-set list; uninstalled");
1284                         }
1285                     }
1286                 }
1287             }
1288         }
1289         return removed;
1290     }
1291 
trimApprovedListsForInvalidServices(String packageName, int userId)1292     private void trimApprovedListsForInvalidServices(String packageName, int userId) {
1293         synchronized (mApproved) {
1294             final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
1295             if (approvedByType == null) {
1296                 return;
1297             }
1298             for (int i = 0; i < approvedByType.size(); i++) {
1299                 final ArraySet<String> approved = approvedByType.valueAt(i);
1300                 for (int j = approved.size() - 1; j >= 0; j--) {
1301                     final String approvedPackageOrComponent = approved.valueAt(j);
1302                     if (TextUtils.equals(getPackageName(approvedPackageOrComponent), packageName)) {
1303                         final ComponentName component = ComponentName.unflattenFromString(
1304                                 approvedPackageOrComponent);
1305                         if (component != null && !componentHasBindPermission(component, userId)) {
1306                             approved.removeAt(j);
1307                             if (DEBUG) {
1308                                 Slog.v(TAG, "Removing " + approvedPackageOrComponent
1309                                         + " from approved list; no bind permission found "
1310                                         + mConfig.bindPermission);
1311                             }
1312                         }
1313                     }
1314                 }
1315             }
1316         }
1317     }
1318 
getPackageName(String packageOrComponent)1319     protected String getPackageName(String packageOrComponent) {
1320         final ComponentName component = ComponentName.unflattenFromString(packageOrComponent);
1321         if (component != null) {
1322             return component.getPackageName();
1323         } else {
1324             return packageOrComponent;
1325         }
1326     }
1327 
isValidEntry(String packageOrComponent, int userId)1328     protected boolean isValidEntry(String packageOrComponent, int userId) {
1329         return hasMatchingServices(packageOrComponent, userId);
1330     }
1331 
hasMatchingServices(String packageOrComponent, int userId)1332     private boolean hasMatchingServices(String packageOrComponent, int userId) {
1333         if (!TextUtils.isEmpty(packageOrComponent)) {
1334             final String packageName = getPackageName(packageOrComponent);
1335             return queryPackageForServices(packageName, userId).size() > 0;
1336         }
1337         return false;
1338     }
1339 
1340     @VisibleForTesting
getAllowedComponents(IntArray userIds)1341     protected SparseArray<ArraySet<ComponentName>> getAllowedComponents(IntArray userIds) {
1342         final int nUserIds = userIds.size();
1343         final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>();
1344 
1345         for (int i = 0; i < nUserIds; ++i) {
1346             final int userId = userIds.get(i);
1347             synchronized (mApproved) {
1348                 final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId);
1349                 if (approvedLists != null) {
1350                     final int N = approvedLists.size();
1351                     for (int j = 0; j < N; j++) {
1352                         ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId);
1353                         if (approvedByUser == null) {
1354                             approvedByUser = new ArraySet<>();
1355                             componentsByUser.put(userId, approvedByUser);
1356                         }
1357                         approvedByUser.addAll(
1358                                 loadComponentNamesFromValues(approvedLists.valueAt(j), userId));
1359                     }
1360                 }
1361             }
1362         }
1363         return componentsByUser;
1364     }
1365 
1366     @GuardedBy("mMutex")
populateComponentsToBind(SparseArray<Set<ComponentName>> componentsToBind, final IntArray activeUsers, SparseArray<ArraySet<ComponentName>> approvedComponentsByUser)1367     protected void populateComponentsToBind(SparseArray<Set<ComponentName>> componentsToBind,
1368             final IntArray activeUsers,
1369             SparseArray<ArraySet<ComponentName>> approvedComponentsByUser) {
1370         mEnabledServicesForCurrentProfiles.clear();
1371         mEnabledServicesPackageNames.clear();
1372         final int nUserIds = activeUsers.size();
1373 
1374         for (int i = 0; i < nUserIds; ++i) {
1375             // decode the list of components
1376             final int userId = activeUsers.get(i);
1377             final ArraySet<ComponentName> userComponents = approvedComponentsByUser.get(userId);
1378             if (null == userComponents) {
1379                 componentsToBind.put(userId, new ArraySet<>());
1380                 continue;
1381             }
1382 
1383             final Set<ComponentName> add = new HashSet<>(userComponents);
1384             synchronized (mSnoozing) {
1385                 ArraySet<ComponentName> snoozed = mSnoozing.get(userId);
1386                 if (snoozed != null) {
1387                     add.removeAll(snoozed);
1388                 }
1389             }
1390 
1391             componentsToBind.put(userId, add);
1392 
1393             mEnabledServicesForCurrentProfiles.addAll(userComponents);
1394 
1395             for (int j = 0; j < userComponents.size(); j++) {
1396                 final ComponentName component = userComponents.valueAt(j);
1397                 mEnabledServicesPackageNames.add(component.getPackageName());
1398             }
1399         }
1400     }
1401 
1402     @GuardedBy("mMutex")
getRemovableConnectedServices()1403     protected Set<ManagedServiceInfo> getRemovableConnectedServices() {
1404         final Set<ManagedServiceInfo> removableBoundServices = new ArraySet<>();
1405         for (ManagedServiceInfo service : mServices) {
1406             if (!service.isSystem && !service.isGuest(this)) {
1407                 removableBoundServices.add(service);
1408             }
1409         }
1410         return removableBoundServices;
1411     }
1412 
populateComponentsToUnbind( boolean forceRebind, Set<ManagedServiceInfo> removableBoundServices, SparseArray<Set<ComponentName>> allowedComponentsToBind, SparseArray<Set<ComponentName>> componentsToUnbind)1413     protected void populateComponentsToUnbind(
1414             boolean forceRebind,
1415             Set<ManagedServiceInfo> removableBoundServices,
1416             SparseArray<Set<ComponentName>> allowedComponentsToBind,
1417             SparseArray<Set<ComponentName>> componentsToUnbind) {
1418         for (ManagedServiceInfo info : removableBoundServices) {
1419             final Set<ComponentName> allowedComponents = allowedComponentsToBind.get(info.userid);
1420             if (allowedComponents != null) {
1421                 if (forceRebind || !allowedComponents.contains(info.component)) {
1422                     Set<ComponentName> toUnbind =
1423                             componentsToUnbind.get(info.userid, new ArraySet<>());
1424                     toUnbind.add(info.component);
1425                     componentsToUnbind.put(info.userid, toUnbind);
1426                 }
1427             }
1428         }
1429     }
1430 
1431     /**
1432      * Called whenever packages change, the user switches, or the secure setting
1433      * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
1434      */
rebindServices(boolean forceRebind, int userToRebind)1435     protected void rebindServices(boolean forceRebind, int userToRebind) {
1436         if (DEBUG) Slog.d(TAG, "rebindServices " + forceRebind + " " + userToRebind);
1437         IntArray userIds = mUserProfiles.getCurrentProfileIds();
1438         boolean rebindAllCurrentUsers = mUserProfiles.isProfileUser(userToRebind, mContext)
1439                 && allowRebindForParentUser();
1440         if (userToRebind != USER_ALL && !rebindAllCurrentUsers) {
1441             userIds = new IntArray(1);
1442             userIds.add(userToRebind);
1443         }
1444 
1445         final SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
1446         final SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
1447 
1448         synchronized (mMutex) {
1449             final SparseArray<ArraySet<ComponentName>> approvedComponentsByUser =
1450                     getAllowedComponents(userIds);
1451             final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();
1452 
1453             // Filter approvedComponentsByUser to collect all of the components that are allowed
1454             // for the currently active user(s).
1455             populateComponentsToBind(componentsToBind, userIds, approvedComponentsByUser);
1456 
1457             // For every current non-system connection, disconnect services that are no longer
1458             // approved, or ALL services if we are force rebinding
1459             populateComponentsToUnbind(
1460                     forceRebind, removableBoundServices, componentsToBind, componentsToUnbind);
1461         }
1462 
1463         unbindFromServices(componentsToUnbind);
1464         bindToServices(componentsToBind);
1465     }
1466 
1467     /**
1468      * Called when user switched to unbind all services from other users.
1469      */
1470     @VisibleForTesting
unbindOtherUserServices(int currentUser)1471     void unbindOtherUserServices(int currentUser) {
1472         TimingsTraceAndSlog t = new TimingsTraceAndSlog();
1473         t.traceBegin("ManagedServices.unbindOtherUserServices_current" + currentUser);
1474         unbindServicesImpl(currentUser, true /* allExceptUser */);
1475         t.traceEnd();
1476     }
1477 
unbindUserServices(int user)1478     void unbindUserServices(int user) {
1479         TimingsTraceAndSlog t = new TimingsTraceAndSlog();
1480         t.traceBegin("ManagedServices.unbindUserServices" + user);
1481         unbindServicesImpl(user, false /* allExceptUser */);
1482         t.traceEnd();
1483     }
1484 
unbindServicesImpl(int user, boolean allExceptUser)1485     void unbindServicesImpl(int user, boolean allExceptUser) {
1486         final SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
1487         synchronized (mMutex) {
1488             final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();
1489             for (ManagedServiceInfo info : removableBoundServices) {
1490                 if ((allExceptUser && (info.userid != user))
1491                         || (!allExceptUser && (info.userid == user))) {
1492                     Set<ComponentName> toUnbind =
1493                             componentsToUnbind.get(info.userid, new ArraySet<>());
1494                     toUnbind.add(info.component);
1495                     componentsToUnbind.put(info.userid, toUnbind);
1496                 }
1497             }
1498         }
1499         unbindFromServices(componentsToUnbind);
1500     }
1501 
unbindFromServices(SparseArray<Set<ComponentName>> componentsToUnbind)1502     protected void unbindFromServices(SparseArray<Set<ComponentName>> componentsToUnbind) {
1503         for (int i = 0; i < componentsToUnbind.size(); i++) {
1504             final int userId = componentsToUnbind.keyAt(i);
1505             final Set<ComponentName> removableComponents = componentsToUnbind.get(userId);
1506             for (ComponentName cn : removableComponents) {
1507                 // No longer allowed to be bound, or must rebind.
1508                 Slog.v(TAG, "disabling " + getCaption() + " for user " + userId + ": " + cn);
1509                 unregisterService(cn, userId);
1510             }
1511         }
1512     }
1513 
1514     // Attempt to bind to services, skipping those that cannot be found or lack the permission.
bindToServices(SparseArray<Set<ComponentName>> componentsToBind)1515     private void bindToServices(SparseArray<Set<ComponentName>> componentsToBind) {
1516         for (int i = 0; i < componentsToBind.size(); i++) {
1517             final int userId = componentsToBind.keyAt(i);
1518             final Set<ComponentName> add = componentsToBind.get(userId);
1519             for (ComponentName component : add) {
1520                 ServiceInfo info = getServiceInfo(component, userId);
1521                 if (info == null) {
1522                     Slog.w(TAG, "Not binding " + getCaption() + " service " + component
1523                             + ": service not found");
1524                     continue;
1525                 }
1526                 if (!mConfig.bindPermission.equals(info.permission)) {
1527                     Slog.w(TAG, "Not binding " + getCaption() + " service " + component
1528                             + ": it does not require the permission " + mConfig.bindPermission);
1529                     continue;
1530                 }
1531                 // Do not (auto)bind if service has meta-data to explicitly disallow it
1532                 if (!isAutobindAllowed(info) && !isBoundOrRebinding(component, userId)) {
1533                     synchronized (mSnoozing) {
1534                         Slog.d(TAG, "Not binding " + getCaption() + " service " + component
1535                                 + ": has META_DATA_DEFAULT_AUTOBIND = false");
1536                         mSnoozing.add(userId, component);
1537                     }
1538                     continue;
1539                 }
1540 
1541                 Slog.v(TAG,
1542                         "enabling " + getCaption() + " for " + userId + ": " + component);
1543                 registerService(info, userId);
1544             }
1545         }
1546     }
1547 
1548     /**
1549      * Version of registerService that takes the name of a service component to bind to.
1550      */
1551     @VisibleForTesting
registerService(final ServiceInfo si, final int userId)1552     void registerService(final ServiceInfo si, final int userId) {
1553         ensureFilters(si, userId);
1554         registerService(si.getComponentName(), userId);
1555     }
1556 
1557     @VisibleForTesting
registerService(final ComponentName cn, final int userId)1558     void registerService(final ComponentName cn, final int userId) {
1559         synchronized (mMutex) {
1560             registerServiceLocked(cn, userId);
1561         }
1562     }
1563 
1564     @VisibleForTesting
reregisterService(final ComponentName cn, final int userId)1565     void reregisterService(final ComponentName cn, final int userId) {
1566         // If rebinding a package that died, ensure it still has permission
1567         // after the rebind delay
1568         if (isPackageOrComponentAllowedWithPermission(cn, userId)) {
1569             registerService(cn, userId);
1570         }
1571     }
1572 
1573     /**
1574      * Inject a system service into the management list.
1575      */
registerSystemService(final ComponentName name, final int userid)1576     public void registerSystemService(final ComponentName name, final int userid) {
1577         synchronized (mMutex) {
1578             registerServiceLocked(name, userid, true /* isSystem */);
1579         }
1580     }
1581 
1582     @GuardedBy("mMutex")
registerServiceLocked(final ComponentName name, final int userid)1583     private void registerServiceLocked(final ComponentName name, final int userid) {
1584         registerServiceLocked(name, userid, false /* isSystem */);
1585     }
1586 
1587     @GuardedBy("mMutex")
registerServiceLocked(final ComponentName name, final int userid, final boolean isSystem)1588     private void registerServiceLocked(final ComponentName name, final int userid,
1589             final boolean isSystem) {
1590         if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid);
1591 
1592         final Pair<ComponentName, Integer> servicesBindingTag = Pair.create(name, userid);
1593         if (mServicesBound.contains(servicesBindingTag)) {
1594             Slog.v(TAG, "Not registering " + name + " is already bound");
1595             // stop registering this thing already! we're working on it
1596             return;
1597         }
1598         mServicesBound.add(servicesBindingTag);
1599 
1600         final int N = mServices.size();
1601         for (int i = N - 1; i >= 0; i--) {
1602             final ManagedServiceInfo info = mServices.get(i);
1603             if (name.equals(info.component)
1604                 && info.userid == userid) {
1605                 // cut old connections
1606                 Slog.v(TAG, "    disconnecting old " + getCaption() + ": " + info.service);
1607                 removeServiceLocked(i);
1608                 if (info.connection != null) {
1609                     unbindService(info.connection, info.component, info.userid);
1610                 }
1611             }
1612         }
1613 
1614         Intent intent = new Intent(mConfig.serviceInterface);
1615         intent.setComponent(name);
1616 
1617         intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel);
1618 
1619         final ActivityOptions activityOptions = ActivityOptions.makeBasic();
1620         activityOptions.setPendingIntentCreatorBackgroundActivityStartMode(
1621                 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED);
1622         final PendingIntent pendingIntent = PendingIntent.getActivity(
1623                 mContext, 0, new Intent(mConfig.settingsAction), PendingIntent.FLAG_IMMUTABLE,
1624                 activityOptions.toBundle());
1625         intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);
1626 
1627         ApplicationInfo appInfo = null;
1628         try {
1629             appInfo = mContext.getPackageManager().getApplicationInfoAsUser(
1630                 name.getPackageName(), 0, userid);
1631         } catch (NameNotFoundException e) {
1632             // Ignore if the package doesn't exist we won't be able to bind to the service.
1633         }
1634         final int targetSdkVersion =
1635             appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
1636         final int uid = appInfo != null ? appInfo.uid : -1;
1637 
1638         try {
1639             Slog.v(TAG, "binding: " + intent);
1640             ServiceConnection serviceConnection = new ServiceConnection() {
1641                 IInterface mService;
1642 
1643                 @Override
1644                 public void onServiceConnected(ComponentName name, IBinder binder) {
1645                     Slog.v(TAG,  userid + " " + getCaption() + " service connected: " + name);
1646                     boolean added = false;
1647                     ManagedServiceInfo info = null;
1648                     synchronized (mMutex) {
1649                         mServicesRebinding.remove(servicesBindingTag);
1650                         try {
1651                             mService = asInterface(binder);
1652                             info = newServiceInfo(mService, name,
1653                                 userid, isSystem, this, targetSdkVersion, uid);
1654                             binder.linkToDeath(info, 0);
1655                             added = mServices.add(info);
1656                         } catch (RemoteException e) {
1657                             Slog.e(TAG, "Failed to linkToDeath, already dead", e);
1658                         }
1659                     }
1660                     if (added) {
1661                         onServiceAdded(info);
1662                     }
1663                 }
1664 
1665                 @Override
1666                 public void onServiceDisconnected(ComponentName name) {
1667                     Slog.v(TAG, userid + " " + getCaption() + " connection lost: " + name);
1668                 }
1669 
1670                 @Override
1671                 public void onBindingDied(ComponentName name) {
1672                     Slog.w(TAG,  userid + " " + getCaption() + " binding died: " + name);
1673                     synchronized (mMutex) {
1674                         unbindService(this, name, userid);
1675                         if (!mServicesRebinding.contains(servicesBindingTag)) {
1676                             mServicesRebinding.add(servicesBindingTag);
1677                             mHandler.postDelayed(() ->
1678                                     reregisterService(name, userid),
1679                                     ON_BINDING_DIED_REBIND_DELAY_MS);
1680                         } else {
1681                             Slog.v(TAG, getCaption() + " not rebinding in user " + userid
1682                                     + " as a previous rebind attempt was made: " + name);
1683                         }
1684                     }
1685                 }
1686 
1687                 @Override
1688                 public void onNullBinding(ComponentName name) {
1689                     Slog.v(TAG, "onNullBinding() called with: name = [" + name + "]");
1690                     mContext.unbindService(this);
1691                 }
1692             };
1693             if (!mContext.bindServiceAsUser(intent,
1694                     serviceConnection,
1695                     getBindFlags(),
1696                     new UserHandle(userid))) {
1697                 mServicesBound.remove(servicesBindingTag);
1698                 Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent
1699                         + " in user " + userid);
1700                 return;
1701             }
1702         } catch (SecurityException ex) {
1703             mServicesBound.remove(servicesBindingTag);
1704             Slog.e(TAG, "Unable to bind " + getCaption() + " service: " + intent, ex);
1705         }
1706     }
1707 
1708     @VisibleForTesting
isBound(ComponentName cn, int userId)1709     boolean isBound(ComponentName cn, int userId) {
1710         final Pair<ComponentName, Integer> servicesBindingTag = Pair.create(cn, userId);
1711         synchronized (mMutex) {
1712             return mServicesBound.contains(servicesBindingTag);
1713         }
1714     }
1715 
isBoundOrRebinding(final ComponentName cn, final int userId)1716     protected boolean isBoundOrRebinding(final ComponentName cn, final int userId) {
1717         synchronized (mMutex) {
1718             return isBound(cn, userId) || mServicesRebinding.contains(Pair.create(cn, userId));
1719         }
1720     }
1721 
1722     /**
1723      * Remove a service for the given user by ComponentName
1724      */
unregisterService(ComponentName name, int userid)1725     private void unregisterService(ComponentName name, int userid) {
1726         synchronized (mMutex) {
1727             unregisterServiceLocked(name, userid);
1728         }
1729     }
1730 
1731     @GuardedBy("mMutex")
unregisterServiceLocked(ComponentName name, int userid)1732     private void unregisterServiceLocked(ComponentName name, int userid) {
1733         final int N = mServices.size();
1734         for (int i = N - 1; i >= 0; i--) {
1735             final ManagedServiceInfo info = mServices.get(i);
1736             if (name.equals(info.component) && info.userid == userid) {
1737                 removeServiceLocked(i);
1738                 if (info.connection != null) {
1739                     unbindService(info.connection, info.component, info.userid);
1740                 }
1741             }
1742         }
1743     }
1744 
1745     /**
1746      * Removes a service from the list but does not unbind
1747      *
1748      * @return the removed service.
1749      */
removeServiceImpl(IInterface service, final int userid)1750     private ManagedServiceInfo removeServiceImpl(IInterface service, final int userid) {
1751         if (DEBUG) Slog.d(TAG, "removeServiceImpl service=" + service + " u=" + userid);
1752         ManagedServiceInfo serviceInfo = null;
1753         synchronized (mMutex) {
1754             final int N = mServices.size();
1755             for (int i = N - 1; i >= 0; i--) {
1756                 final ManagedServiceInfo info = mServices.get(i);
1757                 if (info.service.asBinder() == service.asBinder() && info.userid == userid) {
1758                     Slog.d(TAG, "Removing active service " + info.component);
1759                     serviceInfo = removeServiceLocked(i);
1760                 }
1761             }
1762         }
1763         return serviceInfo;
1764     }
1765 
1766     @GuardedBy("mMutex")
removeServiceLocked(int i)1767     private ManagedServiceInfo removeServiceLocked(int i) {
1768         final ManagedServiceInfo info = mServices.remove(i);
1769         onServiceRemovedLocked(info);
1770         return info;
1771     }
1772 
checkNotNull(IInterface service)1773     private void checkNotNull(IInterface service) {
1774         if (service == null) {
1775             throw new IllegalArgumentException(getCaption() + " must not be null");
1776         }
1777     }
1778 
registerServiceImpl(final IInterface service, final ComponentName component, final int userid, int targetSdk, int uid)1779     private ManagedServiceInfo registerServiceImpl(final IInterface service,
1780             final ComponentName component, final int userid, int targetSdk, int uid) {
1781         ManagedServiceInfo info = newServiceInfo(service, component, userid,
1782                 true /*isSystem*/, null /*connection*/, targetSdk, uid);
1783         return registerServiceImpl(info);
1784     }
1785 
registerServiceImpl(ManagedServiceInfo info)1786     private ManagedServiceInfo registerServiceImpl(ManagedServiceInfo info) {
1787         synchronized (mMutex) {
1788             try {
1789                 info.service.asBinder().linkToDeath(info, 0);
1790                 mServices.add(info);
1791                 return info;
1792             } catch (RemoteException e) {
1793                 // already dead
1794             }
1795         }
1796         return null;
1797     }
1798 
1799     /**
1800      * Removes a service from the list and unbinds.
1801      */
unregisterServiceImpl(IInterface service, int userid)1802     private void unregisterServiceImpl(IInterface service, int userid) {
1803         ManagedServiceInfo info = removeServiceImpl(service, userid);
1804         if (info != null && info.connection != null && !info.isGuest(this)) {
1805             unbindService(info.connection, info.component, info.userid);
1806         }
1807     }
1808 
unbindService(ServiceConnection connection, ComponentName component, int userId)1809     private void unbindService(ServiceConnection connection, ComponentName component, int userId) {
1810         try {
1811             mContext.unbindService(connection);
1812         } catch (IllegalArgumentException e) {
1813             Slog.e(TAG, getCaption() + " " + component + " could not be unbound", e);
1814         }
1815         synchronized (mMutex) {
1816             mServicesBound.remove(Pair.create(component, userId));
1817         }
1818     }
1819 
getServiceInfo(ComponentName component, int userId)1820     private ServiceInfo getServiceInfo(ComponentName component, int userId) {
1821         try {
1822             return mPm.getServiceInfo(component,
1823                     PackageManager.GET_META_DATA
1824                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
1825                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
1826                     userId);
1827         } catch (RemoteException e) {
1828             e.rethrowFromSystemServer();
1829         }
1830         return null;
1831     }
1832 
isAutobindAllowed(ServiceInfo serviceInfo)1833     private boolean isAutobindAllowed(ServiceInfo serviceInfo) {
1834         if (serviceInfo != null && serviceInfo.metaData != null && serviceInfo.metaData.containsKey(
1835                 META_DATA_DEFAULT_AUTOBIND)) {
1836             return serviceInfo.metaData.getBoolean(META_DATA_DEFAULT_AUTOBIND, true);
1837         }
1838         return true;
1839     }
1840 
1841     /**
1842      * Returns true if services in the parent user should be rebound
1843      *  when rebindServices is called with a profile userId.
1844      * Must be false for NotificationAssistants.
1845      */
allowRebindForParentUser()1846     protected abstract boolean allowRebindForParentUser();
1847 
1848     public class ManagedServiceInfo implements IBinder.DeathRecipient {
1849         public IInterface service;
1850         public ComponentName component;
1851         public int userid;
1852         public boolean isSystem;
1853         @FlaggedApi(FLAG_LIFETIME_EXTENSION_REFACTOR)
1854         public boolean isSystemUi;
1855         public ServiceConnection connection;
1856         public int targetSdkVersion;
1857         public Pair<ComponentName, Integer> mKey;
1858         public int uid;
1859 
ManagedServiceInfo(IInterface service, ComponentName component, int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion, int uid)1860         public ManagedServiceInfo(IInterface service, ComponentName component,
1861                 int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion,
1862                 int uid) {
1863             this.service = service;
1864             this.component = component;
1865             this.userid = userid;
1866             this.isSystem = isSystem;
1867             this.connection = connection;
1868             this.targetSdkVersion = targetSdkVersion;
1869             this.uid = uid;
1870             mKey = Pair.create(component, userid);
1871         }
1872 
isGuest(ManagedServices host)1873         public boolean isGuest(ManagedServices host) {
1874             return ManagedServices.this != host;
1875         }
1876 
getOwner()1877         public ManagedServices getOwner() {
1878             return ManagedServices.this;
1879         }
1880 
getService()1881         public IInterface getService() {
1882             return service;
1883         }
1884 
isSystem()1885         public boolean isSystem() {
1886             return isSystem;
1887         }
1888 
1889         @FlaggedApi(FLAG_LIFETIME_EXTENSION_REFACTOR)
isSystemUi()1890         public boolean isSystemUi() {
1891             return isSystemUi;
1892         }
1893 
1894         @Override
toString()1895         public String toString() {
1896             return new StringBuilder("ManagedServiceInfo[")
1897                     .append("component=").append(component)
1898                     .append(",userid=").append(userid)
1899                     .append(",isSystem=").append(isSystem)
1900                     .append(",targetSdkVersion=").append(targetSdkVersion)
1901                     .append(",connection=").append(connection == null ? null : "<connection>")
1902                     .append(",service=").append(service)
1903                     .append(']').toString();
1904         }
1905 
dumpDebug(ProtoOutputStream proto, long fieldId, ManagedServices host)1906         public void dumpDebug(ProtoOutputStream proto, long fieldId, ManagedServices host) {
1907             final long token = proto.start(fieldId);
1908             component.dumpDebug(proto, ManagedServiceInfoProto.COMPONENT);
1909             proto.write(ManagedServiceInfoProto.USER_ID, userid);
1910             proto.write(ManagedServiceInfoProto.SERVICE, service.getClass().getName());
1911             proto.write(ManagedServiceInfoProto.IS_SYSTEM, isSystem);
1912             proto.write(ManagedServiceInfoProto.IS_GUEST, isGuest(host));
1913             proto.end(token);
1914         }
1915 
isSameUser(int userId)1916         public boolean isSameUser(int userId) {
1917             if (!isEnabledForCurrentProfiles()) {
1918                 return false;
1919             }
1920             return userId == USER_ALL || userId == this.userid;
1921         }
1922 
enabledAndUserMatches(int nid)1923         public boolean enabledAndUserMatches(int nid) {
1924             if (!isEnabledForCurrentProfiles()) {
1925                 return false;
1926             }
1927             if (this.userid == USER_ALL) return true;
1928             if (this.isSystem) return true;
1929             if (nid == USER_ALL || nid == this.userid) return true;
1930             return supportsProfiles()
1931                     && mUserProfiles.isCurrentProfile(nid)
1932                     && isPermittedForProfile(nid);
1933         }
1934 
supportsProfiles()1935         public boolean supportsProfiles() {
1936             return targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP;
1937         }
1938 
1939         @Override
binderDied()1940         public void binderDied() {
1941             if (DEBUG) Slog.d(TAG, "binderDied");
1942             // Remove the service, but don't unbind from the service. The system will bring the
1943             // service back up, and the onServiceConnected handler will read the service with the
1944             // new binding. If this isn't a bound service, and is just a registered
1945             // service, just removing it from the list is all we need to do anyway.
1946             removeServiceImpl(this.service, this.userid);
1947         }
1948 
1949         /** convenience method for looking in mEnabledServicesForCurrentProfiles */
isEnabledForCurrentProfiles()1950         public boolean isEnabledForCurrentProfiles() {
1951             if (this.isSystem) return true;
1952             if (this.connection == null) return false;
1953             synchronized (mMutex) {
1954                 return mEnabledServicesForCurrentProfiles.contains(this.component);
1955             }
1956         }
1957 
1958         /**
1959          * Returns true if this service is allowed to receive events for the given userId. A
1960          * managed profile owner can disallow non-system services running outside of the profile
1961          * from receiving events from the profile.
1962          */
isPermittedForProfile(int userId)1963         public boolean isPermittedForProfile(int userId) {
1964             if (!mUserProfiles.isProfileUser(userId, mContext)) {
1965                 return true;
1966             }
1967             DevicePolicyManager dpm =
1968                     (DevicePolicyManager) mContext.getSystemService(DEVICE_POLICY_SERVICE);
1969             final long identity = Binder.clearCallingIdentity();
1970             try {
1971                 return dpm.isNotificationListenerServicePermitted(
1972                         component.getPackageName(), userId);
1973             } finally {
1974                 Binder.restoreCallingIdentity(identity);
1975             }
1976         }
1977 
1978         @Override
equals(Object o)1979         public boolean equals(Object o) {
1980             if (this == o) return true;
1981             if (o == null || getClass() != o.getClass()) return false;
1982             ManagedServiceInfo that = (ManagedServiceInfo) o;
1983             return userid == that.userid
1984                     && isSystem == that.isSystem
1985                     && targetSdkVersion == that.targetSdkVersion
1986                     && Objects.equals(service, that.service)
1987                     && Objects.equals(component, that.component)
1988                     && Objects.equals(connection, that.connection);
1989         }
1990 
1991         @Override
hashCode()1992         public int hashCode() {
1993             return Objects.hash(service, component, userid, isSystem, connection, targetSdkVersion);
1994         }
1995     }
1996 
1997     /** convenience method for looking in mEnabledServicesForCurrentProfiles */
isComponentEnabledForCurrentProfiles(ComponentName component)1998     public boolean isComponentEnabledForCurrentProfiles(ComponentName component) {
1999         synchronized (mMutex) {
2000             return mEnabledServicesForCurrentProfiles.contains(component);
2001         }
2002     }
2003 
2004     public static class UserProfiles {
2005         // Profiles of the current user.
2006         private final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
2007 
updateCache(@onNull Context context)2008         public void updateCache(@NonNull Context context) {
2009             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
2010             if (userManager != null) {
2011                 int currentUserId = ActivityManager.getCurrentUser();
2012                 List<UserInfo> profiles = userManager.getProfiles(currentUserId);
2013                 synchronized (mCurrentProfiles) {
2014                     mCurrentProfiles.clear();
2015                     for (UserInfo user : profiles) {
2016                         mCurrentProfiles.put(user.id, user);
2017                     }
2018                 }
2019             }
2020         }
2021 
2022         /**
2023          * Returns the currently active users (generally one user and its work profile).
2024          */
getCurrentProfileIds()2025         public IntArray getCurrentProfileIds() {
2026             synchronized (mCurrentProfiles) {
2027                 IntArray users = new IntArray(mCurrentProfiles.size());
2028                 final int N = mCurrentProfiles.size();
2029                 for (int i = 0; i < N; ++i) {
2030                     users.add(mCurrentProfiles.keyAt(i));
2031                 }
2032                 return users;
2033             }
2034         }
2035 
isCurrentProfile(int userId)2036         public boolean isCurrentProfile(int userId) {
2037             synchronized (mCurrentProfiles) {
2038                 return mCurrentProfiles.get(userId) != null;
2039             }
2040         }
2041 
isProfileUser(int userId, Context context)2042         public boolean isProfileUser(int userId, Context context) {
2043             synchronized (mCurrentProfiles) {
2044                 UserInfo user = mCurrentProfiles.get(userId);
2045                 if (user == null) {
2046                     return false;
2047                 }
2048                 if (privateSpaceFlagsEnabled()) {
2049                     return user.isProfile() && hasParent(user, context);
2050                 }
2051                 return user.isManagedProfile() || user.isCloneProfile();
2052             }
2053         }
2054 
hasParent(UserInfo profile, Context context)2055         boolean hasParent(UserInfo profile, Context context) {
2056             final long identity = Binder.clearCallingIdentity();
2057             try {
2058                 UserManager um = context.getSystemService(UserManager.class);
2059                 return um.getProfileParent(profile.id) != null;
2060             } finally {
2061                 Binder.restoreCallingIdentity(identity);
2062             }
2063         }
2064     }
2065 
2066     public static class Config {
2067         public String caption;
2068         public String serviceInterface;
2069         public String secureSettingName;
2070         public String secondarySettingName;
2071         public String xmlTag;
2072         public String bindPermission;
2073         public String settingsAction;
2074         public int clientLabel;
2075     }
2076 }
2077