Merge "Compute PermissionInfo.FLAG_INSTALLED instead of mutating ParsedPermission."

This commit is contained in:
Hai Zhang
2023-01-09 18:34:46 +00:00
committed by Android (Google) Code Review
10 changed files with 96 additions and 26 deletions

View File

@@ -1476,14 +1476,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;

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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,

View File

@@ -452,6 +452,18 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
*/
void writeLegacyPermissionStateTEMP();
/**
* Get all the permissions definitions from a package that's installed in the system.
* <p>
* A permission definition in a normal app may not be installed if it's overridden by the
* platform or system app that contains a conflicting definition after system upgrade.
*
* @param packageName the name of the package
* @return the names of the installed permissions
*/
@NonNull
Set<String> getInstalledPermissions(@NonNull String packageName);
/**
* Get all the permissions granted to a package.
*

View File

@@ -127,6 +127,19 @@ public interface PermissionManagerServiceInternal extends PermissionManagerInter
*/
void writeLegacyPermissionStateTEMP();
/**
* Get all the permissions definitions from a package that's installed in the system.
* <p>
* A permission definition in a normal app may not be installed if it's overridden by the
* platform or system app that contains a conflicting definition after system upgrade.
*
* @param packageName the name of the package
* @return the names of the installed permissions
*/
//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
@NonNull
Set<String> getInstalledPermissions(@NonNull String packageName);
/**
* Get all the permissions granted to a package.
*

View File

@@ -291,6 +291,13 @@ public class PermissionManagerServiceLoggingDecorator implements PermissionManag
mService.writeLegacyPermissionStateTEMP();
}
@NonNull
@Override
public Set<String> getInstalledPermissions(@NonNull String packageName) {
Log.i(LOG_TAG, "getInstalledPermissions(packageName = " + packageName + ")");
return mService.getInstalledPermissions(packageName);
}
@NonNull
@Override
public Set<String> getGrantedPermissions(@NonNull String packageName, int userId) {

View File

@@ -241,6 +241,9 @@ class PermissionService(
): PermissionInfo =
@Suppress("DEPRECATION")
PermissionInfo(permissionInfo).apply {
// All Permission objects are registered so the PermissionInfo generated for it should
// also have FLAG_INSTALLED.
this.flags = this.flags or PermissionInfo.FLAG_INSTALLED
if (!flags.hasBits(PackageManager.GET_META_DATA)) {
metaData = null
}
@@ -322,6 +325,21 @@ class PermissionService(
return permission.getGidsForUser(userId)
}
override fun getInstalledPermissions(packageName: String): Set<String> {
requireNotNull(packageName) { "packageName cannot be null" }
val permissions = service.getState {
with(policy) { getPermissions() }
}
return permissions.mapNotNullIndexedToSet { _, _, permission ->
if (permission.packageName == packageName) {
permission.name
} else {
null
}
}
}
override fun addPermission(permissionInfo: PermissionInfo, async: Boolean): Boolean {
val permissionName = permissionInfo.name
requireNotNull(permissionName) { "permissionName cannot be null" }

View File

@@ -780,9 +780,11 @@ public class PackageParserTest {
assertArrayEquals(a.getSplitFlags(), b.getSplitFlags());
PackageInfo aInfo = PackageInfoUtils.generate(a, new int[]{}, 0, 0, 0,
Collections.emptySet(), PackageUserStateInternal.DEFAULT, 0, mockPkgSetting(a));
Collections.emptySet(), Collections.emptySet(), PackageUserStateInternal.DEFAULT, 0,
mockPkgSetting(a));
PackageInfo bInfo = PackageInfoUtils.generate(b, new int[]{}, 0, 0, 0,
Collections.emptySet(), PackageUserStateInternal.DEFAULT, 0, mockPkgSetting(b));
Collections.emptySet(), Collections.emptySet(), PackageUserStateInternal.DEFAULT, 0,
mockPkgSetting(b));
assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo);
assertEquals(ArrayUtils.size(a.getPermissions()), ArrayUtils.size(b.getPermissions()));