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

Commit 11494f6a authored by Eugene Susla's avatar Eugene Susla Committed by Android (Google) Code Review
Browse files

Merge "Replace RemoteCallback with AndroidFuture in PermControler"

parents a30cdc3d e7daff9f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -421,6 +421,7 @@ java_defaults {
        "core/java/com/android/internal/appwidget/IAppWidgetHost.aidl",
        "core/java/com/android/internal/backup/IBackupTransport.aidl",
        "core/java/com/android/internal/backup/IObbBackupService.aidl",
        "core/java/com/android/internal/infra/IAndroidFuture.aidl",
        "core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl",
        "core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl",
        "core/java/com/android/internal/inputmethod/IMultiClientInputMethod.aidl",
+8 −7
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.os.RemoteCallback;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import com.android.internal.infra.AndroidFuture;

/**
 * Interface for system apps to communication with the permission controller.
@@ -28,17 +29,17 @@ import android.os.UserHandle;
 */
oneway interface IPermissionController {
    void revokeRuntimePermissions(in Bundle request, boolean doDryRun, int reason,
            String callerPackageName, in RemoteCallback callback);
            String callerPackageName, in AndroidFuture callback);
    void getRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe);
    void restoreRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe);
    void restoreDelayedRuntimePermissionBackup(String packageName, in UserHandle user,
            in RemoteCallback callback);
    void getAppPermissions(String packageName, in RemoteCallback callback);
            in AndroidFuture callback);
    void getAppPermissions(String packageName, in AndroidFuture callback);
    void revokeRuntimePermission(String packageName, String permissionName);
    void countPermissionApps(in List<String> permissionNames, int flags,
            in RemoteCallback callback);
    void getPermissionUsages(boolean countSystem, long numMillis, in RemoteCallback callback);
            in AndroidFuture callback);
    void getPermissionUsages(boolean countSystem, long numMillis, in AndroidFuture callback);
    void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName, String packageName,
            String permission, int grantState, in RemoteCallback callback);
    void grantOrUpgradeDefaultRuntimePermissions(in RemoteCallback callback);
                String permission, int grantState, in AndroidFuture callback);
    void grantOrUpgradeDefaultRuntimePermissions(in AndroidFuture callback);
}
+27 −63
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteCallback;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
@@ -57,7 +56,6 @@ import com.android.internal.infra.AndroidFuture;
import com.android.internal.infra.RemoteStream;
import com.android.internal.infra.ServiceConnector;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.Preconditions;

import libcore.util.EmptyArray;

@@ -67,7 +65,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

