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