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

Commit c90f85e7 authored by Hai Zhang's avatar Hai Zhang
Browse files

Compute PermissionInfo.FLAG_INSTALLED instead of mutating ParsedPermission.

PermissionInfo.FLAG_INSTALLED is about the current system state
instead of the permission definition itself as in its APK, so we
shouldn't be mutating the ParsedPermission object to return it.

Instead, we now follow what we did for granted permissions and gather
and pass installed permissions similarly, so that we return the right
flag in PackageInfo.permissions.

For other methods returning PermissionInfo, they are all returning
permission definitions that are registered in the system, so we can
just unconditionally add FLAG_INSTALLED to them.

This resolves the issue when the new subsystem is enabled that
PermissionController refuses to manage a permission if its definition
doesn't have FLAG_INSTALLED.

Bug: 263504888
Test: manual
Change-Id: I891fa8b3adf7095a3c09ac448e1e377d432dafdc
parent ef3dd32c
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -1475,14 +1475,18 @@ public class ComputerEngine implements Computer {
            // Compute GIDs only if requested
            final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY
                    : mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.getAppId()));
            // Compute installed permissions only if requested
            final Set<String> installedPermissions = ((flags & PackageManager.GET_PERMISSIONS) == 0
                    || ArrayUtils.isEmpty(p.getPermissions())) ? Collections.emptySet()
                    : mPermissionManager.getInstalledPermissions(ps.getPackageName());
            // Compute granted permissions only if package has requested permissions
            final Set<String> permissions = ((flags & PackageManager.GET_PERMISSIONS) == 0
            final Set<String> grantedPermissions = ((flags & PackageManager.GET_PERMISSIONS) == 0
                    || ArrayUtils.isEmpty(p.getRequestedPermissions())) ? Collections.emptySet()
                    : mPermissionManager.getGrantedPermissions(ps.getPackageName(), userId);

            PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
                    state.getFirstInstallTimeMillis(), ps.getLastUpdateTime(), permissions, state,
                    userId, ps);
                    state.getFirstInstallTimeMillis(), ps.getLastUpdateTime(), installedPermissions,
                    grantedPermissions, state, userId, ps);

            if (packageInfo == null) {
                return null;
+13 −7
Original line number Diff line number Diff line
@@ -104,10 +104,11 @@ public class PackageInfoUtils {
    @Nullable
    public static PackageInfo generate(AndroidPackage pkg, int[] gids,
            @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
            long lastUpdateTime, Set<String> grantedPermissions, PackageUserStateInternal state,
            @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) {
            long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions,
            PackageUserStateInternal state, @UserIdInt int userId,
            @NonNull PackageStateInternal pkgSetting) {
        return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime,
                grantedPermissions, state, userId, pkgSetting);
                installedPermissions, grantedPermissions, state, userId, pkgSetting);
    }

    /**
@@ -115,8 +116,9 @@ public class PackageInfoUtils {
     */
    private static PackageInfo generateWithComponents(AndroidPackage pkg, int[] gids,
            @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
            long lastUpdateTime, Set<String> grantedPermissions, PackageUserStateInternal state,
            @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) {
            long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions,
            PackageUserStateInternal state, @UserIdInt int userId,
            @NonNull PackageStateInternal pkgSetting) {
        ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId,
                pkgSetting);
        if (applicationInfo == null) {
@@ -174,8 +176,12 @@ public class PackageInfoUtils {
            if (size > 0) {
                info.permissions = new PermissionInfo[size];
                for (int i = 0; i < size; i++) {
                    info.permissions[i] = generatePermissionInfo(pkg.getPermissions().get(i),
                            flags);
                    final var permission = pkg.getPermissions().get(i);
                    final var permissionInfo = generatePermissionInfo(permission, flags);
                    if (installedPermissions.contains(permission.getName())) {
                        permissionInfo.flags |= PermissionInfo.FLAG_INSTALLED;
                    }
                    info.permissions[i] = permissionInfo;
                }
            }
            final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
+2 −7
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.util.Log;
import android.util.Slog;

import com.android.server.pm.PackageManagerService;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.component.ParsedPermission;

@@ -215,10 +214,6 @@ public final class Permission {
                == PermissionInfo.PROTECTION_DANGEROUS;
    }

    public boolean isInstalled() {
        return (mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLED) != 0;
    }

    public boolean isRemoved() {
        return (mPermissionInfo.flags & PermissionInfo.FLAG_REMOVED) != 0;
    }
@@ -423,7 +418,6 @@ public final class Permission {
            if (packageState.isSystem()) {
                if (permission.mType == Permission.TYPE_CONFIG && !permission.mReconciled) {
                    // It's a built-in permission and no owner, take ownership now
                    permissionInfo.flags |= PermissionInfo.FLAG_INSTALLED;
                    permission.mPermissionInfo = permissionInfo;
                    permission.mReconciled = true;
                    permission.mUid = packageState.getAppId();
@@ -451,7 +445,6 @@ public final class Permission {
                final Permission tree = findPermissionTree(permissionTrees, permissionInfo.name);
                if (tree == null
                        || tree.mPermissionInfo.packageName.equals(permissionInfo.packageName)) {
                    permissionInfo.flags |= PermissionInfo.FLAG_INSTALLED;
                    permission.mPermissionInfo = permissionInfo;
                    permission.mReconciled = true;
                    permission.mUid = packageState.getAppId();
@@ -562,6 +555,8 @@ public final class Permission {
            permissionInfo.packageName = mPermissionInfo.packageName;
            permissionInfo.nonLocalizedLabel = mPermissionInfo.name;
        }
        // A Permission in PermissionRegistry is always installed.
        permissionInfo.flags |= PermissionInfo.FLAG_INSTALLED;
        if (targetSdkVersion >= Build.VERSION_CODES.O) {
            permissionInfo.protectionLevel = mPermissionInfo.protectionLevel;
        } else {
+5 −0
Original line number Diff line number Diff line
@@ -760,6 +760,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        }
        @NonNull
        @Override
        public Set<String> getInstalledPermissions(@NonNull String packageName) {
            return mPermissionManagerServiceImpl.getInstalledPermissions(packageName);
        }
        @NonNull
        @Override
        public Set<String> getGrantedPermissions(@NonNull String packageName,
                @UserIdInt int userId) {
            return mPermissionManagerServiceImpl.getGrantedPermissions(packageName, userId);
+15 −7
Original line number Diff line number Diff line
@@ -2345,9 +2345,6 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
        for (int i=0; i<N; i++) {
            ParsedPermission p = pkg.getPermissions().get(i);

            // Assume by default that we did not install this permission into the system.
            ComponentMutateUtils.setExactFlags(p, p.getFlags() & ~PermissionInfo.FLAG_INSTALLED);

            final PermissionInfo permissionInfo;
            final Permission oldPermission;
            synchronized (mLock) {
@@ -2384,10 +2381,6 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
                } else {
                    mRegistry.addPermission(permission);
                }
                if (permission.isInstalled()) {
                    ComponentMutateUtils.setExactFlags(p,
                            p.getFlags() | PermissionInfo.FLAG_INSTALLED);
                }
                if (permission.isDefinitionChanged()) {
                    definitionChangedPermissions.add(p.getName());
                    permission.setDefinitionChanged(false);
@@ -5141,6 +5134,21 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
        return isPermissionsReviewRequiredInternal(packageName, userId);
    }

    @NonNull
    @Override
    public Set<String> getInstalledPermissions(@NonNull String packageName) {
        Objects.requireNonNull(packageName, "packageName");
        final Set<String> installedPermissions = new ArraySet<>();
        synchronized (mLock) {
            for (final Permission permission : mRegistry.getPermissions()) {
                if (Objects.equals(permission.getPackageName(), packageName)) {
                    installedPermissions.add(permission.getName());
                }
            }
        }
        return installedPermissions;
    }

    @NonNull
    @Override
    public Set<String> getGrantedPermissions(@NonNull String packageName,
Loading