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

Commit 12d0ee09 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Apply fg/bg state in default grant policy

The fg/bg state is encoded in the app-op of the foreground permission.
I.e. depending whether the background permission is granted, the
foregrounds app-op state need to be different.

Test: Checked that default browser has both fg and bg location
Change-Id: I1428b65f95b23c921a3a5f69d84efe9124b51cd1
parent d82bdafc
Loading
Loading
Loading
Loading
+91 −10
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.DownloadManager;
import android.app.SearchManager;
import android.app.admin.DevicePolicyManager;
@@ -1027,6 +1028,23 @@ public final class DefaultPermissionGrantPolicy {
                | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED)) != 0;
    }

    /**
     * Return the background permission for a permission.
     *
     * @param permission The name of the foreground permission
     *
     * @return The name of the background permission or {@code null} if the permission has no
     *         background permission
     */
    private @Nullable String getBackgroundPermission(@NonNull String permission) {
        try {
            return mContext.getPackageManager().getPermissionInfo(permission,
                    0).backgroundPermission;
        } catch (NameNotFoundException e) {
            return null;
        }
    }

    private void grantRuntimePermissions(PackageInfo pkg,
            Set<String> permissionsWithoutSplits, boolean systemFixed, boolean ignoreSystemPackage,
            int userId) {
@@ -1039,9 +1057,15 @@ public final class DefaultPermissionGrantPolicy {
            return;
        }

        PackageManager pm = mContext.getPackageManager();
        final ArraySet<String> permissions = new ArraySet<>(permissionsWithoutSplits);
        ApplicationInfo applicationInfo = pkg.applicationInfo;

        int newFlags = PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
        if (systemFixed) {
            newFlags |= PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
        }

        // Automatically attempt to grant split permissions to older APKs
        final List<PermissionManager.SplitPermissionInfo> splitPermissions =
                mContext.getSystemService(PermissionManager.class).getSplitPermissions();
@@ -1081,9 +1105,28 @@ public final class DefaultPermissionGrantPolicy {
            }
        }

        final int grantablePermissionCount = requestedPermissions.length;
        for (int i = 0; i < grantablePermissionCount; i++) {
        final int numRequestedPermissions = requestedPermissions.length;

        // Sort requested permissions so that all permissions that are a foreground permission (i.e.
        // permisions that have background permission) are before their background permissions.
        final String[] sortedRequestedPermissions = new String[numRequestedPermissions];
        int numForeground = 0;
        int numOther = 0;
        for (int i = 0; i < numRequestedPermissions; i++) {
            String permission = requestedPermissions[i];
            if (getBackgroundPermission(permission) != null) {
                sortedRequestedPermissions[numForeground] = permission;
                numForeground++;
            } else {
                sortedRequestedPermissions[numRequestedPermissions - 1 - numOther] =
                        permission;
                numOther++;
            }
        }

        for (int requestedPermissionNum = 0; requestedPermissionNum < numRequestedPermissions;
                requestedPermissionNum++) {
            String permission = requestedPermissions[requestedPermissionNum];

            // If there is a disabled system app it may request a permission the updated
            // version ot the data partition doesn't, In this case skip the permission.
@@ -1111,20 +1154,58 @@ public final class DefaultPermissionGrantPolicy {
                        continue;
                    }

                    int uid = UserHandle.getUid(userId,
                            UserHandle.getAppId(pkg.applicationInfo.uid));
                    String op = AppOpsManager.permissionToOp(permission);

                    mContext.getPackageManager()
                            .grantRuntimePermission(pkg.packageName, permission, user);
                    if (DEBUG) {
                        Log.i(TAG, "Granted " + (systemFixed ? "fixed " : "not fixed ")
                                + permission + " to default handler " + pkg);

                    mContext.getPackageManager().updatePermissionFlags(permission, pkg.packageName,
                            newFlags, newFlags, user);

                    List<String> fgPerms = mPermissionManager.getBackgroundPermissions()
                            .get(permission);
                    if (fgPerms != null) {
                        int numFgPerms = fgPerms.size();
                        for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
                            String fgPerm = fgPerms.get(fgPermNum);

                            if (pm.checkPermission(fgPerm, pkg.packageName)
                                    == PackageManager.PERMISSION_GRANTED) {
                                // Upgrade the app-op state of the fg permission to allow bg access
                                mContext.getSystemService(AppOpsManager.class).setMode(
                                        AppOpsManager.permissionToOp(fgPerm), uid,
                                        pkg.packageName, AppOpsManager.MODE_ALLOWED);

                                break;
                            }
                        }
                    }

                    int newFlags = PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
                    if (systemFixed) {
                        newFlags |= PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
                    String bgPerm = getBackgroundPermission(permission);
                    if (bgPerm == null) {
                        if (op != null) {
                            mContext.getSystemService(AppOpsManager.class).setMode(op, uid,
                                    pkg.packageName, AppOpsManager.MODE_ALLOWED);
                        }
                    } else {
                        int mode;
                        if (pm.checkPermission(bgPerm, pkg.packageName)
                                == PackageManager.PERMISSION_GRANTED) {
                            mode = AppOpsManager.MODE_ALLOWED;
                        } else {
                            mode = AppOpsManager.MODE_FOREGROUND;
                        }

                    mContext.getPackageManager().updatePermissionFlags(permission, pkg.packageName,
                            newFlags, newFlags, user);
                        mContext.getSystemService(AppOpsManager.class).setMode(op, uid,
                                pkg.packageName, mode);
                    }

                    if (DEBUG) {
                        Log.i(TAG, "Granted " + (systemFixed ? "fixed " : "not fixed ")
                                + permission + " to default handler " + pkg);
                    }
                }

                // If a component gets a permission for being the default handler A