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

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

Merge "Remove Permissions Hub. DO NOT MERGE" into qt-r1-dev

parents 159b4c81 1cec79bd
Loading
Loading
Loading
Loading
+2 −182
Original line number Diff line number Diff line
@@ -16,12 +16,6 @@

package com.android.packageinstaller.permission.model;

import android.app.AppOpsManager;
import android.app.AppOpsManager.HistoricalOps;
import android.app.AppOpsManager.HistoricalOpsRequest;
import android.app.AppOpsManager.HistoricalPackageOps;
import android.app.AppOpsManager.HistoricalUidOps;
import android.app.AppOpsManager.PackageOps;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.AsyncTaskLoader;
@@ -29,23 +23,13 @@ import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
import android.os.Process;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.packageinstaller.permission.model.AppPermissionUsage.Builder;
import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp;
import com.android.packageinstaller.permission.utils.Utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Loads all permission usages for a set of apps and permission groups.
@@ -142,28 +126,8 @@ public final class PermissionUsages implements LoaderCallbacks<List<AppPermissio

    public static @Nullable AppPermissionUsage.GroupUsage loadLastGroupUsage(
            @NonNull Context context, @NonNull AppPermissionGroup group) {
        if (!Utils.isPermissionsHubEnabled()) {
            return null;
        }
        final ArraySet<String> opNames = new ArraySet<>();
        final List<Permission> permissions = group.getPermissions();
        final int permCount = permissions.size();
        for (int i = 0; i < permCount; i++) {
            final Permission permission = permissions.get(i);
            final String opName = permission.getAppOp();
            if (opName != null) {
                opNames.add(opName);
            }
        }
        final String[] opNamesArray = opNames.toArray(new String[opNames.size()]);
        final List<PackageOps> usageOps = context.getSystemService(AppOpsManager.class)
                        .getOpsForPackage(group.getApp().applicationInfo.uid,
                                group.getApp().packageName, opNamesArray);
        if (usageOps == null || usageOps.isEmpty()) {
        return null;
    }
        return new AppPermissionUsage.GroupUsage(group, usageOps.get(0), null);
    }

    private static final class UsageLoader extends AsyncTaskLoader<List<AppPermissionUsage>> {
        private final int mFilterUid;
@@ -194,151 +158,7 @@ public final class PermissionUsages implements LoaderCallbacks<List<AppPermissio

        @Override
        public @NonNull List<AppPermissionUsage> loadInBackground() {
            final List<PermissionGroup> groups = PermissionGroups.getPermissionGroups(
                    getContext(), this::isLoadInBackgroundCanceled, mGetUiInfo,
                    mGetNonPlatformPermissions, mFilterPermissionGroups, mFilterPackageName);
            if (!Utils.isPermissionsHubEnabled()) {
                return Collections.emptyList();
            }

            if (groups.isEmpty()) {
                return Collections.emptyList();
            }

            final List<AppPermissionUsage> usages = new ArrayList<>();
            final ArraySet<String> opNames = new ArraySet<>();
            final ArrayMap<Pair<Integer, String>, AppPermissionUsage.Builder> usageBuilders =
                    new ArrayMap<>();

            final int groupCount = groups.size();
            for (int groupIdx = 0; groupIdx < groupCount; groupIdx++) {
                final PermissionGroup group = groups.get(groupIdx);
                // Filter out third party permissions
                if (!group.getDeclaringPackage().equals(Utils.OS_PKG)) {
                    continue;
                }
                if (!Utils.shouldShowPermissionUsage(group.getName())) {
                    continue;
                }

                groups.add(group);

                final List<PermissionApp> permissionApps = group.getPermissionApps().getApps();
                final int appCount = permissionApps.size();
                for (int appIdx = 0; appIdx < appCount; appIdx++) {
                    final PermissionApp permissionApp = permissionApps.get(appIdx);
                    if (mFilterUid != Process.INVALID_UID
                            && permissionApp.getAppInfo().uid != mFilterUid) {
                        continue;
                    }

                    final AppPermissionGroup appPermGroup = permissionApp.getPermissionGroup();
                    if (!Utils.shouldShowPermission(getContext(), appPermGroup)) {
                        continue;
                    }
                    final Pair<Integer, String> usageKey = Pair.create(permissionApp.getUid(),
                            permissionApp.getPackageName());
                    AppPermissionUsage.Builder usageBuilder = usageBuilders.get(usageKey);
                    if (usageBuilder == null) {
                        usageBuilder = new Builder(permissionApp);
                        usageBuilders.put(usageKey, usageBuilder);
                    }
                    usageBuilder.addGroup(appPermGroup);
                    final List<Permission> permissions = appPermGroup.getPermissions();
                    final int permCount = permissions.size();
                    for (int permIdx = 0; permIdx < permCount; permIdx++) {
                        final Permission permission = permissions.get(permIdx);
                        final String opName = permission.getAppOp();
                        if (opName != null) {
                            opNames.add(opName);
                        }
                    }
                }
            }

            if (usageBuilders.isEmpty()) {
            return Collections.emptyList();
        }

            final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);

            // Get last usage data and put in a map for a quick lookup.
            final ArrayMap<Pair<Integer, String>, PackageOps> lastUsages =
                    new ArrayMap<>(usageBuilders.size());
            final String[] opNamesArray = opNames.toArray(new String[opNames.size()]);
            if ((mUsageFlags & USAGE_FLAG_LAST) != 0) {
                final List<PackageOps> usageOps;
                if (mFilterPackageName != null || mFilterUid != Process.INVALID_UID) {
                    usageOps = appOpsManager.getOpsForPackage(mFilterUid, mFilterPackageName,
                            opNamesArray);
                } else {
                    usageOps = appOpsManager.getPackagesForOps(opNamesArray);
                }
                if (usageOps != null && !usageOps.isEmpty()) {
                    final int usageOpsCount = usageOps.size();
                    for (int i = 0; i < usageOpsCount; i++) {
                        final PackageOps usageOp = usageOps.get(i);
                        lastUsages.put(Pair.create(usageOp.getUid(), usageOp.getPackageName()),
                                usageOp);
                    }
                }
            }

            if (isLoadInBackgroundCanceled()) {
                return Collections.emptyList();
            }

            // Get historical usage data and put in a map for a quick lookup
            final ArrayMap<Pair<Integer, String>, HistoricalPackageOps> historicalUsages =
                    new ArrayMap<>(usageBuilders.size());
            if ((mUsageFlags & USAGE_FLAG_HISTORICAL) != 0) {
                final AtomicReference<HistoricalOps> historicalOpsRef = new AtomicReference<>();
                final CountDownLatch latch = new CountDownLatch(1);
                final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder(
                        mFilterBeginTimeMillis, mFilterEndTimeMillis)
                        .setUid(mFilterUid)
                        .setPackageName(mFilterPackageName)
                        .setOpNames(new ArrayList<>(opNames))
                        .setFlags(AppOpsManager.OP_FLAGS_ALL_TRUSTED)
                        .build();
                appOpsManager.getHistoricalOps(request, Runnable::run,
                        (HistoricalOps ops) -> {
                            historicalOpsRef.set(ops);
                            latch.countDown();
                        });
                try {
                    latch.await(5, TimeUnit.DAYS);
                } catch (InterruptedException ignored) { }

                final HistoricalOps historicalOps = historicalOpsRef.get();
                if (historicalOps != null) {
                    final int uidCount = historicalOps.getUidCount();
                    for (int i = 0; i < uidCount; i++) {
                        final HistoricalUidOps uidOps = historicalOps.getUidOpsAt(i);
                        final int packageCount = uidOps.getPackageCount();
                        for (int j = 0; j < packageCount; j++) {
                            final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(j);
                            historicalUsages.put(
                                    Pair.create(uidOps.getUid(), packageOps.getPackageName()),
                                    packageOps);
                        }
                    }
                }
            }

            // Construct the historical usages based on data we fetched
            final int builderCount = usageBuilders.size();
            for (int i = 0; i < builderCount; i++) {
                final Pair<Integer, String> key = usageBuilders.keyAt(i);
                final Builder usageBuilder = usageBuilders.valueAt(i);
                final PackageOps lastUsage = lastUsages.get(key);
                usageBuilder.setLastUsage(lastUsage);
                final HistoricalPackageOps historicalUsage = historicalUsages.get(key);
                usageBuilder.setHistoricalUsage(historicalUsage);
                usages.add(usageBuilder.build());
            }

            return usages;
        }
    }
}
+1 −49
Original line number Diff line number Diff line
@@ -47,11 +47,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissionUsage;
import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage;
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.model.Permission;
import com.android.packageinstaller.permission.model.PermissionUsages;
import com.android.packageinstaller.permission.utils.Utils;

