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

Commit de848300 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow role to grant/revoke app op permissions." into rvc-dev

parents 57747f28 7da73a56
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -417,9 +417,9 @@
                </intent-filter>
            </service>
        </required-components>
        <app-ops>
            <app-op name="android:system_alert_window" mode="allowed" />
        </app-ops>
        <app-op-permissions>
            <app-op-permission name="android.permission.SYSTEM_ALERT_WINDOW" />
        </app-op-permissions>
    </role>

    <role
+2 −0
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ when it declares all these components. They follow a similar syntax as in typica
- `<permissions>`: Child tags like `<permission-set>` and `<permission>` can be used to specify the
permissions that should be granted to the app when it has the role. Several `<permission-set>` are
defined at the beginning of `roles.xml`.
- `<app-op-permissions>`: The child tag `<app-op-permission>` can be used to specify the app op
permissions whose app op should be granted to the app when it has the role.
- `<app-ops>`: The child tag `<app-op>` can be used to specify the app ops that should be granted to
the app when it has the role.
- `<preferred-activities>`: The child tag `<preferred-activity>` can be used to specify the
+2 −2
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ public class AppOp {
        if (!checkTargetSdkVersion(packageName, context)) {
            return false;
        }
        return Permissions.setAppOpMode(packageName, mName, mMode, context);
        return Permissions.setAppOpUidMode(packageName, mName, mMode, context);
    }

    /**
@@ -96,7 +96,7 @@ public class AppOp {
            return false;
        }
        int defaultMode = Permissions.getDefaultAppOpMode(mName);
        return Permissions.setAppOpMode(packageName, mName, defaultMode, context);
        return Permissions.setAppOpUidMode(packageName, mName, defaultMode, context);
    }

    private boolean checkTargetSdkVersion(@NonNull String packageName, @NonNull Context context) {
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.permissioncontroller.role.model;

import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import androidx.annotation.NonNull;

import com.android.permissioncontroller.permission.utils.ArrayUtils;
import com.android.permissioncontroller.role.utils.PackageUtils;

/**
 * App op permissions to be granted or revoke by a {@link Role}.
 */
public class AppOpPermissions {

    private AppOpPermissions() {}

    /**
     * Grant the app op of an app op permission to an application.
     *
     * @param packageName the package name of the application
     * @param appOpPermission the name of the app op permission
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether any app op mode has changed
     */
    public static boolean grant(@NonNull String packageName, @NonNull String appOpPermission,
            @NonNull Context context) {
        PackageInfo packageInfo = PackageUtils.getPackageInfo(packageName,
                PackageManager.GET_PERMISSIONS, context);
        if (packageInfo == null) {
            return false;
        }
        if (!ArrayUtils.contains(packageInfo.requestedPermissions, appOpPermission)) {
            return false;
        }
        String appOp = AppOpsManager.permissionToOp(appOpPermission);
        return setAppOpMode(packageName, appOp, AppOpsManager.MODE_ALLOWED, context);
    }

    /**
     * Revoke the app op of an app op permission from an application.
     *
     * @param packageName the package name of the application
     * @param appOpPermission the name of the app op permission
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether any app op mode has changed
     */
    public static boolean revoke(@NonNull String packageName, @NonNull String appOpPermission,
            @NonNull Context context) {
        String appOp = AppOpsManager.permissionToOp(appOpPermission);
        int defaultMode = Permissions.getDefaultAppOpMode(appOp);
        return setAppOpMode(packageName, appOp, defaultMode, context);
    }

    private static boolean setAppOpMode(@NonNull String packageName, @NonNull String appOp,
            int mode, @NonNull Context context) {
        switch (appOp) {
            case AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS:
            case AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW:
            case AppOpsManager.OPSTR_WRITE_SETTINGS:
            case AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES:
            case AppOpsManager.OPSTR_START_FOREGROUND:
            // This isn't an API but we are deprecating it soon anyway.
            //case AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS:
            case AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS:
            case AppOpsManager.OPSTR_INSTANT_APP_START_FOREGROUND:
            case AppOpsManager.OPSTR_INTERACT_ACROSS_PROFILES:
            case AppOpsManager.OPSTR_LOADER_USAGE_STATS:
                return Permissions.setAppOpPackageMode(packageName, appOp, mode, context);
            default:
                return Permissions.setAppOpUidMode(packageName, appOp, mode, context);
        }
    }
}
+21 −7
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ import java.util.List;
import java.util.Set;

/**
 * Permissions to be granted or revoke by a {@link Role}.
 * Runtime permissions to be granted or revoke by a {@link Role}.
 */
public class Permissions {

@@ -336,7 +336,7 @@ public class Permissions {
                    appOpMode = AppOpsManager.MODE_ALLOWED;
                }
            }
            permissionOrAppOpChanged = setAppOpMode(packageName, appOp, appOpMode, context);
            permissionOrAppOpChanged = setAppOpUidMode(packageName, appOp, appOpMode, context);
        } else {
            // This permission is a background permission, set all its foreground permissions' app
            // op modes to MODE_ALLOWED.
@@ -349,7 +349,7 @@ public class Permissions {
                if (foregroundAppOp == null) {
                    continue;
                }
                permissionOrAppOpChanged |= setAppOpMode(packageName, foregroundAppOp,
                permissionOrAppOpChanged |= setAppOpUidMode(packageName, foregroundAppOp,
                        AppOpsManager.MODE_ALLOWED, context);
            }
        }
@@ -499,7 +499,7 @@ public class Permissions {
            // This permission is an ordinary or foreground permission, reset its app op mode to
            // default.
            int appOpMode = getDefaultAppOpMode(appOp);
            boolean appOpModeChanged = setAppOpMode(packageName, appOp, appOpMode, context);
            boolean appOpModeChanged = setAppOpUidMode(packageName, appOp, appOpMode, context);
            permissionOrAppOpChanged |= appOpModeChanged;

            if (appOpModeChanged) {
@@ -528,7 +528,7 @@ public class Permissions {
                if (foregroundAppOp == null) {
                    continue;
                }
                permissionOrAppOpChanged |= setAppOpMode(packageName, foregroundAppOp,
                permissionOrAppOpChanged |= setAppOpUidMode(packageName, foregroundAppOp,
                        AppOpsManager.MODE_FOREGROUND, context);
            }
        }
@@ -777,8 +777,18 @@ public class Permissions {
        return AppOpsManager.opToDefaultMode(appOp);
    }

    static boolean setAppOpMode(@NonNull String packageName, @NonNull String appOp, int mode,
    static boolean setAppOpUidMode(@NonNull String packageName, @NonNull String appOp, int mode,
            @NonNull Context context) {
        return setAppOpMode(packageName, appOp, mode, true, context);
    }

    static boolean setAppOpPackageMode(@NonNull String packageName, @NonNull String appOp, int mode,
            @NonNull Context context) {
        return setAppOpMode(packageName, appOp, mode, false, context);
    }

    private static boolean setAppOpMode(@NonNull String packageName, @NonNull String appOp,
            int mode, boolean setUidMode, @NonNull Context context) {
        Integer currentMode = getAppOpMode(packageName, appOp, context);
        if (currentMode != null && currentMode == mode) {
            return false;
@@ -790,7 +800,11 @@ public class Permissions {
            return false;
        }
        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
        if (setUidMode) {
            appOpsManager.setUidMode(appOp, applicationInfo.uid, mode);
        } else {
            appOpsManager.setMode(appOp, applicationInfo.uid, packageName, mode);
        }
        return true;
    }
}
Loading