1 /* 2 * Copyright (C) 2018 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.role; 18 19 import android.Manifest; 20 import android.annotation.AnyThread; 21 import android.annotation.CheckResult; 22 import android.annotation.MainThread; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.UserIdInt; 26 import android.annotation.WorkerThread; 27 import android.app.ActivityManager; 28 import android.app.AppOpsManager; 29 import android.app.role.IOnRoleHoldersChangedListener; 30 import android.app.role.IRoleManager; 31 import android.app.role.RoleControllerManager; 32 import android.app.role.RoleManager; 33 import android.content.BroadcastReceiver; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.IntentFilter; 37 import android.content.PermissionChecker; 38 import android.content.pm.PackageManager; 39 import android.content.pm.PackageManager.NameNotFoundException; 40 import android.content.pm.PackageManagerInternal; 41 import android.content.pm.Signature; 42 import android.database.CursorWindow; 43 import android.os.Binder; 44 import android.os.Bundle; 45 import android.os.Handler; 46 import android.os.RemoteCallback; 47 import android.os.RemoteCallbackList; 48 import android.os.RemoteException; 49 import android.os.ResultReceiver; 50 import android.os.ShellCallback; 51 import android.os.UserHandle; 52 import android.os.UserManagerInternal; 53 import android.text.TextUtils; 54 import android.util.ArrayMap; 55 import android.util.ArraySet; 56 import android.util.PackageUtils; 57 import android.util.Slog; 58 import android.util.SparseArray; 59 import android.util.proto.ProtoOutputStream; 60 61 import com.android.internal.annotations.GuardedBy; 62 import com.android.internal.infra.AndroidFuture; 63 import com.android.internal.infra.ThrottledRunnable; 64 import com.android.internal.telephony.SmsApplication; 65 import com.android.internal.util.ArrayUtils; 66 import com.android.internal.util.BitUtils; 67 import com.android.internal.util.CollectionUtils; 68 import com.android.internal.util.DumpUtils; 69 import com.android.internal.util.FunctionalUtils; 70 import com.android.internal.util.IndentingPrintWriter; 71 import com.android.internal.util.Preconditions; 72 import com.android.internal.util.dump.DualDumpOutputStream; 73 import com.android.internal.util.function.pooled.PooledLambda; 74 import com.android.server.FgThread; 75 import com.android.server.LocalServices; 76 import com.android.server.SystemService; 77 import com.android.server.pm.permission.PermissionManagerServiceInternal; 78 79 import java.io.ByteArrayOutputStream; 80 import java.io.FileDescriptor; 81 import java.io.PrintWriter; 82 import java.util.ArrayList; 83 import java.util.Collections; 84 import java.util.List; 85 import java.util.Objects; 86 import java.util.concurrent.ExecutionException; 87 import java.util.concurrent.TimeUnit; 88 import java.util.concurrent.TimeoutException; 89 import java.util.function.Consumer; 90 91 /** 92 * Service for role management. 93 * 94 * @see RoleManager 95 */ 96 public class RoleManagerService extends SystemService implements RoleUserState.Callback { 97 98 private static final String LOG_TAG = RoleManagerService.class.getSimpleName(); 99 100 private static final boolean DEBUG = false; 101 102 private static final long GRANT_DEFAULT_ROLES_INTERVAL_MILLIS = 1000; 103 104 @NonNull 105 private final UserManagerInternal mUserManagerInternal; 106 @NonNull 107 private final AppOpsManager mAppOpsManager; 108 109 @NonNull 110 private final Object mLock = new Object(); 111 112 @NonNull 113 private final RoleHoldersResolver mLegacyRoleResolver; 114 115 /** @see #getRoleHolders(String, int) */ 116 public interface RoleHoldersResolver { 117 /** @return a list of packages that hold a given role for a given user */ 118 @NonNull getRoleHolders(@onNull String roleName, @UserIdInt int userId)119 List<String> getRoleHolders(@NonNull String roleName, @UserIdInt int userId); 120 } 121 122 /** 123 * Maps user id to its state. 124 */ 125 @GuardedBy("mLock") 126 @NonNull 127 private final SparseArray<RoleUserState> mUserStates = new SparseArray<>(); 128 129 /** 130 * Maps user id to its controller. 131 */ 132 @GuardedBy("mLock") 133 @NonNull 134 private final SparseArray<RoleControllerManager> mControllers = new SparseArray<>(); 135 136 /** 137 * Maps user id to its list of listeners. 138 */ 139 @GuardedBy("mLock") 140 @NonNull 141 private final SparseArray<RemoteCallbackList<IOnRoleHoldersChangedListener>> mListeners = 142 new SparseArray<>(); 143 144 @NonNull 145 private final Handler mListenerHandler = FgThread.getHandler(); 146 147 /** 148 * Maps user id to its throttled runnable for granting default roles. 149 */ 150 @GuardedBy("mLock") 151 @NonNull 152 private final SparseArray<ThrottledRunnable> mGrantDefaultRolesThrottledRunnables = 153 new SparseArray<>(); 154 RoleManagerService(@onNull Context context, @NonNull RoleHoldersResolver legacyRoleResolver)155 public RoleManagerService(@NonNull Context context, 156 @NonNull RoleHoldersResolver legacyRoleResolver) { 157 super(context); 158 159 mLegacyRoleResolver = legacyRoleResolver; 160 161 RoleControllerManager.initializeRemoteServiceComponentName(context); 162 163 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 164 mAppOpsManager = context.getSystemService(AppOpsManager.class); 165 166 LocalServices.addService(RoleManagerInternal.class, new Internal()); 167 168 PermissionManagerServiceInternal permissionManagerInternal = 169 LocalServices.getService(PermissionManagerServiceInternal.class); 170 permissionManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider()); 171 permissionManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider()); 172 permissionManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider()); 173 174 registerUserRemovedReceiver(); 175 } 176 registerUserRemovedReceiver()177 private void registerUserRemovedReceiver() { 178 IntentFilter intentFilter = new IntentFilter(); 179 intentFilter.addAction(Intent.ACTION_USER_REMOVED); 180 getContext().registerReceiverAsUser(new BroadcastReceiver() { 181 @Override 182 public void onReceive(@NonNull Context context, @NonNull Intent intent) { 183 if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) { 184 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 185 onRemoveUser(userId); 186 } 187 } 188 }, UserHandle.ALL, intentFilter, null, null); 189 } 190 191 @Override onStart()192 public void onStart() { 193 publishBinderService(Context.ROLE_SERVICE, new Stub()); 194 195 IntentFilter intentFilter = new IntentFilter(); 196 intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); 197 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 198 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 199 intentFilter.addDataScheme("package"); 200 intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 201 getContext().registerReceiverAsUser(new BroadcastReceiver() { 202 @Override 203 public void onReceive(Context context, Intent intent) { 204 int userId = UserHandle.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1)); 205 if (DEBUG) { 206 Slog.i(LOG_TAG, "Packages changed - re-running initial grants for user " 207 + userId); 208 } 209 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 210 && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 211 // Package is being upgraded - we're about to get ACTION_PACKAGE_ADDED 212 return; 213 } 214 maybeGrantDefaultRolesAsync(userId); 215 } 216 }, UserHandle.ALL, intentFilter, null, null); 217 } 218 219 @Override onStartUser(@serIdInt int userId)220 public void onStartUser(@UserIdInt int userId) { 221 maybeGrantDefaultRolesSync(userId); 222 } 223 224 @MainThread maybeGrantDefaultRolesSync(@serIdInt int userId)225 private void maybeGrantDefaultRolesSync(@UserIdInt int userId) { 226 AndroidFuture<Void> future = maybeGrantDefaultRolesInternal(userId); 227 try { 228 future.get(30, TimeUnit.SECONDS); 229 } catch (InterruptedException | ExecutionException | TimeoutException e) { 230 Slog.e(LOG_TAG, "Failed to grant default roles for user " + userId, e); 231 } 232 } 233 maybeGrantDefaultRolesAsync(@serIdInt int userId)234 private void maybeGrantDefaultRolesAsync(@UserIdInt int userId) { 235 ThrottledRunnable runnable; 236 synchronized (mLock) { 237 runnable = mGrantDefaultRolesThrottledRunnables.get(userId); 238 if (runnable == null) { 239 runnable = new ThrottledRunnable(FgThread.getHandler(), 240 GRANT_DEFAULT_ROLES_INTERVAL_MILLIS, 241 () -> maybeGrantDefaultRolesInternal(userId)); 242 mGrantDefaultRolesThrottledRunnables.put(userId, runnable); 243 } 244 } 245 runnable.run(); 246 } 247 248 @AnyThread 249 @NonNull maybeGrantDefaultRolesInternal(@serIdInt int userId)250 private AndroidFuture<Void> maybeGrantDefaultRolesInternal(@UserIdInt int userId) { 251 RoleUserState userState = getOrCreateUserState(userId); 252 String oldPackagesHash = userState.getPackagesHash(); 253 String newPackagesHash = computeComponentStateHash(userId); 254 if (Objects.equals(oldPackagesHash, newPackagesHash)) { 255 if (DEBUG) { 256 Slog.i(LOG_TAG, "Already granted default roles for packages hash " 257 + newPackagesHash); 258 } 259 return AndroidFuture.completedFuture(null); 260 } 261 262 //TODO gradually add more role migrations statements here for remaining roles 263 // Make sure to implement LegacyRoleResolutionPolicy#getRoleHolders 264 // for a given role before adding a migration statement for it here 265 maybeMigrateRole(RoleManager.ROLE_ASSISTANT, userId); 266 maybeMigrateRole(RoleManager.ROLE_BROWSER, userId); 267 maybeMigrateRole(RoleManager.ROLE_DIALER, userId); 268 maybeMigrateRole(RoleManager.ROLE_SMS, userId); 269 maybeMigrateRole(RoleManager.ROLE_EMERGENCY, userId); 270 maybeMigrateRole(RoleManager.ROLE_HOME, userId); 271 272 // Some package state has changed, so grant default roles again. 273 Slog.i(LOG_TAG, "Granting default roles..."); 274 AndroidFuture<Void> future = new AndroidFuture<>(); 275 getOrCreateController(userId).grantDefaultRoles(FgThread.getExecutor(), 276 successful -> { 277 if (successful) { 278 userState.setPackagesHash(newPackagesHash); 279 future.complete(null); 280 } else { 281 future.completeExceptionally(new RuntimeException()); 282 } 283 }); 284 return future; 285 } 286 maybeMigrateRole(String role, @UserIdInt int userId)287 private void maybeMigrateRole(String role, @UserIdInt int userId) { 288 // Any role for which we have a record are already migrated 289 RoleUserState userState = getOrCreateUserState(userId); 290 if (!userState.isRoleAvailable(role)) { 291 List<String> roleHolders = mLegacyRoleResolver.getRoleHolders(role, userId); 292 if (roleHolders.isEmpty()) { 293 return; 294 } 295 Slog.i(LOG_TAG, "Migrating " + role + ", legacy holders: " + roleHolders); 296 userState.addRoleName(role); 297 int size = roleHolders.size(); 298 for (int i = 0; i < size; i++) { 299 userState.addRoleHolder(role, roleHolders.get(i)); 300 } 301 } 302 } 303 304 @Nullable computeComponentStateHash(@serIdInt int userId)305 private static String computeComponentStateHash(@UserIdInt int userId) { 306 PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class); 307 ByteArrayOutputStream out = new ByteArrayOutputStream(); 308 309 pm.forEachInstalledPackage(FunctionalUtils.uncheckExceptions(pkg -> { 310 out.write(pkg.getPackageName().getBytes()); 311 out.write(BitUtils.toBytes(pkg.getLongVersionCode())); 312 out.write(pm.getApplicationEnabledState(pkg.getPackageName(), userId)); 313 314 ArraySet<String> enabledComponents = 315 pm.getEnabledComponents(pkg.getPackageName(), userId); 316 int numComponents = CollectionUtils.size(enabledComponents); 317 out.write(numComponents); 318 for (int i = 0; i < numComponents; i++) { 319 out.write(enabledComponents.valueAt(i).getBytes()); 320 } 321 322 ArraySet<String> disabledComponents = 323 pm.getDisabledComponents(pkg.getPackageName(), userId); 324 numComponents = CollectionUtils.size(disabledComponents); 325 for (int i = 0; i < numComponents; i++) { 326 out.write(disabledComponents.valueAt(i).getBytes()); 327 } 328 for (Signature signature : pkg.getSigningDetails().signatures) { 329 out.write(signature.toByteArray()); 330 } 331 }), userId); 332 333 return PackageUtils.computeSha256Digest(out.toByteArray()); 334 } 335 336 @NonNull getOrCreateUserState(@serIdInt int userId)337 private RoleUserState getOrCreateUserState(@UserIdInt int userId) { 338 synchronized (mLock) { 339 RoleUserState userState = mUserStates.get(userId); 340 if (userState == null) { 341 userState = new RoleUserState(userId, this); 342 mUserStates.put(userId, userState); 343 } 344 return userState; 345 } 346 } 347 348 @NonNull getOrCreateController(@serIdInt int userId)349 private RoleControllerManager getOrCreateController(@UserIdInt int userId) { 350 synchronized (mLock) { 351 RoleControllerManager controller = mControllers.get(userId); 352 if (controller == null) { 353 Context systemContext = getContext(); 354 Context context; 355 try { 356 context = systemContext.createPackageContextAsUser( 357 systemContext.getPackageName(), 0, UserHandle.of(userId)); 358 } catch (NameNotFoundException e) { 359 throw new RuntimeException(e); 360 } 361 controller = RoleControllerManager.createWithInitializedRemoteServiceComponentName( 362 FgThread.getHandler(), context); 363 mControllers.put(userId, controller); 364 } 365 return controller; 366 } 367 } 368 369 @Nullable getListeners(@serIdInt int userId)370 private RemoteCallbackList<IOnRoleHoldersChangedListener> getListeners(@UserIdInt int userId) { 371 synchronized (mLock) { 372 return mListeners.get(userId); 373 } 374 } 375 376 @NonNull getOrCreateListeners( @serIdInt int userId)377 private RemoteCallbackList<IOnRoleHoldersChangedListener> getOrCreateListeners( 378 @UserIdInt int userId) { 379 synchronized (mLock) { 380 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = mListeners.get(userId); 381 if (listeners == null) { 382 listeners = new RemoteCallbackList<>(); 383 mListeners.put(userId, listeners); 384 } 385 return listeners; 386 } 387 } 388 onRemoveUser(@serIdInt int userId)389 private void onRemoveUser(@UserIdInt int userId) { 390 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners; 391 RoleUserState userState; 392 synchronized (mLock) { 393 mGrantDefaultRolesThrottledRunnables.remove(userId); 394 listeners = mListeners.removeReturnOld(userId); 395 mControllers.remove(userId); 396 userState = mUserStates.removeReturnOld(userId); 397 } 398 if (listeners != null) { 399 listeners.kill(); 400 } 401 if (userState != null) { 402 userState.destroy(); 403 } 404 } 405 406 @Override onRoleHoldersChanged(@onNull String roleName, @UserIdInt int userId, @Nullable String removedHolder, @Nullable String addedHolder)407 public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId, 408 @Nullable String removedHolder, @Nullable String addedHolder) { 409 mListenerHandler.sendMessage(PooledLambda.obtainMessage( 410 RoleManagerService::notifyRoleHoldersChanged, this, roleName, userId, 411 removedHolder, addedHolder)); 412 } 413 414 @WorkerThread notifyRoleHoldersChanged(@onNull String roleName, @UserIdInt int userId, @Nullable String removedHolder, @Nullable String addedHolder)415 private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId, 416 @Nullable String removedHolder, @Nullable String addedHolder) { 417 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId); 418 if (listeners != null) { 419 notifyRoleHoldersChangedForListeners(listeners, roleName, userId); 420 } 421 422 RemoteCallbackList<IOnRoleHoldersChangedListener> allUsersListeners = getListeners( 423 UserHandle.USER_ALL); 424 if (allUsersListeners != null) { 425 notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId); 426 } 427 428 // Legacy: sms app changed broadcasts 429 if (RoleManager.ROLE_SMS.equals(roleName)) { 430 SmsApplication.broadcastSmsAppChange(getContext(), UserHandle.of(userId), 431 removedHolder, addedHolder); 432 } 433 } 434 435 @WorkerThread notifyRoleHoldersChangedForListeners( @onNull RemoteCallbackList<IOnRoleHoldersChangedListener> listeners, @NonNull String roleName, @UserIdInt int userId)436 private void notifyRoleHoldersChangedForListeners( 437 @NonNull RemoteCallbackList<IOnRoleHoldersChangedListener> listeners, 438 @NonNull String roleName, @UserIdInt int userId) { 439 int broadcastCount = listeners.beginBroadcast(); 440 try { 441 for (int i = 0; i < broadcastCount; i++) { 442 IOnRoleHoldersChangedListener listener = listeners.getBroadcastItem(i); 443 try { 444 listener.onRoleHoldersChanged(roleName, userId); 445 } catch (RemoteException e) { 446 Slog.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e); 447 } 448 } 449 } finally { 450 listeners.finishBroadcast(); 451 } 452 } 453 454 private class Stub extends IRoleManager.Stub { 455 456 @Override isRoleAvailable(@onNull String roleName)457 public boolean isRoleAvailable(@NonNull String roleName) { 458 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 459 460 int userId = UserHandle.getUserId(getCallingUid()); 461 return getOrCreateUserState(userId).isRoleAvailable(roleName); 462 } 463 464 @Override isRoleHeld(@onNull String roleName, @NonNull String packageName)465 public boolean isRoleHeld(@NonNull String roleName, @NonNull String packageName) { 466 int callingUid = getCallingUid(); 467 mAppOpsManager.checkPackage(callingUid, packageName); 468 469 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 470 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); 471 472 int userId = UserHandle.getUserId(callingUid); 473 ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); 474 if (roleHolders == null) { 475 return false; 476 } 477 return roleHolders.contains(packageName); 478 } 479 480 @NonNull 481 @Override getRoleHoldersAsUser(@onNull String roleName, @UserIdInt int userId)482 public List<String> getRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId) { 483 if (!mUserManagerInternal.exists(userId)) { 484 Slog.e(LOG_TAG, "user " + userId + " does not exist"); 485 return Collections.emptyList(); 486 } 487 userId = handleIncomingUser(userId, false, "getRoleHoldersAsUser"); 488 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, 489 "getRoleHoldersAsUser"); 490 491 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 492 493 ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); 494 if (roleHolders == null) { 495 return Collections.emptyList(); 496 } 497 return new ArrayList<>(roleHolders); 498 } 499 500 @Override addRoleHolderAsUser(@onNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, @NonNull RemoteCallback callback)501 public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, 502 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, 503 @NonNull RemoteCallback callback) { 504 if (!mUserManagerInternal.exists(userId)) { 505 Slog.e(LOG_TAG, "user " + userId + " does not exist"); 506 return; 507 } 508 userId = handleIncomingUser(userId, false, "addRoleHolderAsUser"); 509 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, 510 "addRoleHolderAsUser"); 511 512 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 513 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); 514 Objects.requireNonNull(callback, "callback cannot be null"); 515 516 getOrCreateController(userId).onAddRoleHolder(roleName, packageName, flags, 517 callback); 518 } 519 520 @Override removeRoleHolderAsUser(@onNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, @NonNull RemoteCallback callback)521 public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, 522 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, 523 @NonNull RemoteCallback callback) { 524 if (!mUserManagerInternal.exists(userId)) { 525 Slog.e(LOG_TAG, "user " + userId + " does not exist"); 526 return; 527 } 528 userId = handleIncomingUser(userId, false, "removeRoleHolderAsUser"); 529 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, 530 "removeRoleHolderAsUser"); 531 532 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 533 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); 534 Objects.requireNonNull(callback, "callback cannot be null"); 535 536 getOrCreateController(userId).onRemoveRoleHolder(roleName, packageName, flags, 537 callback); 538 } 539 540 @Override clearRoleHoldersAsUser(@onNull String roleName, @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, @NonNull RemoteCallback callback)541 public void clearRoleHoldersAsUser(@NonNull String roleName, 542 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, 543 @NonNull RemoteCallback callback) { 544 if (!mUserManagerInternal.exists(userId)) { 545 Slog.e(LOG_TAG, "user " + userId + " does not exist"); 546 return; 547 } 548 userId = handleIncomingUser(userId, false, "clearRoleHoldersAsUser"); 549 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, 550 "clearRoleHoldersAsUser"); 551 552 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 553 Objects.requireNonNull(callback, "callback cannot be null"); 554 555 getOrCreateController(userId).onClearRoleHolders(roleName, flags, callback); 556 } 557 558 @Override addOnRoleHoldersChangedListenerAsUser( @onNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId)559 public void addOnRoleHoldersChangedListenerAsUser( 560 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { 561 if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) { 562 Slog.e(LOG_TAG, "user " + userId + " does not exist"); 563 return; 564 } 565 userId = handleIncomingUser(userId, true, "addOnRoleHoldersChangedListenerAsUser"); 566 getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, 567 "addOnRoleHoldersChangedListenerAsUser"); 568 569 Objects.requireNonNull(listener, "listener cannot be null"); 570 571 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getOrCreateListeners( 572 userId); 573 listeners.register(listener); 574 } 575 576 @Override removeOnRoleHoldersChangedListenerAsUser( @onNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId)577 public void removeOnRoleHoldersChangedListenerAsUser( 578 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { 579 if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) { 580 Slog.e(LOG_TAG, "user " + userId + " does not exist"); 581 return; 582 } 583 userId = handleIncomingUser(userId, true, "removeOnRoleHoldersChangedListenerAsUser"); 584 getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, 585 "removeOnRoleHoldersChangedListenerAsUser"); 586 587 Objects.requireNonNull(listener, "listener cannot be null"); 588 589 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId); 590 if (listener == null) { 591 return; 592 } 593 listeners.unregister(listener); 594 } 595 596 @Override setRoleNamesFromController(@onNull List<String> roleNames)597 public void setRoleNamesFromController(@NonNull List<String> roleNames) { 598 getContext().enforceCallingOrSelfPermission( 599 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, 600 "setRoleNamesFromController"); 601 602 Objects.requireNonNull(roleNames, "roleNames cannot be null"); 603 604 int userId = UserHandle.getCallingUserId(); 605 getOrCreateUserState(userId).setRoleNames(roleNames); 606 } 607 608 @Override addRoleHolderFromController(@onNull String roleName, @NonNull String packageName)609 public boolean addRoleHolderFromController(@NonNull String roleName, 610 @NonNull String packageName) { 611 getContext().enforceCallingOrSelfPermission( 612 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, 613 "addRoleHolderFromController"); 614 615 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 616 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); 617 618 int userId = UserHandle.getCallingUserId(); 619 return getOrCreateUserState(userId).addRoleHolder(roleName, packageName); 620 } 621 622 @Override removeRoleHolderFromController(@onNull String roleName, @NonNull String packageName)623 public boolean removeRoleHolderFromController(@NonNull String roleName, 624 @NonNull String packageName) { 625 getContext().enforceCallingOrSelfPermission( 626 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, 627 "removeRoleHolderFromController"); 628 629 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); 630 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); 631 632 int userId = UserHandle.getCallingUserId(); 633 return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName); 634 } 635 636 @Override getHeldRolesFromController(@onNull String packageName)637 public List<String> getHeldRolesFromController(@NonNull String packageName) { 638 getContext().enforceCallingOrSelfPermission( 639 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, 640 "getRolesHeldFromController"); 641 642 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); 643 644 int userId = UserHandle.getCallingUserId(); 645 return getOrCreateUserState(userId).getHeldRoles(packageName); 646 } 647 648 @CheckResult handleIncomingUser(@serIdInt int userId, boolean allowAll, @NonNull String name)649 private int handleIncomingUser(@UserIdInt int userId, boolean allowAll, 650 @NonNull String name) { 651 return ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId, 652 allowAll, true, name, null); 653 } 654 655 @Override onShellCommand(@ullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)656 public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, 657 @Nullable FileDescriptor err, @NonNull String[] args, 658 @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) { 659 new RoleManagerShellCommand(this).exec(this, in, out, err, args, callback, 660 resultReceiver); 661 } 662 663 @Override getDefaultSmsPackage(int userId)664 public String getDefaultSmsPackage(int userId) { 665 long identity = Binder.clearCallingIdentity(); 666 try { 667 return CollectionUtils.firstOrNull( 668 getRoleHoldersAsUser(RoleManager.ROLE_SMS, userId)); 669 } finally { 670 Binder.restoreCallingIdentity(identity); 671 } 672 } 673 674 @Override dump(@onNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args)675 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, 676 @Nullable String[] args) { 677 if (!DumpUtils.checkDumpPermission(getContext(), LOG_TAG, fout)) { 678 return; 679 } 680 681 boolean dumpAsProto = args != null && ArrayUtils.contains(args, "--proto"); 682 DualDumpOutputStream dumpOutputStream; 683 if (dumpAsProto) { 684 dumpOutputStream = new DualDumpOutputStream(new ProtoOutputStream(fd)); 685 } else { 686 fout.println("ROLE MANAGER STATE (dumpsys role):"); 687 dumpOutputStream = new DualDumpOutputStream(new IndentingPrintWriter(fout, " ")); 688 } 689 690 int[] userIds = mUserManagerInternal.getUserIds(); 691 int userIdsLength = userIds.length; 692 for (int i = 0; i < userIdsLength; i++) { 693 int userId = userIds[i]; 694 695 RoleUserState userState = getOrCreateUserState(userId); 696 userState.dump(dumpOutputStream, "user_states", 697 RoleManagerServiceDumpProto.USER_STATES); 698 } 699 700 dumpOutputStream.flush(); 701 } 702 getUidForPackage(String packageName)703 private int getUidForPackage(String packageName) { 704 long ident = Binder.clearCallingIdentity(); 705 try { 706 return getContext().getPackageManager().getApplicationInfo(packageName, 707 PackageManager.MATCH_ANY_USER).uid; 708 } catch (NameNotFoundException nnfe) { 709 return -1; 710 } finally { 711 Binder.restoreCallingIdentity(ident); 712 } 713 } 714 } 715 716 private class Internal extends RoleManagerInternal { 717 718 @NonNull 719 @Override getRolesAndHolders(@serIdInt int userId)720 public ArrayMap<String, ArraySet<String>> getRolesAndHolders(@UserIdInt int userId) { 721 return getOrCreateUserState(userId).getRolesAndHolders(); 722 } 723 } 724 725 private class DefaultBrowserProvider implements 726 PermissionManagerServiceInternal.DefaultBrowserProvider { 727 728 @Nullable 729 @Override getDefaultBrowser(@serIdInt int userId)730 public String getDefaultBrowser(@UserIdInt int userId) { 731 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders( 732 RoleManager.ROLE_BROWSER)); 733 } 734 735 @Override setDefaultBrowser(@ullable String packageName, @UserIdInt int userId)736 public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) { 737 AndroidFuture<Void> future = new AndroidFuture<>(); 738 RemoteCallback callback = new RemoteCallback(result -> { 739 boolean successful = result != null; 740 if (successful) { 741 future.complete(null); 742 } else { 743 future.completeExceptionally(new RuntimeException()); 744 } 745 }); 746 if (packageName != null) { 747 getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, 748 packageName, 0, callback); 749 } else { 750 getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, 751 callback); 752 } 753 try { 754 future.get(5, TimeUnit.SECONDS); 755 return true; 756 } catch (InterruptedException | ExecutionException | TimeoutException e) { 757 Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e); 758 return false; 759 } 760 } 761 762 @Override setDefaultBrowserAsync(@ullable String packageName, @UserIdInt int userId)763 public void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId) { 764 RemoteCallback callback = new RemoteCallback(result -> { 765 boolean successful = result != null; 766 if (!successful) { 767 Slog.e(LOG_TAG, "Failed to set default browser: " + packageName); 768 } 769 }); 770 if (packageName != null) { 771 getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, 772 packageName, 0, callback); 773 } else { 774 getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, 775 callback); 776 } 777 } 778 } 779 780 private class DefaultDialerProvider implements 781 PermissionManagerServiceInternal.DefaultDialerProvider { 782 783 @Nullable 784 @Override getDefaultDialer(@serIdInt int userId)785 public String getDefaultDialer(@UserIdInt int userId) { 786 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders( 787 RoleManager.ROLE_DIALER)); 788 } 789 } 790 791 private class DefaultHomeProvider implements 792 PermissionManagerServiceInternal.DefaultHomeProvider { 793 794 @Nullable 795 @Override getDefaultHome(@serIdInt int userId)796 public String getDefaultHome(@UserIdInt int userId) { 797 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders( 798 RoleManager.ROLE_HOME)); 799 } 800 801 @Override setDefaultHomeAsync(@ullable String packageName, @UserIdInt int userId, @NonNull Consumer<Boolean> callback)802 public void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId, 803 @NonNull Consumer<Boolean> callback) { 804 RemoteCallback remoteCallback = new RemoteCallback(result -> { 805 boolean successful = result != null; 806 if (!successful) { 807 Slog.e(LOG_TAG, "Failed to set default home: " + packageName); 808 } 809 callback.accept(successful); 810 }); 811 if (packageName != null) { 812 getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_HOME, 813 packageName, 0, remoteCallback); 814 } else { 815 getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_HOME, 0, 816 remoteCallback); 817 } 818 } 819 } 820 } 821