OSDN Git Service

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