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