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