import org.xmlpull.v1.XmlPullParser;
@@ -499,52 +496,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS

    private @NonNull List<RuntimePermissionUsageInfo> onGetPermissionUsages(
            boolean countSystem, long numMillis) {
        ArrayMap<String, Integer> groupUsers = new ArrayMap<>();

        long curTime = System.currentTimeMillis();
        PermissionUsages usages = new PermissionUsages(this);
        long filterTimeBeginMillis = Math.max(System.currentTimeMillis() - numMillis, 0);
        usages.load(null, null, filterTimeBeginMillis, Long.MAX_VALUE,
                PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, null,
                false, false, null, true);

        List<AppPermissionUsage> appPermissionUsages = usages.getUsages();
        int numApps = appPermissionUsages.size();
        for (int appNum = 0; appNum < numApps; appNum++) {
            AppPermissionUsage appPermissionUsage = appPermissionUsages.get(appNum);

            List<GroupUsage> appGroups = appPermissionUsage.getGroupUsages();
            int numGroups = appGroups.size();
            for (int groupNum = 0; groupNum < numGroups; groupNum++) {
                GroupUsage groupUsage = appGroups.get(groupNum);

                if (groupUsage.getLastAccessTime() < filterTimeBeginMillis) {
                    continue;
                }
                if (!shouldShowPermission(this, groupUsage.getGroup())) {
                    continue;
                }
                if (!countSystem && !Utils.isGroupOrBgGroupUserSensitive(groupUsage.getGroup())) {
                    continue;
                }

                String groupName = groupUsage.getGroup().getName();
                Integer numUsers = groupUsers.get(groupName);
                if (numUsers == null) {
                    groupUsers.put(groupName, 1);
                } else {
                    groupUsers.put(groupName, numUsers + 1);
                }
            }
        }

        List<RuntimePermissionUsageInfo> users = new ArrayList<>();
        int numGroups = groupUsers.size();
        for (int groupNum = 0; groupNum < numGroups; groupNum++) {
            users.add(new RuntimePermissionUsageInfo(groupUsers.keyAt(groupNum),
                    groupUsers.valueAt(groupNum)));
        }
        return users;
        return Collections.emptyList();
    }

    @Override
