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

Commit 4fce75d5 authored by Eugene Susla's avatar Eugene Susla Committed by Nate Myren
Browse files

Update USER_SENSITIVE flags on app install and optimize it

This also parallelizes flag updating.

Currently, the broadcast listener is disabled, due to test flake, so it
will not update on app install/changes

Bug: 141311767
Test: - on first boot go to permissions screen, and ensure system apps
categorization makes sense
- install app that requests location, and ensure it's not listed
as system app in permission screen

Change-Id: I37ea4b196313fe9fa71150c21e7cca591067d572
parent eaf14b27
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8940,7 +8940,7 @@ package android.permission {
    method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>);
    method @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>);
    method @BinderThread public void onStageAndApplyRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);
    method @BinderThread public void onUpdateUserSensitivePermissionFlags();
    method @BinderThread public void onUpdateUserSensitivePermissionFlags(int, @NonNull Runnable);
    field public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService";
  }
+1 −1
Original line number Diff line number Diff line
@@ -42,6 +42,6 @@ oneway interface IPermissionController {
    void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName, String packageName,
                String permission, int grantState, in AndroidFuture callback);
    void grantOrUpgradeDefaultRuntimePermissions(in AndroidFuture callback);
    void updateUserSensitive(in AndroidFuture callback);
    void notifyOneTimePermissionSessionTimeout(String packageName);
    void updateUserSensitiveForApp(int uid, in AndroidFuture callback);
}
+15 −2
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.Process;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
@@ -626,14 +627,26 @@ public final class PermissionControllerManager {
    }

    /**
     * @see PermissionControllerService#onUpdateUserSensitive()
     * @see PermissionControllerManager#updateUserSensitiveForApp
     * @hide
     */
    public void updateUserSensitive() {
        updateUserSensitiveForApp(Process.INVALID_UID);
    }

    /**
     * @see PermissionControllerService#onUpdateUserSensitiveForApp
     * @hide
     */
    public void updateUserSensitiveForApp(int uid) {
        mRemoteService.postAsync(service -> {
            AndroidFuture<Void> future = new AndroidFuture<>();
            service.updateUserSensitive(future);
            service.updateUserSensitiveForApp(uid, future);
            return future;
        }).whenComplete((res, err) -> {
            if (err != null) {
                Log.e(TAG, "Error updating user_sensitive flags for uid " + uid, err);
            }
        });
    }

+12 −6
Original line number Diff line number Diff line
@@ -218,11 +218,14 @@ public abstract class PermissionControllerService extends Service {
     * Called by system to update the
     * {@link PackageManager}{@code .FLAG_PERMISSION_USER_SENSITIVE_WHEN_*} flags for permissions.
     * <p>
     * This is typically when creating a new user or upgrading either system or
     * permission controller package.
     *
     * If uid is -1, updates the permission flags for all packages.
     *
     * Typically called by the system when a new app is installed or updated or when creating a
     * new user or upgrading either system or permission controller package.
     */
    @BinderThread
    public void onUpdateUserSensitivePermissionFlags() {
    public void onUpdateUserSensitivePermissionFlags(int uid, @NonNull Runnable callback) {
        throw new AbstractMethodError("Must be overridden in implementing class");
    }

@@ -459,11 +462,14 @@ public abstract class PermissionControllerService extends Service {
            }

            @Override
            public void updateUserSensitive(AndroidFuture callback) {
            public void updateUserSensitiveForApp(int uid, @NonNull AndroidFuture callback) {
                Preconditions.checkNotNull(callback, "callback cannot be null");

                onUpdateUserSensitivePermissionFlags();
                callback.complete(null);
                try {
                    onUpdateUserSensitivePermissionFlags(uid, () -> callback.complete(null));
                } catch (Exception e) {
                    callback.completeExceptionally(e);
                }
            }

            @Override
+60 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.app.AppOpsManager;
import android.app.AppOpsManagerInternal;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -173,6 +174,65 @@ public final class PermissionPolicyService extends SystemService {
        } catch (RemoteException doesNotHappen) {
            Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
        }

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        intentFilter.addDataScheme("package");


        /* TODO ntmyren: enable receiver when test flakes are fixed
        getContext().registerReceiverAsUser(new BroadcastReceiver() {
            final List<Integer> mUserSetupUids = new ArrayList<>(200);
            final Map<UserHandle, PermissionControllerManager> mPermControllerManagers =
                    new HashMap<>();

            @Override
            public void onReceive(Context context, Intent intent) {
                boolean hasSetupRun = true;
                try {
                    hasSetupRun = Settings.Secure.getInt(getContext().getContentResolver(),
                            Settings.Secure.USER_SETUP_COMPLETE) != 0;
                } catch (Settings.SettingNotFoundException e) {
                    // Ignore error, assume setup has run
                }
                int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
                // If there is no valid package for the given UID, return immediately
                if (packageManagerInternal.getPackage(uid) == null) {
                    return;
                }

                if (hasSetupRun) {
                    if (!mUserSetupUids.isEmpty()) {
                        synchronized (mUserSetupUids) {
                            for (int i = mUserSetupUids.size() - 1; i >= 0; i--) {
                                updateUid(mUserSetupUids.get(i));
                            }
                            mUserSetupUids.clear();
                        }
                    }
                    updateUid(uid);
                } else {
                    synchronized (mUserSetupUids) {
                        if (!mUserSetupUids.contains(uid)) {
                            mUserSetupUids.add(uid);
                        }
                    }
                }
            }

            private void updateUid(int uid) {
                UserHandle user = UserHandle.getUserHandleForUid(uid);
                PermissionControllerManager manager = mPermControllerManagers.get(user);
                if (manager == null) {
                    manager = new PermissionControllerManager(
                            getUserContext(getContext(), user), FgThread.getHandler());
                    mPermControllerManagers.put(user, manager);
                }
                manager.updateUserSensitiveForApp(uid);
            }
        }, UserHandle.ALL, intentFilter, null, null);
         */
    }

    /**
@@ -182,7 +242,6 @@ public final class PermissionPolicyService extends SystemService {
     * {@link AppOpsManager#sOpToSwitch share an op} to control the access.
     *
     * @param permission The permission
     *
     * @return The op that controls the access of the permission
     */
    private static int getSwitchOp(@NonNull String permission) {