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

Commit 9382a751 authored by Nino Jagar's avatar Nino Jagar Committed by Android (Google) Code Review
Browse files

Merge "Allow app protection role to uninstall packages" into main

parents 9317ba87 59e33304
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -302,3 +302,10 @@ flag {
    bug: "332664521"
    is_fixed_read_only: true
}

flag {
    name: "delete_packages_silently_backport"
    namespace: "package_manager_service"
    description: "Feature flag to enable the holder of SYSTEM_APP_PROTECTION_SERVICE role to silently delete packages. To be deprecated by delete_packages_silently."
    bug: "361776825"
}
+33 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.app.PendingIntent;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.role.RoleManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
@@ -201,6 +202,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            Manifest.permission.USE_FULL_SCREEN_INTENT
    );

    private static final String ROLE_SYSTEM_APP_PROTECTION_SERVICE =
            "android.app.role.SYSTEM_APP_PROTECTION_SERVICE";

    final PackageArchiver mPackageArchiver;

    private final Context mContext;
@@ -1454,6 +1458,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                    .createEvent(DevicePolicyEnums.UNINSTALL_PACKAGE)
                    .setAdmin(callerPackageName)
                    .write();
        } else if (isSystemAppProtectionRoleHolder(snapshot, userId, callingUid)) {
            // Allow the SYSTEM_APP_PROTECTION_SERVICE role holder to silently uninstall, with a
            // clean calling identity to get DELETE_PACKAGES permission
            Binder.withCleanCallingIdentity(() ->
                    mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags)
            );
        } else {
            ApplicationInfo appInfo = snapshot.getApplicationInfo(callerPackageName, 0, userId);
            if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
@@ -1475,6 +1485,29 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        }
    }

    private Boolean isSystemAppProtectionRoleHolder(
            @NonNull Computer snapshot, int userId, int callingUid) {
        if (!Flags.deletePackagesSilentlyBackport()) {
            return false;
        }
        String holderPackageName = Binder.withCleanCallingIdentity(() -> {
            RoleManager roleManager = mPm.mContext.getSystemService(RoleManager.class);
            if (roleManager == null) {
                return null;
            }
            List<String> holders = roleManager.getRoleHoldersAsUser(
                    ROLE_SYSTEM_APP_PROTECTION_SERVICE, UserHandle.of(userId));
            if (holders.isEmpty()) {
                return null;
            }
            return holders.get(0);
        });
        if (holderPackageName == null) {
            return false;
        }
        return snapshot.getPackageUid(holderPackageName, /* flags= */ 0, userId) == callingUid;
    }

    @Override
    public void uninstallExistingPackage(VersionedPackage versionedPackage,
            String callerPackageName, IntentSender statusReceiver, int userId) {