+3 −31
Original line number Diff line number Diff line
@@ -36,9 +36,7 @@ import com.android.packageinstaller.permission.ui.auto.AutoAppPermissionsFragmen
import com.android.packageinstaller.permission.ui.auto.AutoManageStandardPermissionsFragment;
import com.android.packageinstaller.permission.ui.auto.AutoPermissionAppsFragment;
import com.android.packageinstaller.permission.ui.handheld.ManageStandardPermissionsFragment;
import com.android.packageinstaller.permission.ui.handheld.PermissionUsageFragment;
import com.android.packageinstaller.permission.ui.wear.AppPermissionsFragmentWear;
import com.android.packageinstaller.permission.utils.Utils;
import com.android.permissioncontroller.R;

import java.util.Random;
@@ -88,35 +86,9 @@ public final class ManagePermissionsActivity extends FragmentActivity {
                }
                break;

            case Intent.ACTION_REVIEW_PERMISSION_USAGE: {
                if (!Utils.isPermissionsHubEnabled()) {
            case Intent.ACTION_REVIEW_PERMISSION_USAGE:
                finish();
                return;
                }

                permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME);
                String groupName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME);
                long numMillis = getIntent().getLongExtra(Intent.EXTRA_DURATION_MILLIS,
                        Long.MAX_VALUE);

                if (permissionName != null) {
                    String permGroupName = Utils.getGroupOfPlatformPermission(permissionName);
                    if (permGroupName == null) {
                        Log.w(LOG_TAG, "Invalid platform permission: " + permissionName);
                    }
                    if (groupName != null && !groupName.equals(permGroupName)) {
                        Log.i(LOG_TAG,
                                "Inconsistent EXTRA_PERMISSION_NAME / EXTRA_PERMISSION_GROUP_NAME");
                        finish();
                        return;
                    }
                    if (groupName == null) {
                        groupName = permGroupName;
                    }
                }

                androidXFragment = PermissionUsageFragment.newInstance(groupName, numMillis);
            } break;

            case Intent.ACTION_MANAGE_APP_PERMISSIONS: {
                String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+2 −43
Original line number Diff line number Diff line
@@ -16,57 +16,16 @@

package com.android.packageinstaller.permission.ui;

import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;

import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;

import com.android.packageinstaller.DeviceUtils;
import com.android.packageinstaller.permission.ui.auto.ReviewOngoingUsageAutoFragment;
import com.android.packageinstaller.permission.ui.handheld.ReviewOngoingUsageFragment;

/**
 * A dialog listing the currently uses of camera, microphone, and location.
 */
public final class ReviewOngoingUsageActivity extends FragmentActivity {

    // Number of milliseconds in the past to look for accesses if nothing was specified.
    private static final long DEFAULT_MILLIS = 5000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);

        long numMillis = getIntent().getLongExtra(Intent.EXTRA_DURATION_MILLIS, DEFAULT_MILLIS);
        if (DeviceUtils.isAuto(this)) {
            getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
                    ReviewOngoingUsageAutoFragment.newInstance(numMillis)).commit();
        } else {
            getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
                    ReviewOngoingUsageFragment.newInstance(numMillis)).commit();
        }
    }


    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                // in automotive mode, there's no system wide back button, so need to add that
                if (DeviceUtils.isAuto(this)) {
                    onBackPressed();
                } else {
        finish();
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
        return;
    }
}
+0 −34
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.content.pm.PackageInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
import android.widget.Toast;

