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