Merge changes from topic "DoNotCallAppOpsFromPermMananager" into qt-dev

* changes:
  Use PermissionPolicySve for fg perm app-ops
  Make perm policy synchronizer per user
  Make perm policy sve ready for additional usages
This commit is contained in:
Philip P. Moltmann
2019-04-11 22:35:14 +00:00
committed by Android (Google) Code Review
2 changed files with 264 additions and 242 deletions

View File

@@ -18,12 +18,6 @@ package com.android.server.pm.permission;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.permissionToOp;
import static android.app.AppOpsManager.permissionToOpCode;
import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
@@ -40,8 +34,6 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRAD
import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
import static android.content.pm.PackageManager.RESTRICTED_PERMISSIONS_ENABLED;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.UserHandle.getAppId;
import static android.os.UserHandle.getUid;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
@@ -56,8 +48,6 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.AppOpsManagerInternal;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PermissionWhitelistFlags;
@@ -1309,9 +1299,6 @@ public class PermissionManagerService {
updatedUserIds);
updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
permissionsState, pkg, updatedUserIds);
// TODO: Move to PermissionPolicyService
setAppOpsLocked(permissionsState, pkg);
}
// Persist the runtime permissions state for users with changes. If permissions
@@ -1326,23 +1313,6 @@ public class PermissionManagerService {
}
}
/**
* Set app op for a app-op related to a permission.
*
* @param permission The permission the app-op belongs to
* @param pkg The package the permission belongs to
* @param userId The user to be changed
* @param mode The new mode to set
*/
private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg,
@UserIdInt int userId, int mode) {
AppOpsManagerInternal appOpsInternal = LocalServices.getService(
AppOpsManagerInternal.class);
appOpsInternal.setUidMode(permissionToOpCode(permission),
getUid(userId, getAppId(pkg.applicationInfo.uid)), mode);
}
/**
* Revoke permissions that are not implicit anymore and that have
* {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
@@ -1357,8 +1327,6 @@ public class PermissionManagerService {
private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
@NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
@NonNull int[] updatedUserIds) {
AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
String pkgName = pkg.packageName;
boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
>= Build.VERSION_CODES.M;
@@ -1390,23 +1358,6 @@ public class PermissionManagerService {
}
flagsToRemove |= USER_PERMISSION_FLAGS;
List<String> fgPerms = mBackgroundPermissions.get(permission);
if (fgPerms != null) {
int numFgPerms = fgPerms.size();
for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
String fgPerm = fgPerms.get(fgPermNum);
int mode = appOpsManager.unsafeCheckOpRaw(
permissionToOp(fgPerm),
getUid(userId, getAppId(pkg.applicationInfo.uid)),
pkgName);
if (mode == MODE_ALLOWED) {
setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND);
}
}
}
}
ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
@@ -1438,91 +1389,39 @@ public class PermissionManagerService {
@NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
@NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
@UserIdInt int userId) {
AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class);
String pkgName = pkg.packageName;
boolean isGranted = false;
int flags = 0;
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
if (permissionToOp(newPerm) != null) {
int mostLenientSourceMode = MODE_ERRORED;
int flags = 0;
// Find most lenient source permission state.
int numSourcePerms = sourcePerms.size();
for (int i = 0; i < numSourcePerms; i++) {
String sourcePerm = sourcePerms.valueAt(i);
if (ps.hasRuntimePermission(sourcePerm, userId)) {
int sourceOp = permissionToOpCode(sourcePerm);
if (sourceOp != OP_NONE) {
int mode = appOpsManager.checkOperationUnchecked(sourceOp,
getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);
if (mode == MODE_FOREGROUND || mode == MODE_ERRORED) {
Log.wtf(TAG, "split permission" + sourcePerm + " has app-op state "
+ AppOpsManager.MODE_NAMES[mode]);
continue;
}
// Leniency order: allowed < ignored < default
if (mode < mostLenientSourceMode) {
mostLenientSourceMode = mode;
flags = ps.getPermissionFlags(sourcePerm, userId);
} else if (mode == mostLenientSourceMode) {
flags |= ps.getPermissionFlags(sourcePerm, userId);
}
}
}
int numSourcePerm = sourcePerms.size();
for (int i = 0; i < numSourcePerm; i++) {
String sourcePerm = sourcePerms.valueAt(i);
if ((ps.hasRuntimePermission(sourcePerm, userId))
|| ps.hasInstallPermission(sourcePerm)) {
if (!isGranted) {
flags = 0;
}
if (mostLenientSourceMode != MODE_ERRORED) {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode
+ " from " + sourcePerms + " for " + pkgName);
}
setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode);
// Add permission flags
ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags,
flags);
}
}
} else {
boolean isGranted = false;
int flags = 0;
int numSourcePerm = sourcePerms.size();
for (int i = 0; i < numSourcePerm; i++) {
String sourcePerm = sourcePerms.valueAt(i);
if ((ps.hasRuntimePermission(sourcePerm, userId))
|| ps.hasInstallPermission(sourcePerm)) {
if (!isGranted) {
flags = 0;
}
isGranted = true;
isGranted = true;
flags |= ps.getPermissionFlags(sourcePerm, userId);
} else {
if (!isGranted) {
flags |= ps.getPermissionFlags(sourcePerm, userId);
} else {
if (!isGranted) {
flags |= ps.getPermissionFlags(sourcePerm, userId);
}
}
}
if (isGranted) {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
+ " for " + pkgName);
}
ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
}
// Add permission flags
ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
}
if (isGranted) {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
+ " for " + pkgName);
}
ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
}
// Add permission flags
ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
}
/**
@@ -1632,48 +1531,6 @@ public class PermissionManagerService {
return updatedUserIds;
}
/**
* Fix app-op modes for runtime permissions.
*
* @param permsState The state of the permissions of the package
* @param pkg The package information
*/
private void setAppOpsLocked(@NonNull PermissionsState permsState,
@NonNull PackageParser.Package pkg) {
for (int userId : UserManagerService.getInstance().getUserIds()) {
int numPerms = pkg.requestedPermissions.size();
for (int i = 0; i < numPerms; i++) {
String permission = pkg.requestedPermissions.get(i);
// For pre-M apps the runtime permission do not store the state
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
continue;
}
PermissionState state = permsState.getRuntimePermissionState(permission, userId);
if (state == null) {
continue;
}
// Adjust app-op mods for foreground/background permissions. If an package used to
// have both fg and bg permission granted and it lost the bg permission during an
// upgrade the app-op mode should get downgraded to foreground.
if (state.isGranted()) {
BasePermission bp = mSettings.getPermission(permission);
if (bp != null && bp.perm != null && bp.perm.info != null
&& bp.perm.info.backgroundPermission != null) {
PermissionState bgState = permsState.getRuntimePermissionState(
bp.perm.info.backgroundPermission, userId);
setAppOpMode(permission, pkg, userId, bgState != null && bgState.isGranted()
? MODE_ALLOWED : MODE_FOREGROUND);
}
}
}
}
}
private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
boolean allowed = false;
final int NP = PackageParser.NEW_PERMISSIONS.length;

