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