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

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

Merge "Add a parameter to filter out system apps" into qt-dev

parents 2351ded4 b1317579
Loading
Loading
Loading
Loading
+54 −15
Original line number Diff line number Diff line
@@ -18,11 +18,11 @@ package com.android.settingslib.location;

import android.app.AppOpsManager;
import android.content.Context;
import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.format.DateUtils;
@@ -48,10 +48,15 @@ public class RecentLocationApps {
    private static final long RECENT_TIME_INTERVAL_MILLIS = DateUtils.DAY_IN_MILLIS;

    @VisibleForTesting
    static final int[] LOCATION_OPS = new int[] {
    static final int[] LOCATION_REQUEST_OPS = new int[]{
            AppOpsManager.OP_MONITOR_LOCATION,
            AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION,
    };
    @VisibleForTesting
    static final int[] LOCATION_PERMISSION_OPS = new int[]{
            AppOpsManager.OP_FINE_LOCATION,
            AppOpsManager.OP_COARSE_LOCATION,
    };

    private final PackageManager mPackageManager;
    private final Context mContext;
@@ -67,11 +72,13 @@ public class RecentLocationApps {
     * Fills a list of applications which queried location recently within specified time.
     * Apps are sorted by recency. Apps with more recent location requests are in the front.
     */
    public List<Request> getAppList() {
    public List<Request> getAppList(boolean showSystemApps) {
        // Retrieve a location usage list from AppOps
        PackageManager pm = mContext.getPackageManager();
        // Retrieve a location usage list from AppOps
        AppOpsManager aoManager =
                (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        List<AppOpsManager.PackageOps> appOps = aoManager.getPackagesForOps(LOCATION_OPS);
        List<AppOpsManager.PackageOps> appOps = aoManager.getPackagesForOps(LOCATION_REQUEST_OPS);

        final int appOpsCount = appOps != null ? appOps.size() : 0;

@@ -83,26 +90,58 @@ public class RecentLocationApps {

        for (int i = 0; i < appOpsCount; ++i) {
            AppOpsManager.PackageOps ops = appOps.get(i);
            // Don't show the Android System in the list - it's not actionable for the user.
            // Also don't show apps belonging to background users except managed users.
            String packageName = ops.getPackageName();
            int uid = ops.getUid();
            int userId = UserHandle.getUserId(uid);
            boolean isAndroidOs =
                    (uid == Process.SYSTEM_UID) && ANDROID_SYSTEM_PACKAGE_NAME.equals(packageName);
            if (isAndroidOs || !profiles.contains(new UserHandle(userId))) {
            final UserHandle user = UserHandle.getUserHandleForUid(uid);

            // Don't show apps belonging to background users except managed users.
            if (!profiles.contains(user)) {
                continue;
            }

            // Don't show apps that do not have user sensitive location permissions
            boolean showApp = true;
            if (!showSystemApps) {
                for (int op : LOCATION_PERMISSION_OPS) {
                    final String permission = AppOpsManager.opToPermission(op);
                    final int permissionFlags = pm.getPermissionFlags(permission, packageName,
                            user);
                    if (PermissionChecker.checkPermission(mContext, permission, -1, uid,
                            packageName)
                            == PermissionChecker.PERMISSION_GRANTED) {
                        if ((permissionFlags
                                & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED)
                                == 0) {
                            showApp = false;
                            break;
                        }
                    } else {
                        if ((permissionFlags
                                & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED) == 0) {
                            showApp = false;
                            break;
                        }
                    }
                }
            }
            if (showApp) {
                Request request = getRequestFromOps(now, ops);
                if (request != null) {
                    requests.add(request);
                }
            }
        }
        return requests;
    }

    public List<Request> getAppListSorted() {
        List<Request> requests = getAppList();
    /**
     * Gets a list of apps that requested for location recently, sorting by recency.
     *
     * @param showSystemApps whether includes system apps in the list.
     * @return the list of apps that recently requested for location.
     */
    public List<Request> getAppListSorted(boolean showSystemApps) {
        List<Request> requests = getAppList(showSystemApps);
        // Sort the list of Requests by recency. Most recent request first.
        Collections.sort(requests, Collections.reverseOrder(new Comparator<Request>() {
            @Override
+11 −9
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@ import android.content.res.Resources;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;

import android.util.LongSparseLongArray;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -75,7 +75,8 @@ public class RecentLocationAppsTest {

        long[] testRequestTime = {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO};
        List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime);
        when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_OPS)).thenReturn(appOps);
        when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_REQUEST_OPS)).thenReturn(
                appOps);
        mockTestApplicationInfos(mTestUserId, TEST_PACKAGE_NAMES);

        mRecentLocationApps = new RecentLocationApps(mContext);
@@ -83,7 +84,7 @@ public class RecentLocationAppsTest {

    @Test
    public void testGetAppList_shouldFilterRecentApps() {
        List<RecentLocationApps.Request> requests = mRecentLocationApps.getAppList();
        List<RecentLocationApps.Request> requests = mRecentLocationApps.getAppList(true);
        // Only two of the apps have requested location within 15 min.
        assertThat(requests).hasSize(2);
        // Make sure apps are ordered by recency
@@ -107,11 +108,12 @@ public class RecentLocationAppsTest {
                {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO, ONE_MIN_AGO};
        List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime);
        appOps.add(androidSystemPackageOps);
        when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_OPS)).thenReturn(appOps);
        when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_REQUEST_OPS)).thenReturn(
                appOps);
        mockTestApplicationInfos(
                Process.SYSTEM_UID, RecentLocationApps.ANDROID_SYSTEM_PACKAGE_NAME);

        List<RecentLocationApps.Request> requests = mRecentLocationApps.getAppList();
        List<RecentLocationApps.Request> requests = mRecentLocationApps.getAppList(true);
        // Android OS shouldn't show up in the list of apps.
        assertThat(requests).hasSize(2);
        // Make sure apps are ordered by recency