import androidx.annotation.NonNull;
@@ -36,7 +35,6 @@ import androidx.preference.PreferenceScreen;
import com.android.packageinstaller.auto.AutoSettingsFrameFragment;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.model.PermissionUsages;
import com.android.packageinstaller.permission.ui.AppPermissionActivity;
import com.android.packageinstaller.permission.utils.Utils;
import com.android.permissioncontroller.R;
@@ -247,7 +245,6 @@ public class AutoAppPermissionsFragment extends AutoSettingsFrameFragment {
        preference.setKey(group.getName());
        preference.setTitle(group.getFullLabel());
        preference.setIcon(Utils.applyTint(context, icon, android.R.attr.colorControlNormal));
        preference.setSummary(getPreferenceSummary(group));
        preference.setOnPreferenceClickListener(pref -> {
            Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName);
@@ -261,37 +258,6 @@ public class AutoAppPermissionsFragment extends AutoSettingsFrameFragment {
        return preference;
    }

    private String getPreferenceSummary(AppPermissionGroup group) {
        String groupSummary = getGroupSummary(group);

        if (Utils.isModernPermissionGroup(group.getName()) && Utils.shouldShowPermissionUsage(
                group.getName())) {
            String lastAccessStr = Utils.getAbsoluteLastUsageString(getContext(),
                    PermissionUsages.loadLastGroupUsage(getContext(), group));
            if (lastAccessStr != null) {
                if (group.areRuntimePermissionsGranted()) {
                    return getContext().getString(R.string.app_permission_most_recent_summary,
                            lastAccessStr);
                } else {
                    return getContext().getString(
                            R.string.app_permission_most_recent_denied_summary, lastAccessStr);
                }
            } else {
                if (TextUtils.isEmpty(groupSummary) && Utils.isPermissionsHubEnabled()) {
                    if (group.areRuntimePermissionsGranted()) {
                        return getContext().getString(
                                R.string.app_permission_never_accessed_summary);
                    } else {
                        return getContext().getString(
                                R.string.app_permission_never_accessed_denied_summary);
                    }
                }
            }
        }

        return groupSummary;
    }

    private String getGroupSummary(AppPermissionGroup group) {
        if (group.hasPermissionWithBackgroundMode() && group.areRuntimePermissionsGranted()) {
            AppPermissionGroup backgroundGroup = group.getBackgroundPermissions();
Loading