summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java106
1 files changed, 106 insertions, 0 deletions
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 81e8c2286755..241cea7a45a3 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -70,11 +70,16 @@ import android.app.ApplicationPackageManager;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
+import android.app.role.RoleManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PermissionGroupInfoFlags;
import android.content.pm.PackageManager.PermissionInfoFlags;
@@ -84,6 +89,7 @@ import android.content.pm.PackageParser;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
+import android.content.pm.UserInfo;
import android.content.pm.parsing.component.ParsedPermission;
import android.content.pm.parsing.component.ParsedPermissionGroup;
import android.content.pm.permission.SplitPermissionInfoParcelable;
@@ -177,6 +183,7 @@ import java.util.function.Consumer;
*/
public class PermissionManagerService extends IPermissionManager.Stub {
private static final String TAG = "PackageManager";
+ private static final String LOG_TAG = PermissionManagerService.class.getSimpleName();
private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
@@ -420,6 +427,105 @@ public class PermissionManagerService extends IPermissionManager.Stub {
new PermissionManagerServiceInternalImpl();
LocalServices.addService(PermissionManagerServiceInternal.class, localService);
LocalServices.addService(PermissionManagerInternal.class, localService);
+
+ context.getMainThreadHandler().post(() -> context.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ return;
+ }
+
+ try {
+ fixBgMicCamera(context);
+ } catch (Throwable t) {
+ // Don't crash the system if this fails for any reason. Any intermediate state
+ // this can leave the permissions in is okay and in the worst case the state is
+ // the same as before the user rebooted.
+ Log.e(LOG_TAG, "Unable to fix background permissions", t);
+ }
+ }
+
+
+ private void fixBgMicCamera(Context context) {
+ PackageManager pm = context.getPackageManager();
+ for (UserInfo userInfo : context.getSystemService(UserManager.class).getUsers()) {
+ UserHandle user = userInfo.getUserHandle();
+ List<String> assistants = context.getSystemService(RoleManager.class)
+ .getRoleHoldersAsUser(RoleManager.ROLE_ASSISTANT, user);
+ List<PackageInfo> packages =
+ pm.getInstalledPackagesAsUser(PackageManager.MATCH_SYSTEM_ONLY
+ | PackageManager.GET_PERMISSIONS, user.getIdentifier());
+ for (PackageInfo packageInfo : packages) {
+ String[] requestedPermissions = packageInfo.requestedPermissions;
+ if (requestedPermissions == null) {
+ continue;
+ }
+ for (String permName : requestedPermissions) {
+ String pkg = packageInfo.packageName;
+ switch (permName) {
+ case Manifest.permission.BACKGROUND_CAMERA:
+ removeFromAllowlistsAndRevoke(pm, pkg, permName, user);
+ break;
+ case Manifest.permission.RECORD_BACKGROUND_AUDIO:
+ if (assistants.contains(pkg)) {
+ removeFromAllowlistsAndRevokeForAssistant(pm, pkg, permName,
+ user);
+ } else {
+ removeFromAllowlistsAndRevoke(pm, pkg, permName, user);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void removeFromAllowlistsAndRevoke(PackageManager pm, String pkg,
+ String permName, UserHandle user) {
+ if ((pm.getPermissionFlags(permName, pkg, user)
+ & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0) {
+ Slog.i(LOG_TAG, "removing " + pkg + " " + permName + " from all allowlists");
+ pm.removeWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_WHITELIST_UPGRADE);
+ pm.removeWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_WHITELIST_SYSTEM);
+ pm.removeWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_WHITELIST_INSTALLER);
+ pm.removeWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_ALLOWLIST_ROLE);
+ }
+ if (pm.checkPermission(permName, pkg) == PackageManager.PERMISSION_GRANTED) {
+ Slog.i(LOG_TAG, "revoking " + pkg + " " + permName);
+ pm.revokeRuntimePermission(pkg, permName, user);
+ }
+ }
+
+ private void removeFromAllowlistsAndRevokeForAssistant(PackageManager pm, String pkg,
+ String permName, UserHandle user) {
+ int anyNonRoleExempt =
+ FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT
+ | FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
+ | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+
+ if ((pm.getPermissionFlags(permName, pkg, user) & anyNonRoleExempt) != 0) {
+ Slog.i(LOG_TAG, "removing " + pkg + " " + permName
+ + " from all allowlists except role");
+ pm.removeWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_WHITELIST_UPGRADE);
+ pm.removeWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_WHITELIST_SYSTEM);
+ pm.removeWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_WHITELIST_INSTALLER);
+ }
+ if ((pm.getPermissionFlags(permName, pkg, user)
+ & FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT) == 0) {
+ Slog.i(LOG_TAG, "adding " + pkg + " " + permName
+ + " to role allowlist");
+ pm.addWhitelistedRestrictedPermission(pkg, permName,
+ FLAG_PERMISSION_ALLOWLIST_ROLE);
+ }
+ }
+ }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED)));
}
@Override