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

Commit 4845667a authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Move permission restore code into permission controller.

- Split system-server internal interface in two. One accessible only
  inside of the services part of system server. One accessible
  everywhere. This is necessary as the second part needs to be
  accessible by the PermissionBackupHelper. But the former uses internal
  data structures that should not be moved into android.permission.
- Remove old delayed permission restore code from
  PermissionManagerService and Settings. This code now lives in
  permission controller
- Keep the logic to remember which users still have delayed permissions
  left. It is quite expensive to call into permission controller for
  ever install of an app, hence this check is necessary. Currently this
  mirrors the original logic. This can be improved further later.

Test: Built
Change-Id: Ibc1d5183c361dc55896882db1f7b765e1bee6e84
parent cee140e2
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -295,8 +295,6 @@ interface IPackageManager {
    void restoreDefaultApps(in byte[] backup, int userId);
    byte[] getIntentFilterVerificationBackup(int userId);
    void restoreIntentFilterVerification(in byte[] backup, int userId);
    byte[] getPermissionGrantBackup(int userId);
    void restorePermissionGrants(in byte[] backup, int userId);

    /**
     * Report the set of 'Home' activity candidates, plus (if any) which of them
+2 −0
Original line number Diff line number Diff line
@@ -2976,6 +2976,7 @@ public abstract class PackageManager {
     * @hide
     */
    @SystemApi
    @TestApi
    public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE =  1 << 3;

    /**
@@ -3014,6 +3015,7 @@ public abstract class PackageManager {
     *
     * @hide
     */
    @TestApi
    public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED =  1 << 7;

    /**
+4 −3
Original line number Diff line number Diff line
@@ -624,7 +624,7 @@ public final class PermissionControllerManager {
         *
         * <p>Needs to be called when canceling this task as it might be hung.
         */
        void interruptRead() {
        void interruptWrite() {
            IoUtils.closeQuietly(mLocalPipe);
        }

@@ -806,18 +806,19 @@ public final class PermissionControllerManager {

        @Override
        public void run(@NonNull IPermissionController service) {
            mBackupSender.execute(mBackup);

            ParcelFileDescriptor remotePipe = mBackupSender.getRemotePipe();
            try {
                service.restoreRuntimePermissionBackup(mUser, remotePipe);
            } catch (RemoteException e) {
                Log.e(TAG, "Error sending runtime permission backup", e);
                mBackupSender.cancel(false);
                mBackupSender.interruptWrite();
            } finally {
                // Remote pipe end is duped by binder call. Local copy is not needed anymore
                IoUtils.closeQuietly(remotePipe);
            }

            mBackupSender.execute(mBackup);
        }
    }

+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 android.permission;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.UserHandle;

/**
 * Internal interfaces to be used by other components within the system server.
 *
 * <p>Only for use within the system server.
 *
 * @hide
 */
public abstract class PermissionManagerInternal {
    /**
     * Get the state of the runtime permissions as xml file.
     *
     * @param user The user the data should be extracted for
     *
     * @return The state as a xml file
     */
    public abstract @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user);

    /**
     * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
     *
     * <p>If not all state can be restored, the un-restoreable state will be delayed and can be
     * re-tried via {@link #restoreDelayedRuntimePermissions}.
     *
     * @param backup The state as an xml file
     * @param user The user the data should be restored for
     */
    public abstract void restoreRuntimePermissions(@NonNull byte[] backup,
            @NonNull UserHandle user);

    /**
     * Try to apply permission backup of a package that was previously not applied.
     *
     * @param packageName The package that is newly installed
     * @param user The user the package is installed for
     *
     * @see #restoreRuntimePermissions
     */
    public abstract void restoreDelayedRuntimePermissions(@NonNull String packageName,
            @NonNull UserHandle user);
}
+12 −8
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package com.android.server.backup;

import android.app.AppGlobals;
import android.annotation.NonNull;
import android.app.backup.BlobBackupHelper;
import android.content.pm.IPackageManager;
import android.os.UserHandle;
import android.permission.PermissionManagerInternal;
import android.util.Slog;

import com.android.server.LocalServices;

public class PermissionBackupHelper extends BlobBackupHelper {
    private static final String TAG = "PermissionBackup";
    private static final boolean DEBUG = false;
@@ -31,24 +34,26 @@ public class PermissionBackupHelper extends BlobBackupHelper {
    // key under which the permission-grant state blob is committed to backup
    private static final String KEY_PERMISSIONS = "permissions";

    private final int mUserId;
    private final @NonNull UserHandle mUser;

    private final @NonNull PermissionManagerInternal mPermissionManager;

    public PermissionBackupHelper(int userId) {
        super(STATE_VERSION, KEY_PERMISSIONS);

        mUserId = userId;
        mUser = UserHandle.of(userId);
        mPermissionManager = LocalServices.getService(PermissionManagerInternal.class);
    }

    @Override
    protected byte[] getBackupPayload(String key) {
        IPackageManager pm = AppGlobals.getPackageManager();
        if (DEBUG) {
            Slog.d(TAG, "Handling backup of " + key);
        }
        try {
            switch (key) {
                case KEY_PERMISSIONS:
                    return pm.getPermissionGrantBackup(mUserId);
                    return mPermissionManager.backupRuntimePermissions(mUser);

                default:
                    Slog.w(TAG, "Unexpected backup key " + key);
@@ -61,14 +66,13 @@ public class PermissionBackupHelper extends BlobBackupHelper {

    @Override
    protected void applyRestoredPayload(String key, byte[] payload) {
        IPackageManager pm = AppGlobals.getPackageManager();
        if (DEBUG) {
            Slog.d(TAG, "Handling restore of " + key);
        }
        try {
            switch (key) {
                case KEY_PERMISSIONS:
                    pm.restorePermissionGrants(payload, mUserId);
                    mPermissionManager.restoreRuntimePermissions(payload, mUser);
                    break;

                default:
Loading