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