• 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 
24 import android.annotation.NonNull;
25 import android.app.ActivityManager;
26 import android.app.PendingIntent;
27 import android.app.admin.DevicePolicyManager;
28 import android.content.ComponentName;
29 import android.content.ContentResolver;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.ServiceConnection;
33 import android.content.pm.ApplicationInfo;
34 import android.content.pm.IPackageManager;
35 import android.content.pm.PackageManager;
36 import android.content.pm.PackageManager.NameNotFoundException;
37 import android.content.pm.ResolveInfo;
38 import android.content.pm.ServiceInfo;
39 import android.content.pm.UserInfo;
40 import android.os.Binder;
41 import android.os.Build;
42 import android.os.Handler;
43 import android.os.IBinder;
44 import android.os.IInterface;
45 import android.os.Looper;
46 import android.os.RemoteException;
47 import android.os.UserHandle;
48 import android.os.UserManager;
49 import android.provider.Settings;
50 import android.service.notification.ManagedServiceInfoProto;
51 import android.service.notification.ManagedServicesProto;
52 import android.service.notification.ManagedServicesProto.ServiceProto;
53 import android.text.TextUtils;
54 import android.util.ArrayMap;
55 import android.util.ArraySet;
56 import android.util.Log;
57 import android.util.Slog;
58 import android.util.SparseArray;
59 import android.util.proto.ProtoOutputStream;
60 
61 import com.android.internal.util.XmlUtils;
62 import com.android.server.notification.NotificationManagerService.DumpFilter;
63 
64 import org.xmlpull.v1.XmlPullParser;
65 import org.xmlpull.v1.XmlPullParserException;
66 import org.xmlpull.v1.XmlSerializer;
67 
68 import java.io.IOException;
69 import java.io.PrintWriter;
70 import java.util.ArrayList;
71 import java.util.Arrays;
72 import java.util.HashSet;
73 import java.util.List;
74 import java.util.Set;
75 import java.util.function.Predicate;
76 import java.util.stream.Collectors;
77 
78 /**
79  * Manages the lifecycle of application-provided services bound by system server.
80  *
81  * Services managed by this helper must have:
82  *  - An associated system settings value with a list of enabled component names.
83  *  - A well-known action for services to use in their intent-filter.
84  *  - A system permission for services to require in order to ensure system has exclusive binding.
85  *  - A settings page for user configuration of enabled services, and associated intent action.
86  *  - A remote interface definition (aidl) provided by the service used for communication.
87  */
88 abstract public class ManagedServices {
89     protected final String TAG = getClass().getSimpleName();
90     protected final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
91 
92     private static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
93     protected static final String ENABLED_SERVICES_SEPARATOR = ":";
94 
95     /**
96      * List of components and apps that can have running {@link ManagedServices}.
97      */
98     static final String TAG_MANAGED_SERVICES = "service_listing";
99     static final String ATT_APPROVED_LIST = "approved";
100     static final String ATT_USER_ID = "user";
101     static final String ATT_IS_PRIMARY = "primary";
102     static final String ATT_VERSION = "version";
103 
104     static final int DB_VERSION = 1;
105 
106     static final int APPROVAL_BY_PACKAGE = 0;
107     static final int APPROVAL_BY_COMPONENT = 1;
108 
109     protected final Context mContext;
110     protected final Object mMutex;
111     private final UserProfiles mUserProfiles;
112     private final IPackageManager mPm;
113     protected final UserManager mUm;
114     private final Config mConfig;
115     private final Handler mHandler = new Handler(Looper.getMainLooper());
116 
117     // contains connections to all connected services, including app services
118     // and system services
119     private final ArrayList<ManagedServiceInfo> mServices = new ArrayList<>();
120     // things that will be put into mServices as soon as they're ready
121     private final ArrayList<String> mServicesBinding = new ArrayList<>();
122     private final ArraySet<String> mServicesRebinding = new ArraySet<>();
123 
124     // lists the component names of all enabled (and therefore potentially connected)
125     // app services for current profiles.
126     private ArraySet<ComponentName> mEnabledServicesForCurrentProfiles
127             = new ArraySet<>();
128     // Just the packages from mEnabledServicesForCurrentProfiles
129     private ArraySet<String> mEnabledServicesPackageNames = new ArraySet<>();
130     // List of enabled packages that have nevertheless asked not to be run
131     private ArraySet<ComponentName> mSnoozingForCurrentProfiles = new ArraySet<>();
132 
133     // List of approved packages or components (by user, then by primary/secondary) that are
134     // allowed to be bound as managed services. A package or component appearing in this list does
135     // not mean that we are currently bound to said package/component.
136     private ArrayMap<Integer, ArrayMap<Boolean, ArraySet<String>>> mApproved = new ArrayMap<>();
137 
138     // Kept to de-dupe user change events (experienced after boot, when we receive a settings and a
139     // user change).
140     private int[] mLastSeenProfileIds;
141 
142     // True if approved services are stored in xml, not settings.
143     private boolean mUseXml;
144 
145     // Whether managed services are approved individually or package wide
146     protected int mApprovalLevel;
147 
ManagedServices(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm)148     public ManagedServices(Context context, Object mutex, UserProfiles userProfiles,
149             IPackageManager pm) {
150         mContext = context;
151         mMutex = mutex;
152         mUserProfiles = userProfiles;
153         mPm = pm;
154         mConfig = getConfig();
155         mApprovalLevel = APPROVAL_BY_COMPONENT;
156         mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
157     }
158 
getConfig()159     abstract protected Config getConfig();
160 
getCaption()161     private String getCaption() {
162         return mConfig.caption;
163     }
164 
asInterface(IBinder binder)165     abstract protected IInterface asInterface(IBinder binder);
166 
checkType(IInterface service)167     abstract protected boolean checkType(IInterface service);
168 
onServiceAdded(ManagedServiceInfo info)169     abstract protected void onServiceAdded(ManagedServiceInfo info);
170 
getServices()171     protected List<ManagedServiceInfo> getServices() {
172         synchronized (mMutex) {
173             List<ManagedServiceInfo> services = new ArrayList<>(mServices);
174             return services;
175         }
176     }
177 
onServiceRemovedLocked(ManagedServiceInfo removed)178     protected void onServiceRemovedLocked(ManagedServiceInfo removed) { }
179 
newServiceInfo(IInterface service, ComponentName component, int userId, boolean isSystem, ServiceConnection connection, int targetSdkVersion)180     private ManagedServiceInfo newServiceInfo(IInterface service,
181             ComponentName component, int userId, boolean isSystem, ServiceConnection connection,
182             int targetSdkVersion) {
183         return new ManagedServiceInfo(service, component, userId, isSystem, connection,
184                 targetSdkVersion);
185     }
186 
onBootPhaseAppsCanStart()187     public void onBootPhaseAppsCanStart() {}
188 
dump(PrintWriter pw, DumpFilter filter)189     public void dump(PrintWriter pw, DumpFilter filter) {
190         pw.println("    Allowed " + getCaption() + "s:");
191         final int N = mApproved.size();
192         for (int i = 0 ; i < N; i++) {
193             final int userId = mApproved.keyAt(i);
194             final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
195             if (approvedByType != null) {
196                 final int M = approvedByType.size();
197                 for (int j = 0; j < M; j++) {
198                     final boolean isPrimary = approvedByType.keyAt(j);
199                     final ArraySet<String> approved = approvedByType.valueAt(j);
200                     if (approvedByType != null && approvedByType.size() > 0) {
201                         pw.println("      " + String.join(ENABLED_SERVICES_SEPARATOR, approved)
202                                 + " (user: " + userId + " isPrimary: " + isPrimary + ")");
203                     }
204                 }
205             }
206         }
207 
208         pw.println("    All " + getCaption() + "s (" + mEnabledServicesForCurrentProfiles.size()
209                 + ") enabled for current profiles:");
210         for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
211             if (filter != null && !filter.matches(cmpt)) continue;
212             pw.println("      " + cmpt);
213         }
214 
215         pw.println("    Live " + getCaption() + "s (" + mServices.size() + "):");
216         for (ManagedServiceInfo info : mServices) {
217             if (filter != null && !filter.matches(info.component)) continue;
218             pw.println("      " + info.component
219                     + " (user " + info.userid + "): " + info.service
220                     + (info.isSystem?" SYSTEM":"")
221                     + (info.isGuest(this)?" GUEST":""));
222         }
223 
224         pw.println("    Snoozed " + getCaption() + "s (" +
225                 mSnoozingForCurrentProfiles.size() + "):");
226         for (ComponentName name : mSnoozingForCurrentProfiles) {
227             pw.println("      " + name.flattenToShortString());
228         }
229     }
230 
dump(ProtoOutputStream proto, DumpFilter filter)231     public void dump(ProtoOutputStream proto, DumpFilter filter) {
232         proto.write(ManagedServicesProto.CAPTION, getCaption());
233         final int N = mApproved.size();
234         for (int i = 0 ; i < N; i++) {
235             final int userId = mApproved.keyAt(i);
236             final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
237             if (approvedByType != null) {
238                 final int M = approvedByType.size();
239                 for (int j = 0; j < M; j++) {
240                     final boolean isPrimary = approvedByType.keyAt(j);
241                     final ArraySet<String> approved = approvedByType.valueAt(j);
242                     if (approvedByType != null && approvedByType.size() > 0) {
243                         final long sToken = proto.start(ManagedServicesProto.APPROVED);
244                         for (String s : approved) {
245                             proto.write(ServiceProto.NAME, s);
246                         }
247                         proto.write(ServiceProto.USER_ID, userId);
248                         proto.write(ServiceProto.IS_PRIMARY, isPrimary);
249                         proto.end(sToken);
250                     }
251                 }
252             }
253         }
254 
255         for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
256             if (filter != null && !filter.matches(cmpt)) continue;
257             cmpt.writeToProto(proto, ManagedServicesProto.ENABLED);
258         }
259 
260         for (ManagedServiceInfo info : mServices) {
261             if (filter != null && !filter.matches(info.component)) continue;
262             info.writeToProto(proto, ManagedServicesProto.LIVE_SERVICES, this);
263         }
264 
265         for (ComponentName name : mSnoozingForCurrentProfiles) {
266             name.writeToProto(proto, ManagedServicesProto.SNOOZED);
267         }
268     }
269 
onSettingRestored(String element, String value, int backupSdkInt, int userId)270     protected void onSettingRestored(String element, String value, int backupSdkInt, int userId) {
271         if (!mUseXml) {
272             Slog.d(TAG, "Restored managed service setting: " + element);
273             if (mConfig.secureSettingName.equals(element) ||
274                     (mConfig.secondarySettingName != null
275                             && mConfig.secondarySettingName.equals(element))) {
276                 if (backupSdkInt < Build.VERSION_CODES.O) {
277                     // automatic system grants were added in O, so append the approved apps
278                     // rather than wiping out the setting
279                     String currentSetting =
280                             getApproved(userId, mConfig.secureSettingName.equals(element));
281                     if (!TextUtils.isEmpty(currentSetting)) {
282                         if (!TextUtils.isEmpty(value)) {
283                             value = value + ENABLED_SERVICES_SEPARATOR + currentSetting;
284                         } else {
285                             value = currentSetting;
286                         }
287                     }
288                 }
289                 Settings.Secure.putStringForUser(
290                         mContext.getContentResolver(), element, value, userId);
291                 loadAllowedComponentsFromSettings();
292                 rebindServices(false);
293             }
294         }
295     }
296 
writeXml(XmlSerializer out, boolean forBackup)297     public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
298         out.startTag(null, getConfig().xmlTag);
299 
300         out.attribute(null, ATT_VERSION, String.valueOf(DB_VERSION));
301 
302         if (forBackup) {
303             trimApprovedListsAccordingToInstalledServices();
304         }
305 
306         final int N = mApproved.size();
307         for (int i = 0 ; i < N; i++) {
308             final int userId = mApproved.keyAt(i);
309             final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
310             if (approvedByType != null) {
311                 final int M = approvedByType.size();
312                 for (int j = 0; j < M; j++) {
313                     final boolean isPrimary = approvedByType.keyAt(j);
314                     final Set<String> approved = approvedByType.valueAt(j);
315                     if (approved != null) {
316                         String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
317                         out.startTag(null, TAG_MANAGED_SERVICES);
318                         out.attribute(null, ATT_APPROVED_LIST, allowedItems);
319                         out.attribute(null, ATT_USER_ID, Integer.toString(userId));
320                         out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary));
321                         out.endTag(null, TAG_MANAGED_SERVICES);
322 
323                         if (!forBackup && isPrimary) {
324                             // Also write values to settings, for observers who haven't migrated yet
325                             Settings.Secure.putStringForUser(mContext.getContentResolver(),
326                                     getConfig().secureSettingName, allowedItems, userId);
327                         }
328 
329                     }
330                 }
331             }
332         }
333 
334         out.endTag(null, getConfig().xmlTag);
335     }
336 
migrateToXml()337     protected void migrateToXml() {
338         loadAllowedComponentsFromSettings();
339     }
340 
readXml(XmlPullParser parser, Predicate<String> allowedManagedServicePackages)341     public void readXml(XmlPullParser parser, Predicate<String> allowedManagedServicePackages)
342             throws XmlPullParserException, IOException {
343         // upgrade xml
344         int xmlVersion = XmlUtils.readIntAttribute(parser, ATT_VERSION, 0);
345         final List<UserInfo> activeUsers = mUm.getUsers(true);
346         for (UserInfo userInfo : activeUsers) {
347             upgradeXml(xmlVersion, userInfo.getUserHandle().getIdentifier());
348         }
349 
350         // read grants
351         int type;
352         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
353             String tag = parser.getName();
354             if (type == XmlPullParser.END_TAG
355                     && getConfig().xmlTag.equals(tag)) {
356                 break;
357             }
358             if (type == XmlPullParser.START_TAG) {
359                 if (TAG_MANAGED_SERVICES.equals(tag)) {
360                     Slog.i(TAG, "Read " + mConfig.caption + " permissions from xml");
361 
362                     final String approved = XmlUtils.readStringAttribute(parser, ATT_APPROVED_LIST);
363                     final int userId = XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
364                     final boolean isPrimary =
365                             XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true);
366 
367                     if (allowedManagedServicePackages == null ||
368                             allowedManagedServicePackages.test(getPackageName(approved))) {
369                         if (mUm.getUserInfo(userId) != null) {
370                             addApprovedList(approved, userId, isPrimary);
371                         }
372                         mUseXml = true;
373                     }
374                 }
375             }
376         }
377         rebindServices(false);
378     }
379 
upgradeXml(final int xmlVersion, final int userId)380     protected void upgradeXml(final int xmlVersion, final int userId) {}
381 
loadAllowedComponentsFromSettings()382     private void loadAllowedComponentsFromSettings() {
383         for (UserInfo user : mUm.getUsers()) {
384             final ContentResolver cr = mContext.getContentResolver();
385             addApprovedList(Settings.Secure.getStringForUser(
386                     cr,
387                     getConfig().secureSettingName,
388                     user.id), user.id, true);
389             if (!TextUtils.isEmpty(getConfig().secondarySettingName)) {
390                 addApprovedList(Settings.Secure.getStringForUser(
391                         cr,
392                         getConfig().secondarySettingName,
393                         user.id), user.id, false);
394             }
395         }
396         Slog.d(TAG, "Done loading approved values from settings");
397     }
398 
addApprovedList(String approved, int userId, boolean isPrimary)399     protected void addApprovedList(String approved, int userId, boolean isPrimary) {
400         if (TextUtils.isEmpty(approved)) {
401             approved = "";
402         }
403         ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
404         if (approvedByType == null) {
405             approvedByType = new ArrayMap<>();
406             mApproved.put(userId, approvedByType);
407         }
408 
409         ArraySet<String> approvedList = approvedByType.get(isPrimary);
410         if (approvedList == null) {
411             approvedList = new ArraySet<>();
412             approvedByType.put(isPrimary, approvedList);
413         }
414 
415         String[] approvedArray = approved.split(ENABLED_SERVICES_SEPARATOR);
416         for (String pkgOrComponent : approvedArray) {
417             String approvedItem = getApprovedValue(pkgOrComponent);
418             if (approvedItem != null) {
419                 approvedList.add(approvedItem);
420             }
421         }
422     }
423 
isComponentEnabledForPackage(String pkg)424     protected boolean isComponentEnabledForPackage(String pkg) {
425         return mEnabledServicesPackageNames.contains(pkg);
426     }
427 
setPackageOrComponentEnabled(String pkgOrComponent, int userId, boolean isPrimary, boolean enabled)428     protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
429             boolean isPrimary, boolean enabled) {
430         Slog.i(TAG,
431                 (enabled ? " Allowing " : "Disallowing ") + mConfig.caption + " " + pkgOrComponent);
432         ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId);
433         if (allowedByType == null) {
434             allowedByType = new ArrayMap<>();
435             mApproved.put(userId, allowedByType);
436         }
437         ArraySet<String> approved = allowedByType.get(isPrimary);
438         if (approved == null) {
439             approved = new ArraySet<>();
440             allowedByType.put(isPrimary, approved);
441         }
442         String approvedItem = getApprovedValue(pkgOrComponent);
443 
444         if (approvedItem != null) {
445             if (enabled) {
446                 approved.add(approvedItem);
447             } else {
448                 approved.remove(approvedItem);
449             }
450         }
451 
452         rebindServices(false);
453     }
454 
getApprovedValue(String pkgOrComponent)455     private String getApprovedValue(String pkgOrComponent) {
456         if (mApprovalLevel == APPROVAL_BY_COMPONENT) {
457             if(ComponentName.unflattenFromString(pkgOrComponent) != null) {
458                 return pkgOrComponent;
459             }
460             return null;
461         } else {
462             return getPackageName(pkgOrComponent);
463         }
464     }
465 
getApproved(int userId, boolean primary)466     protected String getApproved(int userId, boolean primary) {
467         final ArrayMap<Boolean, ArraySet<String>> allowedByType =
468                 mApproved.getOrDefault(userId, new ArrayMap<>());
469         ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>());
470         return String.join(ENABLED_SERVICES_SEPARATOR, approved);
471     }
472 
getAllowedComponents(int userId)473     protected List<ComponentName> getAllowedComponents(int userId) {
474         final List<ComponentName> allowedComponents = new ArrayList<>();
475         final ArrayMap<Boolean, ArraySet<String>> allowedByType =
476                 mApproved.getOrDefault(userId, new ArrayMap<>());
477         for (int i = 0; i < allowedByType.size(); i++) {
478             final ArraySet<String> allowed = allowedByType.valueAt(i);
479             for (int j = 0; j < allowed.size(); j++) {
480                 ComponentName cn = ComponentName.unflattenFromString(allowed.valueAt(j));
481                 if (cn != null) {
482                     allowedComponents.add(cn);
483                 }
484             }
485         }
486         return allowedComponents;
487     }
488 
getAllowedPackages(int userId)489     protected List<String> getAllowedPackages(int userId) {
490         final List<String> allowedPackages = new ArrayList<>();
491         final ArrayMap<Boolean, ArraySet<String>> allowedByType =
492                 mApproved.getOrDefault(userId, new ArrayMap<>());
493         for (int i = 0; i < allowedByType.size(); i++) {
494             final ArraySet<String> allowed = allowedByType.valueAt(i);
495             for (int j = 0; j < allowed.size(); j++) {
496                 String pkgName = getPackageName(allowed.valueAt(j));
497                 if (!TextUtils.isEmpty(pkgName)) {
498                     allowedPackages.add(pkgName);
499                 }
500             }
501         }
502         return allowedPackages;
503     }
504 
isPackageOrComponentAllowed(String pkgOrComponent, int userId)505     protected boolean isPackageOrComponentAllowed(String pkgOrComponent, int userId) {
506         ArrayMap<Boolean, ArraySet<String>> allowedByType =
507                 mApproved.getOrDefault(userId, new ArrayMap<>());
508         for (int i = 0; i < allowedByType.size(); i++) {
509             ArraySet<String> allowed = allowedByType.valueAt(i);
510             if (allowed.contains(pkgOrComponent)) {
511                 return true;
512             }
513         }
514         return false;
515     }
516 
onPackagesChanged(boolean removingPackage, String[] pkgList, int[] uidList)517     public void onPackagesChanged(boolean removingPackage, String[] pkgList, int[] uidList) {
518         if (DEBUG) Slog.d(TAG, "onPackagesChanged removingPackage=" + removingPackage
519                 + " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList))
520                 + " mEnabledServicesPackageNames=" + mEnabledServicesPackageNames);
521 
522         if (pkgList != null && (pkgList.length > 0)) {
523             boolean anyServicesInvolved = false;
524             // Remove notification settings for uninstalled package
525             if (removingPackage) {
526                 int size = Math.min(pkgList.length, uidList.length);
527                 for (int i = 0; i < size; i++) {
528                     final String pkg = pkgList[i];
529                     final int userId = UserHandle.getUserId(uidList[i]);
530                     anyServicesInvolved = removeUninstalledItemsFromApprovedLists(userId, pkg);
531                 }
532             }
533             for (String pkgName : pkgList) {
534                 if (mEnabledServicesPackageNames.contains(pkgName)) {
535                     anyServicesInvolved = true;
536                 }
537             }
538 
539             if (anyServicesInvolved) {
540                 // make sure we're still bound to any of our services who may have just upgraded
541                 rebindServices(false);
542             }
543         }
544     }
545 
onUserRemoved(int user)546     public void onUserRemoved(int user) {
547         Slog.i(TAG, "Removing approved services for removed user " + user);
548         mApproved.remove(user);
549         rebindServices(true);
550     }
551 
onUserSwitched(int user)552     public void onUserSwitched(int user) {
553         if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user);
554         if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) {
555             if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices().");
556             return;
557         }
558         rebindServices(true);
559     }
560 
onUserUnlocked(int user)561     public void onUserUnlocked(int user) {
562         if (DEBUG) Slog.d(TAG, "onUserUnlocked u=" + user);
563         rebindServices(false);
564     }
565 
getServiceFromTokenLocked(IInterface service)566     private ManagedServiceInfo getServiceFromTokenLocked(IInterface service) {
567         if (service == null) {
568             return null;
569         }
570         final IBinder token = service.asBinder();
571         final int N = mServices.size();
572         for (int i = 0; i < N; i++) {
573             final ManagedServiceInfo info = mServices.get(i);
574             if (info.service.asBinder() == token) return info;
575         }
576         return null;
577     }
578 
isServiceTokenValidLocked(IInterface service)579     protected boolean isServiceTokenValidLocked(IInterface service) {
580         if (service == null) {
581             return false;
582         }
583         ManagedServiceInfo info = getServiceFromTokenLocked(service);
584         if (info != null) {
585             return true;
586         }
587         return false;
588     }
589 
checkServiceTokenLocked(IInterface service)590     protected ManagedServiceInfo checkServiceTokenLocked(IInterface service) {
591         checkNotNull(service);
592         ManagedServiceInfo info = getServiceFromTokenLocked(service);
593         if (info != null) {
594             return info;
595         }
596         throw new SecurityException("Disallowed call from unknown " + getCaption() + ": "
597                 + service + " " + service.getClass());
598     }
599 
unregisterService(IInterface service, int userid)600     public void unregisterService(IInterface service, int userid) {
601         checkNotNull(service);
602         // no need to check permissions; if your service binder is in the list,
603         // that's proof that you had permission to add it in the first place
604         unregisterServiceImpl(service, userid);
605     }
606 
registerService(IInterface service, ComponentName component, int userid)607     public void registerService(IInterface service, ComponentName component, int userid) {
608         checkNotNull(service);
609         ManagedServiceInfo info = registerServiceImpl(service, component, userid);
610         if (info != null) {
611             onServiceAdded(info);
612         }
613     }
614 
615     /**
616      * Add a service to our callbacks. The lifecycle of this service is managed externally,
617      * but unlike a system service, it should not be considered privileged.
618      * */
registerGuestService(ManagedServiceInfo guest)619     protected void registerGuestService(ManagedServiceInfo guest) {
620         checkNotNull(guest.service);
621         if (!checkType(guest.service)) {
622             throw new IllegalArgumentException();
623         }
624         if (registerServiceImpl(guest) != null) {
625             onServiceAdded(guest);
626         }
627     }
628 
setComponentState(ComponentName component, boolean enabled)629     protected void setComponentState(ComponentName component, boolean enabled) {
630         boolean previous = !mSnoozingForCurrentProfiles.contains(component);
631         if (previous == enabled) {
632             return;
633         }
634 
635         if (enabled) {
636             mSnoozingForCurrentProfiles.remove(component);
637         } else {
638             mSnoozingForCurrentProfiles.add(component);
639         }
640 
641         // State changed
642         Slog.d(TAG, ((enabled) ? "Enabling " : "Disabling ") + "component " +
643                 component.flattenToShortString());
644 
645         synchronized (mMutex) {
646             final int[] userIds = mUserProfiles.getCurrentProfileIds();
647 
648             for (int userId : userIds) {
649                 if (enabled) {
650                     registerServiceLocked(component, userId);
651                 } else {
652                     unregisterServiceLocked(component, userId);
653                 }
654             }
655         }
656     }
657 
loadComponentNamesFromValues( ArraySet<String> approved, int userId)658     private @NonNull ArraySet<ComponentName> loadComponentNamesFromValues(
659             ArraySet<String> approved, int userId) {
660         if (approved == null || approved.size() == 0)
661             return new ArraySet<>();
662         ArraySet<ComponentName> result = new ArraySet<>(approved.size());
663         for (int i = 0; i < approved.size(); i++) {
664             final String packageOrComponent = approved.valueAt(i);
665             if (!TextUtils.isEmpty(packageOrComponent)) {
666                 ComponentName component = ComponentName.unflattenFromString(packageOrComponent);
667                 if (component != null) {
668                     result.add(component);
669                 } else {
670                     result.addAll(queryPackageForServices(packageOrComponent, userId));
671                 }
672             }
673         }
674         return result;
675     }
676 
queryPackageForServices(String packageName, int userId)677     protected Set<ComponentName> queryPackageForServices(String packageName, int userId) {
678         return queryPackageForServices(packageName, 0, userId);
679     }
680 
queryPackageForServices(String packageName, int extraFlags, int userId)681     protected Set<ComponentName> queryPackageForServices(String packageName, int extraFlags,
682             int userId) {
683         Set<ComponentName> installed = new ArraySet<>();
684         final PackageManager pm = mContext.getPackageManager();
685         Intent queryIntent = new Intent(mConfig.serviceInterface);
686         if (!TextUtils.isEmpty(packageName)) {
687             queryIntent.setPackage(packageName);
688         }
689         List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
690                 queryIntent,
691                 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA | extraFlags,
692                 userId);
693         if (DEBUG)
694             Slog.v(TAG, mConfig.serviceInterface + " services: " + installedServices);
695         if (installedServices != null) {
696             for (int i = 0, count = installedServices.size(); i < count; i++) {
697                 ResolveInfo resolveInfo = installedServices.get(i);
698                 ServiceInfo info = resolveInfo.serviceInfo;
699 
700                 ComponentName component = new ComponentName(info.packageName, info.name);
701                 if (!mConfig.bindPermission.equals(info.permission)) {
702                     Slog.w(TAG, "Skipping " + getCaption() + " service "
703                         + info.packageName + "/" + info.name
704                         + ": it does not require the permission "
705                         + mConfig.bindPermission);
706                     continue;
707                 }
708                 installed.add(component);
709             }
710         }
711         return installed;
712     }
713 
trimApprovedListsAccordingToInstalledServices()714     private void trimApprovedListsAccordingToInstalledServices() {
715         int N = mApproved.size();
716         for (int i = 0 ; i < N; i++) {
717             final int userId = mApproved.keyAt(i);
718             final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
719             int M = approvedByType.size();
720             for (int j = 0; j < M; j++) {
721                 final ArraySet<String> approved = approvedByType.valueAt(j);
722                 int P = approved.size();
723                 for (int k = P - 1; k >= 0; k--) {
724                     final String approvedPackageOrComponent = approved.valueAt(k);
725                     if (!isValidEntry(approvedPackageOrComponent, userId)){
726                         approved.removeAt(k);
727                         Slog.v(TAG, "Removing " + approvedPackageOrComponent
728                                 + " from approved list; no matching services found");
729                     } else {
730                         if (DEBUG) {
731                             Slog.v(TAG, "Keeping " + approvedPackageOrComponent
732                                     + " on approved list; matching services found");
733                         }
734                     }
735                 }
736             }
737         }
738     }
739 
removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg)740     private boolean removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg) {
741         boolean removed = false;
742         final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(uninstalledUserId);
743         if (approvedByType != null) {
744             int M = approvedByType.size();
745             for (int j = 0; j < M; j++) {
746                 final ArraySet<String> approved = approvedByType.valueAt(j);
747                 int O = approved.size();
748                 for (int k = O - 1; k >= 0; k--) {
749                     final String packageOrComponent = approved.valueAt(k);
750                     final String packageName = getPackageName(packageOrComponent);
751                     if (TextUtils.equals(pkg, packageName)) {
752                         approved.removeAt(k);
753                         if (DEBUG) {
754                             Slog.v(TAG, "Removing " + packageOrComponent
755                                     + " from approved list; uninstalled");
756                         }
757                     }
758                 }
759             }
760         }
761         return removed;
762     }
763 
getPackageName(String packageOrComponent)764     protected String getPackageName(String packageOrComponent) {
765         final ComponentName component = ComponentName.unflattenFromString(packageOrComponent);
766         if (component != null) {
767             return component.getPackageName();
768         } else {
769             return packageOrComponent;
770         }
771     }
772 
isValidEntry(String packageOrComponent, int userId)773     protected boolean isValidEntry(String packageOrComponent, int userId) {
774         return hasMatchingServices(packageOrComponent, userId);
775     }
776 
hasMatchingServices(String packageOrComponent, int userId)777     private boolean hasMatchingServices(String packageOrComponent, int userId) {
778         if (!TextUtils.isEmpty(packageOrComponent)) {
779             final String packageName = getPackageName(packageOrComponent);
780             return queryPackageForServices(packageName, userId).size() > 0;
781         }
782         return false;
783     }
784 
785     /**
786      * Called whenever packages change, the user switches, or the secure setting
787      * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
788      */
rebindServices(boolean forceRebind)789     protected void rebindServices(boolean forceRebind) {
790         if (DEBUG) Slog.d(TAG, "rebindServices");
791         final int[] userIds = mUserProfiles.getCurrentProfileIds();
792         final int nUserIds = userIds.length;
793 
794         final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>();
795 
796         for (int i = 0; i < nUserIds; ++i) {
797             final int userId = userIds[i];
798             final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userIds[i]);
799             if (approvedLists != null) {
800                 final int N = approvedLists.size();
801                 for (int j = 0; j < N; j++) {
802                     ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId);
803                     if (approvedByUser == null) {
804                         approvedByUser = new ArraySet<>();
805                         componentsByUser.put(userId, approvedByUser);
806                     }
807                     approvedByUser.addAll(
808                             loadComponentNamesFromValues(approvedLists.valueAt(j), userId));
809                 }
810             }
811         }
812 
813         final ArrayList<ManagedServiceInfo> removableBoundServices = new ArrayList<>();
814         final SparseArray<Set<ComponentName>> toAdd = new SparseArray<>();
815 
816         synchronized (mMutex) {
817             // Rebind to non-system services if user switched
818             for (ManagedServiceInfo service : mServices) {
819                 if (!service.isSystem && !service.isGuest(this)) {
820                     removableBoundServices.add(service);
821                 }
822             }
823 
824             mEnabledServicesForCurrentProfiles.clear();
825             mEnabledServicesPackageNames.clear();
826 
827             for (int i = 0; i < nUserIds; ++i) {
828                 // decode the list of components
829                 final ArraySet<ComponentName> userComponents = componentsByUser.get(userIds[i]);
830                 if (null == userComponents) {
831                     toAdd.put(userIds[i], new ArraySet<>());
832                     continue;
833                 }
834 
835                 final Set<ComponentName> add = new HashSet<>(userComponents);
836                 add.removeAll(mSnoozingForCurrentProfiles);
837 
838                 toAdd.put(userIds[i], add);
839 
840                 mEnabledServicesForCurrentProfiles.addAll(userComponents);
841 
842                 for (int j = 0; j < userComponents.size(); j++) {
843                     final ComponentName component = userComponents.valueAt(j);
844                     mEnabledServicesPackageNames.add(component.getPackageName());
845                 }
846             }
847         }
848 
849         for (ManagedServiceInfo info : removableBoundServices) {
850             final ComponentName component = info.component;
851             final int oldUser = info.userid;
852             final Set<ComponentName> allowedComponents = toAdd.get(info.userid);
853             if (allowedComponents != null) {
854                 if (allowedComponents.contains(component) && !forceRebind) {
855                     // Already bound, don't need to bind again.
856                     allowedComponents.remove(component);
857                 } else {
858                     // No longer allowed to be bound, or must rebind.
859                     Slog.v(TAG, "disabling " + getCaption() + " for user "
860                             + oldUser + ": " + component);
861                     unregisterService(component, oldUser);
862                 }
863             }
864         }
865 
866         for (int i = 0; i < nUserIds; ++i) {
867             final Set<ComponentName> add = toAdd.get(userIds[i]);
868             for (ComponentName component : add) {
869                 try {
870                     ServiceInfo info = mPm.getServiceInfo(component,
871                             PackageManager.MATCH_DIRECT_BOOT_AWARE
872                                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userIds[i]);
873                     if (info == null) {
874                         Slog.w(TAG, "Not binding " + getCaption() + " service " + component
875                                 + ": service not found");
876                         continue;
877                     }
878                     if (!mConfig.bindPermission.equals(info.permission)) {
879                         Slog.w(TAG, "Not binding " + getCaption() + " service " + component
880                                 + ": it does not require the permission " + mConfig.bindPermission);
881                         continue;
882                     }
883                     Slog.v(TAG,
884                             "enabling " + getCaption() + " for " + userIds[i] + ": " + component);
885                     registerService(component, userIds[i]);
886                 } catch (RemoteException e) {
887                     e.rethrowFromSystemServer();
888                 }
889             }
890         }
891 
892         mLastSeenProfileIds = userIds;
893     }
894 
895     /**
896      * Version of registerService that takes the name of a service component to bind to.
897      */
registerService(final ComponentName name, final int userid)898     private void registerService(final ComponentName name, final int userid) {
899         synchronized (mMutex) {
900             registerServiceLocked(name, userid);
901         }
902     }
903 
904     /**
905      * Inject a system service into the management list.
906      */
registerSystemService(final ComponentName name, final int userid)907     public void registerSystemService(final ComponentName name, final int userid) {
908         synchronized (mMutex) {
909             registerServiceLocked(name, userid, true /* isSystem */);
910         }
911     }
912 
registerServiceLocked(final ComponentName name, final int userid)913     private void registerServiceLocked(final ComponentName name, final int userid) {
914         registerServiceLocked(name, userid, false /* isSystem */);
915     }
916 
registerServiceLocked(final ComponentName name, final int userid, final boolean isSystem)917     private void registerServiceLocked(final ComponentName name, final int userid,
918             final boolean isSystem) {
919         if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid);
920 
921         final String servicesBindingTag = name.toString() + "/" + userid;
922         if (mServicesBinding.contains(servicesBindingTag)) {
923             Slog.v(TAG, "Not registering " + name + " as bind is already in progress");
924             // stop registering this thing already! we're working on it
925             return;
926         }
927         mServicesBinding.add(servicesBindingTag);
928 
929         final int N = mServices.size();
930         for (int i = N - 1; i >= 0; i--) {
931             final ManagedServiceInfo info = mServices.get(i);
932             if (name.equals(info.component)
933                 && info.userid == userid) {
934                 // cut old connections
935                 Slog.v(TAG, "    disconnecting old " + getCaption() + ": " + info.service);
936                 removeServiceLocked(i);
937                 if (info.connection != null) {
938                     try {
939                         mContext.unbindService(info.connection);
940                     } catch (IllegalArgumentException e) {
941                         Slog.e(TAG, "failed to unbind " + name, e);
942                     }
943                 }
944             }
945         }
946 
947         Intent intent = new Intent(mConfig.serviceInterface);
948         intent.setComponent(name);
949 
950         intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel);
951 
952         final PendingIntent pendingIntent = PendingIntent.getActivity(
953             mContext, 0, new Intent(mConfig.settingsAction), 0);
954         intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);
955 
956         ApplicationInfo appInfo = null;
957         try {
958             appInfo = mContext.getPackageManager().getApplicationInfo(
959                 name.getPackageName(), 0);
960         } catch (NameNotFoundException e) {
961             // Ignore if the package doesn't exist we won't be able to bind to the service.
962         }
963         final int targetSdkVersion =
964             appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
965 
966         try {
967             Slog.v(TAG, "binding: " + intent);
968             ServiceConnection serviceConnection = new ServiceConnection() {
969                 IInterface mService;
970 
971                 @Override
972                 public void onServiceConnected(ComponentName name, IBinder binder) {
973                     boolean added = false;
974                     ManagedServiceInfo info = null;
975                     synchronized (mMutex) {
976                         mServicesRebinding.remove(servicesBindingTag);
977                         mServicesBinding.remove(servicesBindingTag);
978                         try {
979                             mService = asInterface(binder);
980                             info = newServiceInfo(mService, name,
981                                 userid, isSystem, this, targetSdkVersion);
982                             binder.linkToDeath(info, 0);
983                             added = mServices.add(info);
984                         } catch (RemoteException e) {
985                             // already dead
986                         }
987                     }
988                     if (added) {
989                         onServiceAdded(info);
990                     }
991                 }
992 
993                 @Override
994                 public void onServiceDisconnected(ComponentName name) {
995                     mServicesBinding.remove(servicesBindingTag);
996                     Slog.v(TAG, getCaption() + " connection lost: " + name);
997                 }
998 
999                 @Override
1000                 public void onBindingDied(ComponentName name) {
1001                     Slog.w(TAG, getCaption() + " binding died: " + name);
1002                     synchronized (mMutex) {
1003                         mServicesBinding.remove(servicesBindingTag);
1004                         try {
1005                             mContext.unbindService(this);
1006                         } catch (IllegalArgumentException e) {
1007                             Slog.e(TAG, "failed to unbind " + name, e);
1008                         }
1009                         if (!mServicesRebinding.contains(servicesBindingTag)) {
1010                             mServicesRebinding.add(servicesBindingTag);
1011                             mHandler.postDelayed(new Runnable() {
1012                                     @Override
1013                                     public void run() {
1014                                         registerService(name, userid);
1015                                     }
1016                                }, ON_BINDING_DIED_REBIND_DELAY_MS);
1017                         } else {
1018                             Slog.v(TAG, getCaption() + " not rebinding as "
1019                                     + "a previous rebind attempt was made: " + name);
1020                         }
1021                     }
1022                 }
1023             };
1024             if (!mContext.bindServiceAsUser(intent,
1025                 serviceConnection,
1026                 BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT,
1027                 new UserHandle(userid))) {
1028                 mServicesBinding.remove(servicesBindingTag);
1029                 Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);
1030                 return;
1031             }
1032         } catch (SecurityException ex) {
1033             mServicesBinding.remove(servicesBindingTag);
1034             Slog.e(TAG, "Unable to bind " + getCaption() + " service: " + intent, ex);
1035         }
1036     }
1037 
1038     /**
1039      * Remove a service for the given user by ComponentName
1040      */
unregisterService(ComponentName name, int userid)1041     private void unregisterService(ComponentName name, int userid) {
1042         synchronized (mMutex) {
1043             unregisterServiceLocked(name, userid);
1044         }
1045     }
1046 
unregisterServiceLocked(ComponentName name, int userid)1047     private void unregisterServiceLocked(ComponentName name, int userid) {
1048         final int N = mServices.size();
1049         for (int i = N - 1; i >= 0; i--) {
1050             final ManagedServiceInfo info = mServices.get(i);
1051             if (name.equals(info.component) && info.userid == userid) {
1052                 removeServiceLocked(i);
1053                 if (info.connection != null) {
1054                     try {
1055                         mContext.unbindService(info.connection);
1056                     } catch (IllegalArgumentException ex) {
1057                         // something happened to the service: we think we have a connection
1058                         // but it's bogus.
1059                         Slog.e(TAG, getCaption() + " " + name + " could not be unbound: " + ex);
1060                     }
1061                 }
1062             }
1063         }
1064     }
1065 
1066     /**
1067      * Removes a service from the list but does not unbind
1068      *
1069      * @return the removed service.
1070      */
removeServiceImpl(IInterface service, final int userid)1071     private ManagedServiceInfo removeServiceImpl(IInterface service, final int userid) {
1072         if (DEBUG) Slog.d(TAG, "removeServiceImpl service=" + service + " u=" + userid);
1073         ManagedServiceInfo serviceInfo = null;
1074         synchronized (mMutex) {
1075             final int N = mServices.size();
1076             for (int i = N - 1; i >= 0; i--) {
1077                 final ManagedServiceInfo info = mServices.get(i);
1078                 if (info.service.asBinder() == service.asBinder() && info.userid == userid) {
1079                     Slog.d(TAG, "Removing active service " + info.component);
1080                     serviceInfo = removeServiceLocked(i);
1081                 }
1082             }
1083         }
1084         return serviceInfo;
1085     }
1086 
removeServiceLocked(int i)1087     private ManagedServiceInfo removeServiceLocked(int i) {
1088         final ManagedServiceInfo info = mServices.remove(i);
1089         onServiceRemovedLocked(info);
1090         return info;
1091     }
1092 
checkNotNull(IInterface service)1093     private void checkNotNull(IInterface service) {
1094         if (service == null) {
1095             throw new IllegalArgumentException(getCaption() + " must not be null");
1096         }
1097     }
1098 
registerServiceImpl(final IInterface service, final ComponentName component, final int userid)1099     private ManagedServiceInfo registerServiceImpl(final IInterface service,
1100             final ComponentName component, final int userid) {
1101         ManagedServiceInfo info = newServiceInfo(service, component, userid,
1102                 true /*isSystem*/, null /*connection*/, Build.VERSION_CODES.LOLLIPOP);
1103         return registerServiceImpl(info);
1104     }
1105 
registerServiceImpl(ManagedServiceInfo info)1106     private ManagedServiceInfo registerServiceImpl(ManagedServiceInfo info) {
1107         synchronized (mMutex) {
1108             try {
1109                 info.service.asBinder().linkToDeath(info, 0);
1110                 mServices.add(info);
1111                 return info;
1112             } catch (RemoteException e) {
1113                 // already dead
1114             }
1115         }
1116         return null;
1117     }
1118 
1119     /**
1120      * Removes a service from the list and unbinds.
1121      */
unregisterServiceImpl(IInterface service, int userid)1122     private void unregisterServiceImpl(IInterface service, int userid) {
1123         ManagedServiceInfo info = removeServiceImpl(service, userid);
1124         if (info != null && info.connection != null && !info.isGuest(this)) {
1125             mContext.unbindService(info.connection);
1126         }
1127     }
1128 
1129     public class ManagedServiceInfo implements IBinder.DeathRecipient {
1130         public IInterface service;
1131         public ComponentName component;
1132         public int userid;
1133         public boolean isSystem;
1134         public ServiceConnection connection;
1135         public int targetSdkVersion;
1136 
ManagedServiceInfo(IInterface service, ComponentName component, int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion)1137         public ManagedServiceInfo(IInterface service, ComponentName component,
1138                 int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion) {
1139             this.service = service;
1140             this.component = component;
1141             this.userid = userid;
1142             this.isSystem = isSystem;
1143             this.connection = connection;
1144             this.targetSdkVersion = targetSdkVersion;
1145         }
1146 
isGuest(ManagedServices host)1147         public boolean isGuest(ManagedServices host) {
1148             return ManagedServices.this != host;
1149         }
1150 
getOwner()1151         public ManagedServices getOwner() {
1152             return ManagedServices.this;
1153         }
1154 
1155         @Override
toString()1156         public String toString() {
1157             return new StringBuilder("ManagedServiceInfo[")
1158                     .append("component=").append(component)
1159                     .append(",userid=").append(userid)
1160                     .append(",isSystem=").append(isSystem)
1161                     .append(",targetSdkVersion=").append(targetSdkVersion)
1162                     .append(",connection=").append(connection == null ? null : "<connection>")
1163                     .append(",service=").append(service)
1164                     .append(']').toString();
1165         }
1166 
writeToProto(ProtoOutputStream proto, long fieldId, ManagedServices host)1167         public void writeToProto(ProtoOutputStream proto, long fieldId, ManagedServices host) {
1168             final long token = proto.start(fieldId);
1169             component.writeToProto(proto, ManagedServiceInfoProto.COMPONENT);
1170             proto.write(ManagedServiceInfoProto.USER_ID, userid);
1171             proto.write(ManagedServiceInfoProto.SERVICE, service.getClass().getName());
1172             proto.write(ManagedServiceInfoProto.IS_SYSTEM, isSystem);
1173             proto.write(ManagedServiceInfoProto.IS_GUEST, isGuest(host));
1174             proto.end(token);
1175         }
1176 
enabledAndUserMatches(int nid)1177         public boolean enabledAndUserMatches(int nid) {
1178             if (!isEnabledForCurrentProfiles()) {
1179                 return false;
1180             }
1181             if (this.userid == UserHandle.USER_ALL) return true;
1182             if (this.isSystem) return true;
1183             if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
1184             return supportsProfiles()
1185                     && mUserProfiles.isCurrentProfile(nid)
1186                     && isPermittedForProfile(nid);
1187         }
1188 
supportsProfiles()1189         public boolean supportsProfiles() {
1190             return targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP;
1191         }
1192 
1193         @Override
binderDied()1194         public void binderDied() {
1195             if (DEBUG) Slog.d(TAG, "binderDied");
1196             // Remove the service, but don't unbind from the service. The system will bring the
1197             // service back up, and the onServiceConnected handler will read the service with the
1198             // new binding. If this isn't a bound service, and is just a registered
1199             // service, just removing it from the list is all we need to do anyway.
1200             removeServiceImpl(this.service, this.userid);
1201         }
1202 
1203         /** convenience method for looking in mEnabledServicesForCurrentProfiles */
isEnabledForCurrentProfiles()1204         public boolean isEnabledForCurrentProfiles() {
1205             if (this.isSystem) return true;
1206             if (this.connection == null) return false;
1207             return mEnabledServicesForCurrentProfiles.contains(this.component);
1208         }
1209 
1210         /**
1211          * Returns true if this service is allowed to receive events for the given userId. A
1212          * managed profile owner can disallow non-system services running outside of the profile
1213          * from receiving events from the profile.
1214          */
isPermittedForProfile(int userId)1215         public boolean isPermittedForProfile(int userId) {
1216             if (!mUserProfiles.isManagedProfile(userId)) {
1217                 return true;
1218             }
1219             DevicePolicyManager dpm =
1220                     (DevicePolicyManager) mContext.getSystemService(DEVICE_POLICY_SERVICE);
1221             final long identity = Binder.clearCallingIdentity();
1222             try {
1223                 return dpm.isNotificationListenerServicePermitted(
1224                         component.getPackageName(), userId);
1225             } finally {
1226                 Binder.restoreCallingIdentity(identity);
1227             }
1228         }
1229     }
1230 
1231     /** convenience method for looking in mEnabledServicesForCurrentProfiles */
isComponentEnabledForCurrentProfiles(ComponentName component)1232     public boolean isComponentEnabledForCurrentProfiles(ComponentName component) {
1233         return mEnabledServicesForCurrentProfiles.contains(component);
1234     }
1235 
1236     public static class UserProfiles {
1237         // Profiles of the current user.
1238         private final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
1239 
updateCache(@onNull Context context)1240         public void updateCache(@NonNull Context context) {
1241             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
1242             if (userManager != null) {
1243                 int currentUserId = ActivityManager.getCurrentUser();
1244                 List<UserInfo> profiles = userManager.getProfiles(currentUserId);
1245                 synchronized (mCurrentProfiles) {
1246                     mCurrentProfiles.clear();
1247                     for (UserInfo user : profiles) {
1248                         mCurrentProfiles.put(user.id, user);
1249                     }
1250                 }
1251             }
1252         }
1253 
getCurrentProfileIds()1254         public int[] getCurrentProfileIds() {
1255             synchronized (mCurrentProfiles) {
1256                 int[] users = new int[mCurrentProfiles.size()];
1257                 final int N = mCurrentProfiles.size();
1258                 for (int i = 0; i < N; ++i) {
1259                     users[i] = mCurrentProfiles.keyAt(i);
1260                 }
1261                 return users;
1262             }
1263         }
1264 
isCurrentProfile(int userId)1265         public boolean isCurrentProfile(int userId) {
1266             synchronized (mCurrentProfiles) {
1267                 return mCurrentProfiles.get(userId) != null;
1268             }
1269         }
1270 
isManagedProfile(int userId)1271         public boolean isManagedProfile(int userId) {
1272             synchronized (mCurrentProfiles) {
1273                 UserInfo user = mCurrentProfiles.get(userId);
1274                 return user != null && user.isManagedProfile();
1275             }
1276         }
1277     }
1278 
1279     public static class Config {
1280         public String caption;
1281         public String serviceInterface;
1282         public String secureSettingName;
1283         public String secondarySettingName;
1284         public String xmlTag;
1285         public String bindPermission;
1286         public String settingsAction;
1287         public int clientLabel;
1288     }
1289 }
1290