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

Commit ad2474b6 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by Android (Google) Code Review
Browse files

Merge changes from topic "actuallyUsePermissionControllerToRestoreBackup"

* changes:
  Inherit state into split permissions
  Be careful what state to restore
  Correctly backup granted state for pre-M apps
  Backup if a permission of a pre-M app was reviewed
  Do not backup and restore revoke-on-upgrade
  Move permission restore code into permission controller.
parents 2f101954 0d54491c
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -84,4 +84,10 @@ public class Constants {
     * role holder for a role.
     */
    public static final String IS_NONE_ROLE_HOLDER_SELECTED_KEY = "is_none_role_holder_selected:";

    /**
     * Name of file containing the permissions that should be restored, but have not been restored
     * yet.
     */
    public static final String DELAYED_RESTORE_PERMISSIONS_FILE = "delayed_restore_permissions.xml";
}
+46 −24
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import android.app.ActivityManager;
@@ -428,12 +429,12 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
        return false;
    }

    public void resetReviewRequired() {
    public void unsetReviewRequired() {
        final int permissionCount = mPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            Permission permission = mPermissions.valueAt(i);
            if (permission.isReviewRequired()) {
                permission.resetReviewRequired();
                permission.unsetReviewRequired();
            }
        }

@@ -780,7 +781,7 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
                // Granting a permission explicitly means the user already
                // reviewed it so clear the review flag on every grant.
                if (permission.isReviewRequired()) {
                    permission.resetReviewRequired();
                    permission.unsetReviewRequired();
                }
            }

@@ -889,13 +890,13 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
                continue;
            }

            if (mAppSupportsRuntimePermissions) {
            // Do not touch permissions fixed by the system.
            if (permission.isSystemFixed()) {
                wasAllRevoked = false;
                break;
            }

            if (mAppSupportsRuntimePermissions) {
                // Revoke the permission if needed.
                if (permission.isGranted()) {
                    permission.setGranted(false);
@@ -968,6 +969,23 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
        }
    }

    /**
     * Set the user-fixed flag for all permissions in this group.
     *
     * @param isUsedFixed if the flag should be set or not
     */
    public void setUserFixed(boolean isUsedFixed) {
        final int permissionCount = mPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            Permission permission = mPermissions.valueAt(i);
            permission.setUserFixed(isUsedFixed);
        }

        if (!mDelayChanges) {
            persistChanges(false);
        }
    }

    public ArrayList<Permission> getPermissions() {
        return new ArrayList<>(mPermissions.values());
    }
@@ -1124,6 +1142,7 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
        for (int i = 0; i < numPermissions; i++) {
            Permission permission = mPermissions.valueAt(i);

            if (!permission.isSystemFixed()) {
                if (permission.isGranted()) {
                    mPackageManager.grantRuntimePermission(mPackageInfo.packageName,
                            permission.getName(), mUserHandle);
@@ -1131,6 +1150,7 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
                    mPackageManager.revokeRuntimePermission(mPackageInfo.packageName,
                            permission.getName(), mUserHandle);
                }
            }

            int flags = (permission.isUserSet() ? PackageManager.FLAG_PERMISSION_USER_SET : 0)
                    | (permission.isUserFixed() ? PackageManager.FLAG_PERMISSION_USER_FIXED : 0)
@@ -1150,6 +1170,7 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
                    flags, mUserHandle);

            if (permission.affectsAppOp()) {
                if (!permission.isSystemFixed()) {
                    if (permission.isAppOpAllowed()) {
                        allowAppOp(permission, mPackageInfo.applicationInfo.uid);
                    } else {
@@ -1157,10 +1178,11 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
                    }

                    // Enabling/Disabling an app op may put the app in a situation in which it has a
                // handle to state it shouldn't have, so we have to kill the app. This matches the
                // revoke runtime permission behavior.
                    // handle to state it shouldn't have, so we have to kill the app. This matches
                    // the revoke runtime permission behavior.
                    shouldKillApp = true;
                }
            }

            switch (permission.getName()) {
                case READ_MEDIA_AUDIO:
+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ public final class Permission {
        return (mFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0;
    }

    public void resetReviewRequired() {
    public void unsetReviewRequired() {
        mFlags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
    }

+475 −22

File changed.

Preview size limit exceeded, changes collapsed.

+18 −4
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.permission.RuntimePermissionUsageInfo;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Xml;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -53,10 +54,12 @@ import com.android.packageinstaller.permission.model.PermissionUsages;
import com.android.packageinstaller.permission.utils.Utils;
import com.android.packageinstaller.role.service.PermissionControllerServiceImplRoleMixin;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -182,7 +185,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS

            // Mark the permissions as reviewed as we don't want to use to accidentally grant
            // the permission during review
            group.resetReviewRequired();
            group.unsetReviewRequired();

            int numPerms = perms.size();
            for (int permNum = 0; permNum < numPerms; permNum++) {
@@ -306,14 +309,25 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS
    @Override
    public void onRestoreRuntimePermissionsBackup(@NonNull UserHandle user,
            @NonNull InputStream backup) {
        // TODO: Implement
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(backup, StandardCharsets.UTF_8.name());

            new BackupHelper(this, user).restoreState(parser);
        } catch (Exception e) {
            Log.e(LOG_TAG, "Exception restoring permissions: " + e.getMessage());
        }
    }

    @Override
    public boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String packageName,
            @NonNull UserHandle user) {
        // TODO: Implement
        return true;
        try {
            return new BackupHelper(this, user).restoreDelayedState(packageName);
        } catch (Exception e) {
            Log.e(LOG_TAG, "Exception restoring delayed permissions: " + e.getMessage());
            return false;
        }
    }

    @Override
Loading