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

Commit eac70795 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow resetting runtime permissions for all packages with a single write."

parents fa148044 904b0d59
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -331,6 +331,16 @@ public class ArrayUtils {
        return array;
    }

    @NonNull
    public static int[] convertToIntArray(@NonNull ArraySet<Integer> set) {
        final int size = set.size();
        int[] array = new int[size];
        for (int i = 0; i < size; i++) {
            array[i] = set.valueAt(i);
        }
        return array;
    }

    public static @Nullable long[] convertToLongArray(@Nullable int[] intArray) {
        if (intArray == null) return null;
        long[] array = new long[intArray.length];
+1 −6
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ import android.util.Xml;

import com.android.internal.util.ArrayUtils;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;

import org.xmlpull.v1.XmlPullParser;
@@ -595,11 +594,7 @@ final class PreferredActivityHelper {
            synchronized (mPm.mLock) {
                mPm.mSettings.applyDefaultPreferredAppsLPw(userId);
                mPm.mDomainVerificationManager.clearUser(userId);
                final int numPackages = mPm.mPackages.size();
                for (int i = 0; i < numPackages; i++) {
                    final AndroidPackage pkg = mPm.mPackages.valueAt(i);
                    mPm.mPermissionManager.resetRuntimePermissions(pkg, userId);
                }
                mPm.mPermissionManager.resetRuntimePermissionsForUser(userId);
            }
            updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId);
            resetNetworkPolicies(userId);
+4 −0
Original line number Diff line number Diff line
@@ -780,6 +780,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        public void resetRuntimePermissions(@NonNull AndroidPackage pkg, @UserIdInt int userId) {
            mPermissionManagerServiceImpl.resetRuntimePermissions(pkg, userId);
        }
        @Override
        public void resetRuntimePermissionsForUser(@UserIdInt int userId) {
            mPermissionManagerServiceImpl.resetRuntimePermissionsForUser(userId);
        }

        @Override
        public Permission getPermissionTEMP(String permName) {
+59 −43
Original line number Diff line number Diff line
@@ -103,7 +103,6 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.EventLog;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -1661,30 +1660,16 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
    /**
     * Reverts user permission state changes (permissions and flags).
     *
     * @param pkg The package for which to reset.
     * @param filterPkg The package for which to reset, or {@code null} for all packages.
     * @param userId The device user for which to do a reset.
     */
    private void resetRuntimePermissionsInternal(@NonNull AndroidPackage pkg,
    private void resetRuntimePermissionsInternal(@Nullable AndroidPackage filterPkg,
            @UserIdInt int userId) {
        final String packageName = pkg.getPackageName();

        // These are flags that can change base on user actions.
        final int userSettableMask = FLAG_PERMISSION_USER_SET
                | FLAG_PERMISSION_USER_FIXED
                | FLAG_PERMISSION_REVOKED_COMPAT
                | FLAG_PERMISSION_REVIEW_REQUIRED
                | FLAG_PERMISSION_ONE_TIME
                | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;

        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
                | FLAG_PERMISSION_POLICY_FIXED;

        // Delay and combine non-async permission callbacks
        final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
        final boolean[] permissionRemoved = new boolean[1];
        final ArraySet<Long> revokedPermissions = new ArraySet<>();
        final IntArray syncUpdatedUsers = new IntArray(permissionCount);
        final IntArray asyncUpdatedUsers = new IntArray(permissionCount);
        final ArraySet<Integer> syncUpdatedUsers = new ArraySet<>();
        final ArraySet<Integer> asyncUpdatedUsers = new ArraySet<>();

        PermissionCallback delayingPermCallback = new PermissionCallback() {
            public void onGidsChanged(int appId, int userId) {
@@ -1746,6 +1731,55 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
            }
        };

        if (filterPkg != null) {
            resetRuntimePermissionsInternal(filterPkg, userId, delayingPermCallback);
        } else {
            mPackageManagerInt.forEachPackage(pkg ->
                    resetRuntimePermissionsInternal(pkg, userId, delayingPermCallback));
        }

        // Execute delayed callbacks
        if (permissionRemoved[0]) {
            mDefaultPermissionCallback.onPermissionRemoved();
        }

        // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
        // kill uid while holding mPackages-lock
        if (!revokedPermissions.isEmpty()) {
            int numRevokedPermissions = revokedPermissions.size();
            for (int i = 0; i < numRevokedPermissions; i++) {
                int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
                int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));

                mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);

                // Kill app later as we are holding mPackages
                mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
                        KILL_APP_REASON_PERMISSIONS_REVOKED));
            }
        }

        mPackageManagerInt.writePermissionSettings(ArrayUtils.convertToIntArray(syncUpdatedUsers),
                false);
        mPackageManagerInt.writePermissionSettings(ArrayUtils.convertToIntArray(asyncUpdatedUsers),
                true);
    }

    private void resetRuntimePermissionsInternal(@NonNull AndroidPackage pkg,
            @UserIdInt int userId, @NonNull PermissionCallback delayingPermCallback) {
        // These are flags that can change base on user actions.
        final int userSettableMask = FLAG_PERMISSION_USER_SET
                | FLAG_PERMISSION_USER_FIXED
                | FLAG_PERMISSION_REVOKED_COMPAT
                | FLAG_PERMISSION_REVIEW_REQUIRED
                | FLAG_PERMISSION_ONE_TIME
                | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;

        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
                | FLAG_PERMISSION_POLICY_FIXED;

        final String packageName = pkg.getPackageName();
        final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
        for (int i = 0; i < permissionCount; i++) {
            final String permName = pkg.getRequestedPermissions().get(i);

@@ -1824,30 +1858,6 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
                        userId, null, delayingPermCallback);
            }
        }

        // Execute delayed callbacks
        if (permissionRemoved[0]) {
            mDefaultPermissionCallback.onPermissionRemoved();
        }

        // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
        // kill uid while holding mPackages-lock
        if (!revokedPermissions.isEmpty()) {
            int numRevokedPermissions = revokedPermissions.size();
            for (int i = 0; i < numRevokedPermissions; i++) {
                int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
                int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));

                mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);

                // Kill app later as we are holding mPackages
                mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
                        KILL_APP_REASON_PERMISSIONS_REVOKED));
            }
        }

        mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false);
        mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
    }

    /**
@@ -5177,6 +5187,12 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
        resetRuntimePermissionsInternal(pkg, userId);
    }

    @Override
    public void resetRuntimePermissionsForUser(@UserIdInt int userId) {
        Preconditions.checkArgumentNonNegative(userId, "userId");
        resetRuntimePermissionsInternal(null, userId);
    }

    @Override
    public Permission getPermissionTEMP(String permName) {
        synchronized (mLock) {
+7 −0
Original line number Diff line number Diff line
@@ -427,6 +427,13 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
    void resetRuntimePermissions(@NonNull AndroidPackage pkg,
            @UserIdInt int userId);

    /**
     * Reset the runtime permission state changes for all packages in a user.
     *
     * @param userId the user ID
     */
    void resetRuntimePermissionsForUser(@UserIdInt int userId);

    /**
     * Read legacy permission state from package settings.
     *
Loading