View File

@@ -17,8 +17,10 @@
package com.android.server.policy;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.content.Context;
@@ -29,6 +31,7 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackageListObserver;
import android.content.pm.PackageParser;
import android.content.pm.PermissionInfo;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.permission.PermissionControllerManager;
@@ -158,37 +161,59 @@ public final class PermissionPolicyService extends SystemService {
});
}
private static @Nullable Context getUserContext(@NonNull Context context,
@NonNull UserHandle user) {
if (context.getUser().equals(user)) {
return context;
} else {
try {
return context.createPackageContextAsUser(context.getPackageName(), 0, user);
} catch (NameNotFoundException e) {
Slog.e(LOG_TAG, "Cannot create context for user " + user, e);
return null;
}
}
}
/**
* Synchronize a single package.
*/
private static void synchronizePackagePermissionsAndAppOpsForUser(@NonNull Context context,
@NonNull String packageName, @UserIdInt int userId) {
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
PackageManagerInternal.class);
final PackageParser.Package pkg = packageManagerInternal.getPackage(packageName);
final PackageInfo pkg = packageManagerInternal.getPackageInfo(packageName, 0,
Process.SYSTEM_UID, userId);
if (pkg == null) {
return;
}
final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(context);
synchroniser.addPackage(context, pkg, userId);
final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(
getUserContext(context, UserHandle.of(userId)));
synchroniser.addPackage(pkg.packageName);
final String[] sharedPkgNames = packageManagerInternal.getPackagesForSharedUserId(
pkg.mSharedUserId, userId);
pkg.sharedUserId, userId);
if (sharedPkgNames != null) {
for (String sharedPkgName : sharedPkgNames) {
final PackageParser.Package sharedPkg = packageManagerInternal
.getPackage(sharedPkgName);
if (sharedPkg != null) {
synchroniser.addPackage(context, sharedPkg, userId);
synchroniser.addPackage(sharedPkg.packageName);
}
}
}
synchroniser.syncPackages();
}
/**
* Synchronize all packages
*/
private static void synchronizePermissionsAndAppOpsForUser(@NonNull Context context,
@UserIdInt int userId) {
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
PackageManagerInternal.class);
final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser(context);
packageManagerInternal.forEachPackage((pkg) ->
synchronizer.addPackage(context, pkg, userId));
final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser(
getUserContext(context, UserHandle.of(userId)));
packageManagerInternal.forEachPackage((pkg) -> synchronizer.addPackage(pkg.packageName));
synchronizer.syncPackages();
}
@@ -198,17 +223,47 @@ public final class PermissionPolicyService extends SystemService {
*/
private static class PermissionToOpSynchroniser {
private final @NonNull Context mContext;
private final @NonNull PackageManager mPackageManager;
private final @NonNull AppOpsManager mAppOpsManager;
private final @NonNull SparseIntArray mUids = new SparseIntArray();
private final @NonNull SparseArray<String> mPackageNames = new SparseArray<>();
private final @NonNull SparseIntArray mAllowedUidOps = new SparseIntArray();
private final @NonNull SparseIntArray mDefaultUidOps = new SparseIntArray();
/** All uid that need to be synchronized */
private final @NonNull SparseIntArray mAllUids = new SparseIntArray();
/**
* All ops that need to be restricted
*
* @see #syncRestrictedOps
*/
private final @NonNull ArrayList<OpToRestrict> mOpsToRestrict = new ArrayList<>();
/**
* All ops that need to be unrestricted
*
* @see #syncRestrictedOps
*/
private final @NonNull ArrayList<OpToUnrestrict> mOpsToUnrestrict = new ArrayList<>();
/**
* All foreground permissions
*
* @see #syncOpsOfFgPermissions()
*/
private final @NonNull ArrayList<FgPermission> mFgPermOps = new ArrayList<>();
PermissionToOpSynchroniser(@NonNull Context context) {
mContext = context;
mPackageManager = context.getPackageManager();
mAppOpsManager = context.getSystemService(AppOpsManager.class);
}
void syncPackages() {
/**
* Set app ops that belong to restricted permissions.
*
* <p>This processes ops previously added by {@link #addOpIfRestricted}
*/
private void syncRestrictedOps() {
final SparseIntArray unprocessedUids = mAllUids.clone();
// TRICKY: we set the app op for a restricted permission to allow if the app
// requesting the permission is whitelisted and to deny if the app requesting
// the permission is not whitelisted. However, there is another case where an
@@ -222,52 +277,48 @@ public final class PermissionPolicyService extends SystemService {
final SparseArray<List<String>> unrequestedRestrictedPermissionsForUid =
new SparseArray<>();
final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
final int allowedCount = mAllowedUidOps.size();
for (int i = 0; i < allowedCount; i++) {
final int opCode = mAllowedUidOps.keyAt(i);
final int uid = mAllowedUidOps.valueAt(i);
final String packageName = mPackageNames.valueAt(i);
setUidModeAllowed(appOpsManager, opCode, uid, packageName);
final int unrestrictCount = mOpsToUnrestrict.size();
for (int i = 0; i < unrestrictCount; i++) {
final OpToUnrestrict op = mOpsToUnrestrict.get(i);
setUidModeAllowed(op.code, op.uid, op.packageName);
// Keep track this permission was requested by the UID.
List<String> unrequestedRestrictedPermissions =
unrequestedRestrictedPermissionsForUid.get(uid);
unrequestedRestrictedPermissionsForUid.get(op.uid);
if (unrequestedRestrictedPermissions == null) {
unrequestedRestrictedPermissions = new ArrayList<>(sAllRestrictedPermissions);
unrequestedRestrictedPermissionsForUid.put(uid,
unrequestedRestrictedPermissionsForUid.put(op.uid,
unrequestedRestrictedPermissions);
}
unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(opCode));
unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(op.code));
mUids.delete(uid);
unprocessedUids.delete(op.uid);
}
final int defaultCount = mDefaultUidOps.size();
for (int i = 0; i < defaultCount; i++) {
final int opCode = mDefaultUidOps.keyAt(i);
final int uid = mDefaultUidOps.valueAt(i);
setUidModeDefault(appOpsManager, opCode, uid);
final int restrictCount = mOpsToRestrict.size();
for (int i = 0; i < restrictCount; i++) {
final OpToRestrict op = mOpsToRestrict.get(i);
setUidModeDefault(op.code, op.uid);
// Keep track this permission was requested by the UID.
List<String> unrequestedRestrictedPermissions =
unrequestedRestrictedPermissionsForUid.get(uid);
unrequestedRestrictedPermissionsForUid.get(op.uid);
if (unrequestedRestrictedPermissions == null) {
unrequestedRestrictedPermissions = new ArrayList<>(sAllRestrictedPermissions);
unrequestedRestrictedPermissionsForUid.put(uid,
unrequestedRestrictedPermissionsForUid.put(op.uid,
unrequestedRestrictedPermissions);
}
unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(opCode));
unrequestedRestrictedPermissions.remove(AppOpsManager.opToPermission(op.code));
mUids.delete(uid);
unprocessedUids.delete(op.uid);
}
// Give root access
mUids.put(Process.ROOT_UID, Process.ROOT_UID);
unprocessedUids.put(Process.ROOT_UID, Process.ROOT_UID);
// Add records for UIDs that don't use any restricted permissions.
final int uidCount = mUids.size();
final int uidCount = unprocessedUids.size();
for (int i = 0; i < uidCount; i++) {
final int uid = mUids.keyAt(i);
final int uid = unprocessedUids.keyAt(i);
unrequestedRestrictedPermissionsForUid.put(uid,
new ArrayList<>(sAllRestrictedPermissions));
}
@@ -280,7 +331,7 @@ public final class PermissionPolicyService extends SystemService {
if (unrequestedRestrictedPermissions != null) {
final int uid = unrequestedRestrictedPermissionsForUid.keyAt(i);
final String[] packageNames = (uid != Process.ROOT_UID)
? mContext.getPackageManager().getPackagesForUid(uid)
? mPackageManager.getPackagesForUid(uid)
: new String[] {"root"};
if (packageNames == null) {
continue;
@@ -289,8 +340,7 @@ public final class PermissionPolicyService extends SystemService {
for (int j = 0; j < permissionCount; j++) {
final String permission = unrequestedRestrictedPermissions.get(j);
for (String packageName : packageNames) {
setUidModeAllowed(appOpsManager,
AppOpsManager.permissionToOpCode(permission), uid,
setUidModeAllowed(AppOpsManager.permissionToOpCode(permission), uid,
packageName);
}
}
@@ -298,19 +348,115 @@ public final class PermissionPolicyService extends SystemService {
}
}
private void addPackage(@NonNull Context context,
@NonNull PackageParser.Package pkg, @UserIdInt int userId) {
final PackageManager packageManager = context.getPackageManager();
/**
* Set app ops that belong to restricted permissions.
*
* <p>This processed ops previously added by {@link #addOpIfRestricted}
*/
private void syncOpsOfFgPermissions() {
int numFgPermOps = mFgPermOps.size();
for (int i = 0; i < numFgPermOps; i++) {
FgPermission perm = mFgPermOps.get(i);
final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.applicationInfo.uid));
final UserHandle userHandle = UserHandle.of(userId);
if (mPackageManager.checkPermission(perm.fgPermissionName, perm.packageName)
== PackageManager.PERMISSION_GRANTED) {
if (mPackageManager.checkPermission(perm.bgPermissionName, perm.packageName)
== PackageManager.PERMISSION_GRANTED) {
mAppOpsManager.setUidMode(
AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
AppOpsManager.MODE_ALLOWED);
} else {
mAppOpsManager.setUidMode(
AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
AppOpsManager.MODE_FOREGROUND);
}
} else {
mAppOpsManager.setUidMode(
AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
AppOpsManager.MODE_IGNORED);
}
}
}
mUids.put(uid, uid);
/**
* Synchronize all previously {@link #addPackage added} packages.
*/
void syncPackages() {
syncRestrictedOps();
syncOpsOfFgPermissions();
}
final int permissionCount = pkg.requestedPermissions.size();
for (int i = 0; i < permissionCount; i++) {
final String permission = pkg.requestedPermissions.get(i);
/**
* Add op that belong to a restricted permission for later processing in
* {@link #syncRestrictedOps}.
*
* <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
*
* @param permissionInfo The permission that is currently looked at
* @param pkg The package looked at
*/
private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
@NonNull PackageInfo pkg) {
final String permission = permissionInfo.name;
final int opCode = AppOpsManager.permissionToOpCode(permission);
final int uid = pkg.applicationInfo.uid;
if (!permissionInfo.isRestricted()) {
return;
}
final boolean applyRestriction = PackageManager.RESTRICTED_PERMISSIONS_ENABLED
&& (mPackageManager.getPermissionFlags(permission, pkg.packageName,
mContext.getUser()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
if (permissionInfo.isHardRestricted()) {
if (applyRestriction) {
mOpsToRestrict.add(new OpToRestrict(uid, opCode));
} else {
mOpsToUnrestrict.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
}
} else if (permissionInfo.isSoftRestricted()) {
//TODO: Implement soft restrictions like storage here.
}
}
private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo,
@NonNull PackageInfo pkg) {
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
// Pre-M apps do not store their fg/bg state in the permissions
return;
}
if (permissionInfo.backgroundPermission == null) {
return;
}
mFgPermOps.add(new FgPermission(pkg.applicationInfo.uid, pkg.packageName,
permissionInfo.name, permissionInfo.backgroundPermission));
}
/**
* Add a package for {@link #syncPackages() processing} later.
*
* <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
*
* @param pkgName The package to add for later processing.
*/
void addPackage(@NonNull String pkgName) {
final PackageInfo pkg;
try {
pkg = mPackageManager.getPackageInfo(pkgName, GET_PERMISSIONS);
} catch (NameNotFoundException e) {
return;
}
mAllUids.put(pkg.applicationInfo.uid, pkg.applicationInfo.uid);
if (pkg.requestedPermissions == null) {
return;
}
for (String permission : pkg.requestedPermissions) {
final int opCode = AppOpsManager.permissionToOpCode(permission);
if (opCode == AppOpsManager.OP_NONE) {
continue;
@@ -318,44 +464,63 @@ public final class PermissionPolicyService extends SystemService {
final PermissionInfo permissionInfo;
try {
permissionInfo = packageManager.getPermissionInfo(permission, 0);
permissionInfo = mPackageManager.getPermissionInfo(permission, 0);
} catch (PackageManager.NameNotFoundException e) {
continue;
}
if (!permissionInfo.isRestricted()) {
continue;
}
final boolean applyRestriction = PackageManager.RESTRICTED_PERMISSIONS_ENABLED
&& (packageManager.getPermissionFlags(permission, pkg.packageName,
userHandle) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
if (permissionInfo.isHardRestricted()) {
if (applyRestriction) {
mDefaultUidOps.put(opCode, uid);
} else {
mPackageNames.put(opCode, pkg.packageName);
mAllowedUidOps.put(opCode, uid);
}
} else if (permissionInfo.isSoftRestricted()) {
//TODO: Implement soft restrictions like storage here.
}
addOpIfRestricted(permissionInfo, pkg);
addOpIfFgPermissions(permissionInfo, pkg);
}
}
private static void setUidModeAllowed(@NonNull AppOpsManager appOpsManager,
int opCode, int uid, @NonNull String packageName) {
final int currentMode = appOpsManager.unsafeCheckOpRaw(AppOpsManager
private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
.opToPublicName(opCode), uid, packageName);
if (currentMode == AppOpsManager.MODE_DEFAULT) {
appOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
}
}
private static void setUidModeDefault(@NonNull AppOpsManager appOpsManager,
int opCode, int uid) {
appOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_DEFAULT);
private void setUidModeDefault(int opCode, int uid) {
mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_DEFAULT);
}
private class OpToRestrict {
final int uid;
final int code;
OpToRestrict(int uid, int code) {
this.uid = uid;
this.code = code;
}
}
private class OpToUnrestrict {
final int uid;
final @NonNull String packageName;
final int code;
OpToUnrestrict(int uid, @NonNull String packageName, int code) {
this.uid = uid;
this.packageName = packageName;
this.code = code;
}
}
private class FgPermission {
final int uid;
final @NonNull String packageName;
final @NonNull String fgPermissionName;
final @NonNull String bgPermissionName;
private FgPermission(int uid, @NonNull String packageName,
@NonNull String fgPermissionName, @NonNull String bgPermissionName) {
this.uid = uid;
this.packageName = packageName;
this.fgPermissionName = fgPermissionName;
this.bgPermissionName = bgPermissionName;
}
}
}
}