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 24 import android.annotation.NonNull; 25 import android.app.ActivityManager; 26 import android.app.PendingIntent; 27 import android.app.admin.DevicePolicyManager; 28 import android.content.BroadcastReceiver; 29 import android.content.ComponentName; 30 import android.content.ContentResolver; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.IntentFilter; 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.database.ContentObserver; 43 import android.net.Uri; 44 import android.os.Binder; 45 import android.os.Build; 46 import android.os.Handler; 47 import android.os.IBinder; 48 import android.os.IInterface; 49 import android.os.RemoteException; 50 import android.os.ServiceManager; 51 import android.os.UserHandle; 52 import android.os.UserManager; 53 import android.provider.Settings; 54 import android.text.TextUtils; 55 import android.util.ArraySet; 56 import android.util.Log; 57 import android.util.Slog; 58 import android.util.SparseArray; 59 60 import com.android.server.notification.NotificationManagerService.DumpFilter; 61 62 import java.io.PrintWriter; 63 import java.util.ArrayList; 64 import java.util.Arrays; 65 import java.util.HashSet; 66 import java.util.List; 67 import java.util.Objects; 68 import java.util.Set; 69 70 /** 71 * Manages the lifecycle of application-provided services bound by system server. 72 * 73 * Services managed by this helper must have: 74 * - An associated system settings value with a list of enabled component names. 75 * - A well-known action for services to use in their intent-filter. 76 * - A system permission for services to require in order to ensure system has exclusive binding. 77 * - A settings page for user configuration of enabled services, and associated intent action. 78 * - A remote interface definition (aidl) provided by the service used for communication. 79 */ 80 abstract public class ManagedServices { 81 protected final String TAG = getClass().getSimpleName(); 82 protected final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 83 84 protected static final String ENABLED_SERVICES_SEPARATOR = ":"; 85 86 protected final Context mContext; 87 protected final Object mMutex; 88 private final UserProfiles mUserProfiles; 89 private final SettingsObserver mSettingsObserver; 90 private final IPackageManager mPm; 91 private final Config mConfig; 92 private ArraySet<String> mRestored; 93 94 // contains connections to all connected services, including app services 95 // and system services 96 private final ArrayList<ManagedServiceInfo> mServices = new ArrayList<ManagedServiceInfo>(); 97 // things that will be put into mServices as soon as they're ready 98 private final ArrayList<String> mServicesBinding = new ArrayList<String>(); 99 // lists the component names of all enabled (and therefore potentially connected) 100 // app services for current profiles. 101 private ArraySet<ComponentName> mEnabledServicesForCurrentProfiles 102 = new ArraySet<ComponentName>(); 103 // Just the packages from mEnabledServicesForCurrentProfiles 104 private ArraySet<String> mEnabledServicesPackageNames = new ArraySet<String>(); 105 // List of packages in restored setting across all mUserProfiles, for quick 106 // filtering upon package updates. 107 private ArraySet<String> mRestoredPackages = new ArraySet<>(); 108 // List of enabled packages that have nevertheless asked not to be run 109 private ArraySet<ComponentName> mSnoozingForCurrentProfiles = new ArraySet<>(); 110 111 112 // Kept to de-dupe user change events (experienced after boot, when we receive a settings and a 113 // user change). 114 private int[] mLastSeenProfileIds; 115 116 private final BroadcastReceiver mRestoreReceiver; 117 ManagedServices(Context context, Handler handler, Object mutex, UserProfiles userProfiles)118 public ManagedServices(Context context, Handler handler, Object mutex, 119 UserProfiles userProfiles) { 120 mContext = context; 121 mMutex = mutex; 122 mUserProfiles = userProfiles; 123 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 124 mConfig = getConfig(); 125 mSettingsObserver = new SettingsObserver(handler); 126 127 mRestoreReceiver = new SettingRestoredReceiver(); 128 IntentFilter filter = new IntentFilter(Intent.ACTION_SETTING_RESTORED); 129 context.registerReceiver(mRestoreReceiver, filter); 130 rebuildRestoredPackages(); 131 } 132 133 class SettingRestoredReceiver extends BroadcastReceiver { 134 @Override onReceive(Context context, Intent intent)135 public void onReceive(Context context, Intent intent) { 136 if (Intent.ACTION_SETTING_RESTORED.equals(intent.getAction())) { 137 String element = intent.getStringExtra(Intent.EXTRA_SETTING_NAME); 138 if (Objects.equals(element, mConfig.secureSettingName) 139 || Objects.equals(element, mConfig.secondarySettingName)) { 140 String prevValue = intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE); 141 String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE); 142 settingRestored(element, prevValue, newValue, getSendingUserId()); 143 } 144 } 145 } 146 } 147 getConfig()148 abstract protected Config getConfig(); 149 getCaption()150 private String getCaption() { 151 return mConfig.caption; 152 } 153 asInterface(IBinder binder)154 abstract protected IInterface asInterface(IBinder binder); 155 checkType(IInterface service)156 abstract protected boolean checkType(IInterface service); 157 onServiceAdded(ManagedServiceInfo info)158 abstract protected void onServiceAdded(ManagedServiceInfo info); 159 getServices()160 protected List<ManagedServiceInfo> getServices() { 161 synchronized (mMutex) { 162 List<ManagedServiceInfo> services = new ArrayList<>(mServices); 163 return services; 164 } 165 } 166 onServiceRemovedLocked(ManagedServiceInfo removed)167 protected void onServiceRemovedLocked(ManagedServiceInfo removed) { } 168 newServiceInfo(IInterface service, ComponentName component, int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion)169 private ManagedServiceInfo newServiceInfo(IInterface service, 170 ComponentName component, int userid, boolean isSystem, ServiceConnection connection, 171 int targetSdkVersion) { 172 return new ManagedServiceInfo(service, component, userid, isSystem, connection, 173 targetSdkVersion); 174 } 175 onBootPhaseAppsCanStart()176 public void onBootPhaseAppsCanStart() { 177 mSettingsObserver.observe(); 178 } 179 dump(PrintWriter pw, DumpFilter filter)180 public void dump(PrintWriter pw, DumpFilter filter) { 181 pw.println(" All " + getCaption() + "s (" + mEnabledServicesForCurrentProfiles.size() 182 + ") enabled for current profiles:"); 183 for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) { 184 if (filter != null && !filter.matches(cmpt)) continue; 185 pw.println(" " + cmpt); 186 } 187 188 pw.println(" Live " + getCaption() + "s (" + mServices.size() + "):"); 189 for (ManagedServiceInfo info : mServices) { 190 if (filter != null && !filter.matches(info.component)) continue; 191 pw.println(" " + info.component 192 + " (user " + info.userid + "): " + info.service 193 + (info.isSystem?" SYSTEM":"") 194 + (info.isGuest(this)?" GUEST":"")); 195 } 196 197 pw.println(" Snoozed " + getCaption() + "s (" + 198 mSnoozingForCurrentProfiles.size() + "):"); 199 for (ComponentName name : mSnoozingForCurrentProfiles) { 200 pw.println(" " + name.flattenToShortString()); 201 } 202 } 203 204 // By convention, restored settings are replicated to another settings 205 // entry, named similarly but with a disambiguation suffix. restoredSettingName(String setting)206 public static String restoredSettingName(String setting) { 207 return setting + ":restored"; 208 } 209 210 // The OS has done a restore of this service's saved state. We clone it to the 211 // 'restored' reserve, and then once we return and the actual write to settings is 212 // performed, our observer will do the work of maintaining the restored vs live 213 // settings data. settingRestored(String element, String oldValue, String newValue, int userid)214 public void settingRestored(String element, String oldValue, String newValue, int userid) { 215 if (DEBUG) Slog.d(TAG, "Restored managed service setting: " + element 216 + " ovalue=" + oldValue + " nvalue=" + newValue); 217 if (mConfig.secureSettingName.equals(element) || 218 mConfig.secondarySettingName.equals(element)) { 219 if (element != null) { 220 Settings.Secure.putStringForUser(mContext.getContentResolver(), 221 restoredSettingName(element), 222 newValue, 223 userid); 224 if (mConfig.secureSettingName.equals(element)) { 225 updateSettingsAccordingToInstalledServices(element, userid); 226 } 227 rebuildRestoredPackages(); 228 } 229 } 230 } 231 isComponentEnabledForPackage(String pkg)232 public boolean isComponentEnabledForPackage(String pkg) { 233 return mEnabledServicesPackageNames.contains(pkg); 234 } 235 onPackagesChanged(boolean removingPackage, String[] pkgList)236 public void onPackagesChanged(boolean removingPackage, String[] pkgList) { 237 if (DEBUG) Slog.d(TAG, "onPackagesChanged removingPackage=" + removingPackage 238 + " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList)) 239 + " mEnabledServicesPackageNames=" + mEnabledServicesPackageNames); 240 boolean anyServicesInvolved = false; 241 242 if (pkgList != null && (pkgList.length > 0)) { 243 for (String pkgName : pkgList) { 244 if (mEnabledServicesPackageNames.contains(pkgName) || 245 mRestoredPackages.contains(pkgName)) { 246 anyServicesInvolved = true; 247 } 248 } 249 } 250 251 if (anyServicesInvolved) { 252 // if we're not replacing a package, clean up orphaned bits 253 if (removingPackage) { 254 updateSettingsAccordingToInstalledServices(); 255 rebuildRestoredPackages(); 256 } 257 // make sure we're still bound to any of our services who may have just upgraded 258 rebindServices(false); 259 } 260 } 261 onUserSwitched(int user)262 public void onUserSwitched(int user) { 263 if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user); 264 rebuildRestoredPackages(); 265 if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) { 266 if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices()."); 267 return; 268 } 269 rebindServices(true); 270 } 271 onUserUnlocked(int user)272 public void onUserUnlocked(int user) { 273 if (DEBUG) Slog.d(TAG, "onUserUnlocked u=" + user); 274 rebuildRestoredPackages(); 275 rebindServices(false); 276 } 277 getServiceFromTokenLocked(IInterface service)278 public ManagedServiceInfo getServiceFromTokenLocked(IInterface service) { 279 if (service == null) { 280 return null; 281 } 282 final IBinder token = service.asBinder(); 283 final int N = mServices.size(); 284 for (int i = 0; i < N; i++) { 285 final ManagedServiceInfo info = mServices.get(i); 286 if (info.service.asBinder() == token) return info; 287 } 288 return null; 289 } 290 checkServiceTokenLocked(IInterface service)291 public ManagedServiceInfo checkServiceTokenLocked(IInterface service) { 292 checkNotNull(service); 293 ManagedServiceInfo info = getServiceFromTokenLocked(service); 294 if (info != null) { 295 return info; 296 } 297 throw new SecurityException("Disallowed call from unknown " + getCaption() + ": " 298 + service); 299 } 300 unregisterService(IInterface service, int userid)301 public void unregisterService(IInterface service, int userid) { 302 checkNotNull(service); 303 // no need to check permissions; if your service binder is in the list, 304 // that's proof that you had permission to add it in the first place 305 unregisterServiceImpl(service, userid); 306 } 307 registerService(IInterface service, ComponentName component, int userid)308 public void registerService(IInterface service, ComponentName component, int userid) { 309 checkNotNull(service); 310 ManagedServiceInfo info = registerServiceImpl(service, component, userid); 311 if (info != null) { 312 onServiceAdded(info); 313 } 314 } 315 316 /** 317 * Add a service to our callbacks. The lifecycle of this service is managed externally, 318 * but unlike a system service, it should not be considered privledged. 319 * */ registerGuestService(ManagedServiceInfo guest)320 public void registerGuestService(ManagedServiceInfo guest) { 321 checkNotNull(guest.service); 322 if (!checkType(guest.service)) { 323 throw new IllegalArgumentException(); 324 } 325 if (registerServiceImpl(guest) != null) { 326 onServiceAdded(guest); 327 } 328 } 329 setComponentState(ComponentName component, boolean enabled)330 public void setComponentState(ComponentName component, boolean enabled) { 331 boolean previous = !mSnoozingForCurrentProfiles.contains(component); 332 if (previous == enabled) { 333 return; 334 } 335 336 if (enabled) { 337 mSnoozingForCurrentProfiles.remove(component); 338 } else { 339 mSnoozingForCurrentProfiles.add(component); 340 } 341 342 // State changed 343 if (DEBUG) { 344 Slog.d(TAG, ((enabled) ? "Enabling " : "Disabling ") + "component " + 345 component.flattenToShortString()); 346 } 347 348 349 synchronized (mMutex) { 350 final int[] userIds = mUserProfiles.getCurrentProfileIds(); 351 352 for (int userId : userIds) { 353 if (enabled) { 354 registerServiceLocked(component, userId); 355 } else { 356 unregisterServiceLocked(component, userId); 357 } 358 } 359 } 360 } 361 rebuildRestoredPackages()362 private void rebuildRestoredPackages() { 363 mRestoredPackages.clear(); 364 String secureSettingName = restoredSettingName(mConfig.secureSettingName); 365 String secondarySettingName = mConfig.secondarySettingName == null 366 ? null : restoredSettingName(mConfig.secondarySettingName); 367 int[] userIds = mUserProfiles.getCurrentProfileIds(); 368 final int N = userIds.length; 369 for (int i = 0; i < N; ++i) { 370 ArraySet<ComponentName> names = 371 loadComponentNamesFromSetting(secureSettingName, userIds[i]); 372 if (secondarySettingName != null) { 373 names.addAll(loadComponentNamesFromSetting(secondarySettingName, userIds[i])); 374 } 375 for (ComponentName name : names) { 376 mRestoredPackages.add(name.getPackageName()); 377 } 378 } 379 } 380 381 loadComponentNamesFromSetting(String settingName, int userId)382 protected @NonNull ArraySet<ComponentName> loadComponentNamesFromSetting(String settingName, 383 int userId) { 384 final ContentResolver cr = mContext.getContentResolver(); 385 String settingValue = Settings.Secure.getStringForUser( 386 cr, 387 settingName, 388 userId); 389 if (TextUtils.isEmpty(settingValue)) 390 return new ArraySet<>(); 391 String[] restored = settingValue.split(ENABLED_SERVICES_SEPARATOR); 392 ArraySet<ComponentName> result = new ArraySet<>(restored.length); 393 for (int i = 0; i < restored.length; i++) { 394 ComponentName value = ComponentName.unflattenFromString(restored[i]); 395 if (null != value) { 396 result.add(value); 397 } 398 } 399 return result; 400 } 401 storeComponentsToSetting(Set<ComponentName> components, String settingName, int userId)402 private void storeComponentsToSetting(Set<ComponentName> components, 403 String settingName, 404 int userId) { 405 String[] componentNames = null; 406 if (null != components) { 407 componentNames = new String[components.size()]; 408 int index = 0; 409 for (ComponentName c: components) { 410 componentNames[index++] = c.flattenToString(); 411 } 412 } 413 final String value = (componentNames == null) ? "" : 414 TextUtils.join(ENABLED_SERVICES_SEPARATOR, componentNames); 415 final ContentResolver cr = mContext.getContentResolver(); 416 Settings.Secure.putStringForUser( 417 cr, 418 settingName, 419 value, 420 userId); 421 } 422 423 /** 424 * Remove access for any services that no longer exist. 425 */ updateSettingsAccordingToInstalledServices()426 private void updateSettingsAccordingToInstalledServices() { 427 int[] userIds = mUserProfiles.getCurrentProfileIds(); 428 final int N = userIds.length; 429 for (int i = 0; i < N; ++i) { 430 updateSettingsAccordingToInstalledServices(mConfig.secureSettingName, userIds[i]); 431 if (mConfig.secondarySettingName != null) { 432 updateSettingsAccordingToInstalledServices( 433 mConfig.secondarySettingName, userIds[i]); 434 } 435 } 436 rebuildRestoredPackages(); 437 } 438 queryPackageForServices(String packageName, int userId)439 protected Set<ComponentName> queryPackageForServices(String packageName, int userId) { 440 Set<ComponentName> installed = new ArraySet<>(); 441 final PackageManager pm = mContext.getPackageManager(); 442 Intent queryIntent = new Intent(mConfig.serviceInterface); 443 if (!TextUtils.isEmpty(packageName)) { 444 queryIntent.setPackage(packageName); 445 } 446 List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser( 447 queryIntent, 448 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, 449 userId); 450 if (DEBUG) 451 Slog.v(TAG, mConfig.serviceInterface + " services: " + installedServices); 452 if (installedServices != null) { 453 for (int i = 0, count = installedServices.size(); i < count; i++) { 454 ResolveInfo resolveInfo = installedServices.get(i); 455 ServiceInfo info = resolveInfo.serviceInfo; 456 457 ComponentName component = new ComponentName(info.packageName, info.name); 458 if (!mConfig.bindPermission.equals(info.permission)) { 459 Slog.w(TAG, "Skipping " + getCaption() + " service " 460 + info.packageName + "/" + info.name 461 + ": it does not require the permission " 462 + mConfig.bindPermission); 463 continue; 464 } 465 installed.add(component); 466 } 467 } 468 return installed; 469 } 470 updateSettingsAccordingToInstalledServices(String setting, int userId)471 private void updateSettingsAccordingToInstalledServices(String setting, int userId) { 472 boolean restoredChanged = false; 473 boolean currentChanged = false; 474 Set<ComponentName> restored = 475 loadComponentNamesFromSetting(restoredSettingName(setting), userId); 476 Set<ComponentName> current = 477 loadComponentNamesFromSetting(setting, userId); 478 // Load all services for all packages. 479 Set<ComponentName> installed = queryPackageForServices(null, userId); 480 481 ArraySet<ComponentName> retained = new ArraySet<>(); 482 483 for (ComponentName component : installed) { 484 if (null != restored) { 485 boolean wasRestored = restored.remove(component); 486 if (wasRestored) { 487 // Freshly installed package has service that was mentioned in restored setting. 488 if (DEBUG) 489 Slog.v(TAG, "Restoring " + component + " for user " + userId); 490 restoredChanged = true; 491 currentChanged = true; 492 retained.add(component); 493 continue; 494 } 495 } 496 497 if (null != current) { 498 if (current.contains(component)) 499 retained.add(component); 500 } 501 } 502 503 currentChanged |= ((current == null ? 0 : current.size()) != retained.size()); 504 505 if (currentChanged) { 506 if (DEBUG) Slog.v(TAG, "List of " + getCaption() + " services was updated " + current); 507 storeComponentsToSetting(retained, setting, userId); 508 } 509 510 if (restoredChanged) { 511 if (DEBUG) Slog.v(TAG, 512 "List of " + getCaption() + " restored services was updated " + restored); 513 storeComponentsToSetting(restored, restoredSettingName(setting), userId); 514 } 515 } 516 517 /** 518 * Called whenever packages change, the user switches, or the secure setting 519 * is altered. (For example in response to USER_SWITCHED in our broadcast receiver) 520 */ rebindServices(boolean forceRebind)521 private void rebindServices(boolean forceRebind) { 522 if (DEBUG) Slog.d(TAG, "rebindServices"); 523 final int[] userIds = mUserProfiles.getCurrentProfileIds(); 524 final int nUserIds = userIds.length; 525 526 final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>(); 527 528 for (int i = 0; i < nUserIds; ++i) { 529 componentsByUser.put(userIds[i], 530 loadComponentNamesFromSetting(mConfig.secureSettingName, userIds[i])); 531 if (mConfig.secondarySettingName != null) { 532 componentsByUser.get(userIds[i]).addAll( 533 loadComponentNamesFromSetting(mConfig.secondarySettingName, userIds[i])); 534 } 535 } 536 537 final ArrayList<ManagedServiceInfo> removableBoundServices = new ArrayList<>(); 538 final SparseArray<Set<ComponentName>> toAdd = new SparseArray<>(); 539 540 synchronized (mMutex) { 541 // Rebind to non-system services if user switched 542 for (ManagedServiceInfo service : mServices) { 543 if (!service.isSystem && !service.isGuest(this)) { 544 removableBoundServices.add(service); 545 } 546 } 547 548 mEnabledServicesForCurrentProfiles.clear(); 549 mEnabledServicesPackageNames.clear(); 550 551 for (int i = 0; i < nUserIds; ++i) { 552 // decode the list of components 553 final ArraySet<ComponentName> userComponents = componentsByUser.get(userIds[i]); 554 if (null == userComponents) { 555 toAdd.put(userIds[i], new ArraySet<ComponentName>()); 556 continue; 557 } 558 559 final Set<ComponentName> add = new HashSet<>(userComponents); 560 add.removeAll(mSnoozingForCurrentProfiles); 561 562 toAdd.put(userIds[i], add); 563 564 mEnabledServicesForCurrentProfiles.addAll(userComponents); 565 566 for (int j = 0; j < userComponents.size(); j++) { 567 final ComponentName component = userComponents.valueAt(j); 568 mEnabledServicesPackageNames.add(component.getPackageName()); 569 } 570 } 571 } 572 573 for (ManagedServiceInfo info : removableBoundServices) { 574 final ComponentName component = info.component; 575 final int oldUser = info.userid; 576 final Set<ComponentName> allowedComponents = toAdd.get(info.userid); 577 if (allowedComponents != null) { 578 if (allowedComponents.contains(component) && !forceRebind) { 579 // Already bound, don't need to bind again. 580 allowedComponents.remove(component); 581 } else { 582 // No longer allowed to be bound, or must rebind. 583 Slog.v(TAG, "disabling " + getCaption() + " for user " 584 + oldUser + ": " + component); 585 unregisterService(component, oldUser); 586 } 587 } 588 } 589 590 for (int i = 0; i < nUserIds; ++i) { 591 final Set<ComponentName> add = toAdd.get(userIds[i]); 592 for (ComponentName component : add) { 593 try { 594 ServiceInfo info = mPm.getServiceInfo(component, 595 PackageManager.MATCH_DIRECT_BOOT_AWARE 596 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userIds[i]); 597 if (info == null || !mConfig.bindPermission.equals(info.permission)) { 598 Slog.w(TAG, "Skipping " + getCaption() + " service " + component 599 + ": it does not require the permission " + mConfig.bindPermission); 600 continue; 601 } 602 Slog.v(TAG, 603 "enabling " + getCaption() + " for " + userIds[i] + ": " + component); 604 registerService(component, userIds[i]); 605 } catch (RemoteException e) { 606 e.rethrowFromSystemServer(); 607 } 608 } 609 } 610 611 mLastSeenProfileIds = userIds; 612 } 613 614 /** 615 * Version of registerService that takes the name of a service component to bind to. 616 */ registerService(final ComponentName name, final int userid)617 private void registerService(final ComponentName name, final int userid) { 618 synchronized (mMutex) { 619 registerServiceLocked(name, userid); 620 } 621 } 622 623 /** 624 * Inject a system service into the management list. 625 */ registerSystemService(final ComponentName name, final int userid)626 public void registerSystemService(final ComponentName name, final int userid) { 627 synchronized (mMutex) { 628 registerServiceLocked(name, userid, true /* isSystem */); 629 } 630 } 631 registerServiceLocked(final ComponentName name, final int userid)632 private void registerServiceLocked(final ComponentName name, final int userid) { 633 registerServiceLocked(name, userid, false /* isSystem */); 634 } 635 registerServiceLocked(final ComponentName name, final int userid, final boolean isSystem)636 private void registerServiceLocked(final ComponentName name, final int userid, 637 final boolean isSystem) { 638 if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid); 639 640 final String servicesBindingTag = name.toString() + "/" + userid; 641 if (mServicesBinding.contains(servicesBindingTag)) { 642 // stop registering this thing already! we're working on it 643 return; 644 } 645 mServicesBinding.add(servicesBindingTag); 646 647 final int N = mServices.size(); 648 for (int i = N - 1; i >= 0; i--) { 649 final ManagedServiceInfo info = mServices.get(i); 650 if (name.equals(info.component) 651 && info.userid == userid) { 652 // cut old connections 653 if (DEBUG) Slog.v(TAG, " disconnecting old " + getCaption() + ": " 654 + info.service); 655 removeServiceLocked(i); 656 if (info.connection != null) { 657 mContext.unbindService(info.connection); 658 } 659 } 660 } 661 662 Intent intent = new Intent(mConfig.serviceInterface); 663 intent.setComponent(name); 664 665 intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel); 666 667 final PendingIntent pendingIntent = PendingIntent.getActivity( 668 mContext, 0, new Intent(mConfig.settingsAction), 0); 669 intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent); 670 671 ApplicationInfo appInfo = null; 672 try { 673 appInfo = mContext.getPackageManager().getApplicationInfo( 674 name.getPackageName(), 0); 675 } catch (NameNotFoundException e) { 676 // Ignore if the package doesn't exist we won't be able to bind to the service. 677 } 678 final int targetSdkVersion = 679 appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE; 680 681 try { 682 if (DEBUG) Slog.v(TAG, "binding: " + intent); 683 ServiceConnection serviceConnection = new ServiceConnection() { 684 IInterface mService; 685 686 @Override 687 public void onServiceConnected(ComponentName name, IBinder binder) { 688 boolean added = false; 689 ManagedServiceInfo info = null; 690 synchronized (mMutex) { 691 mServicesBinding.remove(servicesBindingTag); 692 try { 693 mService = asInterface(binder); 694 info = newServiceInfo(mService, name, 695 userid, isSystem, this, targetSdkVersion); 696 binder.linkToDeath(info, 0); 697 added = mServices.add(info); 698 } catch (RemoteException e) { 699 // already dead 700 } 701 } 702 if (added) { 703 onServiceAdded(info); 704 } 705 } 706 707 @Override 708 public void onServiceDisconnected(ComponentName name) { 709 Slog.v(TAG, getCaption() + " connection lost: " + name); 710 } 711 }; 712 if (!mContext.bindServiceAsUser(intent, 713 serviceConnection, 714 BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT, 715 new UserHandle(userid))) { 716 mServicesBinding.remove(servicesBindingTag); 717 Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent); 718 return; 719 } 720 } catch (SecurityException ex) { 721 Slog.e(TAG, "Unable to bind " + getCaption() + " service: " + intent, ex); 722 return; 723 } 724 } 725 726 /** 727 * Remove a service for the given user by ComponentName 728 */ unregisterService(ComponentName name, int userid)729 private void unregisterService(ComponentName name, int userid) { 730 synchronized (mMutex) { 731 unregisterServiceLocked(name, userid); 732 } 733 } 734 unregisterServiceLocked(ComponentName name, int userid)735 private void unregisterServiceLocked(ComponentName name, int userid) { 736 final int N = mServices.size(); 737 for (int i = N - 1; i >= 0; i--) { 738 final ManagedServiceInfo info = mServices.get(i); 739 if (name.equals(info.component) 740 && info.userid == userid) { 741 removeServiceLocked(i); 742 if (info.connection != null) { 743 try { 744 mContext.unbindService(info.connection); 745 } catch (IllegalArgumentException ex) { 746 // something happened to the service: we think we have a connection 747 // but it's bogus. 748 Slog.e(TAG, getCaption() + " " + name + " could not be unbound: " + ex); 749 } 750 } 751 } 752 } 753 } 754 755 /** 756 * Removes a service from the list but does not unbind 757 * 758 * @return the removed service. 759 */ removeServiceImpl(IInterface service, final int userid)760 private ManagedServiceInfo removeServiceImpl(IInterface service, final int userid) { 761 if (DEBUG) Slog.d(TAG, "removeServiceImpl service=" + service + " u=" + userid); 762 ManagedServiceInfo serviceInfo = null; 763 synchronized (mMutex) { 764 final int N = mServices.size(); 765 for (int i = N - 1; i >= 0; i--) { 766 final ManagedServiceInfo info = mServices.get(i); 767 if (info.service.asBinder() == service.asBinder() 768 && info.userid == userid) { 769 if (DEBUG) Slog.d(TAG, "Removing active service " + info.component); 770 serviceInfo = removeServiceLocked(i); 771 } 772 } 773 } 774 return serviceInfo; 775 } 776 removeServiceLocked(int i)777 private ManagedServiceInfo removeServiceLocked(int i) { 778 final ManagedServiceInfo info = mServices.remove(i); 779 onServiceRemovedLocked(info); 780 return info; 781 } 782 checkNotNull(IInterface service)783 private void checkNotNull(IInterface service) { 784 if (service == null) { 785 throw new IllegalArgumentException(getCaption() + " must not be null"); 786 } 787 } 788 registerServiceImpl(final IInterface service, final ComponentName component, final int userid)789 private ManagedServiceInfo registerServiceImpl(final IInterface service, 790 final ComponentName component, final int userid) { 791 ManagedServiceInfo info = newServiceInfo(service, component, userid, 792 true /*isSystem*/, null /*connection*/, Build.VERSION_CODES.LOLLIPOP); 793 return registerServiceImpl(info); 794 } 795 registerServiceImpl(ManagedServiceInfo info)796 private ManagedServiceInfo registerServiceImpl(ManagedServiceInfo info) { 797 synchronized (mMutex) { 798 try { 799 info.service.asBinder().linkToDeath(info, 0); 800 mServices.add(info); 801 return info; 802 } catch (RemoteException e) { 803 // already dead 804 } 805 } 806 return null; 807 } 808 809 /** 810 * Removes a service from the list and unbinds. 811 */ unregisterServiceImpl(IInterface service, int userid)812 private void unregisterServiceImpl(IInterface service, int userid) { 813 ManagedServiceInfo info = removeServiceImpl(service, userid); 814 if (info != null && info.connection != null && !info.isGuest(this)) { 815 mContext.unbindService(info.connection); 816 } 817 } 818 819 private class SettingsObserver extends ContentObserver { 820 private final Uri mSecureSettingsUri = Settings.Secure.getUriFor(mConfig.secureSettingName); 821 private final Uri mSecondarySettingsUri; 822 SettingsObserver(Handler handler)823 private SettingsObserver(Handler handler) { 824 super(handler); 825 if (mConfig.secondarySettingName != null) { 826 mSecondarySettingsUri = Settings.Secure.getUriFor(mConfig.secondarySettingName); 827 } else { 828 mSecondarySettingsUri = null; 829 } 830 } 831 observe()832 private void observe() { 833 ContentResolver resolver = mContext.getContentResolver(); 834 resolver.registerContentObserver(mSecureSettingsUri, 835 false, this, UserHandle.USER_ALL); 836 if (mSecondarySettingsUri != null) { 837 resolver.registerContentObserver(mSecondarySettingsUri, 838 false, this, UserHandle.USER_ALL); 839 } 840 update(null); 841 } 842 843 @Override onChange(boolean selfChange, Uri uri)844 public void onChange(boolean selfChange, Uri uri) { 845 update(uri); 846 } 847 update(Uri uri)848 private void update(Uri uri) { 849 if (uri == null || mSecureSettingsUri.equals(uri) 850 || uri.equals(mSecondarySettingsUri)) { 851 if (DEBUG) Slog.d(TAG, "Setting changed: uri=" + uri); 852 rebindServices(false); 853 rebuildRestoredPackages(); 854 } 855 } 856 } 857 858 public class ManagedServiceInfo implements IBinder.DeathRecipient { 859 public IInterface service; 860 public ComponentName component; 861 public int userid; 862 public boolean isSystem; 863 public ServiceConnection connection; 864 public int targetSdkVersion; 865 ManagedServiceInfo(IInterface service, ComponentName component, int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion)866 public ManagedServiceInfo(IInterface service, ComponentName component, 867 int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion) { 868 this.service = service; 869 this.component = component; 870 this.userid = userid; 871 this.isSystem = isSystem; 872 this.connection = connection; 873 this.targetSdkVersion = targetSdkVersion; 874 } 875 isGuest(ManagedServices host)876 public boolean isGuest(ManagedServices host) { 877 return ManagedServices.this != host; 878 } 879 getOwner()880 public ManagedServices getOwner() { 881 return ManagedServices.this; 882 } 883 884 @Override toString()885 public String toString() { 886 return new StringBuilder("ManagedServiceInfo[") 887 .append("component=").append(component) 888 .append(",userid=").append(userid) 889 .append(",isSystem=").append(isSystem) 890 .append(",targetSdkVersion=").append(targetSdkVersion) 891 .append(",connection=").append(connection == null ? null : "<connection>") 892 .append(",service=").append(service) 893 .append(']').toString(); 894 } 895 enabledAndUserMatches(int nid)896 public boolean enabledAndUserMatches(int nid) { 897 if (!isEnabledForCurrentProfiles()) { 898 return false; 899 } 900 if (this.userid == UserHandle.USER_ALL) return true; 901 if (this.isSystem) return true; 902 if (nid == UserHandle.USER_ALL || nid == this.userid) return true; 903 return supportsProfiles() 904 && mUserProfiles.isCurrentProfile(nid) 905 && isPermittedForProfile(nid); 906 } 907 supportsProfiles()908 public boolean supportsProfiles() { 909 return targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP; 910 } 911 912 @Override binderDied()913 public void binderDied() { 914 if (DEBUG) Slog.d(TAG, "binderDied"); 915 // Remove the service, but don't unbind from the service. The system will bring the 916 // service back up, and the onServiceConnected handler will read the service with the 917 // new binding. If this isn't a bound service, and is just a registered 918 // service, just removing it from the list is all we need to do anyway. 919 removeServiceImpl(this.service, this.userid); 920 } 921 922 /** convenience method for looking in mEnabledServicesForCurrentProfiles */ isEnabledForCurrentProfiles()923 public boolean isEnabledForCurrentProfiles() { 924 if (this.isSystem) return true; 925 if (this.connection == null) return false; 926 return mEnabledServicesForCurrentProfiles.contains(this.component); 927 } 928 929 /** 930 * Returns true if this service is allowed to receive events for the given userId. A 931 * managed profile owner can disallow non-system services running outside of the profile 932 * from receiving events from the profile. 933 */ isPermittedForProfile(int userId)934 public boolean isPermittedForProfile(int userId) { 935 if (!mUserProfiles.isManagedProfile(userId)) { 936 return true; 937 } 938 DevicePolicyManager dpm = 939 (DevicePolicyManager) mContext.getSystemService(DEVICE_POLICY_SERVICE); 940 final long identity = Binder.clearCallingIdentity(); 941 try { 942 return dpm.isNotificationListenerServicePermitted( 943 component.getPackageName(), userId); 944 } finally { 945 Binder.restoreCallingIdentity(identity); 946 } 947 } 948 } 949 950 /** convenience method for looking in mEnabledServicesForCurrentProfiles */ isComponentEnabledForCurrentProfiles(ComponentName component)951 public boolean isComponentEnabledForCurrentProfiles(ComponentName component) { 952 return mEnabledServicesForCurrentProfiles.contains(component); 953 } 954 955 public static class UserProfiles { 956 // Profiles of the current user. 957 private final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>(); 958 updateCache(@onNull Context context)959 public void updateCache(@NonNull Context context) { 960 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 961 if (userManager != null) { 962 int currentUserId = ActivityManager.getCurrentUser(); 963 List<UserInfo> profiles = userManager.getProfiles(currentUserId); 964 synchronized (mCurrentProfiles) { 965 mCurrentProfiles.clear(); 966 for (UserInfo user : profiles) { 967 mCurrentProfiles.put(user.id, user); 968 } 969 } 970 } 971 } 972 getCurrentProfileIds()973 public int[] getCurrentProfileIds() { 974 synchronized (mCurrentProfiles) { 975 int[] users = new int[mCurrentProfiles.size()]; 976 final int N = mCurrentProfiles.size(); 977 for (int i = 0; i < N; ++i) { 978 users[i] = mCurrentProfiles.keyAt(i); 979 } 980 return users; 981 } 982 } 983 isCurrentProfile(int userId)984 public boolean isCurrentProfile(int userId) { 985 synchronized (mCurrentProfiles) { 986 return mCurrentProfiles.get(userId) != null; 987 } 988 } 989 isManagedProfile(int userId)990 public boolean isManagedProfile(int userId) { 991 synchronized (mCurrentProfiles) { 992 UserInfo user = mCurrentProfiles.get(userId); 993 return user != null && user.isManagedProfile(); 994 } 995 } 996 } 997 998 public static class Config { 999 public String caption; 1000 public String serviceInterface; 1001 public String secureSettingName; 1002 public String secondarySettingName; 1003 public String bindPermission; 1004 public String settingsAction; 1005 public int clientLabel; 1006 } 1007 } 1008