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