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