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