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

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

Merge "Revert "Replace RemoteCallback with AndroidFuture in PermControler""

parents c5823966 8feb3a1d
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -421,7 +421,6 @@ 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",
+7 −8
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ 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.
@@ -29,17 +28,17 @@ import com.android.internal.infra.AndroidFuture;
 */
oneway interface IPermissionController {
    void revokeRuntimePermissions(in Bundle request, boolean doDryRun, int reason,
            String callerPackageName, in AndroidFuture callback);
            String callerPackageName, in RemoteCallback 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 AndroidFuture callback);
    void getAppPermissions(String packageName, in AndroidFuture callback);
            in RemoteCallback callback);
    void getAppPermissions(String packageName, in RemoteCallback callback);
    void revokeRuntimePermission(String packageName, String permissionName);
    void countPermissionApps(in List<String> permissionNames, int flags,
            in AndroidFuture callback);
    void getPermissionUsages(boolean countSystem, long numMillis, in AndroidFuture callback);
            in RemoteCallback callback);
    void getPermissionUsages(boolean countSystem, long numMillis, in RemoteCallback callback);
    void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName, String packageName,
                String permission, int grantState, in AndroidFuture callback);
    void grantOrUpgradeDefaultRuntimePermissions(in AndroidFuture callback);
            String permission, int grantState, in RemoteCallback callback);
    void grantOrUpgradeDefaultRuntimePermissions(in RemoteCallback callback);
}
+63 −27
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ 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;
@@ -56,6 +57,7 @@ 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;

@@ -65,6 +67,7 @@ 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;

@@ -91,6 +94,14 @@ 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,
@@ -280,17 +291,31 @@ public final class PermissionControllerManager {
                        new ArrayList<>(appRequest.getValue()));
            }

            AndroidFuture<Map<String, List<String>>> revokeRuntimePermissionsResult =
                    new AndroidFuture<>();
            AndroidFuture<Bundle> revokeRuntimePermissionsResult = new AndroidFuture<>();
            service.revokeRuntimePermissions(bundledizedRequest, doDryRun, reason,
                    mContext.getPackageName(),
                    revokeRuntimePermissionsResult);
                    new RemoteCallback(revokeRuntimePermissionsResult::complete));
            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 " + revoked, err);
                    Log.e(TAG, "Failure when revoking runtime permissions", err);
                    callback.onRevokeRuntimePermissions(Collections.emptyMap());
                } else {
                    callback.onRevokeRuntimePermissions(revoked);
@@ -331,10 +356,11 @@ public final class PermissionControllerManager {
        checkNotNull(callback);

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

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

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

        mRemoteService.postAsync(service -> {
            AndroidFuture<Integer> countPermissionAppsResult = new AndroidFuture<>();
            service.countPermissionApps(permissionNames, flags, countPermissionAppsResult);
            CompletableFuture<Bundle> countPermissionAppsResult = new CompletableFuture<>();
            service.countPermissionApps(permissionNames, flags,
                    new RemoteCallback(countPermissionAppsResult::complete));
            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);
                callback.onCountPermissionApps(countPermissionAppsResult != null
                        ? countPermissionAppsResult.getInt(KEY_RESULT)
                        : 0);
            }
        }));
    }
@@ -549,9 +584,9 @@ public final class PermissionControllerManager {


        mRemoteService.postAsync(service -> {
            AndroidFuture<List<RuntimePermissionUsageInfo>> getPermissionUsagesResult =
                    new AndroidFuture<>();
            service.getPermissionUsages(countSystem, numMillis, getPermissionUsagesResult);
            CompletableFuture<Bundle> getPermissionUsagesResult = new CompletableFuture<>();
            service.getPermissionUsages(countSystem, numMillis,
                    new RemoteCallback(getPermissionUsagesResult::complete));
            return getPermissionUsagesResult;
        }).whenCompleteAsync((getPermissionUsagesResult, err) -> {
            if (err != null) {
@@ -560,8 +595,9 @@ public final class PermissionControllerManager {
            } else {
                long token = Binder.clearCallingIdentity();
                try {
                    callback.onPermissionUsageResult(
                            CollectionUtils.emptyIfNull(getPermissionUsagesResult));
                    callback.onPermissionUsageResult(getPermissionUsagesResult != null
                            ? getPermissionUsagesResult.getParcelableArrayList(KEY_RESULT)
                            : Collections.emptyList());
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
@@ -583,17 +619,17 @@ public final class PermissionControllerManager {
    public void grantOrUpgradeDefaultRuntimePermissions(
            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
        mRemoteService.postAsync(service -> {
            AndroidFuture<Boolean> grantOrUpgradeDefaultRuntimePermissionsResult =
                    new AndroidFuture<>();
            CompletableFuture<Bundle> grantOrUpgradeDefaultRuntimePermissionsResult =
                    new CompletableFuture<>();
            service.grantOrUpgradeDefaultRuntimePermissions(
                    grantOrUpgradeDefaultRuntimePermissionsResult);
                    new RemoteCallback(grantOrUpgradeDefaultRuntimePermissionsResult::complete));
            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);
                callback.accept(grantOrUpgradeDefaultRuntimePermissionsResult != null);
            }
        }, executor);
    }
+62 −20
Original line number Diff line number Diff line
@@ -41,13 +41,12 @@ 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;
@@ -210,7 +209,7 @@ public abstract class PermissionControllerService extends Service {
            @Override
            public void revokeRuntimePermissions(
                    Bundle bundleizedRequest, boolean doDryRun, int reason,
                    String callerPackageName, AndroidFuture callback) {
                    String callerPackageName, RemoteCallback callback) {
                checkNotNull(bundleizedRequest, "bundleizedRequest");
                checkNotNull(callerPackageName);
                checkNotNull(callback);
@@ -238,11 +237,22 @@ public abstract class PermissionControllerService extends Service {

                onRevokeRuntimePermissions(request,
                        doDryRun, reason, callerPackageName, revoked -> {
                            CollectionUtils.forEach(revoked, (pkg, perms) -> {
                                Preconditions.checkNotNull(pkg);
                                Preconditions.checkCollectionElementsNotNull(perms, "permissions");
                            });
                            callback.complete(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);
                        });
            }

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

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

                enforceCallingPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, null);

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

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

                enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);

                onGetAppPermissions(packageName, callback::complete);
                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);
                            }
                        });
            }

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

            @Override
            public void countPermissionApps(List<String> permissionNames, int flags,
                    AndroidFuture callback) {
                    RemoteCallback 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, callback::complete);
                onCountPermissionApps(permissionNames, flags, numApps -> {
                    Bundle result = new Bundle();
                    result.putInt(PermissionControllerManager.KEY_RESULT, numApps);
                    callback.sendResult(result);
                });
            }

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

                enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);

                onGetPermissionUsages(countSystem, numMillis, callback::complete);
                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);
                    }
                });
            }

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

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

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

                enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
                        null);

                onGrantOrUpgradeDefaultRuntimePermissions(() -> callback.complete(null));
                onGrantOrUpgradeDefaultRuntimePermissions(() -> callback.sendResult(Bundle.EMPTY));
            }
        };
    }
+0 −20
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