diff options
Diffstat (limited to 'service/java/com/android/role/RoleService.java')
-rw-r--r-- | service/java/com/android/role/RoleService.java | 776 |
1 files changed, 0 insertions, 776 deletions
diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java deleted file mode 100644 index 802e38b91..000000000 --- a/service/java/com/android/role/RoleService.java +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.role; - -import android.Manifest; -import android.annotation.AnyThread; -import android.annotation.MainThread; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.UserIdInt; -import android.annotation.WorkerThread; -import android.app.AppOpsManager; -import android.app.role.IOnRoleHoldersChangedListener; -import android.app.role.IRoleManager; -import android.app.role.RoleControllerManager; -import android.app.role.RoleManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.os.Binder; -import android.os.Build; -import android.os.Handler; -import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.os.RemoteCallback; -import android.os.RemoteCallbackList; -import android.os.RemoteException; -import android.os.UserHandle; -import android.os.UserManager; -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.IndentingPrintWriter; -import android.util.Log; -import android.util.SparseArray; -import android.util.proto.ProtoOutputStream; - -import androidx.annotation.RequiresApi; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.infra.AndroidFuture; -import com.android.internal.util.Preconditions; -import com.android.internal.util.dump.DualDumpOutputStream; -import com.android.permission.compat.UserHandleCompat; -import com.android.permission.util.ArrayUtils; -import com.android.permission.util.CollectionUtils; -import com.android.permission.util.ForegroundThread; -import com.android.permission.util.ThrottledRunnable; -import com.android.server.LocalManagerRegistry; -import com.android.server.SystemService; -import com.android.server.role.RoleServicePlatformHelper; - -import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Service for role management. - * - * @see RoleManager - */ -@RequiresApi(Build.VERSION_CODES.S) -public class RoleService extends SystemService implements RoleUserState.Callback { - private static final String LOG_TAG = RoleService.class.getSimpleName(); - - private static final boolean DEBUG = false; - - private static final long GRANT_DEFAULT_ROLES_INTERVAL_MILLIS = 1000; - - @NonNull - private final AppOpsManager mAppOpsManager; - @NonNull - private final UserManager mUserManager; - - @NonNull - private final Object mLock = new Object(); - - @NonNull - private final RoleServicePlatformHelper mPlatformHelper; - - /** - * Maps user id to its state. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray<RoleUserState> mUserStates = new SparseArray<>(); - - /** - * Maps user id to its controller. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray<RoleControllerManager> mControllers = new SparseArray<>(); - - /** - * Maps user id to its list of listeners. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray<RemoteCallbackList<IOnRoleHoldersChangedListener>> mListeners = - new SparseArray<>(); - - @NonNull - private final Handler mListenerHandler = ForegroundThread.getHandler(); - - @GuardedBy("mLock") - private boolean mBypassingRoleQualification; - - /** - * Maps user id to its throttled runnable for granting default roles. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray<ThrottledRunnable> mGrantDefaultRolesThrottledRunnables = - new SparseArray<>(); - - public RoleService(@NonNull Context context) { - super(context); - - mPlatformHelper = LocalManagerRegistry.getManager(RoleServicePlatformHelper.class); - - RoleControllerManager.initializeRemoteServiceComponentName(context); - - mAppOpsManager = context.getSystemService(AppOpsManager.class); - mUserManager = context.getSystemService(UserManager.class); - - LocalManagerRegistry.addManager(RoleManagerLocal.class, new Local()); - - registerUserRemovedReceiver(); - } - - private void registerUserRemovedReceiver() { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_USER_REMOVED); - getContext().registerReceiverForAllUsers(new BroadcastReceiver() { - @Override - public void onReceive(@NonNull Context context, @NonNull Intent intent) { - if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) { - int userId = intent.<UserHandle>getParcelableExtra(Intent.EXTRA_USER) - .getIdentifier(); - onRemoveUser(userId); - } - } - }, intentFilter, null, null); - } - - @Override - public void onStart() { - publishBinderService(Context.ROLE_SERVICE, new Stub()); - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); - intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); - intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); - intentFilter.addDataScheme("package"); - intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - getContext().registerReceiverForAllUsers(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - int userId = UserHandleCompat.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1)); - if (DEBUG) { - Log.i(LOG_TAG, "Packages changed - re-running initial grants for user " - + userId); - } - if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) - && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { - // Package is being upgraded - we're about to get ACTION_PACKAGE_ADDED - return; - } - maybeGrantDefaultRolesAsync(userId); - } - }, intentFilter, null, null); - } - - @Override - public void onUserStarting(@NonNull TargetUser user) { - maybeGrantDefaultRolesSync(user.getUserHandle().getIdentifier()); - } - - @MainThread - private void maybeGrantDefaultRolesSync(@UserIdInt int userId) { - AndroidFuture<Void> future = maybeGrantDefaultRolesInternal(userId); - try { - future.get(30, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - Log.e(LOG_TAG, "Failed to grant default roles for user " + userId, e); - } - } - - private void maybeGrantDefaultRolesAsync(@UserIdInt int userId) { - ThrottledRunnable runnable; - synchronized (mLock) { - runnable = mGrantDefaultRolesThrottledRunnables.get(userId); - if (runnable == null) { - runnable = new ThrottledRunnable(ForegroundThread.getHandler(), - GRANT_DEFAULT_ROLES_INTERVAL_MILLIS, - () -> maybeGrantDefaultRolesInternal(userId)); - mGrantDefaultRolesThrottledRunnables.put(userId, runnable); - } - } - runnable.run(); - } - - @AnyThread - @NonNull - private AndroidFuture<Void> maybeGrantDefaultRolesInternal(@UserIdInt int userId) { - RoleUserState userState = getOrCreateUserState(userId); - String oldPackagesHash = userState.getPackagesHash(); - String newPackagesHash = mPlatformHelper.computePackageStateHash(userId); - if (Objects.equals(oldPackagesHash, newPackagesHash)) { - if (DEBUG) { - Log.i(LOG_TAG, "Already granted default roles for packages hash " - + newPackagesHash); - } - return AndroidFuture.completedFuture(null); - } - - // Some package state has changed, so grant default roles again. - Log.i(LOG_TAG, "Granting default roles..."); - AndroidFuture<Void> future = new AndroidFuture<>(); - getOrCreateController(userId).grantDefaultRoles(ForegroundThread.getExecutor(), - successful -> { - if (successful) { - userState.setPackagesHash(newPackagesHash); - future.complete(null); - } else { - future.completeExceptionally(new RuntimeException()); - } - }); - return future; - } - - @NonNull - private RoleUserState getOrCreateUserState(@UserIdInt int userId) { - synchronized (mLock) { - RoleUserState userState = mUserStates.get(userId); - if (userState == null) { - userState = new RoleUserState(userId, mPlatformHelper, this); - mUserStates.put(userId, userState); - } - return userState; - } - } - - @NonNull - private RoleControllerManager getOrCreateController(@UserIdInt int userId) { - synchronized (mLock) { - RoleControllerManager controller = mControllers.get(userId); - if (controller == null) { - Context systemContext = getContext(); - Context context; - try { - context = systemContext.createPackageContextAsUser( - systemContext.getPackageName(), 0, UserHandle.of(userId)); - } catch (PackageManager.NameNotFoundException e) { - throw new RuntimeException(e); - } - controller = RoleControllerManager.createWithInitializedRemoteServiceComponentName( - ForegroundThread.getHandler(), context); - mControllers.put(userId, controller); - } - return controller; - } - } - - @Nullable - private RemoteCallbackList<IOnRoleHoldersChangedListener> getListeners(@UserIdInt int userId) { - synchronized (mLock) { - return mListeners.get(userId); - } - } - - @NonNull - private RemoteCallbackList<IOnRoleHoldersChangedListener> getOrCreateListeners( - @UserIdInt int userId) { - synchronized (mLock) { - RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = mListeners.get(userId); - if (listeners == null) { - listeners = new RemoteCallbackList<>(); - mListeners.put(userId, listeners); - } - return listeners; - } - } - - private void onRemoveUser(@UserIdInt int userId) { - RemoteCallbackList<IOnRoleHoldersChangedListener> listeners; - RoleUserState userState; - synchronized (mLock) { - mGrantDefaultRolesThrottledRunnables.remove(userId); - listeners = mListeners.get(userId); - mListeners.remove(userId); - mControllers.remove(userId); - userState = mUserStates.get(userId); - mUserStates.remove(userId); - } - if (listeners != null) { - listeners.kill(); - } - if (userState != null) { - userState.destroy(); - } - } - - @Override - public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) { - mListenerHandler.post(() -> notifyRoleHoldersChanged(roleName, userId)); - } - - @WorkerThread - private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) { - RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId); - if (listeners != null) { - notifyRoleHoldersChangedForListeners(listeners, roleName, userId); - } - - RemoteCallbackList<IOnRoleHoldersChangedListener> allUsersListeners = getListeners( - UserHandleCompat.USER_ALL); - if (allUsersListeners != null) { - notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId); - } - } - - @WorkerThread - private void notifyRoleHoldersChangedForListeners( - @NonNull RemoteCallbackList<IOnRoleHoldersChangedListener> listeners, - @NonNull String roleName, @UserIdInt int userId) { - int broadcastCount = listeners.beginBroadcast(); - try { - for (int i = 0; i < broadcastCount; i++) { - IOnRoleHoldersChangedListener listener = listeners.getBroadcastItem(i); - try { - listener.onRoleHoldersChanged(roleName, userId); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e); - } - } - } finally { - listeners.finishBroadcast(); - } - } - - private class Stub extends IRoleManager.Stub { - - @Override - public boolean isRoleAvailable(@NonNull String roleName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(getCallingUid()); - return getOrCreateUserState(userId).isRoleAvailable(roleName); - } - - @Override - public boolean isRoleHeld(@NonNull String roleName, @NonNull String packageName) { - int callingUid = getCallingUid(); - mAppOpsManager.checkPackage(callingUid, packageName); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(callingUid); - ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); - if (roleHolders == null) { - return false; - } - return roleHolders.contains(packageName); - } - - @NonNull - @Override - public List<String> getRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId) { - enforceCrossUserPermission(userId, false, "getRoleHoldersAsUser"); - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return Collections.emptyList(); - } - - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "getRoleHoldersAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - - ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); - if (roleHolders == null) { - return Collections.emptyList(); - } - return new ArrayList<>(roleHolders); - } - - @Override - public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull RemoteCallback callback) { - enforceCrossUserPermission(userId, false, "addRoleHolderAsUser"); - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "addRoleHolderAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - getOrCreateController(userId).onAddRoleHolder(roleName, packageName, flags, - callback); - } - - @Override - public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull RemoteCallback callback) { - enforceCrossUserPermission(userId, false, "removeRoleHolderAsUser"); - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "removeRoleHolderAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - getOrCreateController(userId).onRemoveRoleHolder(roleName, packageName, flags, - callback); - } - - @Override - public void clearRoleHoldersAsUser(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull RemoteCallback callback) { - enforceCrossUserPermission(userId, false, "clearRoleHoldersAsUser"); - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "clearRoleHoldersAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - getOrCreateController(userId).onClearRoleHolders(roleName, flags, callback); - } - - @Override - public void addOnRoleHoldersChangedListenerAsUser( - @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { - enforceCrossUserPermission(userId, true, "addOnRoleHoldersChangedListenerAsUser"); - if (userId != UserHandleCompat.USER_ALL && !isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - - getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, - "addOnRoleHoldersChangedListenerAsUser"); - - Objects.requireNonNull(listener, "listener cannot be null"); - - RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getOrCreateListeners( - userId); - listeners.register(listener); - } - - @Override - public void removeOnRoleHoldersChangedListenerAsUser( - @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { - enforceCrossUserPermission(userId, true, "removeOnRoleHoldersChangedListenerAsUser"); - if (userId != UserHandleCompat.USER_ALL && !isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - - getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, - "removeOnRoleHoldersChangedListenerAsUser"); - - Objects.requireNonNull(listener, "listener cannot be null"); - - RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId); - if (listener == null) { - return; - } - listeners.unregister(listener); - } - - @Override - public boolean isBypassingRoleQualification() { - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "isBypassingRoleQualification"); - synchronized (mLock) { - return mBypassingRoleQualification; - } - } - - @Override - public void setBypassingRoleQualification(boolean bypassRoleQualification) { - getContext().enforceCallingOrSelfPermission( - Manifest.permission.BYPASS_ROLE_QUALIFICATION, "setBypassingRoleQualification"); - synchronized (mLock) { - mBypassingRoleQualification = bypassRoleQualification; - } - } - - @Override - public void setRoleNamesFromController(@NonNull List<String> roleNames) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "setRoleNamesFromController"); - - Objects.requireNonNull(roleNames, "roleNames cannot be null"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - getOrCreateUserState(userId).setRoleNames(roleNames); - } - - @Override - public boolean addRoleHolderFromController(@NonNull String roleName, - @NonNull String packageName) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "addRoleHolderFromController"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - return getOrCreateUserState(userId).addRoleHolder(roleName, packageName); - } - - @Override - public boolean removeRoleHolderFromController(@NonNull String roleName, - @NonNull String packageName) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "removeRoleHolderFromController"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName); - } - - @Override - public List<String> getHeldRolesFromController(@NonNull String packageName) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "getRolesHeldFromController"); - - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - return getOrCreateUserState(userId).getHeldRoles(packageName); - } - - private boolean isUserExistent(@UserIdInt int userId) { - final long identity = Binder.clearCallingIdentity(); - try { - return mUserManager.getUserHandles(true).contains(UserHandle.of(userId)); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - private void enforceCrossUserPermission(@UserIdInt int userId, boolean allowAll, - @NonNull String message) { - final int callingUid = Binder.getCallingUid(); - final int callingUserId = UserHandleCompat.getUserId(callingUid); - if (userId == callingUserId) { - return; - } - Preconditions.checkArgument(userId >= UserHandleCompat.USER_SYSTEM - || (allowAll && userId == UserHandleCompat.USER_ALL), "Invalid user " + userId); - getContext().enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); - if (callingUid == Process.SHELL_UID && userId >= UserHandleCompat.USER_SYSTEM) { - if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_DEBUGGING_FEATURES, - UserHandle.of(userId))) { - throw new SecurityException("Shell does not have permission to access user " - + userId); - } - } - } - - @Override - public int handleShellCommand(@NonNull ParcelFileDescriptor in, - @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, - @NonNull String[] args) { - return new RoleShellCommand(this).exec(this, in.getFileDescriptor(), - out.getFileDescriptor(), err.getFileDescriptor(), args); - } - - @Nullable - @Override - public String getBrowserRoleHolder(@UserIdInt int userId) { - final int callingUid = Binder.getCallingUid(); - if (UserHandleCompat.getUserId(callingUid) != userId) { - getContext().enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - } - if (isInstantApp(callingUid)) { - return null; - } - - final long identity = Binder.clearCallingIdentity(); - try { - return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_BROWSER, - userId)); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - private boolean isInstantApp(int uid) { - final long identity = Binder.clearCallingIdentity(); - try { - final UserHandle user = UserHandle.getUserHandleForUid(uid); - final Context userContext = getContext().createContextAsUser(user, 0); - final PackageManager userPackageManager = userContext.getPackageManager(); - // Instant apps can not have shared UID, so it's safe to check only the first - // package name here. - final String packageName = ArrayUtils.firstOrNull( - userPackageManager.getPackagesForUid(uid)); - if (packageName == null) { - return false; - } - return userPackageManager.isInstantApp(packageName); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public boolean setBrowserRoleHolder(@Nullable String packageName, @UserIdInt int userId) { - final Context context = getContext(); - context.enforceCallingOrSelfPermission( - android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); - if (UserHandleCompat.getUserId(Binder.getCallingUid()) != userId) { - context.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - } - - if (!isUserExistent(userId)) { - return false; - } - - final AndroidFuture<Void> future = new AndroidFuture<>(); - final RemoteCallback callback = new RemoteCallback(result -> { - boolean successful = result != null; - if (successful) { - future.complete(null); - } else { - future.completeExceptionally(new RuntimeException()); - } - }); - final long identity = Binder.clearCallingIdentity(); - try { - if (packageName != null) { - addRoleHolderAsUser(RoleManager.ROLE_BROWSER, packageName, 0, userId, callback); - } else { - clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, userId, callback); - } - try { - future.get(5, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - Log.e(LOG_TAG, "Exception while setting default browser: " + packageName, e); - return false; - } - } finally { - Binder.restoreCallingIdentity(identity); - } - - return true; - } - - @Override - public String getSmsRoleHolder(int userId) { - enforceCrossUserPermission(userId, false, "getSmsRoleHolder"); - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return null; - } - - final long identity = Binder.clearCallingIdentity(); - try { - return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_SMS, - userId)); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, - @Nullable String[] args) { - if (!checkDumpPermission("role", fout)) { - return; - } - - boolean dumpAsProto = args != null && ArrayUtils.contains(args, "--proto"); - DualDumpOutputStream dumpOutputStream; - if (dumpAsProto) { - dumpOutputStream = new DualDumpOutputStream(new ProtoOutputStream( - new FileOutputStream(fd))); - } else { - fout.println("ROLE STATE (dumpsys role):"); - dumpOutputStream = new DualDumpOutputStream(new IndentingPrintWriter(fout, " ")); - } - - synchronized (mLock) { - final int userStatesSize = mUserStates.size(); - for (int i = 0; i < userStatesSize; i++) { - final RoleUserState userState = mUserStates.valueAt(i); - - userState.dump(dumpOutputStream, "user_states", - RoleServiceDumpProto.USER_STATES); - } - } - - dumpOutputStream.flush(); - } - - private boolean checkDumpPermission(@NonNull String serviceName, - @NonNull PrintWriter writer) { - if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - writer.println("Permission Denial: can't dump " + serviceName + " from from pid=" - + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() - + " due to missing " + android.Manifest.permission.DUMP + " permission"); - return false; - } else { - return true; - } - } - } - - private class Local implements RoleManagerLocal { - @NonNull - @Override - public Map<String, Set<String>> getRolesAndHolders(@UserIdInt int userId) { - // Convert ArrayMap<String, ArraySet<String>> to Map<String, Set<String>> for the API. - //noinspection unchecked - return (Map<String, Set<String>>) (Map<String, ?>) - getOrCreateUserState(userId).getRolesAndHolders(); - } - } -} |