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