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

Commit daaa6b79 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "estricted permission mechanism - PermissionController" into qt-dev

parents 3d908f2f 95834e5c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
    <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" />
    <uses-permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" />
    <uses-permission android:name="android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY" />
    <uses-permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <uses-permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" />
    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+8 −13
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import android.content.pm.PermissionInfo;
import android.os.Build;
import android.os.UserHandle;
import android.permission.PermissionManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -54,6 +53,7 @@ import com.android.permissioncontroller.R;
import java.text.Collator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * All permissions of a permission group that are requested by an app.
@@ -229,6 +229,10 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
                getBackgroundRequestDetail(groupInfo), groupInfo.packageName, groupInfo.icon,
                userHandle, delayChanges, appOpsManager);

        final Set<String> whitelistedRestrictedPermissions = context.getPackageManager()
                .getWhitelistedRestrictedPermissions(packageInfo.packageName,
                        Utils.FLAGS_PERMISSION_WHITELIST_ALL);

        // Parse and create permissions reqested by the app
        ArrayMap<String, Permission> allPermissions = new ArrayMap<>();
        final int permissionCount = packageInfo.requestedPermissions == null ? 0
@@ -337,22 +341,13 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>

                group.getBackgroundPermissions().addPermission(permission);
            } else {
                boolean smsAccessRestrictionEnabled = Settings.Global.getInt(
                        group.mContext.getContentResolver(),
                        Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0) == 1;
                if (!smsAccessRestrictionEnabled) {
                    group.addPermission(permission);
                } else {
                    String appOp = permission.getAppOp();
                    boolean appOpDefault = appOp != null && group.mAppOps.unsafeCheckOpNoThrow(
                            appOp, packageInfo.applicationInfo.uid, packageName)
                            == AppOpsManager.MODE_DEFAULT;
                    if (!appOpDefault) {
                if (!PackageManager.RESTRICTED_PERMISSIONS_ENABLED
                        || (!permission.isHardRestricted()
                            || whitelistedRestrictedPermissions.contains(permission.getName()))) {
                    group.addPermission(permission);
                }
            }
        }
        }

        if (group.getPermissions().isEmpty()) {
            return null;
+5 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ public final class Permission {
    private boolean mIsRuntimeOnly;
    private Permission mBackgroundPermission;
    private ArrayList<Permission> mForegroundPermissions;
    private boolean mWhitelisted;

    public Permission(String name, @NonNull PermissionInfo permissionInfo, boolean granted,
            String appOp, boolean appOpAllowed, int flags) {
@@ -94,6 +95,10 @@ public final class Permission {
        return mFlags;
    }

    boolean isHardRestricted() {
        return (mPermissionInfo.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0;
    }

    /**
     * Does this permission affect app ops.
     *
+6 −0
Original line number Diff line number Diff line
@@ -548,4 +548,10 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS

        return true;
    }

    @Override
    public void onGrantOrUpgradeDefaultRuntimePermissions() {
        // TODO: Default permission grants should go here
        RuntimePermissionsUpgradeController.upgradeIfNeeded(this);
    }
}
+107 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.packageinstaller.permission.service;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.permission.PermissionManager;
import android.util.Log;

import androidx.annotation.NonNull;

import com.android.packageinstaller.permission.utils.Utils;

import java.util.List;

/**
 * This class handles upgrading the runtime permissions database
 */
class RuntimePermissionsUpgradeController {

    // The latest version of the runtime permissions database
    private static final int LATEST_VERSION = 1;

    private RuntimePermissionsUpgradeController() {
        /* do nothing - hide constructor */
    }

    static void upgradeIfNeeded(@NonNull Context context) {
        final PermissionManager permissionManager = context.getSystemService(
                PermissionManager.class);
        final int currentVersion = permissionManager.getRuntimePermissionsVersion();

        final int upgradedVersion = onUpgradeLocked(context, currentVersion);

        if (upgradedVersion != LATEST_VERSION) {
            Log.wtf("PermissionControllerService", "warning: upgrading permission database"
                            + " to version " + LATEST_VERSION + " left it at " + currentVersion
                            + " instead; this is probably a bug. Did you update LATEST_VERSION?",
                    new Throwable());
            throw new RuntimeException("db upgrade error");
        }

        if (currentVersion != upgradedVersion) {
            permissionManager.setRuntimePermissionsVersion(LATEST_VERSION);
        }
    }

    /**
     * You must perform all necessary mutations to bring the runtime permissions
     * database from the old to the new version. When you add a new upgrade step
     * you *must* update LATEST_VERSION.
     *
     * @param context Context to access APIs.
     * @param currentVersion The current db version.
     */
    private static int onUpgradeLocked(@NonNull Context context, int currentVersion) {
        // Grandfather SMS and CallLog permissions.
        if (currentVersion <= 0) {
            final List<String> smsPermissions = Utils.getPlatformPermissionNamesOfGroup(
                    android.Manifest.permission_group.SMS);
            final List<String> callLogPermissions = Utils.getPlatformPermissionNamesOfGroup(
                    Manifest.permission_group.CALL_LOG);

            final List<PackageInfo> apps = context.getPackageManager()
                    .getInstalledPackages(PackageManager.MATCH_ALL
                            | PackageManager.GET_PERMISSIONS);

            final int appCount = apps.size();
            for (int i = 0; i < appCount; i++) {
                final PackageInfo app = apps.get(i);
                if (app.requestedPermissions == null) {
                    continue;
                }

                for (String requestedPermission : app.requestedPermissions) {
                    if (smsPermissions.contains(requestedPermission)
                            || callLogPermissions.contains(requestedPermission)) {
                        context.getPackageManager().addWhitelistedRestrictedPermission(
                                app.packageName, requestedPermission,
                                PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE);
                    }
                }
            }
            currentVersion = 1;
        }

        // XXX: Add new upgrade steps above this point.

        return currentVersion;
    }
}
Loading