diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2020-09-22 22:18:40 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-09-22 22:18:40 +0000 |
| commit | fbffe3f137dfcd10f0166ed41c446ac7fc7fa4d3 (patch) | |
| tree | df3691be0d065683daf99010ca0bb8c30c1aa1eb | |
| parent | cc848e93c1f97ff7ff2a12d8f7fa727b89932e84 (diff) | |
| parent | 36744c716794df4b64f3975f165a2d7b2299316d (diff) | |
Merge "Refactor PermissionsState to be a data class for migration."
11 files changed, 591 insertions, 1189 deletions
diff --git a/core/java/android/util/IntArray.java b/core/java/android/util/IntArray.java index 5a74ec0e52c0..b77265b0ebf6 100644 --- a/core/java/android/util/IntArray.java +++ b/core/java/android/util/IntArray.java @@ -144,6 +144,17 @@ public class IntArray implements Cloneable { } /** + * Adds the values in the specified array to this array. + */ + public void addAll(int[] values) { + final int count = values.length; + ensureCapacity(count); + + System.arraycopy(values, 0, mValues, mSize, count); + mSize += count; + } + + /** * Ensures capacity to append at least <code>count</code> values. */ private void ensureCapacity(int count) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 697c31a78ec7..16424d214995 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1849,7 +1849,6 @@ public class PackageManagerService extends IPackageManager.Stub Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); synchronized (mLock) { removeMessages(WRITE_PACKAGE_LIST); - mPermissionManager.writeStateToPackageSettingsTEMP(); mSettings.writePackageListLPr(msg.arg1); } Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); @@ -2686,7 +2685,8 @@ public class PackageManagerService extends IPackageManager.Stub (i, pm) -> new Settings(Environment.getDataDirectory(), i.getPermissionManagerServiceInternal().getPermissionSettings(), - RuntimePermissionsPersistence.createInstance(), lock), + RuntimePermissionsPersistence.createInstance(), + i.getPermissionManagerServiceInternal(), lock), new Injector.LocalServicesProducer<>(ActivityTaskManagerInternal.class), new Injector.LocalServicesProducer<>(ActivityManagerInternal.class), new Injector.LocalServicesProducer<>(DeviceIdleInternal.class), @@ -4486,8 +4486,8 @@ public class PackageManagerService extends IPackageManager.Stub AndroidPackage p = ps.pkg; if (p != null) { // Compute GIDs only if requested - final int[] gids = (flags & PackageManager.GET_GIDS) == 0 - ? EMPTY_INT_ARRAY : mPermissionManager.getPackageGids(ps.name, userId); + final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY + : mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId)); // Compute granted permissions only if package has requested permissions final Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions()) ? Collections.emptySet() @@ -4962,13 +4962,13 @@ public class PackageManagerService extends IPackageManager.Stub } // TODO: Shouldn't this be checking for package installed state for userId and // return null? - return mPermissionManager.getPackageGids(packageName, userId); + return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId)); } if ((flags & MATCH_KNOWN_PACKAGES) != 0) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps != null && ps.isMatch(flags) && !shouldFilterApplicationLocked(ps, callingUid, userId)) { - return mPermissionManager.getPackageGids(packageName, userId); + return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId)); } } } @@ -18983,7 +18983,7 @@ public class PackageManagerService extends IPackageManager.Stub } if ((deletedPs.sharedUser == null || deletedPs.sharedUser.packages.size() == 0) && !isUpdatedSystemApp(deletedPs)) { - mPermissionManager.removePermissionsStateTEMP(removedAppId); + mPermissionManager.removeAppIdStateTEMP(removedAppId); } mPermissionManager.updatePermissions(deletedPs.name, null); if (deletedPs.sharedUser != null) { @@ -21854,8 +21854,6 @@ public class PackageManagerService extends IPackageManager.Stub protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; - mPermissionManager.writeStateToPackageSettingsTEMP(); - DumpState dumpState = new DumpState(); boolean fullPreferred = false; boolean checkin = false; @@ -23734,7 +23732,6 @@ public class PackageManagerService extends IPackageManager.Stub mDirtyUsers.remove(userId); mUserNeedsBadging.delete(userId); mPermissionManager.onUserRemoved(userId); - mPermissionManager.writeStateToPackageSettingsTEMP(); mSettings.removeUserLPw(userId); mPendingBroadcasts.remove(userId); mInstantAppRegistry.onUserRemovedLPw(userId); diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index 276f88082df0..855a5ff524fd 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -28,7 +28,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.server.pm.parsing.pkg.AndroidPackage; -import com.android.server.pm.permission.PermissionsState; +import com.android.server.pm.permission.AppIdPermissionState; import com.android.server.pm.pkg.PackageStateUnserialized; import java.io.File; @@ -215,7 +215,7 @@ public class PackageSetting extends PackageSettingBase { } @Override - public PermissionsState getPermissionsState() { + public AppIdPermissionState getPermissionsState() { return (sharedUser != null) ? sharedUser.getPermissionsState() : super.getPermissionsState(); diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java index 3e2ab05e83ec..c1258b1efd48 100644 --- a/services/core/java/com/android/server/pm/SettingBase.java +++ b/services/core/java/com/android/server/pm/SettingBase.java @@ -19,23 +19,23 @@ package com.android.server.pm; import android.content.pm.ApplicationInfo; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.pm.permission.PermissionsState; +import com.android.server.pm.permission.AppIdPermissionState; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public abstract class SettingBase { int pkgFlags; int pkgPrivateFlags; - protected final PermissionsState mPermissionsState; + protected final AppIdPermissionState mPermissionsState; SettingBase(int pkgFlags, int pkgPrivateFlags) { setFlags(pkgFlags); setPrivateFlags(pkgPrivateFlags); - mPermissionsState = new PermissionsState(); + mPermissionsState = new AppIdPermissionState(); } SettingBase(SettingBase orig) { - mPermissionsState = new PermissionsState(); + mPermissionsState = new AppIdPermissionState(); doCopy(orig); } @@ -49,7 +49,7 @@ public abstract class SettingBase { mPermissionsState.copyFrom(orig.mPermissionsState); } - public PermissionsState getPermissionsState() { + public AppIdPermissionState getPermissionsState() { return mPermissionsState; } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 965430727d3c..bae36b2ad353 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -79,6 +79,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; +import android.util.IntArray; import android.util.Log; import android.util.LogPrinter; import android.util.Pair; @@ -106,10 +107,11 @@ import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; +import com.android.server.pm.permission.AppIdPermissionState; +import com.android.server.pm.permission.AppIdPermissionState.PermissionState; import com.android.server.pm.permission.BasePermission; +import com.android.server.pm.permission.LegacyPermissionDataProvider; import com.android.server.pm.permission.PermissionSettings; -import com.android.server.pm.permission.PermissionsState; -import com.android.server.pm.permission.PermissionsState.PermissionState; import com.android.server.utils.TimingsTraceAndSlog; import libcore.io.IoUtils; @@ -416,9 +418,12 @@ public final class Settings { private final File mSystemDir; public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages); + /** Settings and other information about permissions */ final PermissionSettings mPermissions; + private final LegacyPermissionDataProvider mPermissionDataProvider; + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) public Settings(Map<String, PackageSetting> pkgSettings) { mLock = new Object(); @@ -426,6 +431,7 @@ public final class Settings { mSystemDir = null; mPermissions = null; mRuntimePermissionsPersistence = null; + mPermissionDataProvider = null; mSettingsFilename = null; mBackupSettingsFilename = null; mPackageListFilename = null; @@ -434,12 +440,14 @@ public final class Settings { mKernelMappingFilename = null; } - Settings(File dataDir, PermissionSettings permission, - RuntimePermissionsPersistence runtimePermissionsPersistence, Object lock) { + Settings(File dataDir, PermissionSettings permissionSettings, + RuntimePermissionsPersistence runtimePermissionsPersistence, + LegacyPermissionDataProvider permissionDataProvider, Object lock) { mLock = lock; - mPermissions = permission; + mPermissions = permissionSettings; mRuntimePermissionsPersistence = new RuntimePermissionPersistence( - runtimePermissionsPersistence, mLock); + runtimePermissionsPersistence); + mPermissionDataProvider = permissionDataProvider; mSystemDir = new File(dataDir, "system"); mSystemDir.mkdirs(); @@ -1239,7 +1247,7 @@ public final class Settings { void writeAllRuntimePermissionsLPr() { for (int userId : UserManagerService.getInstance().getUserIds()) { - mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId); + mRuntimePermissionsPersistence.writeStateForUserAsyncLPr(userId); } } @@ -2102,7 +2110,7 @@ public final class Settings { } void readInstallPermissionsLPr(XmlPullParser parser, - PermissionsState permissionsState) throws IOException, XmlPullParserException { + AppIdPermissionState permissionsState) throws IOException, XmlPullParserException { int outerDepth = parser.getDepth(); int type; while ((type=parser.next()) != XmlPullParser.END_DOCUMENT @@ -2131,25 +2139,7 @@ public final class Settings { final int flags = (flagsStr != null) ? Integer.parseInt(flagsStr, 16) : 0; - if (granted) { - if (permissionsState.grantInstallPermission(bp) == - PermissionsState.PERMISSION_OPERATION_FAILURE) { - Slog.w(PackageManagerService.TAG, "Permission already added: " + name); - XmlUtils.skipCurrentTag(parser); - } else { - permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, - PackageManager.MASK_PERMISSION_FLAGS_ALL, flags); - } - } else { - if (permissionsState.revokeInstallPermission(bp) == - PermissionsState.PERMISSION_OPERATION_FAILURE) { - Slog.w(PackageManagerService.TAG, "Permission already added: " + name); - XmlUtils.skipCurrentTag(parser); - } else { - permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, - PackageManager.MASK_PERMISSION_FLAGS_ALL, flags); - } - } + permissionsState.putInstallPermissionState(new PermissionState(bp, granted, flags)); } else { Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: " + parser.getName()); @@ -2158,7 +2148,7 @@ public final class Settings { } } - void writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates) + void writePermissionsLPr(XmlSerializer serializer, Collection<PermissionState> permissionStates) throws IOException { if (permissionStates.isEmpty()) { return; @@ -2641,7 +2631,11 @@ public final class Settings { } final boolean isDebug = pkg.pkg.isDebuggable(); - final int[] gids = pkg.getPermissionsState().computeGids(userIds); + final IntArray gids = new IntArray(); + for (final int userId : userIds) { + gids.addAll(mPermissionDataProvider.getGidsForUid(UserHandle.getUid(userId, + pkg.appId))); + } // Avoid any application that has a space in its path. if (dataPath.indexOf(' ') >= 0) @@ -2673,11 +2667,12 @@ public final class Settings { sb.append(" "); sb.append(AndroidPackageUtils.getSeInfo(pkg.pkg, pkg)); sb.append(" "); - if (gids != null && gids.length > 0) { - sb.append(gids[0]); - for (int i = 1; i < gids.length; i++) { + final int gidsSize = gids.size(); + if (gids != null && gids.size() > 0) { + sb.append(gids.get(0)); + for (int i = 1; i < gidsSize; i++) { sb.append(","); - sb.append(gids[i]); + sb.append(gids.get(i)); } } else { sb.append("none"); @@ -4482,8 +4477,9 @@ public final class Settings { } void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, - ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, - Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) { + ArraySet<String> permissionNames, PackageSetting ps, + AppIdPermissionState permissionsState, SimpleDateFormat sdf, Date date, + List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) { AndroidPackage pkg = ps.pkg; if (checkinTag != null) { pw.print(checkinTag); @@ -4810,7 +4806,6 @@ public final class Settings { } if (ps.sharedUser == null || permissionNames != null || dumpAll) { - PermissionsState permissionsState = ps.getPermissionsState(); dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState); } @@ -4889,8 +4884,8 @@ public final class Settings { } if (ps.sharedUser == null) { - PermissionsState permissionsState = ps.getPermissionsState(); - dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id)); + dumpGidsLPr(pw, prefix + " ", mPermissionDataProvider.getGidsForUid( + UserHandle.getUid(user.id, ps.appId))); dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState .getRuntimePermissionStates(user.id), dumpAll); } @@ -4933,8 +4928,10 @@ public final class Settings { && !packageName.equals(ps.name)) { continue; } + final AppIdPermissionState permissionsState = + mPermissionDataProvider.getAppIdPermissionState(ps.appId); if (permissionNames != null - && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) { + && !permissionsState.hasPermissionState(permissionNames)) { continue; } @@ -4948,8 +4945,8 @@ public final class Settings { pw.println("Packages:"); printedSomething = true; } - dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users, - packageName != null, dumpAllComponents); + dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, permissionsState, + sdf, date, users, packageName != null, dumpAllComponents); } printedSomething = false; @@ -4989,8 +4986,10 @@ public final class Settings { pw.println("Hidden system packages:"); printedSomething = true; } - dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date, - users, packageName != null, dumpAllComponents); + final AppIdPermissionState permissionsState = + mPermissionDataProvider.getAppIdPermissionState(ps.appId); + dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, + permissionsState, sdf, date, users, packageName != null, dumpAllComponents); } } } @@ -5018,8 +5017,10 @@ public final class Settings { if (packageName != null && su != dumpState.getSharedUser()) { continue; } + final AppIdPermissionState permissionsState = + mPermissionDataProvider.getAppIdPermissionState(su.userId); if (permissionNames != null - && !su.getPermissionsState().hasRequestedPermission(permissionNames)) { + && !permissionsState.hasPermissionState(permissionNames)) { continue; } if (!checkin) { @@ -5054,12 +5055,12 @@ public final class Settings { continue; } - final PermissionsState permissionsState = su.getPermissionsState(); dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState); for (int userId : UserManagerService.getInstance().getUserIds()) { - final int[] gids = permissionsState.computeGids(userId); - final List<PermissionState> permissions = + final int[] gids = mPermissionDataProvider.getGidsForUid(UserHandle.getUid( + userId, su.userId)); + final Collection<PermissionState> permissions = permissionsState.getRuntimePermissionStates(userId); if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) { pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": "); @@ -5120,7 +5121,7 @@ public final class Settings { } void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, - List<PermissionState> permissionStates, boolean dumpAll) { + Collection<PermissionState> permissionStates, boolean dumpAll) { if (!permissionStates.isEmpty() || dumpAll) { pw.print(prefix); pw.println("runtime permissions:"); for (PermissionState permissionState : permissionStates) { @@ -5161,8 +5162,9 @@ public final class Settings { } void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, - PermissionsState permissionsState) { - List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates(); + AppIdPermissionState permissionsState) { + Collection<PermissionState> permissionStates = + permissionsState.getInstallPermissionStates(); if (!permissionStates.isEmpty()) { pw.print(prefix); pw.println("install permissions:"); for (PermissionState permissionState : permissionStates) { @@ -5202,9 +5204,9 @@ public final class Settings { public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) { if (sync) { - mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId); + mRuntimePermissionsPersistence.writeStateForUserSyncLPr(userId); } else { - mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId); + mRuntimePermissionsPersistence.writeStateForUserAsyncLPr(userId); } } @@ -5292,8 +5294,6 @@ public final class Settings { private final Handler mHandler = new MyHandler(); - private final Object mPersistenceLock; - @GuardedBy("mLock") private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray(); @@ -5313,10 +5313,8 @@ public final class Settings { // The mapping keys are user ids. private final SparseBooleanArray mPermissionUpgradeNeeded = new SparseBooleanArray(); - public RuntimePermissionPersistence(RuntimePermissionsPersistence persistence, - Object persistenceLock) { + public RuntimePermissionPersistence(RuntimePermissionsPersistence persistence) { mPersistence = persistence; - mPersistenceLock = persistenceLock; } @GuardedBy("Settings.this.mLock") @@ -5327,7 +5325,7 @@ public final class Settings { @GuardedBy("Settings.this.mLock") void setVersionLPr(int version, int userId) { mVersions.put(userId, version); - writePermissionsForUserAsyncLPr(userId); + writeStateForUserAsyncLPr(userId); } @GuardedBy("Settings.this.mLock") @@ -5342,7 +5340,7 @@ public final class Settings { + "set before trying to update the fingerprint."); } mFingerprints.put(userId, mExtendedFingerprint); - writePermissionsForUserAsyncLPr(userId); + writeStateForUserAsyncLPr(userId); } public void setPermissionControllerVersion(long version) { @@ -5361,13 +5359,7 @@ public final class Settings { return Build.FINGERPRINT + "?pc_version=" + version; } - public void writePermissionsForUserSyncLPr(int userId) { - mHandler.removeMessages(userId); - writePermissionsSync(userId); - } - - @GuardedBy("Settings.this.mLock") - public void writePermissionsForUserAsyncLPr(int userId) { + public void writeStateForUserAsyncLPr(int userId) { final long currentTimeMillis = SystemClock.uptimeMillis(); if (mWriteScheduled.get(userId)) { @@ -5399,59 +5391,53 @@ public final class Settings { } } - private void writePermissionsSync(int userId) { - RuntimePermissionsState runtimePermissions; - synchronized (mPersistenceLock) { - mWriteScheduled.delete(userId); - - int version = mVersions.get(userId, INITIAL_VERSION); + public void writeStateForUserSyncLPr(int userId) { + mHandler.removeMessages(userId); + mWriteScheduled.delete(userId); - String fingerprint = mFingerprints.get(userId); + int version = mVersions.get(userId, INITIAL_VERSION); - Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions = - new ArrayMap<>(); - int packagesSize = mPackages.size(); - for (int i = 0; i < packagesSize; i++) { - String packageName = mPackages.keyAt(i); - PackageSetting packageSetting = mPackages.valueAt(i); - if (packageSetting.sharedUser == null) { - List<RuntimePermissionsState.PermissionState> permissions = - getPermissionsFromPermissionsState( - packageSetting.getPermissionsState(), userId); - packagePermissions.put(packageName, permissions); - } - } + String fingerprint = mFingerprints.get(userId); - Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions = - new ArrayMap<>(); - final int sharedUsersSize = mSharedUsers.size(); - for (int i = 0; i < sharedUsersSize; i++) { - String sharedUserName = mSharedUsers.keyAt(i); - SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i); + Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions = + new ArrayMap<>(); + int packagesSize = mPackages.size(); + for (int i = 0; i < packagesSize; i++) { + String packageName = mPackages.keyAt(i); + PackageSetting packageSetting = mPackages.valueAt(i); + if (packageSetting.sharedUser == null) { List<RuntimePermissionsState.PermissionState> permissions = getPermissionsFromPermissionsState( - sharedUserSetting.getPermissionsState(), userId); - sharedUserPermissions.put(sharedUserName, permissions); + packageSetting.getPermissionsState(), userId); + packagePermissions.put(packageName, permissions); } + } - runtimePermissions = new RuntimePermissionsState(version, fingerprint, - packagePermissions, sharedUserPermissions); + Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions = + new ArrayMap<>(); + final int sharedUsersSize = mSharedUsers.size(); + for (int i = 0; i < sharedUsersSize; i++) { + String sharedUserName = mSharedUsers.keyAt(i); + SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i); + List<RuntimePermissionsState.PermissionState> permissions = + getPermissionsFromPermissionsState( + sharedUserSetting.getPermissionsState(), userId); + sharedUserPermissions.put(sharedUserName, permissions); } + RuntimePermissionsState runtimePermissions = new RuntimePermissionsState(version, + fingerprint, packagePermissions, sharedUserPermissions); + mPersistence.writeForUser(runtimePermissions, UserHandle.of(userId)); } @NonNull private List<RuntimePermissionsState.PermissionState> getPermissionsFromPermissionsState( - @NonNull PermissionsState permissionsState, @UserIdInt int userId) { - List<PermissionState> permissionStates = permissionsState.getRuntimePermissionStates( - userId); - List<RuntimePermissionsState.PermissionState> permissions = - new ArrayList<>(); - int permissionStatesSize = permissionStates.size(); - for (int i = 0; i < permissionStatesSize; i++) { - PermissionState permissionState = permissionStates.get(i); - + @NonNull AppIdPermissionState permissionsState, @UserIdInt int userId) { + Collection<PermissionState> permissionStates = + permissionsState.getRuntimePermissionStates(userId); + List<RuntimePermissionsState.PermissionState> permissions = new ArrayList<>(); + for (PermissionState permissionState : permissionStates) { RuntimePermissionsState.PermissionState permission = new RuntimePermissionsState.PermissionState(permissionState.getName(), permissionState.isGranted(), permissionState.getFlags()); @@ -5480,7 +5466,7 @@ public final class Settings { userId)); if (runtimePermissions == null) { readLegacyStateForUserSyncLPr(userId); - writePermissionsForUserAsyncLPr(userId); + writeStateForUserAsyncLPr(userId); return; } @@ -5536,7 +5522,7 @@ public final class Settings { private void readPermissionsStateLpr( @NonNull List<RuntimePermissionsState.PermissionState> permissions, - @NonNull PermissionsState permissionsState, @UserIdInt int userId) { + @NonNull AppIdPermissionState permissionsState, @UserIdInt int userId) { int permissionsSize = permissions.size(); for (int i = 0; i < permissionsSize; i++) { RuntimePermissionsState.PermissionState permission = permissions.get(i); @@ -5550,14 +5536,8 @@ public final class Settings { boolean granted = permission.isGranted(); int flags = permission.getFlags(); - if (granted) { - permissionsState.grantRuntimePermission(basePermission, userId); - permissionsState.updatePermissionFlags(basePermission, userId, - PackageManager.MASK_PERMISSION_FLAGS_ALL, flags); - } else { - permissionsState.updatePermissionFlags(basePermission, userId, - PackageManager.MASK_PERMISSION_FLAGS_ALL, flags); - } + permissionsState.putRuntimePermissionState(new PermissionState(basePermission, + granted, flags), userId); } } @@ -5638,8 +5618,9 @@ public final class Settings { } } - private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState, - int userId) throws IOException, XmlPullParserException { + private void parsePermissionsLPr(XmlPullParser parser, + AppIdPermissionState permissionsState, int userId) + throws IOException, XmlPullParserException { final int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT @@ -5666,15 +5647,8 @@ public final class Settings { final int flags = (flagsStr != null) ? Integer.parseInt(flagsStr, 16) : 0; - if (granted) { - permissionsState.grantRuntimePermission(bp, userId); - permissionsState.updatePermissionFlags(bp, userId, - PackageManager.MASK_PERMISSION_FLAGS_ALL, flags); - } else { - permissionsState.updatePermissionFlags(bp, userId, - PackageManager.MASK_PERMISSION_FLAGS_ALL, flags); - } - + permissionsState.putRuntimePermissionState(new PermissionState(bp, granted, + flags), userId); } break; } @@ -5690,7 +5664,9 @@ public final class Settings { public void handleMessage(Message message) { final int userId = message.what; Runnable callback = (Runnable) message.obj; - writePermissionsSync(userId); + synchronized (mLock) { + writeStateForUserSyncLPr(userId); + } if (callback != null) { callback.run(); } diff --git a/services/core/java/com/android/server/pm/permission/AppIdPermissionState.java b/services/core/java/com/android/server/pm/permission/AppIdPermissionState.java new file mode 100644 index 000000000000..aabdafdd453a --- /dev/null +++ b/services/core/java/com/android/server/pm/permission/AppIdPermissionState.java @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm.permission; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.os.UserHandle; +import android.util.ArrayMap; +import android.util.SparseArray; +import android.util.SparseBooleanArray; + +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; + +/** + * Legacy permission state that was associated with packages or shared users. + */ +//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) +public final class AppIdPermissionState { + // Maps from user IDs to user states. + @NonNull + private final SparseArray<UserState> mUserStates = new SparseArray<>(); + + // Keyed by user IDs. + @NonNull + private final SparseBooleanArray mMissing = new SparseBooleanArray(); + + /** + * Copy from another permission state. + * + * @param other the other permission state. + * + * @hide + */ + public void copyFrom(@NonNull AppIdPermissionState other) { + if (other == this) { + return; + } + + mUserStates.clear(); + final int userStatesSize = other.mUserStates.size(); + for (int i = 0; i < userStatesSize; i++) { + mUserStates.put(other.mUserStates.keyAt(i), + new UserState(other.mUserStates.valueAt(i))); + } + + mMissing.clear(); + final int missingSize = other.mMissing.size(); + for (int i = 0; i < missingSize; i++) { + mMissing.put(other.mMissing.keyAt(i), other.mMissing.valueAt(i)); + } + } + + /** + * Reset this permission state. + * + * @hide + */ + public void reset() { + mUserStates.clear(); + mMissing.clear(); + } + + @Override + public boolean equals(@Nullable Object object) { + if (this == object) { + return true; + } + if (object == null) { + return false; + } + if (getClass() != object.getClass()) { + return false; + } + final AppIdPermissionState other = (AppIdPermissionState) object; + return Objects.equals(mUserStates, other.mUserStates) + && Objects.equals(mMissing, other.mMissing); + } + + /** + * Put a install permission state. + * + * @param permissionState the permission state + */ + public void putInstallPermissionState(@NonNull PermissionState permissionState) { + putPermissionState(permissionState, UserHandle.USER_ALL); + } + + /** + * Put a runtime permission state for a user. + * + * @param permissionState the permission state + * @param userId the user ID + */ + public void putRuntimePermissionState(@NonNull PermissionState permissionState, + @UserIdInt int userId) { + checkUserId(userId); + putPermissionState(permissionState, userId); + } + + private void putPermissionState(@NonNull PermissionState permissionState, + @UserIdInt int userId) { + UserState userState = mUserStates.get(userId); + if (userState == null) { + userState = new UserState(); + mUserStates.put(userId, userState); + } + userState.putPermissionState(permissionState); + } + + /** + * Check whether there are any permission states for the given permissions. + * + * @param permissionNames the permission names + * @return whether there are any permission states + * + * @hide + */ + public boolean hasPermissionState(@NonNull Collection<String> permissionNames) { + final int userStatesSize = mUserStates.size(); + for (int i = 0; i < userStatesSize; i++) { + final UserState userState = mUserStates.valueAt(i); + for (final String permissionName : permissionNames) { + if (userState.getPermissionState(permissionName) != null) { + return true; + } + } + } + return false; + } + + /** + * Get all the install permission states. + * + * @return the install permission states + */ + @NonNull + public Collection<PermissionState> getInstallPermissionStates() { + return getPermissionStates(UserHandle.USER_ALL); + } + + /** + * Get all the runtime permission states for a user. + * + * @param userId the user ID + * @return the runtime permission states + */ + @NonNull + public Collection<PermissionState> getRuntimePermissionStates(@UserIdInt int userId) { + checkUserId(userId); + return getPermissionStates(userId); + } + + @NonNull + private Collection<PermissionState> getPermissionStates(@UserIdInt int userId) { + final UserState userState = mUserStates.get(userId); + if (userState == null) { + return Collections.emptyList(); + } + return userState.getPermissionStates(); + } + + /** + * Check whether the permission state is missing for a user. + * <p> + * This can happen if permission state is rolled back and we'll need to generate a reasonable + * default state to keep the app usable. + * + * @param userId the user ID + * @return whether the permission state is missing + */ + public boolean isMissing(@UserIdInt int userId) { + checkUserId(userId); + return mMissing.get(userId); + } + + /** + * Set whether the permission state is missing for a user. + * <p> + * This can happen if permission state is rolled back and we'll need to generate a reasonable + * default state to keep the app usable. + * + * @param missing whether the permission state is missing + * @param userId the user ID + */ + public void setMissing(boolean missing, @UserIdInt int userId) { + checkUserId(userId); + if (missing) { + mMissing.put(userId, true); + } else { + mMissing.delete(userId); + } + } + + private static void checkUserId(@UserIdInt int userId) { + if (userId < 0) { + throw new IllegalArgumentException("Invalid user ID " + userId); + } + } + + /** + * Legacy state for permissions for a user. + */ + private static final class UserState { + // Maps from permission names to permission states. + @NonNull + private final ArrayMap<String, PermissionState> mPermissionStates = new ArrayMap<>(); + + public UserState() {} + + public UserState(@NonNull UserState other) { + final int permissionStatesSize = other.mPermissionStates.size(); + for (int i = 0; i < permissionStatesSize; i++) { + mPermissionStates.put(other.mPermissionStates.keyAt(i), + new PermissionState(other.mPermissionStates.valueAt(i))); + } + } + + @Nullable + public PermissionState getPermissionState(@NonNull String permissionName) { + return mPermissionStates.get(permissionName); + } + + public void putPermissionState(@NonNull PermissionState permissionState) { + mPermissionStates.put(permissionState.getName(), permissionState); + } + + @NonNull + public Collection<PermissionState> getPermissionStates() { + return Collections.unmodifiableCollection(mPermissionStates.values()); + } + } + + /** + * Legacy state for a single permission. + */ + public static final class PermissionState { + @NonNull + private final BasePermission mPermission; + + private final boolean mGranted; + + private final int mFlags; + + /** + * Create a new instance of this class. + * + * @param permission the {@link BasePermission} for the permission + * @param granted whether the permission is granted + * @param flags the permission flags + */ + public PermissionState(@NonNull BasePermission permission, boolean granted, int flags) { + mPermission = permission; + mGranted = granted; + mFlags = flags; + } + + private PermissionState(@NonNull PermissionState other) { + mPermission = other.mPermission; + mGranted = other.mGranted; + mFlags = other.mFlags; + } + + /** + * Get the {@link BasePermission} for the permission. + * + * @return the {@link BasePermission} + */ + @NonNull + public BasePermission getPermission() { + return mPermission; + } + + /** + * Get the permission name. + * + * @return the permission name + */ + @NonNull + public String getName() { + return mPermission.getName(); + } + + /** + * Get whether the permission is granted. + * + * @return whether the permission is granted + */ + @NonNull + public boolean isGranted() { + return mGranted; + } + + /** + * Get the permission flags. + * + * @return the permission flags + */ + @NonNull + public int getFlags() { + return mFlags; + } + } +} diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java new file mode 100644 index 000000000000..7452b522b20a --- /dev/null +++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm.permission; + +import android.annotation.AppIdInt; +import android.annotation.NonNull; + +/** + * An interface for legacy code to read permission data in order to maintain compatibility. + */ +//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) +public interface LegacyPermissionDataProvider { + /** + * Get the legacy permission state of an app ID, either a package or a shared user. + * + * @param appId the app ID + * @return the legacy permission state + */ + @NonNull + public abstract AppIdPermissionState getAppIdPermissionState(@AppIdInt int appId); + + /** + * Get the GIDs computed from the permission state of a UID, either a package or a shared user. + * + * @param uid the UID + * @return the GIDs for the UID + */ + @NonNull + public abstract int[] getGidsForUid(int uid); +} 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 2f9e199bc506..544f1225916e 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -58,6 +58,7 @@ import static com.android.server.pm.permission.UidPermissionState.PERMISSION_OPE import static java.util.concurrent.TimeUnit.SECONDS; import android.Manifest; +import android.annotation.AppIdInt; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -2514,20 +2515,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return permission.computeGids(userId); } - @Nullable - private int[] getPackageGids(@NonNull String packageName, @UserIdInt int userId) { - final PackageSetting ps = mPackageManagerInt.getPackageSetting(packageName); - if (ps == null) { - return null; - } - final UidPermissionState uidState = getUidState(ps, userId); - if (uidState == null) { - Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId); - return null; - } - return uidState.computeGids(userId); - } - /** * Restore the permission state for a package. * @@ -4766,7 +4753,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - private void removeAppState(int appId) { + private void removeAppIdState(@AppIdInt int appId) { synchronized (mLock) { final int[] userIds = mState.getUserIds(); for (final int userId : userIds) { @@ -4780,7 +4767,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int[] userIds = getAllUserIds(); mPackageManagerInt.forEachPackageSetting(ps -> { final int appId = ps.getAppId(); - final PermissionsState permissionsState = ps.getPermissionsState(); + final AppIdPermissionState appIdState = ps.getPermissionsState(); synchronized (mLock) { for (final int userId : userIds) { @@ -4789,25 +4776,22 @@ public class PermissionManagerService extends IPermissionManager.Stub { userState.setInstallPermissionsFixed(ps.name, ps.areInstallPermissionsFixed()); final UidPermissionState uidState = userState.getOrCreateUidState(appId); uidState.reset(); - uidState.setGlobalGids(permissionsState.getGlobalGids()); - uidState.setMissing(permissionsState.isMissing(userId)); + uidState.setMissing(appIdState.isMissing(userId)); readStateFromPermissionStates(uidState, - permissionsState.getInstallPermissionStates(), false); + appIdState.getInstallPermissionStates(), false); readStateFromPermissionStates(uidState, - permissionsState.getRuntimePermissionStates(userId), true); + appIdState.getRuntimePermissionStates(userId), true); } } }); } private void readStateFromPermissionStates(@NonNull UidPermissionState uidState, - @NonNull List<PermissionsState.PermissionState> permissionStates, boolean isRuntime) { - final int permissionStatesSize = permissionStates.size(); - for (int i = 0; i < permissionStatesSize; i++) { - final PermissionsState.PermissionState permissionState = permissionStates.get(i); - final BasePermission permission = permissionState.getPermission(); - uidState.putPermissionState(permission, isRuntime, permissionState.isGranted(), - permissionState.getFlags()); + @NonNull Collection<AppIdPermissionState.PermissionState> permissionStates, + boolean isRuntime) { + for (final AppIdPermissionState.PermissionState permissionState : permissionStates) { + uidState.putPermissionState(permissionState.getPermission(), isRuntime, + permissionState.isGranted(), permissionState.getFlags()); } } @@ -4815,8 +4799,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int[] userIds = mState.getUserIds(); mPackageManagerInt.forEachPackageSetting(ps -> { ps.setInstallPermissionsFixed(false); - final PermissionsState permissionsState = ps.getPermissionsState(); - permissionsState.reset(); + final AppIdPermissionState appIdState = ps.getPermissionsState(); + appIdState.reset(); final int appId = ps.getAppId(); synchronized (mLock) { @@ -4838,27 +4822,21 @@ public class PermissionManagerService extends IPermissionManager.Stub { continue; } - permissionsState.setGlobalGids(uidState.getGlobalGids()); - permissionsState.setMissing(uidState.isMissing(), userId); + appIdState.setMissing(uidState.isMissing(), userId); final List<PermissionState> permissionStates = uidState.getPermissionStates(); final int permissionStatesSize = permissionStates.size(); for (int i = 0; i < permissionStatesSize; i++) { final PermissionState permissionState = permissionStates.get(i); - final BasePermission permission = permissionState.getPermission(); - if (permissionState.isGranted()) { - if (permissionState.isRuntime()) { - permissionsState.grantRuntimePermission(permission, userId); - } else { - permissionsState.grantInstallPermission(permission); - } - } - final int flags = permissionState.getFlags(); - if (flags != 0) { - final int flagsUserId = permissionState.isRuntime() ? userId - : UserHandle.USER_ALL; - permissionsState.updatePermissionFlags(permission, flagsUserId, flags, - flags); + final AppIdPermissionState.PermissionState legacyPermissionState = + new AppIdPermissionState.PermissionState( + permissionState.getPermission(), + permissionState.isGranted(), permissionState.getFlags()); + if (permissionState.isRuntime()) { + appIdState.putRuntimePermissionState(legacyPermissionState, + userId); + } else { + appIdState.putInstallPermissionState(legacyPermissionState); } } } @@ -4866,6 +4844,48 @@ public class PermissionManagerService extends IPermissionManager.Stub { }); } + @NonNull + private AppIdPermissionState getAppIdPermissionState(@AppIdInt int appId) { + final AppIdPermissionState appIdState = new AppIdPermissionState(); + final int[] userIds = mState.getUserIds(); + for (final int userId : userIds) { + final UidPermissionState uidState = getUidState(appId, userId); + if (uidState == null) { + Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID " + + userId); + continue; + } + + final List<PermissionState> permissionStates = uidState.getPermissionStates(); + final int permissionStatesSize = permissionStates.size(); + for (int i = 0; i < permissionStatesSize; i++) { + final PermissionState permissionState = permissionStates.get(i); + + final AppIdPermissionState.PermissionState legacyPermissionState = + new AppIdPermissionState.PermissionState(permissionState.getPermission(), + permissionState.isGranted(), permissionState.getFlags()); + if (permissionState.isRuntime()) { + appIdState.putRuntimePermissionState(legacyPermissionState, userId); + } else if (userId == UserHandle.USER_SYSTEM) { + appIdState.putInstallPermissionState(legacyPermissionState); + } + } + } + return appIdState; + } + + @NonNull + private int[] getGidsForUid(int uid) { + final int appId = UserHandle.getAppId(uid); + final int userId = UserHandle.getUserId(uid); + final UidPermissionState uidState = getUidState(appId, userId); + if (uidState == null) { + Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID " + userId); + return EMPTY_INT_ARRAY; + } + return uidState.computeGids(userId); + } + private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal { @Override public void systemReady() { @@ -4910,8 +4930,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { PermissionManagerService.this.onUserRemoved(userId); } @Override - public void removePermissionsStateTEMP(int appId) { - PermissionManagerService.this.removeAppState(appId); + public void removeAppIdStateTEMP(@AppIdInt int appId) { + PermissionManagerService.this.removeAppIdState(appId); } @Override @UserIdInt @@ -4931,11 +4951,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { public int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) { return PermissionManagerService.this.getPermissionGids(permissionName, userId); } - @Nullable - @Override - public int[] getPackageGids(@NonNull String packageName, @UserIdInt int userId) { - return PermissionManagerService.this.getPackageGids(packageName, userId); - } @Override public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds, String[] grantedPermissions, int callingUid) { @@ -5263,6 +5278,16 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } } + + @NonNull + public AppIdPermissionState getAppIdPermissionState(@AppIdInt int appId) { + return PermissionManagerService.this.getAppIdPermissionState(appId); + } + + @NonNull + public int[] getGidsForUid(int uid) { + return PermissionManagerService.this.getGidsForUid(uid); + } } private static final class OnPermissionChangeListeners extends Handler { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java index 6d9bd2a1b30d..5ea3458fcbfa 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -37,8 +37,8 @@ import java.util.function.Consumer; * * TODO: Should be merged into PermissionManagerInternal, but currently uses internal classes. */ -public abstract class PermissionManagerServiceInternal extends PermissionManagerInternal { - +public abstract class PermissionManagerServiceInternal extends PermissionManagerInternal + implements LegacyPermissionDataProvider { /** * Provider for package names. */ @@ -288,13 +288,13 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager public abstract void onUserRemoved(@UserIdInt int userId); /** - * Remove the {@code PermissionsState} associated with an app ID, called the same time as the + * Remove the permission state associated with an app ID, called the same time as the * removal of a {@code PackageSetitng}. * * TODO(zhanghai): This is a temporary method before we figure out a way to get notified of app * ID removal via API. */ - public abstract void removePermissionsStateTEMP(int appId); + public abstract void removeAppIdStateTEMP(@AppIdInt int appId); /** * Update the shared user setting when a package with a shared user id is removed. The gids @@ -324,12 +324,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @Nullable public abstract int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId); - /** - * Get the GIDs computed from the permission state of a package. - */ - @Nullable - public abstract int[] getPackageGids(@NonNull String packageName, @UserIdInt int userId); - /** Retrieve the packages that have requested the given app op permission */ public abstract @Nullable String[] getAppOpPermissionPackages( @NonNull String permName, int callingUid); diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java deleted file mode 100644 index 4fb2d5fc200e..000000000000 --- a/services/core/java/com/android/server/pm/permission/PermissionsState.java +++ /dev/null @@ -1,970 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.pm.permission; - -import android.annotation.Nullable; -import android.annotation.UserIdInt; -import android.content.pm.PackageManager; -import android.os.UserHandle; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.SparseArray; -import android.util.SparseBooleanArray; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.ArrayUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -/** - * This class encapsulates the permissions for a package or a shared user. - * <p> - * There are two types of permissions: install (granted at installation) - * and runtime (granted at runtime). Install permissions are granted to - * all device users while runtime permissions are granted explicitly to - * specific users. - * </p> - * <p> - * The permissions are kept on a per device user basis. For example, an - * application may have some runtime permissions granted under the device - * owner but not granted under the secondary user. - * <p> - * This class is also responsible for keeping track of the Linux gids per - * user for a package or a shared user. The gids are computed as a set of - * the gids for all granted permissions' gids on a per user basis. - * </p> - */ -public final class PermissionsState { - - /** The permission operation failed. */ - public static final int PERMISSION_OPERATION_FAILURE = -1; - - /** The permission operation succeeded and no gids changed. */ - public static final int PERMISSION_OPERATION_SUCCESS = 0; - - /** The permission operation succeeded and gids changed. */ - public static final int PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED = 1; - - private static final int[] NO_GIDS = {}; - - private final Object mLock = new Object(); - - @GuardedBy("mLock") - private ArrayMap<String, PermissionData> mPermissions; - - private int[] mGlobalGids = NO_GIDS; - - @Nullable - private SparseBooleanArray mMissing; - - private SparseBooleanArray mPermissionReviewRequired; - - public PermissionsState() { - /* do nothing */ - } - - public PermissionsState(PermissionsState prototype) { - copyFrom(prototype); - } - - public int[] getGlobalGids() { - return mGlobalGids; - } - - /** - * Sets the global gids, applicable to all users. - * - * @param globalGids The global gids. - */ - public void setGlobalGids(int[] globalGids) { - if (!ArrayUtils.isEmpty(globalGids)) { - mGlobalGids = Arrays.copyOf(globalGids, globalGids.length); - } - } - - private static void invalidateCache() { - PackageManager.invalidatePackageInfoCache(); - } - - /** - * Initialized this instance from another one. - * - * @param other The other instance. - */ - public void copyFrom(PermissionsState other) { - if (other == this) { - return; - } - - synchronized (mLock) { - if (mPermissions != null) { - if (other.mPermissions == null) { - mPermissions = null; - } else { - mPermissions.clear(); - } - } - if (other.mPermissions != null) { - if (mPermissions == null) { - mPermissions = new ArrayMap<>(); - } - final int permissionCount = other.mPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - String name = other.mPermissions.keyAt(i); - PermissionData permissionData = other.mPermissions.valueAt(i); - mPermissions.put(name, new PermissionData(permissionData)); - } - } - } - - mGlobalGids = NO_GIDS; - if (other.mGlobalGids != NO_GIDS) { - mGlobalGids = Arrays.copyOf(other.mGlobalGids, - other.mGlobalGids.length); - } - - if (mMissing != null) { - if (other.mMissing == null) { - mMissing = null; - } else { - mMissing.clear(); - } - } - if (other.mMissing != null) { - if (mMissing == null) { - mMissing = new SparseBooleanArray(); - } - final int missingSize = other.mMissing.size(); - for (int i = 0; i < missingSize; i++) { - mMissing.put(other.mMissing.keyAt(i), other.mMissing.valueAt(i)); - } - } - - if (mPermissionReviewRequired != null) { - if (other.mPermissionReviewRequired == null) { - mPermissionReviewRequired = null; - } else { - mPermissionReviewRequired.clear(); - } - } - if (other.mPermissionReviewRequired != null) { - if (mPermissionReviewRequired == null) { - mPermissionReviewRequired = new SparseBooleanArray(); - } - final int userCount = other.mPermissionReviewRequired.size(); - for (int i = 0; i < userCount; i++) { - final boolean reviewRequired = other.mPermissionReviewRequired.valueAt(i); - mPermissionReviewRequired.put(other.mPermissionReviewRequired.keyAt(i), - reviewRequired); - } - } - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final PermissionsState other = (PermissionsState) obj; - - synchronized (mLock) { - if (mPermissions == null) { - if (other.mPermissions != null) { - return false; - } - } else if (!mPermissions.equals(other.mPermissions)) { - return false; - } - } - - if (!Objects.equals(mMissing, other.mMissing)) { - return false; - } - - if (mPermissionReviewRequired == null) { - if (other.mPermissionReviewRequired != null) { - return false; - } - } else if (!mPermissionReviewRequired.equals(other.mPermissionReviewRequired)) { - return false; - } - return Arrays.equals(mGlobalGids, other.mGlobalGids); - } - - /** - * Check whether the permissions state is missing for a user. This can happen if permission - * state is rolled back and we'll need to generate a reasonable default state to keep the app - * usable. - */ - public boolean isMissing(@UserIdInt int userId) { - return mMissing != null && mMissing.get(userId); - } - - /** - * Set whether the permissions state is missing for a user. This can happen if permission state - * is rolled back and we'll need to generate a reasonable default state to keep the app usable. - */ - public void setMissing(boolean missing, @UserIdInt int userId) { - if (missing) { - if (mMissing == null) { - mMissing = new SparseBooleanArray(); - } - mMissing.put(userId, true); - } else { - if (mMissing != null) { - mMissing.delete(userId); - if (mMissing.size() == 0) { - mMissing = null; - } - } - } - } - - public boolean isPermissionReviewRequired(int userId) { - return mPermissionReviewRequired != null && mPermissionReviewRequired.get(userId); - } - - /** - * Grant an install permission. - * - * @param permission The permission to grant. - * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS}, - * or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link - * #PERMISSION_OPERATION_FAILURE}. - */ - public int grantInstallPermission(BasePermission permission) { - return grantPermission(permission, UserHandle.USER_ALL); - } - - /** - * Revoke an install permission. - * - * @param permission The permission to revoke. - * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS}, - * or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link - * #PERMISSION_OPERATION_FAILURE}. - */ - public int revokeInstallPermission(BasePermission permission) { - return revokePermission(permission, UserHandle.USER_ALL); - } - - /** - * Grant a runtime permission for a given device user. - * - * @param permission The permission to grant. - * @param userId The device user id. - * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS}, - * or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link - * #PERMISSION_OPERATION_FAILURE}. - */ - public int grantRuntimePermission(BasePermission permission, int userId) { - enforceValidUserId(userId); - if (userId == UserHandle.USER_ALL) { - return PERMISSION_OPERATION_FAILURE; - } - return grantPermission(permission, userId); - } - - /** - * Revoke a runtime permission for a given device user. - * - * @param permission The permission to revoke. - * @param userId The device user id. - * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS}, - * or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link - * #PERMISSION_OPERATION_FAILURE}. - */ - public int revokeRuntimePermission(BasePermission permission, int userId) { - enforceValidUserId(userId); - if (userId == UserHandle.USER_ALL) { - return PERMISSION_OPERATION_FAILURE; - } - return revokePermission(permission, userId); - } - - /** - * Gets whether this state has a given runtime permission for a - * given device user id. - * - * @param name The permission name. - * @param userId The device user id. - * @return Whether this state has the permission. - */ - public boolean hasRuntimePermission(String name, int userId) { - enforceValidUserId(userId); - return !hasInstallPermission(name) && hasPermission(name, userId); - } - - /** - * Gets whether this state has a given install permission. - * - * @param name The permission name. - * @return Whether this state has the permission. - */ - public boolean hasInstallPermission(String name) { - return hasPermission(name, UserHandle.USER_ALL); - } - - /** - * Gets whether the state has a given permission for the specified - * user, regardless if this is an install or a runtime permission. - * - * @param name The permission name. - * @param userId The device user id. - * @return Whether the user has the permission. - */ - public boolean hasPermission(String name, int userId) { - enforceValidUserId(userId); - - synchronized (mLock) { - if (mPermissions == null) { - return false; - } - PermissionData permissionData = mPermissions.get(name); - - return permissionData != null && permissionData.isGranted(userId); - } - - } - - /** - * Returns whether the state has any known request for the given permission name, - * whether or not it has been granted. - */ - public boolean hasRequestedPermission(ArraySet<String> names) { - synchronized (mLock) { - if (mPermissions == null) { - return false; - } - for (int i=names.size()-1; i>=0; i--) { - if (mPermissions.get(names.valueAt(i)) != null) { - return true; - } - } - } - - return false; - } - - /** - * Returns whether the state has any known request for the given permission name, - * whether or not it has been granted. - */ - public boolean hasRequestedPermission(String name) { - return mPermissions != null && (mPermissions.get(name) != null); - } - /** - * Gets all permissions for a given device user id regardless if they - * are install time or runtime permissions. - * - * @param userId The device user id. - * @return The permissions or an empty set. - */ - public Set<String> getPermissions(int userId) { - enforceValidUserId(userId); - - synchronized (mLock) { - if (mPermissions == null) { - return Collections.emptySet(); - } - - Set<String> permissions = new ArraySet<>(mPermissions.size()); - - final int permissionCount = mPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - String permission = mPermissions.keyAt(i); - - if (hasInstallPermission(permission)) { - permissions.add(permission); - continue; - } - - if (userId != UserHandle.USER_ALL) { - if (hasRuntimePermission(permission, userId)) { - permissions.add(permission); - } - } - } - - return permissions; - } - } - - /** - * Gets the state for an install permission or null if no such. - * - * @param name The permission name. - * @return The permission state. - */ - public PermissionState getInstallPermissionState(String name) { - return getPermissionState(name, UserHandle.USER_ALL); - } - - /** - * Gets the state for a runtime permission or null if no such. - * - * @param name The permission name. - * @param userId The device user id. - * @return The permission state. - */ - public PermissionState getRuntimePermissionState(String name, int userId) { - enforceValidUserId(userId); - return getPermissionState(name, userId); - } - - /** - * Gets all install permission states. - * - * @return The permission states or an empty set. - */ - public List<PermissionState> getInstallPermissionStates() { - return getPermissionStatesInternal(UserHandle.USER_ALL); - } - - /** - * Gets all runtime permission states. - * - * @return The permission states or an empty set. - */ - public List<PermissionState> getRuntimePermissionStates(int userId) { - enforceValidUserId(userId); - return getPermissionStatesInternal(userId); - } - - /** - * Gets the flags for a permission regardless if it is install or - * runtime permission. - * - * @param name The permission name. - * @return The permission state or null if no such. - */ - public int getPermissionFlags(String name, int userId) { - PermissionState installPermState = getInstallPermissionState(name); - if (installPermState != null) { - return installPermState.getFlags(); - } - PermissionState runtimePermState = getRuntimePermissionState(name, userId); - if (runtimePermState != null) { - return runtimePermState.getFlags(); - } - return 0; - } - - /** - * Update the flags associated with a given permission. - * @param permission The permission whose flags to update. - * @param userId The user for which to update. - * @param flagMask Mask for which flags to change. - * @param flagValues New values for the mask flags. - * @return Whether the permission flags changed. - */ - public boolean updatePermissionFlags(BasePermission permission, int userId, - int flagMask, int flagValues) { - enforceValidUserId(userId); - - final boolean mayChangeFlags = flagValues != 0 || flagMask != 0; - - synchronized (mLock) { - if (mPermissions == null) { - if (!mayChangeFlags) { - return false; - } - ensurePermissionData(permission); - } - } - - PermissionData permissionData = null; - synchronized (mLock) { - permissionData = mPermissions.get(permission.getName()); - } - - if (permissionData == null) { - if (!mayChangeFlags) { - return false; - } - permissionData = ensurePermissionData(permission); - } - - final int oldFlags = permissionData.getFlags(userId); - - final boolean updated = permissionData.updateFlags(userId, flagMask, flagValues); - if (updated) { - final int newFlags = permissionData.getFlags(userId); - if ((oldFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) == 0 - && (newFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { - if (mPermissionReviewRequired == null) { - mPermissionReviewRequired = new SparseBooleanArray(); - } - mPermissionReviewRequired.put(userId, true); - } else if ((oldFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0 - && (newFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { - if (mPermissionReviewRequired != null && !hasPermissionRequiringReview(userId)) { - mPermissionReviewRequired.delete(userId); - if (mPermissionReviewRequired.size() <= 0) { - mPermissionReviewRequired = null; - } - } - } - } - return updated; - } - - private boolean hasPermissionRequiringReview(int userId) { - synchronized (mLock) { - final int permissionCount = mPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - final PermissionData permission = mPermissions.valueAt(i); - if ((permission.getFlags(userId) - & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { - return true; - } - } - } - - return false; - } - - public boolean updatePermissionFlagsForAllPermissions( - int userId, int flagMask, int flagValues) { - enforceValidUserId(userId); - - synchronized (mLock) { - if (mPermissions == null) { - return false; - } - boolean changed = false; - final int permissionCount = mPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - PermissionData permissionData = mPermissions.valueAt(i); - changed |= permissionData.updateFlags(userId, flagMask, flagValues); - } - - return changed; - } - } - - /** - * Compute the Linux gids for a given device user from the permissions - * granted to this user. Note that these are computed to avoid additional - * state as they are rarely accessed. - * - * @param userId The device user id. - * @return The gids for the device user. - */ - public int[] computeGids(int userId) { - enforceValidUserId(userId); - - int[] gids = mGlobalGids; - - synchronized (mLock) { - if (mPermissions != null) { - final int permissionCount = mPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - String permission = mPermissions.keyAt(i); - if (!hasPermission(permission, userId)) { - continue; - } - PermissionData permissionData = mPermissions.valueAt(i); - final int[] permGids = permissionData.computeGids(userId); - if (permGids != NO_GIDS) { - gids = appendInts(gids, permGids); - } - } - } - } - - return gids; - } - - /** - * Compute the Linux gids for all device users from the permissions - * granted to these users. - * - * @return The gids for all device users. - */ - public int[] computeGids(int[] userIds) { - int[] gids = mGlobalGids; - - for (int userId : userIds) { - final int[] userGids = computeGids(userId); - gids = appendInts(gids, userGids); - } - - return gids; - } - - /** - * Resets the internal state of this object. - */ - public void reset() { - mGlobalGids = NO_GIDS; - - synchronized (mLock) { - mPermissions = null; - invalidateCache(); - } - - mMissing = null; - mPermissionReviewRequired = null; - } - - private PermissionState getPermissionState(String name, int userId) { - synchronized (mLock) { - if (mPermissions == null) { - return null; - } - PermissionData permissionData = mPermissions.get(name); - if (permissionData == null) { - return null; - } - - return permissionData.getPermissionState(userId); - } - } - - private List<PermissionState> getPermissionStatesInternal(int userId) { - enforceValidUserId(userId); - - synchronized (mLock) { - if (mPermissions == null) { - return Collections.emptyList(); - } - - List<PermissionState> permissionStates = new ArrayList<>(); - - final int permissionCount = mPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - PermissionData permissionData = mPermissions.valueAt(i); - - PermissionState permissionState = permissionData.getPermissionState(userId); - if (permissionState != null) { - permissionStates.add(permissionState); - } - } - - return permissionStates; - } - } - - private int grantPermission(BasePermission permission, int userId) { - if (hasPermission(permission.getName(), userId)) { - return PERMISSION_OPERATION_SUCCESS; - } - - final boolean hasGids = !ArrayUtils.isEmpty(permission.computeGids(userId)); - final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS; - - PermissionData permissionData = ensurePermissionData(permission); - - if (!permissionData.grant(userId)) { - return PERMISSION_OPERATION_FAILURE; - } - - if (hasGids) { - final int[] newGids = computeGids(userId); - if (oldGids.length != newGids.length) { - return PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; - } - } - - return PERMISSION_OPERATION_SUCCESS; - } - - private int revokePermission(BasePermission permission, int userId) { - final String permName = permission.getName(); - if (!hasPermission(permName, userId)) { - return PERMISSION_OPERATION_SUCCESS; - } - - final boolean hasGids = !ArrayUtils.isEmpty(permission.computeGids(userId)); - final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS; - - PermissionData permissionData = null; - synchronized (mLock) { - permissionData = mPermissions.get(permName); - } - - if (!permissionData.revoke(userId)) { - return PERMISSION_OPERATION_FAILURE; - } - - if (permissionData.isDefault()) { - ensureNoPermissionData(permName); - } - - if (hasGids) { - final int[] newGids = computeGids(userId); - if (oldGids.length != newGids.length) { - return PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; - } - } - - return PERMISSION_OPERATION_SUCCESS; - } - - // TODO: fix this to use arraycopy and append all ints in one go - private static int[] appendInts(int[] current, int[] added) { - if (current != null && added != null) { - for (int guid : added) { - current = ArrayUtils.appendInt(current, guid); - } - } - return current; - } - - private static void enforceValidUserId(int userId) { - if (userId != UserHandle.USER_ALL && userId < 0) { - throw new IllegalArgumentException("Invalid userId:" + userId); - } - } - - private PermissionData ensurePermissionData(BasePermission permission) { - final String permName = permission.getName(); - - synchronized (mLock) { - if (mPermissions == null) { - mPermissions = new ArrayMap<>(); - } - PermissionData permissionData = mPermissions.get(permName); - if (permissionData == null) { - permissionData = new PermissionData(permission); - mPermissions.put(permName, permissionData); - } - return permissionData; - } - - } - - private void ensureNoPermissionData(String name) { - synchronized (mLock) { - if (mPermissions == null) { - return; - } - mPermissions.remove(name); - if (mPermissions.isEmpty()) { - mPermissions = null; - } - } - - } - - private static final class PermissionData { - - private final Object mLock = new Object(); - - private final BasePermission mPerm; - @GuardedBy("mLock") - private SparseArray<PermissionState> mUserStates = new SparseArray<>(); - - public PermissionData(BasePermission perm) { - mPerm = perm; - } - - public PermissionData(PermissionData other) { - this(other.mPerm); - - synchronized (mLock) { - final int otherStateCount = other.mUserStates.size(); - for (int i = 0; i < otherStateCount; i++) { - final int otherUserId = other.mUserStates.keyAt(i); - PermissionState otherState = other.mUserStates.valueAt(i); - mUserStates.put(otherUserId, new PermissionState(otherState)); - } - } - } - - public int[] computeGids(int userId) { - return mPerm.computeGids(userId); - } - - public boolean isGranted(int userId) { - synchronized (mLock) { - if (isInstallPermission()) { - userId = UserHandle.USER_ALL; - } - - PermissionState userState = mUserStates.get(userId); - if (userState == null) { - return false; - } - - return userState.mGranted; - } - } - - public boolean grant(int userId) { - synchronized (mLock) { - if (!isCompatibleUserId(userId)) { - return false; - } - - if (isGranted(userId)) { - return false; - } - - PermissionState userState = mUserStates.get(userId); - if (userState == null) { - userState = new PermissionState(mPerm); - mUserStates.put(userId, userState); - } - - userState.mGranted = true; - - invalidateCache(); - return true; - } - } - - public boolean revoke(int userId) { - synchronized (mLock) { - if (!isCompatibleUserId(userId)) { - return false; - } - - if (!isGranted(userId)) { - return false; - } - - PermissionState userState = mUserStates.get(userId); - userState.mGranted = false; - - if (userState.isDefault()) { - mUserStates.remove(userId); - } - - invalidateCache(); - return true; - } - } - - public PermissionState getPermissionState(int userId) { - synchronized (mLock) { - return mUserStates.get(userId); - } - } - - public int getFlags(int userId) { - synchronized (mLock) { - PermissionState userState = mUserStates.get(userId); - if (userState != null) { - return userState.mFlags; - } - return 0; - } - } - - public boolean isDefault() { - synchronized (mLock) { - return mUserStates.size() <= 0; - } - } - - public static boolean isInstallPermissionKey(int userId) { - return userId == UserHandle.USER_ALL; - } - - public boolean updateFlags(int userId, int flagMask, int flagValues) { - synchronized (mLock) { - if (isInstallPermission()) { - userId = UserHandle.USER_ALL; - } - - if (!isCompatibleUserId(userId)) { - return false; - } - - final int newFlags = flagValues & flagMask; - - // Okay to do before the modification because we hold the lock. - invalidateCache(); - - PermissionState userState = mUserStates.get(userId); - if (userState != null) { - final int oldFlags = userState.mFlags; - userState.mFlags = (userState.mFlags & ~flagMask) | newFlags; - if (userState.isDefault()) { - mUserStates.remove(userId); - } - return userState.mFlags != oldFlags; - } else if (newFlags != 0) { - userState = new PermissionState(mPerm); - userState.mFlags = newFlags; - mUserStates.put(userId, userState); - return true; - } - - return false; - } - } - - private boolean isCompatibleUserId(int userId) { - return isDefault() || !(isInstallPermission() ^ isInstallPermissionKey(userId)); - } - - private boolean isInstallPermission() { - return mUserStates.size() == 1 - && mUserStates.get(UserHandle.USER_ALL) != null; - } - } - - public static final class PermissionState { - private final BasePermission mPermission; - private boolean mGranted; - private int mFlags; - - public PermissionState(BasePermission permission) { - mPermission = permission; - } - - public PermissionState(PermissionState other) { - mPermission = other.mPermission; - mGranted = other.mGranted; - mFlags = other.mFlags; - } - - public boolean isDefault() { - return !mGranted && mFlags == 0; - } - - public BasePermission getPermission() { - return mPermission; - } - - public String getName() { - return mPermission.getName(); - } - - public boolean isGranted() { - return mGranted; - } - - public int getFlags() { - return mFlags; - } - } -} diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index dac05424e01f..bc747832e253 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -62,6 +62,7 @@ import com.android.permission.persistence.RuntimePermissionsPersistence; import com.android.server.LocalServices; import com.android.server.pm.parsing.pkg.PackageImpl; import com.android.server.pm.parsing.pkg.ParsedPackage; +import com.android.server.pm.permission.LegacyPermissionDataProvider; import com.android.server.pm.permission.PermissionSettings; import com.google.common.truth.Truth; @@ -94,6 +95,8 @@ public class PackageManagerSettingsTests { PermissionSettings mPermissionSettings; @Mock RuntimePermissionsPersistence mRuntimePermissionsPersistence; + @Mock + LegacyPermissionDataProvider mPermissionDataProvider; @Before public void initializeMocks() { @@ -115,7 +118,7 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getContext(); final Object lock = new Object(); Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); assertThat(settings.readLPw(createFakeUsers()), is(true)); verifyKeySetMetaData(settings); } @@ -129,7 +132,7 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getContext(); final Object lock = new Object(); Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); assertThat(settings.readLPw(createFakeUsers()), is(true)); // write out, read back in and verify the same @@ -145,7 +148,7 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getContext(); final Object lock = new Object(); Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); assertThat(settings.readLPw(createFakeUsers()), is(true)); assertThat(settings.getPackageLPr(PACKAGE_NAME_3), is(notNullValue())); assertThat(settings.getPackageLPr(PACKAGE_NAME_1), is(notNullValue())); @@ -167,13 +170,13 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getContext(); final Object lock = new Object(); Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); assertThat(settings.readLPw(createFakeUsers()), is(true)); settings.writeLPr(); // Create Settings again to make it read from the new files settings = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); assertThat(settings.readLPw(createFakeUsers()), is(true)); PackageSetting ps = settings.getPackageLPr(PACKAGE_NAME_2); @@ -196,7 +199,8 @@ public class PackageManagerSettingsTests { writePackageRestrictions_noSuspendingPackageXml(0); final Object lock = new Object(); final Context context = InstrumentationRegistry.getTargetContext(); - final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, lock); + final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, null, + lock); settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1)); settingsUnderTest.mPackages.put(PACKAGE_NAME_2, createPackageSetting(PACKAGE_NAME_2)); settingsUnderTest.readPackageRestrictionsLPr(0); @@ -219,7 +223,8 @@ public class PackageManagerSettingsTests { writePackageRestrictions_noSuspendParamsMapXml(0); final Object lock = new Object(); final Context context = InstrumentationRegistry.getTargetContext(); - final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, lock); + final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, null, + lock); settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1)); settingsUnderTest.readPackageRestrictionsLPr(0); @@ -246,7 +251,7 @@ public class PackageManagerSettingsTests { @Test public void testReadWritePackageRestrictions_suspendInfo() { final Context context = InstrumentationRegistry.getTargetContext(); - final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, + final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, null, new Object()); final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1); final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2); @@ -344,7 +349,7 @@ public class PackageManagerSettingsTests { @Test public void testReadWritePackageRestrictions_distractionFlags() { final Context context = InstrumentationRegistry.getTargetContext(); - final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, + final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, null, new Object()); final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1); final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2); @@ -389,7 +394,7 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getTargetContext(); final Object lock = new Object(); final Settings settingsUnderTest = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1); ps1.appId = Process.FIRST_APPLICATION_UID; ps1.pkg = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed()) @@ -465,7 +470,7 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getContext(); final Object lock = new Object(); Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); assertThat(settings.readLPw(createFakeUsers()), is(true)); // Enable/Disable a package @@ -638,7 +643,7 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getContext(); final Object lock = new Object(); final Settings testSettings01 = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); final SharedUserSetting testUserSetting01 = createSharedUserSetting( testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/); final PackageSetting testPkgSetting01 = @@ -748,7 +753,7 @@ public class PackageManagerSettingsTests { final Context context = InstrumentationRegistry.getContext(); final Object lock = new Object(); final Settings testSettings01 = new Settings(context.getFilesDir(), mPermissionSettings, - mRuntimePermissionsPersistence, lock); + mRuntimePermissionsPersistence, mPermissionDataProvider, lock); final SharedUserSetting testUserSetting01 = createSharedUserSetting( testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/); final PackageSetting testPkgSetting01 = Settings.createNewSetting( |
