Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e287358 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I7f2729b3,I8ad30cd3

* changes:
  Fix users' permissions with bg mic/camera
  Don't exempt background mic / camera when device upgrades
parents 54c1598b 0684160d
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1272,7 +1272,12 @@ public final class DefaultPermissionGrantPolicy {
                    newFlags |= (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT);

                    // If we are allowlisting the permission, update the exempt flag before grant.
                    if (whitelistRestrictedPermissions && pm.isPermissionRestricted(permission)) {
                    // If the permission can't be allowlisted by an installer, skip it here because
                    // this is where the platform takes the role of the installer for exempting
                    // preinstalled apps.
                    if (whitelistRestrictedPermissions && pm.isPermissionRestricted(permission)
                            && !pm.getPermissionInfo(permission).isInstallerExemptIgnored()) {

                        pm.updatePermissionFlags(permission, pkg,
                                PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT,
                                PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, user);
+106 −0
Original line number Diff line number Diff line
@@ -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);

@@ -417,6 +424,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