@@ -94,14 +91,6 @@ public final class PermissionControllerManager {
    private static ArrayMap<Pair<Integer, Thread>, ServiceConnector<IPermissionController>>
            sRemoteServices = new ArrayMap<>(1);

    /**
     * The key for retrieving the result from the returned bundle.
     *
     * @hide
     */
    public static final String KEY_RESULT =
            "android.permission.PermissionControllerManager.key.result";

    /** @hide */
    @IntDef(prefix = { "REASON_" }, value = {
            REASON_MALWARE,
@@ -291,31 +280,17 @@ public final class PermissionControllerManager {
                        new ArrayList<>(appRequest.getValue()));
            }

            AndroidFuture<Bundle> revokeRuntimePermissionsResult = new AndroidFuture<>();
            AndroidFuture<Map<String, List<String>>> revokeRuntimePermissionsResult =
                    new AndroidFuture<>();
            service.revokeRuntimePermissions(bundledizedRequest, doDryRun, reason,
                    mContext.getPackageName(),
                    new RemoteCallback(revokeRuntimePermissionsResult::complete));
                    revokeRuntimePermissionsResult);
            return revokeRuntimePermissionsResult;
        }).thenApply(revokeRuntimePermissionsResult -> {
            Map<String, List<String>> revoked = new ArrayMap<>();
            Bundle bundleizedRevoked = revokeRuntimePermissionsResult.getBundle(KEY_RESULT);

            for (String packageName : bundleizedRevoked.keySet()) {
                Preconditions.checkNotNull(packageName);

                ArrayList<String> permissions =
                        bundleizedRevoked.getStringArrayList(packageName);
                Preconditions.checkCollectionElementsNotNull(permissions,
                        "permissions");

                revoked.put(packageName, permissions);
            }
            return revoked;
        }).whenCompleteAsync((revoked, err) -> {
            long token = Binder.clearCallingIdentity();
            try {
                if (err != null) {
                    Log.e(TAG, "Failure when revoking runtime permissions", err);
                    Log.e(TAG, "Failure when revoking runtime permissions " + revoked, err);
                    callback.onRevokeRuntimePermissions(Collections.emptyMap());
                } else {
                    callback.onRevokeRuntimePermissions(revoked);
@@ -356,11 +331,10 @@ public final class PermissionControllerManager {
        checkNotNull(callback);

        mRemoteService.postAsync(service -> {
            CompletableFuture<Bundle> setRuntimePermissionGrantStateResult =
                    new CompletableFuture<>();
            AndroidFuture<Boolean> setRuntimePermissionGrantStateResult = new AndroidFuture<>();
            service.setRuntimePermissionGrantStateByDeviceAdmin(
                    callerPackageName, packageName, permission, grantState,
                    new RemoteCallback(setRuntimePermissionGrantStateResult::complete));
                    setRuntimePermissionGrantStateResult);
            return setRuntimePermissionGrantStateResult;
        }).whenCompleteAsync((setRuntimePermissionGrantStateResult, err) -> {
            long token = Binder.clearCallingIdentity();
@@ -370,8 +344,7 @@ public final class PermissionControllerManager {
                            err);
                    callback.accept(false);
                } else {
                    callback.accept(
                            setRuntimePermissionGrantStateResult.getBoolean(KEY_RESULT, false));
                    callback.accept(setRuntimePermissionGrantStateResult);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
@@ -453,10 +426,10 @@ public final class PermissionControllerManager {
        checkNotNull(callback);

        mRemoteService.postAsync(service -> {
            CompletableFuture<Bundle> restoreDelayedRuntimePermissionBackupResult =
                    new CompletableFuture<>();
            AndroidFuture<Boolean> restoreDelayedRuntimePermissionBackupResult =
                    new AndroidFuture<>();
            service.restoreDelayedRuntimePermissionBackup(packageName, user,
                    new RemoteCallback(restoreDelayedRuntimePermissionBackupResult::complete));
                    restoreDelayedRuntimePermissionBackupResult);
            return restoreDelayedRuntimePermissionBackupResult;
        }).whenCompleteAsync((restoreDelayedRuntimePermissionBackupResult, err) -> {
            long token = Binder.clearCallingIdentity();
@@ -466,8 +439,7 @@ public final class PermissionControllerManager {
                    callback.accept(true);
                } else {
                    callback.accept(
                            restoreDelayedRuntimePermissionBackupResult
                                    .getBoolean(KEY_RESULT, false));
                            Boolean.TRUE.equals(restoreDelayedRuntimePermissionBackupResult));
                }
            } finally {
                Binder.restoreCallingIdentity(token);
@@ -492,20 +464,16 @@ public final class PermissionControllerManager {
        Handler finalHandler = handler != null ? handler : mHandler;

        mRemoteService.postAsync(service -> {
            CompletableFuture<Bundle> getAppPermissionsResult = new CompletableFuture<>();
            service.getAppPermissions(packageName,
                    new RemoteCallback(getAppPermissionsResult::complete));
            AndroidFuture<List<RuntimePermissionPresentationInfo>> getAppPermissionsResult =
                    new AndroidFuture<>();
            service.getAppPermissions(packageName, getAppPermissionsResult);
            return getAppPermissionsResult;
        }).whenComplete((getAppPermissionsResult, err) -> finalHandler.post(() -> {
            if (err != null) {
                Log.e(TAG, "Error getting app permission", err);
                callback.onGetAppPermissions(Collections.emptyList());
            } else {
                List<RuntimePermissionPresentationInfo> permissions = null;
                if (getAppPermissionsResult != null) {
                    permissions = getAppPermissionsResult.getParcelableArrayList(KEY_RESULT);
                }
                callback.onGetAppPermissions(CollectionUtils.emptyIfNull(permissions));
                callback.onGetAppPermissions(CollectionUtils.emptyIfNull(getAppPermissionsResult));
            }
        }));
    }
@@ -548,18 +516,15 @@ public final class PermissionControllerManager {
        Handler finalHandler = handler != null ? handler : mHandler;

        mRemoteService.postAsync(service -> {
            CompletableFuture<Bundle> countPermissionAppsResult = new CompletableFuture<>();
            service.countPermissionApps(permissionNames, flags,
                    new RemoteCallback(countPermissionAppsResult::complete));
            AndroidFuture<Integer> countPermissionAppsResult = new AndroidFuture<>();
            service.countPermissionApps(permissionNames, flags, countPermissionAppsResult);
            return countPermissionAppsResult;
        }).whenComplete((countPermissionAppsResult, err) -> finalHandler.post(() -> {
            if (err != null) {
                Log.e(TAG, "Error counting permission apps", err);
                callback.onCountPermissionApps(0);
            } else {
                callback.onCountPermissionApps(countPermissionAppsResult != null
                        ? countPermissionAppsResult.getInt(KEY_RESULT)
                        : 0);
                callback.onCountPermissionApps(countPermissionAppsResult);
            }
        }));
    }
@@ -584,9 +549,9 @@ public final class PermissionControllerManager {


        mRemoteService.postAsync(service -> {
            CompletableFuture<Bundle> getPermissionUsagesResult = new CompletableFuture<>();
            service.getPermissionUsages(countSystem, numMillis,
                    new RemoteCallback(getPermissionUsagesResult::complete));
            AndroidFuture<List<RuntimePermissionUsageInfo>> getPermissionUsagesResult =
                    new AndroidFuture<>();
            service.getPermissionUsages(countSystem, numMillis, getPermissionUsagesResult);
            return getPermissionUsagesResult;
        }).whenCompleteAsync((getPermissionUsagesResult, err) -> {
            if (err != null) {
@@ -595,9 +560,8 @@ public final class PermissionControllerManager {
            } else {
                long token = Binder.clearCallingIdentity();
                try {
                    callback.onPermissionUsageResult(getPermissionUsagesResult != null
                            ? getPermissionUsagesResult.getParcelableArrayList(KEY_RESULT)
                            : Collections.emptyList());
                    callback.onPermissionUsageResult(
                            CollectionUtils.emptyIfNull(getPermissionUsagesResult));
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
@@ -619,17 +583,17 @@ public final class PermissionControllerManager {
    public void grantOrUpgradeDefaultRuntimePermissions(
            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
        mRemoteService.postAsync(service -> {
            CompletableFuture<Bundle> grantOrUpgradeDefaultRuntimePermissionsResult =
                    new CompletableFuture<>();
            AndroidFuture<Boolean> grantOrUpgradeDefaultRuntimePermissionsResult =
                    new AndroidFuture<>();
            service.grantOrUpgradeDefaultRuntimePermissions(
                    new RemoteCallback(grantOrUpgradeDefaultRuntimePermissionsResult::complete));
                    grantOrUpgradeDefaultRuntimePermissionsResult);
            return grantOrUpgradeDefaultRuntimePermissionsResult;
        }).whenCompleteAsync((grantOrUpgradeDefaultRuntimePermissionsResult, err) -> {
            if (err != null) {
                Log.e(TAG, "Error granting or upgrading runtime permissions", err);
                callback.accept(false);
            } else {
                callback.accept(grantOrUpgradeDefaultRuntimePermissionsResult != null);
                callback.accept(grantOrUpgradeDefaultRuntimePermissionsResult);
            }
        }, executor);
    }
+20 −62
Original line number Diff line number Diff line
@@ -41,12 +41,13 @@ import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
import android.os.UserHandle;
import android.permission.PermissionControllerManager.CountPermissionAppsFlag;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.Preconditions;

import java.io.IOException;
@@ -209,7 +210,7 @@ public abstract class PermissionControllerService extends Service {
            @Override
            public void revokeRuntimePermissions(
                    Bundle bundleizedRequest, boolean doDryRun, int reason,
                    String callerPackageName, RemoteCallback callback) {
                    String callerPackageName, AndroidFuture callback) {
                checkNotNull(bundleizedRequest, "bundleizedRequest");
                checkNotNull(callerPackageName);
                checkNotNull(callback);
@@ -237,22 +238,11 @@ public abstract class PermissionControllerService extends Service {

                onRevokeRuntimePermissions(request,
                        doDryRun, reason, callerPackageName, revoked -> {
                            checkNotNull(revoked);
                            Bundle bundledizedRevoked = new Bundle();
                            for (Map.Entry<String, List<String>> appRevocation :
                                    revoked.entrySet()) {
                                checkNotNull(appRevocation.getKey());
                                checkCollectionElementsNotNull(appRevocation.getValue(),
                                        "permissions");

                                bundledizedRevoked.putStringArrayList(appRevocation.getKey(),
                                        new ArrayList<>(appRevocation.getValue()));
                            }

                            Bundle result = new Bundle();
                            result.putBundle(PermissionControllerManager.KEY_RESULT,
                                    bundledizedRevoked);
                            callback.sendResult(result);
                            CollectionUtils.forEach(revoked, (pkg, perms) -> {
                                Preconditions.checkNotNull(pkg);
                                Preconditions.checkCollectionElementsNotNull(perms, "permissions");
                            });
                            callback.complete(revoked);
                        });
            }

@@ -294,40 +284,24 @@ public abstract class PermissionControllerService extends Service {

            @Override
            public void restoreDelayedRuntimePermissionBackup(String packageName, UserHandle user,
                    RemoteCallback callback) {
                    AndroidFuture callback) {
                checkNotNull(packageName);
                checkNotNull(user);
                checkNotNull(callback);

                enforceCallingPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, null);

                onRestoreDelayedRuntimePermissionsBackup(packageName, user,
                        hasMoreBackup -> {
                            Bundle result = new Bundle();
                            result.putBoolean(PermissionControllerManager.KEY_RESULT,
                                    hasMoreBackup);
                            callback.sendResult(result);
                        });
                onRestoreDelayedRuntimePermissionsBackup(packageName, user, callback::complete);
            }

            @Override
            public void getAppPermissions(String packageName, RemoteCallback callback) {
            public void getAppPermissions(String packageName, AndroidFuture callback) {
                checkNotNull(packageName, "packageName");
                checkNotNull(callback, "callback");

                enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);

                onGetAppPermissions(packageName,
                        permissions -> {
                            if (permissions != null && !permissions.isEmpty()) {
                                Bundle result = new Bundle();
                                result.putParcelableList(PermissionControllerManager.KEY_RESULT,
                                        permissions);
                                callback.sendResult(result);
                            } else {
                                callback.sendResult(null);
                            }
                        });
                onGetAppPermissions(packageName, callback::complete);
            }

            @Override
@@ -349,43 +323,31 @@ public abstract class PermissionControllerService extends Service {

            @Override
            public void countPermissionApps(List<String> permissionNames, int flags,
                    RemoteCallback callback) {
                    AndroidFuture callback) {
                checkCollectionElementsNotNull(permissionNames, "permissionNames");
                checkFlagsArgument(flags, COUNT_WHEN_SYSTEM | COUNT_ONLY_WHEN_GRANTED);
                checkNotNull(callback, "callback");

                enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);

                onCountPermissionApps(permissionNames, flags, numApps -> {
                    Bundle result = new Bundle();
                    result.putInt(PermissionControllerManager.KEY_RESULT, numApps);
                    callback.sendResult(result);
                });
                onCountPermissionApps(permissionNames, flags, callback::complete);
            }

            @Override
            public void getPermissionUsages(boolean countSystem, long numMillis,
                    RemoteCallback callback) {
                    AndroidFuture callback) {
                checkArgumentNonnegative(numMillis);
                checkNotNull(callback, "callback");

                enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);

                onGetPermissionUsages(countSystem, numMillis, users -> {
                    if (users != null && !users.isEmpty()) {
                        Bundle result = new Bundle();
                        result.putParcelableList(PermissionControllerManager.KEY_RESULT, users);
                        callback.sendResult(result);
                    } else {
                        callback.sendResult(null);
                    }
                });
                onGetPermissionUsages(countSystem, numMillis, callback::complete);
            }

            @Override
            public void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName,
                    String packageName, String permission, int grantState,
                    RemoteCallback callback) {
                    AndroidFuture callback) {
                checkStringNotEmpty(callerPackageName);
                checkStringNotEmpty(packageName);
                checkStringNotEmpty(permission);
@@ -406,21 +368,17 @@ public abstract class PermissionControllerService extends Service {
                        null);

                onSetRuntimePermissionGrantStateByDeviceAdmin(callerPackageName,
                        packageName, permission, grantState, wasSet -> {
                            Bundle result = new Bundle();
                            result.putBoolean(PermissionControllerManager.KEY_RESULT, wasSet);
                            callback.sendResult(result);
                        });
                        packageName, permission, grantState, callback::complete);
            }

            @Override
            public void grantOrUpgradeDefaultRuntimePermissions(@NonNull RemoteCallback callback) {
            public void grantOrUpgradeDefaultRuntimePermissions(@NonNull AndroidFuture callback) {
                checkNotNull(callback, "callback");

                enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
                        null);

                onGrantOrUpgradeDefaultRuntimePermissions(() -> callback.sendResult(Bundle.EMPTY));
                onGrantOrUpgradeDefaultRuntimePermissions(() -> callback.complete(null));
            }
        };
    }
+20 −0
Original line number Diff line number Diff line
/*
** Copyright 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 com.android.internal.infra;

/** @hide */
parcelable AndroidFuture;
Loading