Allow setting app op permissions to support

PackageInstaller.SessionParams#setPermisisonStates API.

This is the first part of the Permission & app op support of Fullscreen
Intent Protection that implements the actual grant/revocation of the FSI
permission/app op to back the new PackageInstaller#setPermissionStates
API.

Test: atest

Bug: 268092291
Change-Id: I8ff039a388796dc8cebf877f25e1f535aab6e006
This commit is contained in:
fayey
2023-02-09 21:44:32 +00:00
committed by Winson Chiu
parent c366288ac1
commit 0434c2a8b7
4 changed files with 49 additions and 22 deletions

View File

@@ -172,7 +172,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
private static final int ADB_DEV_MODE = PackageManager.INSTALL_FROM_ADB
| PackageManager.INSTALL_ALLOW_TEST;
private static final Set<String> ALLOWED_PERMISSION_STATE_NAMES = Set.of(
/**
* Set of app op permissions that the installer of a session is allowed to change through
* {@link PackageInstaller.SessionParams#setPermissionState(String, int)}.
*/
public static final Set<String> INSTALLER_CHANGEABLE_APP_OP_PERMISSIONS = Set.of(
Manifest.permission.USE_FULL_SCREEN_INTENT
);
@@ -809,7 +813,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
if (!hasInstallGrantRuntimePermissions) {
for (int index = 0; index < permissionStates.size(); index++) {
var permissionName = permissionStates.keyAt(index);
if (!ALLOWED_PERMISSION_STATE_NAMES.contains(permissionName)) {
if (!INSTALLER_CHANGEABLE_APP_OP_PERMISSIONS.contains(permissionName)) {
throw new SecurityException("You need the "
+ Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS
+ " permission to grant runtime permissions for a session");

View File

@@ -95,6 +95,7 @@ import java.util.function.BiFunction;
* Manages all permissions and handles permissions related tasks.
*/
public class PermissionManagerService extends IPermissionManager.Stub {
private static final String LOG_TAG = PermissionManagerService.class.getSimpleName();
/** Map of IBinder -> Running AttributionSource */

View File

@@ -20,6 +20,10 @@ import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
import static android.Manifest.permission.POST_NOTIFICATIONS;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DEFAULT;
import static android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED;
import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED;
@@ -63,6 +67,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.compat.annotation.ChangeId;
@@ -70,7 +75,6 @@ import android.compat.annotation.EnabledAfter;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PermissionGroupInfo;
@@ -129,6 +133,7 @@ import com.android.server.SystemConfig;
import com.android.server.Watchdog;
import com.android.server.pm.ApexManager;
import com.android.server.pm.KnownPackages;
import com.android.server.pm.PackageInstallerService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.parsing.PackageInfoUtils;
@@ -3633,8 +3638,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
}
private void grantRequestedRuntimePermissionsInternal(@NonNull AndroidPackage pkg,
@Nullable List<String> permissions, int userId) {
private void grantRequestedPermissionsInternal(@NonNull AndroidPackage pkg,
@Nullable ArrayMap<String, Integer> permissionStates, int userId) {
final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
| PackageManager.FLAG_PERMISSION_POLICY_FIXED;
@@ -3649,15 +3654,26 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
final int myUid = Process.myUid();
for (String permission : pkg.getRequestedPermissions()) {
final boolean shouldGrantPermission;
Integer permissionState = permissionStates.get(permission);
if (permissionState == null || permissionState == PERMISSION_STATE_DEFAULT) {
continue;
}
final boolean shouldGrantRuntimePermission;
final boolean isAppOpPermission;
synchronized (mLock) {
final Permission bp = mRegistry.getPermission(permission);
shouldGrantPermission = bp != null && (bp.isRuntime() || bp.isDevelopment())
if (bp == null) {
continue;
}
shouldGrantRuntimePermission = (bp.isRuntime() || bp.isDevelopment())
&& (!instantApp || bp.isInstant())
&& (supportsRuntimePermissions || !bp.isRuntimeOnly())
&& (permissions.contains(permission));
&& permissionState == PERMISSION_STATE_GRANTED;
isAppOpPermission = bp.isAppOp();
}
if (shouldGrantPermission) {
if (shouldGrantRuntimePermission) {
final int flags = getPermissionFlagsInternal(pkg.getPackageName(), permission,
myUid, userId);
if (supportsRuntimePermissions) {
@@ -3674,6 +3690,17 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
0, myUid, userId, false, mDefaultPermissionCallback);
}
}
} else if (isAppOpPermission
&& PackageInstallerService.INSTALLER_CHANGEABLE_APP_OP_PERMISSIONS
.contains(permission)) {
int mode =
permissionState == PERMISSION_STATE_GRANTED ? MODE_ALLOWED : MODE_ERRORED;
int uid = UserHandle.getUid(userId, pkg.getUid());
String appOp = AppOpsManager.permissionToOp(permission);
mHandler.post(() -> {
AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
appOpsManager.setUidMode(appOp, uid, mode);
});
}
}
}
@@ -4991,15 +5018,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
addAllowlistedRestrictedPermissionsInternal(pkg,
params.getAllowlistedRestrictedPermissions(),
FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
var grantedPermissions = new ArrayList<String>();
var permissionStates = params.getPermissionStates();
for (int index = 0; index < permissionStates.size(); index++) {
if (permissionStates.valueAt(index)
== PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED) {
grantedPermissions.add(permissionStates.keyAt(index));
}
}
grantRequestedRuntimePermissionsInternal(pkg, grantedPermissions, userId);
grantRequestedPermissionsInternal(pkg, params.getPermissionStates(), userId);
}
}

View File

@@ -72,6 +72,7 @@ import com.android.server.permission.access.util.hasAnyBit
import com.android.server.permission.access.util.hasBits
import com.android.server.permission.access.util.withClearedCallingIdentity
import com.android.server.pm.KnownPackages
import com.android.server.pm.PackageInstallerService
import com.android.server.pm.PackageManagerLocal
import com.android.server.pm.UserManagerInternal
import com.android.server.pm.UserManagerService
@@ -770,10 +771,12 @@ class PermissionService(
)
}
}
permission.isAppOp -> setAppOpPermissionGranted(
packageState, userId, permissionName,
permissionState == PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED
)
permission.isAppOp && permissionName in
PackageInstallerService.INSTALLER_CHANGEABLE_APP_OP_PERMISSIONS ->
setAppOpPermissionGranted(
packageState, userId, permissionName, permissionState ==
PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED
)
else -> {}
}
}