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