diff options
11 files changed, 518 insertions, 513 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 34437afb614a..3642d318e820 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -30,6 +30,7 @@ import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.UserIdInt; import android.annotation.XmlRes; +import android.app.role.RoleManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; @@ -2306,20 +2307,14 @@ public class ApplicationPackageManager extends PackageManager { @Override public String getDefaultBrowserPackageNameAsUser(int userId) { - try { - return mPermissionManager.getDefaultBrowser(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + return roleManager.getBrowserRoleHolder(userId); } @Override public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) { - try { - return mPermissionManager.setDefaultBrowser(packageName, userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + return roleManager.setBrowserRoleHolder(packageName, userId); } @Override diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl index 6d790b381ace..5fc25f0422e2 100644 --- a/core/java/android/app/role/IRoleManager.aidl +++ b/core/java/android/app/role/IRoleManager.aidl @@ -53,5 +53,9 @@ interface IRoleManager { List<String> getHeldRolesFromController(in String packageName); - String getDefaultSmsPackage(int userId); + String getBrowserRoleHolder(int userId); + + boolean setBrowserRoleHolder(String packageName, int userId); + + String getSmsRoleHolder(int userId); } diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java index 408ce0f2ab1a..8b2e07b09701 100644 --- a/core/java/android/app/role/RoleManager.java +++ b/core/java/android/app/role/RoleManager.java @@ -613,12 +613,56 @@ public final class RoleManager { } /** - * Allows getting the role holder for {@link #ROLE_SMS} without - * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as required by - * {@link android.provider.Telephony.Sms#getDefaultSmsPackage(Context)} + * Get the role holder of {@link #ROLE_BROWSER} without requiring + * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as in + * {@link android.content.pm.PackageManager#getDefaultBrowserPackageNameAsUser(int)} + * + * @param userId the user ID + * @return the package name of the default browser, or {@code null} if none + * + * @hide + */ + @Nullable + //@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public String getBrowserRoleHolder(@UserIdInt int userId) { + try { + return mService.getBrowserRoleHolder(userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Set the role holder of {@link #ROLE_BROWSER} requiring + * {@link Manifest.permission.SET_PREFERRED_APPLICATIONS} instead of + * {@link Manifest.permission#MANAGE_ROLE_HOLDERS}, as in + * {@link android.content.pm.PackageManager#setDefaultBrowserPackageNameAsUser(String, int)} + * + * @param packageName the package name of the default browser, or {@code null} if none + * @param userId the user ID + * @return whether the default browser was set successfully + * + * @hide + */ + @Nullable + @RequiresPermission(Manifest.permission.SET_PREFERRED_APPLICATIONS) + //@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public boolean setBrowserRoleHolder(@Nullable String packageName, @UserIdInt int userId) { + try { + return mService.setBrowserRoleHolder(packageName, userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Allows getting the role holder for {@link #ROLE_SMS} without requiring + * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as in + * {@link android.provider.Telephony.Sms#getDefaultSmsPackage(Context)}. + * + * @param userId the user ID to get the default SMS package for + * @return the package name of the default SMS app, or {@code null} if none * - * @param userId The user ID to get the default SMS package for. - * @return the package name of the default SMS app, or {@code null} if not configured. * @hide */ @Nullable @@ -626,7 +670,7 @@ public final class RoleManager { @TestApi public String getSmsRoleHolder(@UserIdInt int userId) { try { - return mService.getDefaultSmsPackage(userId); + return mService.getSmsRoleHolder(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl index 100166814975..9855a9a98cfb 100644 --- a/core/java/android/permission/IPermissionManager.aidl +++ b/core/java/android/permission/IPermissionManager.aidl @@ -73,10 +73,6 @@ interface IPermissionManager { void resetRuntimePermissions(); - boolean setDefaultBrowser(String packageName, int userId); - - String getDefaultBrowser(int userId); - void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId); void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId); diff --git a/core/java/android/permission/PermissionManagerInternal.java b/core/java/android/permission/PermissionManagerInternal.java index 3134ec06fe50..71674311965c 100644 --- a/core/java/android/permission/PermissionManagerInternal.java +++ b/core/java/android/permission/PermissionManagerInternal.java @@ -21,10 +21,6 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.os.UserHandle; -import com.android.internal.util.function.TriFunction; - -import java.util.function.BiFunction; - /** * Internal interfaces to be used by other components within the system server. * @@ -50,33 +46,6 @@ public abstract class PermissionManagerInternal { @UserIdInt int userId); } - /** Interface to override permission checks via composition */ - public interface CheckPermissionDelegate { - /** - * Checks whether the given package has been granted the specified permission. - * - * @return If the package has the permission, PERMISSION_GRANTED is - * returned. If it does not have the permission, PERMISSION_DENIED - * is returned. - * - * @see android.content.pm.PackageManager#checkPermission(String, String) - */ - int checkPermission(String permName, String pkgName, int userId, - TriFunction<String, String, Integer, Integer> superImpl); - - /** - /** - * Checks whether the given uid has been granted the specified permission. - * - * @return If the package has the permission, PERMISSION_GRANTED is - * returned. If it does not have the permission, PERMISSION_DENIED - * is returned. - * - */ - int checkUidPermission(String permName, int uid, - BiFunction<String, Integer, Integer> superImpl); - } - /** * Get the state of the runtime permissions as xml file. * diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 63128ced8f93..bcd122d33f7d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -265,7 +265,6 @@ import android.os.UserManager; import android.os.WorkSource; import android.os.storage.IStorageManager; import android.os.storage.StorageManager; -import android.permission.PermissionManagerInternal.CheckPermissionDelegate; import android.provider.DeviceConfig; import android.provider.Settings; import android.server.ServerProtoEnums; @@ -326,7 +325,6 @@ import com.android.internal.util.MemInfoReader; import com.android.internal.util.Preconditions; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.QuadFunction; -import com.android.internal.util.function.TriFunction; import com.android.server.AlarmManagerInternal; import com.android.server.AttributeCache; import com.android.server.DeviceIdleInternal; @@ -394,7 +392,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; -import java.util.function.BiFunction; public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { @@ -14486,7 +14483,7 @@ public class ActivityManagerService extends IActivityManager.Stub mAppOpsService.setMode(AppOpsManager.OP_NO_ISOLATED_STORAGE, app.uid, app.info.packageName, AppOpsManager.MODE_ERRORED); mAppOpsService.setAppOpsServiceDelegate(null); - getPermissionManagerInternalLocked().setCheckPermissionDelegate(null); + getPermissionManagerInternalLocked().stopShellPermissionIdentityDelegation(); mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG, instr.mUiAutomationConnection).sendToTarget(); } @@ -17201,12 +17198,6 @@ public class ActivityManagerService extends IActivityManager.Stub // We allow delegation only to one instrumentation started from the shell synchronized (ActivityManagerService.this) { - // If there is a delegate it should be the same instance for app ops and permissions. - if (mAppOpsService.getAppOpsServiceDelegate() - != getPermissionManagerInternalLocked().getCheckPermissionDelegate()) { - throw new IllegalStateException("Bad shell delegate state"); - } - // If the delegate is already set up for the target UID, nothing to do. if (mAppOpsService.getAppOpsServiceDelegate() != null) { if (!(mAppOpsService.getAppOpsServiceDelegate() instanceof ShellDelegate)) { @@ -17235,10 +17226,14 @@ public class ActivityManagerService extends IActivityManager.Stub } // Hook them up... - final ShellDelegate shellDelegate = new ShellDelegate( - instr.mTargetInfo.packageName, delegateUid, permissions); + final ShellDelegate shellDelegate = new ShellDelegate(delegateUid, + permissions); mAppOpsService.setAppOpsServiceDelegate(shellDelegate); - getPermissionManagerInternalLocked().setCheckPermissionDelegate(shellDelegate); + final String packageName = instr.mTargetInfo.packageName; + final List<String> permissionNames = permissions != null ? + Arrays.asList(permissions) : null; + getPermissionManagerInternalLocked().startShellPermissionIdentityDelegation( + delegateUid, packageName, permissionNames); return; } } @@ -17252,17 +17247,15 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized (ActivityManagerService.this) { mAppOpsService.setAppOpsServiceDelegate(null); - getPermissionManagerInternalLocked().setCheckPermissionDelegate(null); + getPermissionManagerInternalLocked().stopShellPermissionIdentityDelegation(); } } - private class ShellDelegate implements CheckOpsDelegate, CheckPermissionDelegate { - private final String mTargetPackageName; + private class ShellDelegate implements CheckOpsDelegate { private final int mTargetUid; private @Nullable String[] mPermissions; - ShellDelegate(String targetPackageName, int targetUid, @Nullable String[] permissions) { - mTargetPackageName = targetPackageName; + ShellDelegate(int targetUid, @Nullable String[] permissions) { mTargetUid = targetUid; mPermissions = permissions; } @@ -17325,34 +17318,6 @@ public class ActivityManagerService extends IActivityManager.Stub message, shouldCollectMessage); } - @Override - public int checkPermission(String permName, String pkgName, int userId, - TriFunction<String, String, Integer, Integer> superImpl) { - if (mTargetPackageName.equals(pkgName) && isTargetPermission(permName)) { - final long identity = Binder.clearCallingIdentity(); - try { - return superImpl.apply(permName, "com.android.shell", userId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - return superImpl.apply(permName, pkgName, userId); - } - - @Override - public int checkUidPermission(String permName, int uid, - BiFunction<String, Integer, Integer> superImpl) { - if (uid == mTargetUid && isTargetPermission(permName)) { - final long identity = Binder.clearCallingIdentity(); - try { - return superImpl.apply(permName, Process.SHELL_UID); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - return superImpl.apply(permName, uid); - } - private boolean isTargetOp(int code) { // null permissions means all ops are targeted if (mPermissions == null) { diff --git a/services/core/java/com/android/server/pm/DefaultAppProvider.java b/services/core/java/com/android/server/pm/DefaultAppProvider.java new file mode 100644 index 000000000000..cc11fb2c00bd --- /dev/null +++ b/services/core/java/com/android/server/pm/DefaultAppProvider.java @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2020 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.server.pm; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.app.role.RoleManager; +import android.os.Binder; +import android.os.UserHandle; +import android.util.Slog; + +import com.android.internal.infra.AndroidFuture; +import com.android.internal.util.CollectionUtils; +import com.android.server.FgThread; +import com.android.server.pm.permission.PermissionManagerServiceInternal; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * Interacts with {@link RoleManager} to provide and manage default apps. + */ +public class DefaultAppProvider { + @NonNull + private final Supplier<RoleManager> mRoleManagerSupplier; + @NonNull + private final PermissionManagerServiceInternal mPermissionManager; + + /** + * Create a new instance of this class + * + * @param roleManagerSupplier the supplier for {@link RoleManager} + * @param permissionManager the {@link PermissionManagerServiceInternal} + */ + public DefaultAppProvider(@NonNull Supplier<RoleManager> roleManagerSupplier, @NonNull + PermissionManagerServiceInternal permissionManager) { + mRoleManagerSupplier = roleManagerSupplier; + mPermissionManager = permissionManager; + } + + /** + * Get the package name of the default browser. + * + * @param userId the user ID + * @return the package name of the default browser, or {@code null} if none + */ + @Nullable + public String getDefaultBrowser(@UserIdInt int userId) { + return getRoleHolder(RoleManager.ROLE_BROWSER, userId); + } + + /** + * Set the package name of the default browser. + * + * @param packageName package name of the default browser, or {@code null} to unset + * @param async whether the operation should be asynchronous + * @param doGrant whether to grant default permissions + * @param userId the user ID + * @return whether the default browser was successfully set. + */ + public boolean setDefaultBrowser(@Nullable String packageName, boolean async, boolean doGrant, + @UserIdInt int userId) { + if (userId == UserHandle.USER_ALL) { + return false; + } + final RoleManager roleManager = mRoleManagerSupplier.get(); + if (roleManager == null) { + return false; + } + final UserHandle user = UserHandle.of(userId); + final Executor executor = FgThread.getExecutor(); + final AndroidFuture<Void> future = new AndroidFuture<>(); + final Consumer<Boolean> callback = successful -> { + if (successful) { + future.complete(null); + } else { + future.completeExceptionally(new RuntimeException()); + } + }; + final long identity = Binder.clearCallingIdentity(); + try { + if (packageName != null) { + roleManager.addRoleHolderAsUser(RoleManager.ROLE_BROWSER, packageName, 0, user, + executor, callback); + } else { + roleManager.clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, user, executor, + callback); + } + if (!async) { + try { + future.get(5, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Slog.e(PackageManagerService.TAG, "Exception while setting default browser: " + + packageName, e); + return false; + } + } + if (doGrant && packageName != null) { + mPermissionManager.grantDefaultPermissionsToDefaultBrowser(packageName, userId); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + return true; + } + + /** + * Get the package name of the default dialer. + * + * @param userId the user ID + * @return the package name of the default dialer, or {@code null} if none + */ + @Nullable + public String getDefaultDialer(@NonNull int userId) { + return getRoleHolder(RoleManager.ROLE_DIALER, userId); + } + + /** + * Get the package name of the default home. + * + * @param userId the user ID + * @return the package name of the default home, or {@code null} if none + */ + @Nullable + public String getDefaultHome(@NonNull int userId) { + return getRoleHolder(RoleManager.ROLE_HOME, userId); + } + + /** + * Set the package name of the default home. + * + * @param packageName package name of the default home + * @param userId the user ID + * @param executor the {@link Executor} to execute callback on + * @param callback the callback made after the default home as been updated + * @return whether the default home was set + */ + public boolean setDefaultHome(@NonNull String packageName, @UserIdInt int userId, + @NonNull Executor executor, @NonNull Consumer<Boolean> callback) { + final RoleManager roleManager = mRoleManagerSupplier.get(); + if (roleManager == null) { + return false; + } + final long identity = Binder.clearCallingIdentity(); + try { + roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, packageName, 0, + UserHandle.of(userId), executor, callback); + } finally { + Binder.restoreCallingIdentity(identity); + } + return true; + } + + @Nullable + private String getRoleHolder(@NonNull String roleName, @NonNull int userId) { + final RoleManager roleManager = mRoleManagerSupplier.get(); + if (roleManager == null) { + return null; + } + final long identity = Binder.clearCallingIdentity(); + try { + return CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser(roleName, + UserHandle.of(userId))); + } finally { + Binder.restoreCallingIdentity(identity); + } + } +} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9a0be06b914e..cd4fe5723a83 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -152,6 +152,7 @@ import android.app.ResourcesManager; import android.app.admin.IDevicePolicyManager; import android.app.admin.SecurityLog; import android.app.backup.IBackupManager; +import android.app.role.RoleManager; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.BroadcastReceiver; @@ -940,6 +941,7 @@ public class PackageManagerService extends IPackageManager.Stub private final Singleton<ViewCompiler> mViewCompilerProducer; private final Singleton<IPermissionManager> mPermissionManagerProducer; private final Singleton<IncrementalManager> mIncrementalManagerProducer; + private final Singleton<DefaultAppProvider> mDefaultAppProviderProducer; private final SystemWrapper mSystemWrapper; private final ServiceProducer mGetLocalServiceProducer; private final ServiceProducer mGetSystemServiceProducer; @@ -961,6 +963,7 @@ public class PackageManagerService extends IPackageManager.Stub Producer<IPermissionManager> permissionManagerProducer, Producer<ViewCompiler> viewCompilerProducer, Producer<IncrementalManager> incrementalManagerProducer, + Producer<DefaultAppProvider> defaultAppProviderProducer, SystemWrapper systemWrapper, ServiceProducer getLocalServiceProducer, ServiceProducer getSystemServiceProducer) { @@ -985,6 +988,7 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManagerProducer = new Singleton<>(permissionManagerProducer); mViewCompilerProducer = new Singleton<>(viewCompilerProducer); mIncrementalManagerProducer = new Singleton<>(incrementalManagerProducer); + mDefaultAppProviderProducer = new Singleton<>(defaultAppProviderProducer); mSystemWrapper = systemWrapper; mGetLocalServiceProducer = getLocalServiceProducer; mGetSystemServiceProducer = getSystemServiceProducer; @@ -1097,6 +1101,10 @@ public class PackageManagerService extends IPackageManager.Stub public IncrementalManager getIncrementalManager() { return mIncrementalManagerProducer.get(this, mPackageManager); } + + public DefaultAppProvider getDefaultAppProvider() { + return mDefaultAppProviderProducer.get(this, mPackageManager); + } } /** Provides an abstraction to static access to system state. */ @@ -1154,6 +1162,7 @@ public class PackageManagerService extends IPackageManager.Stub public ArtManagerService artManagerService; public @Nullable String configuratorPackage; public int defParseFlags; + public DefaultAppProvider defaultAppProvider; public DexManager dexManager; public List<ScanPartition> dirsToScanAsSystem; public @Nullable String documenterPackage; @@ -1307,6 +1316,8 @@ public class PackageManagerService extends IPackageManager.Stub private final IncrementalManager mIncrementalManager; + private final DefaultAppProvider mDefaultAppProvider; + private final PackageProperty mPackageProperty = new PackageProperty(); private static class IFVerificationParams { @@ -2769,6 +2780,8 @@ public class PackageManagerService extends IPackageManager.Stub (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()), (i, pm) -> (IncrementalManager) pm.mContext.getSystemService(Context.INCREMENTAL_SERVICE), + (i, pm) -> new DefaultAppProvider(() -> context.getSystemService(RoleManager.class), + i.getPermissionManagerServiceInternal()), new DefaultSystemWrapper(), LocalServices::getService, context::getSystemService); @@ -2944,6 +2957,7 @@ public class PackageManagerService extends IPackageManager.Stub mArtManagerService = testParams.artManagerService; mAvailableFeatures = testParams.availableFeatures; mDefParseFlags = testParams.defParseFlags; + mDefaultAppProvider = testParams.defaultAppProvider; mDexManager = testParams.dexManager; mDirsToScanAsSystem = testParams.dirsToScanAsSystem; mFactoryTest = testParams.factoryTest; @@ -3051,6 +3065,7 @@ public class PackageManagerService extends IPackageManager.Stub mSettings = injector.getSettings(); mPermissionManagerService = injector.getPermissionManagerService(); mIncrementalManager = mInjector.getIncrementalManager(); + mDefaultAppProvider = mInjector.getDefaultAppProvider(); PlatformCompat platformCompat = mInjector.getCompatibility(); mPackageParserCallback = new PackageParser2.Callback() { @Override @@ -7964,8 +7979,8 @@ public class PackageManagerService extends IPackageManager.Stub } else { // Browser/generic handling case. If there's a default browser, go straight // to that (but only if there is no other higher-priority match). - final String defaultBrowserPackageName = - mPermissionManager.getDefaultBrowser(userId); + final String defaultBrowserPackageName = mDefaultAppProvider.getDefaultBrowser( + userId); int maxMatchPrio = 0; ResolveInfo defaultBrowserMatch = null; final int numCandidates = matchAllList.size(); @@ -14162,8 +14177,8 @@ public class PackageManagerService extends IPackageManager.Stub final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId); final long callingId = Binder.clearCallingIdentity(); try { - final String activeLauncherPackageName = mPermissionManager.getDefaultHome(userId); - final String dialerPackageName = mPermissionManager.getDefaultDialer(userId); + final String activeLauncherPackageName = mDefaultAppProvider.getDefaultHome(userId); + final String dialerPackageName = mDefaultAppProvider.getDefaultDialer(userId); for (int i = 0; i < packageNames.length; i++) { canSuspend[i] = false; final String packageName = packageNames[i]; @@ -20621,10 +20636,10 @@ public class PackageManagerService extends IPackageManager.Stub } private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) { - final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId); + final String defaultBrowserPackageName = mDefaultAppProvider.getDefaultBrowser(userId); if (!TextUtils.isEmpty(defaultBrowserPackageName)) { if (packageName.equals(defaultBrowserPackageName)) { - mPermissionManager.setDefaultBrowser(null, true, true, userId); + mDefaultAppProvider.setDefaultBrowser(null, true, true, userId); } } } @@ -20639,7 +20654,7 @@ public class PackageManagerService extends IPackageManager.Stub // If this browser is restored from user's backup, do not clear // default-browser state for this user if (installReason != PackageManager.INSTALL_REASON_DEVICE_RESTORE) { - mPermissionManager.setDefaultBrowser(null, true, true, userId); + mDefaultAppProvider.setDefaultBrowser(null, true, true, userId); } } @@ -20678,7 +20693,7 @@ public class PackageManagerService extends IPackageManager.Stub // significant refactoring to keep all default apps in the package // manager (cleaner but more work) or have the services provide // callbacks to the package manager to request a default app reset. - mPermissionManager.setDefaultBrowser(null, true, true, userId); + mDefaultAppProvider.setDefaultBrowser(null, true, true, userId); resetNetworkPolicies(userId); synchronized (mLock) { scheduleWritePackageRestrictionsLocked(userId); @@ -20912,8 +20927,8 @@ public class PackageManagerService extends IPackageManager.Stub defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1); } if (defaultBrowser != null) { - mPermissionManager - .setDefaultBrowser(defaultBrowser, false, false, userId1); + mDefaultAppProvider.setDefaultBrowser(defaultBrowser, false, false, + userId1); } }); } catch (Exception e) { @@ -21153,7 +21168,7 @@ public class PackageManagerService extends IPackageManager.Stub } allHomeCandidates.addAll(resolveInfos); - final String packageName = mPermissionManager.getDefaultHome(userId); + final String packageName = mDefaultAppProvider.getDefaultHome(userId); if (packageName == null) { return null; } @@ -21207,7 +21222,7 @@ public class PackageManagerService extends IPackageManager.Stub final String packageName = preferredResolveInfo != null && preferredResolveInfo.activityInfo != null ? preferredResolveInfo.activityInfo.packageName : null; - final String currentPackageName = mPermissionManager.getDefaultHome(userId); + final String currentPackageName = mDefaultAppProvider.getDefaultHome(userId); if (TextUtils.equals(currentPackageName, packageName)) { return false; } @@ -21222,12 +21237,12 @@ public class PackageManagerService extends IPackageManager.Stub // Keep the default home package in RoleManager. return false; } - mPermissionManager.setDefaultHome(packageName, userId, (successful) -> { - if (successful) { - postPreferredActivityChangedBroadcast(userId); - } - }); - return true; + return mDefaultAppProvider.setDefaultHome(packageName, userId, mContext.getMainExecutor(), + successful -> { + if (successful) { + postPreferredActivityChangedBroadcast(userId); + } + }); } @Override @@ -24977,7 +24992,7 @@ public class PackageManagerService extends IPackageManager.Stub private String[] getKnownPackageNamesInternal(int knownPackage, int userId) { switch (knownPackage) { case PackageManagerInternal.PACKAGE_BROWSER: - return new String[]{mPermissionManager.getDefaultBrowser(userId)}; + return new String[] { mDefaultAppProvider.getDefaultBrowser(userId) }; case PackageManagerInternal.PACKAGE_INSTALLER: return filterOnlySystemPackages(mRequiredInstallerPackage); case PackageManagerInternal.PACKAGE_SETUP_WIZARD: diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 48e18f1b8b38..7ed887d9680a 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -114,7 +114,6 @@ import android.permission.IPermissionManager; import android.permission.PermissionControllerManager; import android.permission.PermissionManager; import android.permission.PermissionManagerInternal; -import android.permission.PermissionManagerInternal.CheckPermissionDelegate; import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener; import android.text.TextUtils; import android.util.ArrayMap; @@ -138,6 +137,7 @@ import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.IntPair; import com.android.internal.util.Preconditions; +import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.FgThread; import com.android.server.LocalServices; @@ -151,9 +151,6 @@ import com.android.server.pm.UserManagerInternal; import com.android.server.pm.UserManagerService; import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; -import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider; -import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider; -import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.SoftRestrictedPermissionPolicy; @@ -176,7 +173,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.Consumer; +import java.util.function.BiFunction; /** * Manages all permissions and handles permissions related tasks. @@ -304,15 +301,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { @NonNull private final OnPermissionChangeListeners mOnPermissionChangeListeners; - @GuardedBy("mLock") - private DefaultBrowserProvider mDefaultBrowserProvider; - - @GuardedBy("mLock") - private DefaultDialerProvider mDefaultDialerProvider; - - @GuardedBy("mLock") - private DefaultHomeProvider mDefaultHomeProvider; - // TODO: Take a look at the methods defined in the callback. // The callback was initially created to support the split between permission // manager and the package manager. However, it's started to be used for other @@ -2018,60 +2006,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override - public String getDefaultBrowser(int userId) { - final int callingUid = Binder.getCallingUid(); - if (UserHandle.getUserId(callingUid) != userId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - } - if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { - return null; - } - DefaultBrowserProvider provider; - synchronized (mLock) { - provider = mDefaultBrowserProvider; - } - return provider != null ? provider.getDefaultBrowser(userId) : null; - } - - @Override - public boolean setDefaultBrowser(String packageName, int userId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); - if (UserHandle.getCallingUserId() != userId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - } - return setDefaultBrowserInternal(packageName, false, true, userId); - } - - private boolean setDefaultBrowserInternal(String packageName, boolean async, - boolean doGrant, int userId) { - if (userId == UserHandle.USER_ALL) { - return false; - } - DefaultBrowserProvider provider; - synchronized (mLock) { - provider = mDefaultBrowserProvider; - } - if (provider == null) { - return false; - } - if (async) { - provider.setDefaultBrowserAsync(packageName, userId); - } else { - if (!provider.setDefaultBrowser(packageName, userId)) { - return false; - } - } - if (doGrant && packageName != null) { - mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName, - userId); - } - return true; - } - - @Override public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { final int callingUid = Binder.getCallingUid(); PackageManagerServiceUtils @@ -2360,6 +2294,32 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } + private void startShellPermissionIdentityDelegationInternal(int uid, + @NonNull String packageName, @Nullable List<String> permissionNames) { + synchronized (mLock) { + final CheckPermissionDelegate oldDelegate = mCheckPermissionDelegate; + if (oldDelegate != null && oldDelegate.getDelegatedUid() != uid) { + throw new SecurityException( + "Shell can delegate permissions only to one UID at a time"); + } + final ShellDelegate delegate = new ShellDelegate(uid, packageName, permissionNames); + setCheckPermissionDelegateLocked(delegate); + } + } + + private void stopShellPermissionIdentityDelegationInternal() { + synchronized (mLock) { + setCheckPermissionDelegateLocked(null); + } + } + + private void setCheckPermissionDelegateLocked(@Nullable CheckPermissionDelegate delegate) { + if (delegate != null || mCheckPermissionDelegate != null) { + PackageManager.invalidatePackageInfoCache(); + } + mCheckPermissionDelegate = delegate; + } + /** * If the app is updated, and has scoped storage permissions, then it is possible that the * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. @@ -5233,62 +5193,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override - public CheckPermissionDelegate getCheckPermissionDelegate() { - synchronized (mLock) { - return mCheckPermissionDelegate; - } - } - - @Override - public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) { - synchronized (mLock) { - if (delegate != null || mCheckPermissionDelegate != null) { - PackageManager.invalidatePackageInfoCache(); - } - mCheckPermissionDelegate = delegate; - } - } - - @Override - public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) { - synchronized (mLock) { - mDefaultBrowserProvider = provider; - } - } - - @Override - public void setDefaultBrowser(String packageName, boolean async, boolean doGrant, - int userId) { - setDefaultBrowserInternal(packageName, async, doGrant, userId); - } - - @Override - public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) { - synchronized (mLock) { - mDefaultDialerProvider = provider; - } - } - - @Override - public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) { - synchronized (mLock) { - mDefaultHomeProvider = provider; - } + public void startShellPermissionIdentityDelegation(int uid, @NonNull String packageName, + @Nullable List<String> permissionNames) { + Objects.requireNonNull(packageName, "packageName"); + startShellPermissionIdentityDelegationInternal(uid, packageName, permissionNames); } @Override - public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) { - if (userId == UserHandle.USER_ALL) { - return; - } - DefaultHomeProvider provider; - synchronized (mLock) { - provider = mDefaultHomeProvider; - } - if (provider == null) { - return; - } - provider.setDefaultHomeAsync(packageName, userId, callback); + public void stopShellPermissionIdentityDelegation() { + stopShellPermissionIdentityDelegationInternal(); } @Override @@ -5332,30 +5245,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override - public String getDefaultBrowser(int userId) { - DefaultBrowserProvider provider; - synchronized (mLock) { - provider = mDefaultBrowserProvider; - } - return provider != null ? provider.getDefaultBrowser(userId) : null; - } - - @Override - public String getDefaultDialer(int userId) { - DefaultDialerProvider provider; - synchronized (mLock) { - provider = mDefaultDialerProvider; - } - return provider != null ? provider.getDefaultDialer(userId) : null; - } - - @Override - public String getDefaultHome(int userId) { - DefaultHomeProvider provider; - synchronized (mLock) { - provider = mDefaultHomeProvider; - } - return provider != null ? provider.getDefaultHome(userId) : null; + public void grantDefaultPermissionsToDefaultBrowser(@NonNull String packageName, + @UserIdInt int userId) { + mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName, + userId); } @Override @@ -5545,6 +5438,102 @@ public class PermissionManagerService extends IPermissionManager.Stub { } /** + * Interface to intercept permission checks and optionally pass through to the original + * implementation. + */ + private interface CheckPermissionDelegate { + /** + * Get the UID whose permission checks is being delegated. + * + * @return the UID + */ + int getDelegatedUid(); + + /** + * Check whether the given package has been granted the specified permission. + * + * @param permissionName the name of the permission to be checked + * @param packageName the name of the package to be checked + * @param userId the user ID + * @param superImpl the original implementation that can be delegated to + * @return {@link android.content.pm.PackageManager.PERMISSION_GRANTED} if the package has + * the permission, or {@link android.content.pm.PackageManager.PERMISSION_DENITED} otherwise + * + * @see android.content.pm.PackageManager#checkPermission(String, String) + */ + int checkPermission(@NonNull String permissionName, @NonNull String packageName, + @UserIdInt int userId, + @NonNull TriFunction<String, String, Integer, Integer> superImpl); + + /** + * Check whether the given UID has been granted the specified permission. + * + * @param permissionName the name of the permission to be checked + * @param uid the UID to be checked + * @param superImpl the original implementation that can be delegated to + * @return {@link android.content.pm.PackageManager.PERMISSION_GRANTED} if the package has + * the permission, or {@link android.content.pm.PackageManager.PERMISSION_DENITED} otherwise + */ + int checkUidPermission(@NonNull String permissionName, int uid, + BiFunction<String, Integer, Integer> superImpl); + } + + private class ShellDelegate implements CheckPermissionDelegate { + private final int mDelegatedUid; + @NonNull + private final String mDelegatedPackageName; + @Nullable + private final List<String> mDelegatedPermissionNames; + + public ShellDelegate(int delegatedUid, @NonNull String delegatedPackageName, + @Nullable List<String> delegatedPermissionNames) { + mDelegatedUid = delegatedUid; + mDelegatedPackageName = delegatedPackageName; + mDelegatedPermissionNames = delegatedPermissionNames; + } + + @Override + public int getDelegatedUid() { + return mDelegatedUid; + } + + @Override + public int checkPermission(@NonNull String permissionName, @NonNull String packageName, + int userId, @NonNull TriFunction<String, String, Integer, Integer> superImpl) { + if (mDelegatedPackageName.equals(packageName) + && isDelegatedPermission(permissionName)) { + final long identity = Binder.clearCallingIdentity(); + try { + return superImpl.apply(permissionName, "com.android.shell", userId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + return superImpl.apply(permissionName, packageName, userId); + } + + @Override + public int checkUidPermission(@NonNull String permissionName, int uid, + @NonNull BiFunction<String, Integer, Integer> superImpl) { + if (uid == mDelegatedUid && isDelegatedPermission(permissionName)) { + final long identity = Binder.clearCallingIdentity(); + try { + return superImpl.apply(permissionName, Process.SHELL_UID); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + return superImpl.apply(permissionName, uid); + } + + private boolean isDelegatedPermission(@NonNull String permissionName) { + // null permissions means all permissions are targeted + return mDelegatedPermissionNames == null + || mDelegatedPermissionNames.contains(permissionName); + } + } + + /** * Allows injection of services and method responses to facilitate testing. * * <p>Test classes can create a mock of this class and pass it to the PermissionManagerService diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java index f924651f1051..e006fa784cce 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -30,7 +30,6 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.function.Consumer; /** * Internal interfaces services. @@ -66,82 +65,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager String[] getPackages(String authority, int userId); } - /** - * Provider for default browser - */ - public interface DefaultBrowserProvider { - - /** - * Get the package name of the default browser. - * - * @param userId the user id - * - * @return the package name of the default browser, or {@code null} if none - */ - @Nullable - String getDefaultBrowser(@UserIdInt int userId); - - /** - * Set the package name of the default browser. - * - * @param packageName package name of the default browser, or {@code null} to remove - * @param userId the user id - * - * @return whether the default browser was successfully set. - */ - boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId); - - /** - * Set the package name of the default browser asynchronously. - * - * @param packageName package name of the default browser, or {@code null} to remove - * @param userId the user id - */ - void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId); - } - - /** - * Provider for default dialer - */ - public interface DefaultDialerProvider { - - /** - * Get the package name of the default dialer. - * - * @param userId the user id - * - * @return the package name of the default dialer, or {@code null} if none - */ - @Nullable - String getDefaultDialer(@UserIdInt int userId); - } - - /** - * Provider for default home - */ - public interface DefaultHomeProvider { - - /** - * Get the package name of the default home. - * - * @param userId the user id - * - * @return the package name of the default home, or {@code null} if none - */ - @Nullable - String getDefaultHome(@UserIdInt int userId); - - /** - * Set the package name of the default home. - * - * @param packageName package name of the default home, or {@code null} to remove - * @param userId the user id - * @param callback the callback made after the default home as been updated - */ - void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId, - @NonNull Consumer<Boolean> callback); - } - public abstract void systemReady(); /** @@ -257,18 +180,24 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @PermissionInfo.ProtectionFlags int protectionFlags); /** - * Returns the delegate used to influence permission checking. + * Start delegate the permission identity of the shell UID to the given UID. * - * @return The delegate instance. + * @param uid the UID to delegate shell permission identity to + * @param packageName the name of the package to delegate shell permission identity to + * @param permissionNames the names of the permissions to delegate shell permission identity + * for, or {@code null} for all permissions */ - public abstract @Nullable CheckPermissionDelegate getCheckPermissionDelegate(); + //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) + public abstract void startShellPermissionIdentityDelegation(int uid, + @NonNull String packageName, @Nullable List<String> permissionNames); /** - * Sets the delegate used to influence permission checking. + * Stop delegating the permission identity of the shell UID. * - * @param delegate A delegate instance or {@code null} to clear. + * @see #startShellPermissionIdentityDelegation(int, String, List) */ - public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate); + //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) + public abstract void stopShellPermissionIdentityDelegation(); /** * Sets the dialer application packages provider. @@ -319,69 +248,12 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider); /** - * Sets the default browser provider. - * - * @param provider the provider - */ - public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider); - - /** - * Sets the package name of the default browser provider for the given user. - * - * @param packageName The package name of the default browser or {@code null} - * to clear the default browser - * @param async If {@code true}, set the default browser asynchronously, - * otherwise set it synchronously - * @param doGrant If {@code true} and if {@code packageName} is not {@code null}, - * perform default permission grants on the browser, otherwise skip the - * default permission grants. - * @param userId The user to set the default browser for. - */ - public abstract void setDefaultBrowser(@Nullable String packageName, boolean async, - boolean doGrant, @UserIdInt int userId); - - /** - * Sets the default dialer provider. - * - * @param provider the provider - */ - public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider); - - /** - * Sets the default home provider. - * - * @param provider the provider - */ - public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider); - - /** - * Asynchronously sets the package name of the default home provider for the given user. - * - * @param packageName The package name of the default home or {@code null} - * to clear the default browser - * @param userId The user to set the default browser for - * @param callback Invoked after the default home has been set - */ - public abstract void setDefaultHome(@Nullable String packageName, @UserIdInt int userId, - @NonNull Consumer<Boolean> callback); - - /** - * Returns the default browser package name for the given user. - */ - @Nullable - public abstract String getDefaultBrowser(@UserIdInt int userId); - - /** - * Returns the default dialer package name for the given user. - */ - @Nullable - public abstract String getDefaultDialer(@UserIdInt int userId); - - /** - * Returns the default home package name for the given user. + * Requests granting of the default permissions to the current default browser. + * @param packageName The default browser package name. + * @param userId The user for which to grant the permissions. */ - @Nullable - public abstract String getDefaultHome(@UserIdInt int userId); + public abstract void grantDefaultPermissionsToDefaultBrowser( + @NonNull String packageName, @UserIdInt int userId); /** * Requests granting of the default permissions to the current default Use Open Wifi app. diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java index ab6ada2f85f7..3d91a8502097 100644 --- a/services/core/java/com/android/server/role/RoleManagerService.java +++ b/services/core/java/com/android/server/role/RoleManagerService.java @@ -83,7 +83,6 @@ import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.Consumer; /** * Service for role management. @@ -162,12 +161,6 @@ public class RoleManagerService extends SystemService implements RoleUserState.C LocalServices.addService(RoleManagerInternal.class, new Internal()); - PermissionManagerServiceInternal permissionManagerInternal = - LocalServices.getService(PermissionManagerServiceInternal.class); - permissionManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider()); - permissionManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider()); - permissionManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider()); - registerUserRemovedReceiver(); } @@ -657,12 +650,84 @@ public class RoleManagerService extends SystemService implements RoleUserState.C resultReceiver); } + @Nullable @Override - public String getDefaultSmsPackage(int userId) { + public String getBrowserRoleHolder(@UserIdInt int userId) { + final int callingUid = Binder.getCallingUid(); + if (UserHandle.getUserId(callingUid) != userId) { + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + } + final PackageManagerInternal packageManager = LocalServices.getService( + PackageManagerInternal.class); + if (packageManager.getInstantAppPackageName(callingUid) != null) { + return null; + } + final long identity = Binder.clearCallingIdentity(); try { - return CollectionUtils.firstOrNull( - getRoleHoldersAsUser(RoleManager.ROLE_SMS, userId)); + return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_BROWSER, + userId)); + } 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 (UserHandle.getCallingUserId() != userId) { + context.enforceCallingOrSelfPermission( + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + } + + if (!mUserManagerInternal.exists(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) { + Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e); + return false; + } + + if (packageName != null) { + final PermissionManagerServiceInternal permissionManager = + LocalServices.getService(PermissionManagerServiceInternal.class); + permissionManager.grantDefaultPermissionsToDefaultBrowser(packageName, userId); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + + return true; + } + + @Override + public String getSmsRoleHolder(int userId) { + final long identity = Binder.clearCallingIdentity(); + try { + return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_SMS, + userId)); } finally { Binder.restoreCallingIdentity(identity); } @@ -718,100 +783,4 @@ public class RoleManagerService extends SystemService implements RoleUserState.C return getOrCreateUserState(userId).getRolesAndHolders(); } } - - private class DefaultBrowserProvider implements - PermissionManagerServiceInternal.DefaultBrowserProvider { - - @Nullable - @Override - public String getDefaultBrowser(@UserIdInt int userId) { - return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders( - RoleManager.ROLE_BROWSER)); - } - - @Override - public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) { - AndroidFuture<Void> future = new AndroidFuture<>(); - RemoteCallback callback = new RemoteCallback(result -> { - boolean successful = result != null; - if (successful) { - future.complete(null); - } else { - future.completeExceptionally(new RuntimeException()); - } - }); - if (packageName != null) { - getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, - packageName, 0, callback); - } else { - getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, - callback); - } - try { - future.get(5, TimeUnit.SECONDS); - return true; - } catch (InterruptedException | ExecutionException | TimeoutException e) { - Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e); - return false; - } - } - - @Override - public void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId) { - RemoteCallback callback = new RemoteCallback(result -> { - boolean successful = result != null; - if (!successful) { - Slog.e(LOG_TAG, "Failed to set default browser: " + packageName); - } - }); - if (packageName != null) { - getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, - packageName, 0, callback); - } else { - getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0, - callback); - } - } - } - - private class DefaultDialerProvider implements - PermissionManagerServiceInternal.DefaultDialerProvider { - - @Nullable - @Override - public String getDefaultDialer(@UserIdInt int userId) { - return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders( - RoleManager.ROLE_DIALER)); - } - } - - private class DefaultHomeProvider implements - PermissionManagerServiceInternal.DefaultHomeProvider { - - @Nullable - @Override - public String getDefaultHome(@UserIdInt int userId) { - return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders( - RoleManager.ROLE_HOME)); - } - - @Override - public void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId, - @NonNull Consumer<Boolean> callback) { - RemoteCallback remoteCallback = new RemoteCallback(result -> { - boolean successful = result != null; - if (!successful) { - Slog.e(LOG_TAG, "Failed to set default home: " + packageName); - } - callback.accept(successful); - }); - if (packageName != null) { - getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_HOME, - packageName, 0, remoteCallback); - } else { - getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_HOME, 0, - remoteCallback); - } - } - } } |