Loading services/core/java/com/android/server/policy/PermissionPolicyService.java +95 −125 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal.PackageListObserver; import android.content.pm.PermissionInfo; import android.content.pm.parsing.AndroidPackage; import android.os.Build; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading @@ -50,15 +52,14 @@ import android.telecom.TelecomManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LongSparseLongArray; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.infra.AndroidFuture; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IntPair; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.FgThread; Loading @@ -69,7 +70,6 @@ import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.ExecutionException; /** Loading Loading @@ -100,7 +100,7 @@ public final class PermissionPolicyService extends SystemService { * scheduled for a package/user. */ @GuardedBy("mLock") private final ArraySet<Integer> mIsPackageSyncsScheduled = new ArraySet<>(); private final ArraySet<Pair<String, Integer>> mIsPackageSyncsScheduled = new ArraySet<>(); public PermissionPolicyService(@NonNull Context context) { super(context); Loading @@ -125,8 +125,10 @@ public final class PermissionPolicyService extends SystemService { @Override public void onPackageChanged(String packageName, int uid) { if (isStarted(UserHandle.getUserId(uid))) { synchronizePackagePermissionsAndAppOpsForUser(uid); final int userId = UserHandle.getUserId(uid); if (isStarted(userId)) { synchronizePackagePermissionsAndAppOpsForUser(packageName, userId); } } Loading @@ -137,21 +139,12 @@ public final class PermissionPolicyService extends SystemService { }); permManagerInternal.addOnRuntimePermissionStateChangedListener( (packageName, userId) -> { int uid; try { uid = getContext().getPackageManager().getPackageUidAsUser(packageName, 0, userId); } catch (NameNotFoundException e) { Slog.e(LOG_TAG, "Cannot synchronize changed package " + packageName, e); return; } synchronizeUidPermissionsAndAppOpsAsync(uid); }); this::synchronizePackagePermissionsAndAppOpsAsyncForUser); mAppOpsCallback = new IAppOpsCallback.Stub() { public void opChanged(int op, int uid, String packageName) { synchronizeUidPermissionsAndAppOpsAsync(uid); synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName, UserHandle.getUserId(uid)); } }; Loading Loading @@ -201,17 +194,19 @@ public final class PermissionPolicyService extends SystemService { return AppOpsManager.opToSwitch(op); } private void synchronizeUidPermissionsAndAppOpsAsync(int uid) { if (isStarted(UserHandle.getUserId(uid))) { private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName, @UserIdInt int changedUserId) { if (isStarted(changedUserId)) { synchronized (mLock) { if (mIsPackageSyncsScheduled.add(uid)) { if (mIsPackageSyncsScheduled.add(new Pair<>(packageName, changedUserId))) { FgThread.getHandler().sendMessage(PooledLambda.obtainMessage( PermissionPolicyService ::synchronizePackagePermissionsAndAppOpsForUser, this, uid)); this, packageName, changedUserId)); } else { if (DEBUG) { Slog.v(LOG_TAG, "sync for " + uid + " already scheduled"); Slog.v(LOG_TAG, "sync for " + packageName + "/" + changedUserId + " already scheduled"); } } } Loading Loading @@ -340,20 +335,39 @@ public final class PermissionPolicyService extends SystemService { /** * Synchronize a single package. */ private void synchronizePackagePermissionsAndAppOpsForUser(int uid) { private void synchronizePackagePermissionsAndAppOpsForUser(@NonNull String packageName, @UserIdInt int userId) { synchronized (mLock) { mIsPackageSyncsScheduled.remove(uid); mIsPackageSyncsScheduled.remove(new Pair<>(packageName, userId)); } if (DEBUG) { Slog.v(LOG_TAG, "synchronizePackagePermissionsAndAppOpsForUser(" + uid + ")"); "synchronizePackagePermissionsAndAppOpsForUser(" + packageName + ", " + userId + ")"); } final PackageManagerInternal packageManagerInternal = LocalServices.getService( PackageManagerInternal.class); final PackageInfo pkg = packageManagerInternal.getPackageInfo(packageName, 0, Process.SYSTEM_UID, userId); if (pkg == null) { return; } final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser( getUserContext(getContext(), UserHandle.getUserHandleForUid(uid))); synchroniser.addUid(uid); synchroniser.syncUids(); getUserContext(getContext(), UserHandle.of(userId))); synchroniser.addPackage(pkg.packageName); final String[] sharedPkgNames = packageManagerInternal.getSharedUserPackagesForPackage( pkg.packageName, userId); for (String sharedPkgName : sharedPkgNames) { final AndroidPackage sharedPkg = packageManagerInternal .getPackage(sharedPkgName); if (sharedPkg != null) { synchroniser.addPackage(sharedPkg.getPackageName()); } } synchroniser.syncPackages(); } /** Loading @@ -367,8 +381,8 @@ public final class PermissionPolicyService extends SystemService { final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser( getUserContext(getContext(), UserHandle.of(userId))); packageManagerInternal.forEachPackage( (pkg) -> synchronizer.addUid(pkg.getUid())); synchronizer.syncUids(); (pkg) -> synchronizer.addPackage(pkg.getPackageName())); synchronizer.syncPackages(); } /** Loading @@ -383,51 +397,37 @@ public final class PermissionPolicyService extends SystemService { private final @NonNull ArrayMap<String, PermissionInfo> mRuntimePermissionInfos; // Cache uid -> packageNames private SparseArray<String[]> mUidToPkg = new SparseArray<>(); /** * All ops that need to be flipped to allow. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToAllow = new ArraySet<>(); private final @NonNull ArrayList<OpToChange> mOpsToAllow = new ArrayList<>(); /** * All ops that need to be flipped to ignore. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToIgnore = new ArraySet<>(); private final @NonNull ArrayList<OpToChange> mOpsToIgnore = new ArrayList<>(); /** * All ops that need to be flipped to ignore if not allowed. * * Currently, only used by soft restricted permissions logic. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToIgnoreIfNotAllowed = new ArraySet<>(); private final @NonNull ArrayList<OpToChange> mOpsToIgnoreIfNotAllowed = new ArrayList<>(); /** * All ops that need to be flipped to foreground. * * Currently, only used by the foreground/background permissions logic. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToForeground = new ArraySet<>(); private @Nullable String[] getPackageNamesForUid(int uid) { String[] pkgs = mUidToPkg.get(uid); if (pkgs != null) { return pkgs; } pkgs = mPackageManager.getPackagesForUid(uid); mUidToPkg.put(uid, pkgs); return pkgs; } private final @NonNull ArrayList<OpToChange> mOpsToForeground = new ArrayList<>(); PermissionToOpSynchroniser(@NonNull Context context) { mContext = context; Loading @@ -449,11 +449,11 @@ public final class PermissionPolicyService extends SystemService { } /** * Set app ops that were added in {@link #addUid}. * Set app ops that were added in {@link #addPackage}. * * <p>This processes ops previously added by {@link #addAppOps(PackageInfo, String)} */ private void syncUids() { private void syncPackages() { // Remember which ops were already set. This makes sure that we always set the most // permissive mode if two OpChanges are scheduled. This can e.g. happen if two // permissions change the same op. See {@link #getSwitchOp}. Loading @@ -461,42 +461,42 @@ public final class PermissionPolicyService extends SystemService { final int allowCount = mOpsToAllow.size(); for (int i = 0; i < allowCount; i++) { final OpToChange op = mOpsToAllow.valueAt(i); final OpToChange op = mOpsToAllow.get(i); setUidModeAllowed(op.code, op.uid); setUidModeAllowed(op.code, op.uid, op.packageName); alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } final int foregroundCount = mOpsToForeground.size(); for (int i = 0; i < foregroundCount; i++) { final OpToChange op = mOpsToForeground.valueAt(i); final OpToChange op = mOpsToForeground.get(i); if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) { continue; } setUidModeForeground(op.code, op.uid); setUidModeForeground(op.code, op.uid, op.packageName); alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } final int ignoreCount = mOpsToIgnore.size(); for (int i = 0; i < ignoreCount; i++) { final OpToChange op = mOpsToIgnore.valueAt(i); final OpToChange op = mOpsToIgnore.get(i); if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) { continue; } setUidModeIgnored(op.code, op.uid); setUidModeIgnored(op.code, op.uid, op.packageName); alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } final int ignoreIfNotAllowedCount = mOpsToIgnoreIfNotAllowed.size(); for (int i = 0; i < ignoreIfNotAllowedCount; i++) { final OpToChange op = mOpsToIgnoreIfNotAllowed.valueAt(i); final OpToChange op = mOpsToIgnoreIfNotAllowed.get(i); if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) { continue; } boolean wasSet = setUidModeIgnoredIfNotAllowed(op.code, op.uid); boolean wasSet = setUidModeIgnoredIfNotAllowed(op.code, op.uid, op.packageName); if (wasSet) { alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } Loading Loading @@ -555,7 +555,7 @@ public final class PermissionPolicyService extends SystemService { } int uid = packageInfo.applicationInfo.uid; OpToChange opToChange = new OpToChange(uid, appOpCode); OpToChange opToChange = new OpToChange(uid, packageName, appOpCode); switch (appOpMode) { case MODE_ALLOWED: mOpsToAllow.add(opToChange); Loading Loading @@ -618,7 +618,8 @@ public final class PermissionPolicyService extends SystemService { } int uid = packageInfo.applicationInfo.uid; OpToChange extraOpToChange = new OpToChange(uid, extraOpCode); String packageName = packageInfo.packageName; OpToChange extraOpToChange = new OpToChange(uid, packageName, extraOpCode); if (policy.mayAllowExtraAppOp()) { mOpsToAllow.add(extraOpToChange); } else { Loading @@ -631,56 +632,45 @@ public final class PermissionPolicyService extends SystemService { } /** * Add a Uid for {@link #syncUids() processing} later. * 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 uid The uid to add for later processing. * @param pkgName The package to add for later processing. */ void addUid(int uid) { String[] pkgNames = getPackageNamesForUid(uid); if (pkgNames == null) { return; } for (String pkgName : pkgNames) { void addPackage(@NonNull String pkgName) { final PackageInfo pkg; try { pkg = mPackageManager.getPackageInfo(pkgName, GET_PERMISSIONS); } catch (NameNotFoundException e) { continue; return; } if (pkg.requestedPermissions == null) { continue; return; } for (String permission : pkg.requestedPermissions) { addAppOps(pkg, permission); } } } private void setUidModeAllowed(int opCode, int uid) { setUidMode(opCode, uid, MODE_ALLOWED); private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) { setUidMode(opCode, uid, MODE_ALLOWED, packageName); } private void setUidModeForeground(int opCode, int uid) { setUidMode(opCode, uid, MODE_FOREGROUND); private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) { setUidMode(opCode, uid, MODE_FOREGROUND, packageName); } private void setUidModeIgnored(int opCode, int uid) { setUidMode(opCode, uid, MODE_IGNORED); } private boolean setUidModeIgnoredIfNotAllowed(int opCode, int uid) { String[] pkgsOfUid = getPackageNamesForUid(uid); if (ArrayUtils.isEmpty(pkgsOfUid)) { return false; private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) { setUidMode(opCode, uid, MODE_IGNORED, packageName); } private boolean setUidModeIgnoredIfNotAllowed(int opCode, int uid, @NonNull String packageName) { final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager.opToPublicName( opCode), uid, pkgsOfUid[0]); opCode), uid, packageName); if (currentMode != MODE_ALLOWED) { if (currentMode != MODE_IGNORED) { mAppOpsManagerInternal.setUidModeFromPermissionPolicy(opCode, uid, MODE_IGNORED, Loading @@ -691,24 +681,20 @@ public final class PermissionPolicyService extends SystemService { return false; } private void setUidMode(int opCode, int uid, int mode) { String[] pkgsOfUid = getPackageNamesForUid(uid); if (ArrayUtils.isEmpty(pkgsOfUid)) { return; } private void setUidMode(int opCode, int uid, int mode, @NonNull String packageName) { final int oldMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager.opToPublicName( opCode), uid, pkgsOfUid[0]); opCode), uid, packageName); if (oldMode != mode) { mAppOpsManagerInternal.setUidModeFromPermissionPolicy(opCode, uid, mode, mAppOpsCallback); final int newMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager.opToPublicName( opCode), uid, pkgsOfUid[0]); opCode), uid, packageName); if (newMode != mode) { // Work around incorrectly-set package mode. It never makes sense for app ops // related to runtime permissions, but can get in the way and we have to reset // it. mAppOpsManagerInternal.setModeFromPermissionPolicy(opCode, uid, pkgsOfUid[0], mAppOpsManagerInternal.setModeFromPermissionPolicy(opCode, uid, packageName, AppOpsManager.opToDefaultMode(opCode), mAppOpsCallback); } } Loading @@ -716,30 +702,14 @@ public final class PermissionPolicyService extends SystemService { private class OpToChange { final int uid; final @NonNull String packageName; final int code; OpToChange(int uid, int code) { OpToChange(int uid, @NonNull String packageName, int code) { this.uid = uid; this.packageName = packageName; this.code = code; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } OpToChange other = (OpToChange) o; return uid == other.uid && code == other.code; } @Override public int hashCode() { return Objects.hash(uid, code); } } } Loading Loading
services/core/java/com/android/server/policy/PermissionPolicyService.java +95 −125 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal.PackageListObserver; import android.content.pm.PermissionInfo; import android.content.pm.parsing.AndroidPackage; import android.os.Build; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading @@ -50,15 +52,14 @@ import android.telecom.TelecomManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LongSparseLongArray; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.infra.AndroidFuture; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IntPair; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.FgThread; Loading @@ -69,7 +70,6 @@ import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.ExecutionException; /** Loading Loading @@ -100,7 +100,7 @@ public final class PermissionPolicyService extends SystemService { * scheduled for a package/user. */ @GuardedBy("mLock") private final ArraySet<Integer> mIsPackageSyncsScheduled = new ArraySet<>(); private final ArraySet<Pair<String, Integer>> mIsPackageSyncsScheduled = new ArraySet<>(); public PermissionPolicyService(@NonNull Context context) { super(context); Loading @@ -125,8 +125,10 @@ public final class PermissionPolicyService extends SystemService { @Override public void onPackageChanged(String packageName, int uid) { if (isStarted(UserHandle.getUserId(uid))) { synchronizePackagePermissionsAndAppOpsForUser(uid); final int userId = UserHandle.getUserId(uid); if (isStarted(userId)) { synchronizePackagePermissionsAndAppOpsForUser(packageName, userId); } } Loading @@ -137,21 +139,12 @@ public final class PermissionPolicyService extends SystemService { }); permManagerInternal.addOnRuntimePermissionStateChangedListener( (packageName, userId) -> { int uid; try { uid = getContext().getPackageManager().getPackageUidAsUser(packageName, 0, userId); } catch (NameNotFoundException e) { Slog.e(LOG_TAG, "Cannot synchronize changed package " + packageName, e); return; } synchronizeUidPermissionsAndAppOpsAsync(uid); }); this::synchronizePackagePermissionsAndAppOpsAsyncForUser); mAppOpsCallback = new IAppOpsCallback.Stub() { public void opChanged(int op, int uid, String packageName) { synchronizeUidPermissionsAndAppOpsAsync(uid); synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName, UserHandle.getUserId(uid)); } }; Loading Loading @@ -201,17 +194,19 @@ public final class PermissionPolicyService extends SystemService { return AppOpsManager.opToSwitch(op); } private void synchronizeUidPermissionsAndAppOpsAsync(int uid) { if (isStarted(UserHandle.getUserId(uid))) { private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName, @UserIdInt int changedUserId) { if (isStarted(changedUserId)) { synchronized (mLock) { if (mIsPackageSyncsScheduled.add(uid)) { if (mIsPackageSyncsScheduled.add(new Pair<>(packageName, changedUserId))) { FgThread.getHandler().sendMessage(PooledLambda.obtainMessage( PermissionPolicyService ::synchronizePackagePermissionsAndAppOpsForUser, this, uid)); this, packageName, changedUserId)); } else { if (DEBUG) { Slog.v(LOG_TAG, "sync for " + uid + " already scheduled"); Slog.v(LOG_TAG, "sync for " + packageName + "/" + changedUserId + " already scheduled"); } } } Loading Loading @@ -340,20 +335,39 @@ public final class PermissionPolicyService extends SystemService { /** * Synchronize a single package. */ private void synchronizePackagePermissionsAndAppOpsForUser(int uid) { private void synchronizePackagePermissionsAndAppOpsForUser(@NonNull String packageName, @UserIdInt int userId) { synchronized (mLock) { mIsPackageSyncsScheduled.remove(uid); mIsPackageSyncsScheduled.remove(new Pair<>(packageName, userId)); } if (DEBUG) { Slog.v(LOG_TAG, "synchronizePackagePermissionsAndAppOpsForUser(" + uid + ")"); "synchronizePackagePermissionsAndAppOpsForUser(" + packageName + ", " + userId + ")"); } final PackageManagerInternal packageManagerInternal = LocalServices.getService( PackageManagerInternal.class); final PackageInfo pkg = packageManagerInternal.getPackageInfo(packageName, 0, Process.SYSTEM_UID, userId); if (pkg == null) { return; } final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser( getUserContext(getContext(), UserHandle.getUserHandleForUid(uid))); synchroniser.addUid(uid); synchroniser.syncUids(); getUserContext(getContext(), UserHandle.of(userId))); synchroniser.addPackage(pkg.packageName); final String[] sharedPkgNames = packageManagerInternal.getSharedUserPackagesForPackage( pkg.packageName, userId); for (String sharedPkgName : sharedPkgNames) { final AndroidPackage sharedPkg = packageManagerInternal .getPackage(sharedPkgName); if (sharedPkg != null) { synchroniser.addPackage(sharedPkg.getPackageName()); } } synchroniser.syncPackages(); } /** Loading @@ -367,8 +381,8 @@ public final class PermissionPolicyService extends SystemService { final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser( getUserContext(getContext(), UserHandle.of(userId))); packageManagerInternal.forEachPackage( (pkg) -> synchronizer.addUid(pkg.getUid())); synchronizer.syncUids(); (pkg) -> synchronizer.addPackage(pkg.getPackageName())); synchronizer.syncPackages(); } /** Loading @@ -383,51 +397,37 @@ public final class PermissionPolicyService extends SystemService { private final @NonNull ArrayMap<String, PermissionInfo> mRuntimePermissionInfos; // Cache uid -> packageNames private SparseArray<String[]> mUidToPkg = new SparseArray<>(); /** * All ops that need to be flipped to allow. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToAllow = new ArraySet<>(); private final @NonNull ArrayList<OpToChange> mOpsToAllow = new ArrayList<>(); /** * All ops that need to be flipped to ignore. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToIgnore = new ArraySet<>(); private final @NonNull ArrayList<OpToChange> mOpsToIgnore = new ArrayList<>(); /** * All ops that need to be flipped to ignore if not allowed. * * Currently, only used by soft restricted permissions logic. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToIgnoreIfNotAllowed = new ArraySet<>(); private final @NonNull ArrayList<OpToChange> mOpsToIgnoreIfNotAllowed = new ArrayList<>(); /** * All ops that need to be flipped to foreground. * * Currently, only used by the foreground/background permissions logic. * * @see #syncUids * @see #syncPackages */ private final @NonNull ArraySet<OpToChange> mOpsToForeground = new ArraySet<>(); private @Nullable String[] getPackageNamesForUid(int uid) { String[] pkgs = mUidToPkg.get(uid); if (pkgs != null) { return pkgs; } pkgs = mPackageManager.getPackagesForUid(uid); mUidToPkg.put(uid, pkgs); return pkgs; } private final @NonNull ArrayList<OpToChange> mOpsToForeground = new ArrayList<>(); PermissionToOpSynchroniser(@NonNull Context context) { mContext = context; Loading @@ -449,11 +449,11 @@ public final class PermissionPolicyService extends SystemService { } /** * Set app ops that were added in {@link #addUid}. * Set app ops that were added in {@link #addPackage}. * * <p>This processes ops previously added by {@link #addAppOps(PackageInfo, String)} */ private void syncUids() { private void syncPackages() { // Remember which ops were already set. This makes sure that we always set the most // permissive mode if two OpChanges are scheduled. This can e.g. happen if two // permissions change the same op. See {@link #getSwitchOp}. Loading @@ -461,42 +461,42 @@ public final class PermissionPolicyService extends SystemService { final int allowCount = mOpsToAllow.size(); for (int i = 0; i < allowCount; i++) { final OpToChange op = mOpsToAllow.valueAt(i); final OpToChange op = mOpsToAllow.get(i); setUidModeAllowed(op.code, op.uid); setUidModeAllowed(op.code, op.uid, op.packageName); alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } final int foregroundCount = mOpsToForeground.size(); for (int i = 0; i < foregroundCount; i++) { final OpToChange op = mOpsToForeground.valueAt(i); final OpToChange op = mOpsToForeground.get(i); if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) { continue; } setUidModeForeground(op.code, op.uid); setUidModeForeground(op.code, op.uid, op.packageName); alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } final int ignoreCount = mOpsToIgnore.size(); for (int i = 0; i < ignoreCount; i++) { final OpToChange op = mOpsToIgnore.valueAt(i); final OpToChange op = mOpsToIgnore.get(i); if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) { continue; } setUidModeIgnored(op.code, op.uid); setUidModeIgnored(op.code, op.uid, op.packageName); alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } final int ignoreIfNotAllowedCount = mOpsToIgnoreIfNotAllowed.size(); for (int i = 0; i < ignoreIfNotAllowedCount; i++) { final OpToChange op = mOpsToIgnoreIfNotAllowed.valueAt(i); final OpToChange op = mOpsToIgnoreIfNotAllowed.get(i); if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) { continue; } boolean wasSet = setUidModeIgnoredIfNotAllowed(op.code, op.uid); boolean wasSet = setUidModeIgnoredIfNotAllowed(op.code, op.uid, op.packageName); if (wasSet) { alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1); } Loading Loading @@ -555,7 +555,7 @@ public final class PermissionPolicyService extends SystemService { } int uid = packageInfo.applicationInfo.uid; OpToChange opToChange = new OpToChange(uid, appOpCode); OpToChange opToChange = new OpToChange(uid, packageName, appOpCode); switch (appOpMode) { case MODE_ALLOWED: mOpsToAllow.add(opToChange); Loading Loading @@ -618,7 +618,8 @@ public final class PermissionPolicyService extends SystemService { } int uid = packageInfo.applicationInfo.uid; OpToChange extraOpToChange = new OpToChange(uid, extraOpCode); String packageName = packageInfo.packageName; OpToChange extraOpToChange = new OpToChange(uid, packageName, extraOpCode); if (policy.mayAllowExtraAppOp()) { mOpsToAllow.add(extraOpToChange); } else { Loading @@ -631,56 +632,45 @@ public final class PermissionPolicyService extends SystemService { } /** * Add a Uid for {@link #syncUids() processing} later. * 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 uid The uid to add for later processing. * @param pkgName The package to add for later processing. */ void addUid(int uid) { String[] pkgNames = getPackageNamesForUid(uid); if (pkgNames == null) { return; } for (String pkgName : pkgNames) { void addPackage(@NonNull String pkgName) { final PackageInfo pkg; try { pkg = mPackageManager.getPackageInfo(pkgName, GET_PERMISSIONS); } catch (NameNotFoundException e) { continue; return; } if (pkg.requestedPermissions == null) { continue; return; } for (String permission : pkg.requestedPermissions) { addAppOps(pkg, permission); } } } private void setUidModeAllowed(int opCode, int uid) { setUidMode(opCode, uid, MODE_ALLOWED); private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) { setUidMode(opCode, uid, MODE_ALLOWED, packageName); } private void setUidModeForeground(int opCode, int uid) { setUidMode(opCode, uid, MODE_FOREGROUND); private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) { setUidMode(opCode, uid, MODE_FOREGROUND, packageName); } private void setUidModeIgnored(int opCode, int uid) { setUidMode(opCode, uid, MODE_IGNORED); } private boolean setUidModeIgnoredIfNotAllowed(int opCode, int uid) { String[] pkgsOfUid = getPackageNamesForUid(uid); if (ArrayUtils.isEmpty(pkgsOfUid)) { return false; private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) { setUidMode(opCode, uid, MODE_IGNORED, packageName); } private boolean setUidModeIgnoredIfNotAllowed(int opCode, int uid, @NonNull String packageName) { final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager.opToPublicName( opCode), uid, pkgsOfUid[0]); opCode), uid, packageName); if (currentMode != MODE_ALLOWED) { if (currentMode != MODE_IGNORED) { mAppOpsManagerInternal.setUidModeFromPermissionPolicy(opCode, uid, MODE_IGNORED, Loading @@ -691,24 +681,20 @@ public final class PermissionPolicyService extends SystemService { return false; } private void setUidMode(int opCode, int uid, int mode) { String[] pkgsOfUid = getPackageNamesForUid(uid); if (ArrayUtils.isEmpty(pkgsOfUid)) { return; } private void setUidMode(int opCode, int uid, int mode, @NonNull String packageName) { final int oldMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager.opToPublicName( opCode), uid, pkgsOfUid[0]); opCode), uid, packageName); if (oldMode != mode) { mAppOpsManagerInternal.setUidModeFromPermissionPolicy(opCode, uid, mode, mAppOpsCallback); final int newMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager.opToPublicName( opCode), uid, pkgsOfUid[0]); opCode), uid, packageName); if (newMode != mode) { // Work around incorrectly-set package mode. It never makes sense for app ops // related to runtime permissions, but can get in the way and we have to reset // it. mAppOpsManagerInternal.setModeFromPermissionPolicy(opCode, uid, pkgsOfUid[0], mAppOpsManagerInternal.setModeFromPermissionPolicy(opCode, uid, packageName, AppOpsManager.opToDefaultMode(opCode), mAppOpsCallback); } } Loading @@ -716,30 +702,14 @@ public final class PermissionPolicyService extends SystemService { private class OpToChange { final int uid; final @NonNull String packageName; final int code; OpToChange(int uid, int code) { OpToChange(int uid, @NonNull String packageName, int code) { this.uid = uid; this.packageName = packageName; this.code = code; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } OpToChange other = (OpToChange) o; return uid == other.uid && code == other.code; } @Override public int hashCode() { return Objects.hash(uid, code); } } } Loading