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