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

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

Merge "Add location op apps to "Recent app use" UI" into main

parents a01ff0ff 23c26269
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1329,7 +1329,7 @@ public final class PermissionManager {
        // Lazily initialize the usage helper
        initializeUsageHelper();
        boolean includeMicrophoneUsage = !micMuted;
        return mUsageHelper.getOpUsageDataByDevice(includeMicrophoneUsage,
        return mUsageHelper.getOpUsageDataForIndicatorsByDevice(includeMicrophoneUsage,
                VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
    }

+86 −3
Original line number Diff line number Diff line
@@ -40,10 +40,12 @@ import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_AC

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.companion.virtual.VirtualDevice;
import android.companion.virtual.VirtualDeviceManager;
import android.content.Context;
import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.Attribution;
import android.content.pm.PackageInfo;
@@ -54,6 +56,7 @@ import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.flags.Flags;
import android.provider.DeviceConfig;
import android.telephony.TelephonyManager;
@@ -103,7 +106,8 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis

    private static boolean shouldShowIndicators() {
        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
                PROPERTY_CAMERA_MIC_ICONS_ENABLED, true);
                PROPERTY_CAMERA_MIC_ICONS_ENABLED, true)
                || android.location.flags.Flags.locationIndicatorsEnabled();
    }

    private static long getRecentThreshold(Long now) {
@@ -116,6 +120,11 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
                RUNNING_ACCESS_TIME_MS, DEFAULT_RUNNING_TIME_MS);
    }

    private static final List<String> LOCATION_OPS = List.of(
            OPSTR_COARSE_LOCATION,
            OPSTR_FINE_LOCATION
    );

    private static final List<String> MIC_OPS = List.of(
            OPSTR_PHONE_CALL_MICROPHONE,
            OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO,
@@ -274,8 +283,10 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
    /**
     * Return Op usage for CAMERA, LOCATION AND MICROPHONE for all packages for a device.
     * The returned data is to power privacy indicator.
     *
     * <p>The system apps and background apps are excluded for LOCATION Op usage.
     */
    public @NonNull List<PermissionGroupUsage> getOpUsageDataByDevice(
    public @NonNull List<PermissionGroupUsage> getOpUsageDataForIndicatorsByDevice(
            boolean includeMicrophoneUsage, String deviceId) {
        List<PermissionGroupUsage> usages = new ArrayList<>();

@@ -287,6 +298,9 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
        if (includeMicrophoneUsage) {
            ops.addAll(MIC_OPS);
        }
        if (android.location.flags.Flags.locationIndicatorsEnabled()) {
            ops.addAll(LOCATION_OPS);
        }

        Map<String, List<OpUsage>> rawUsages = getOpUsagesByDevice(ops, deviceId);

@@ -367,7 +381,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis

            for (int index = 0; index < persistentDeviceIds.size(); index++) {
                allUsages.addAll(
                        getOpUsageDataByDevice(includeMicrophoneUsage,
                        getOpUsageDataForIndicatorsByDevice(includeMicrophoneUsage,
                                persistentDeviceIds.valueAt(index)));
            }
        }
@@ -455,12 +469,75 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
                mContext.getSystemService(LocationManager.class)).isProviderPackage(packageName);
    }

    /**
     * Returns true if the package is a system app.
     *
     * <p>TODO(b/422799135): refactor isSystemApp() and isBackgroundApp(). Before this is fixed,
     *           make sure to update AppOpsPrivacyItemMonitor when changing this method
     */
    private boolean isSystemApp(String op, String packageName, UserHandle user, int uid) {
        UserManager userManager = mContext.getSystemService(UserManager.class);
        if (userManager != null) {
            // Don't show apps belonging to background users except managed users.
            boolean foundUser = false;
            List<UserHandle> userProfiles = userManager.getUserProfiles();
            for (UserHandle profile : userProfiles) {
                if (profile.equals(user)) {
                    foundUser = true;
                    break;
                }
            }
            if (!foundUser) {
                return true;
            }
        }

        String permission = mAppOpsManager.opToPermission(op);
        int permissionFlags = mPkgManager.getPermissionFlags(permission, packageName, user);
        if (PermissionChecker.checkPermissionForPreflight(
                mContext,
                permission,
                PermissionChecker.PID_UNKNOWN,
                uid,
                packageName) == PermissionChecker.PERMISSION_GRANTED) {
            return (permissionFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED)
                    == 0;
        } else {
            return (permissionFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED)
                    == 0;
        }
    }

    /**
     * Returns true if it is a background app
     *
     * <p>TODO(b/422799135): refactor isSystemApp() and isBackgroundApp(). Before this is fixed,
     *           make sure to update AppOpsPrivacyItemMonitor when changing this method
     */
    private boolean isBackgroundApp(int uid) {
        ActivityManager activityManager =  mContext.getSystemService(ActivityManager.class);
        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses =
                activityManager.getRunningAppProcesses();
        if (runningAppProcesses == null) {
            return false;
        }
        for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcesses) {
            if (processInfo.uid == uid) {
                return processInfo.importance
                        > ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
            }
        }
        return false;
    }

    /**
     * Get the raw usages from the system, and then parse out the ones that are not recent enough,
     * determine which permission group each belongs in, and removes duplicates (if the same app
     * uses multiple permissions of the same group). Stores the package name, attribution tag, user,
     * running/recent info, if the usage is a phone call, per permission group.
     *
     * <p>The system apps and background apps are excluded for location Op usage.
     *
     * @param opNames a list of op names to get usage for
     * @param deviceId which device to get op usage for
     * @return A map of permission group -> list of usages that are recent or running
@@ -532,6 +609,12 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
                    }

                    String permGroupName = getGroupForOp(op);
                    if (LOCATION.equals(permGroupName)) {
                        if (isSystemApp(op, packageName, user, uid) || isBackgroundApp(uid)) {
                            // Remove the system & background apps for location op
                            continue;
                        }
                    }
                    OpUsage usage = new OpUsage(packageName, attributionTag, op, uid,
                            lastAccessTime, isRunning, proxyUsage);

+7 −7
Original line number Diff line number Diff line
@@ -24,8 +24,8 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.TextView
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -62,7 +62,7 @@ class PrivacyDialogV2Test : SysuiTestCase() {
            isPhoneCall: Boolean = false,
            isService: Boolean = false,
            permGroupName: String = TEST_PERM_GROUP,
            navigationIntent: Intent = TEST_INTENT
            navigationIntent: Intent = TEST_INTENT,
        ) =
            PrivacyDialogV2.PrivacyElement(
                type,
@@ -77,7 +77,7 @@ class PrivacyDialogV2Test : SysuiTestCase() {
                isPhoneCall,
                isService,
                permGroupName,
                navigationIntent
                navigationIntent,
            )
    }

@@ -184,7 +184,7 @@ class PrivacyDialogV2Test : SysuiTestCase() {
        val list =
            listOf(
                createPrivacyElement(type = PrivacyType.TYPE_CAMERA, isActive = true),
                createPrivacyElement()
                createPrivacyElement(),
            )
        dialog = PrivacyDialogV2(context, list, manageApp, closeApp, openPrivacyDashboard)

@@ -275,7 +275,7 @@ class PrivacyDialogV2Test : SysuiTestCase() {
                createPrivacyElement(
                    attributionLabel = "For subattribution",
                    isActive = true,
                    isService = true
                    isService = true,
                )
            )
        dialog = PrivacyDialogV2(context, list, manageApp, closeApp, openPrivacyDashboard)
@@ -293,7 +293,7 @@ class PrivacyDialogV2Test : SysuiTestCase() {
                createPrivacyElement(
                    attributionLabel = "For subattribution",
                    proxyLabel = "proxy label",
                    isActive = true
                    isActive = true,
                )
            )
        dialog = PrivacyDialogV2(context, list, manageApp, closeApp, openPrivacyDashboard)
@@ -308,7 +308,7 @@ class PrivacyDialogV2Test : SysuiTestCase() {
        dialog = PrivacyDialogV2(context, list, manageApp, closeApp, openPrivacyDashboard)
        dialog.show()

        assertThat(dialog.window?.attributes?.title).isEqualTo("Microphone & Camera")
        assertThat(dialog.window?.attributes?.title).isEqualTo("Microphone, Camera & Location")
    }

    @Test
+1 −1
Original line number Diff line number Diff line
@@ -3957,7 +3957,7 @@
    <string name="connected_display_icon_desc">Display connected</string>

    <!-- Title of the privacy dialog, shown for active / recent app usage of some phone sensors [CHAR LIMIT=30] -->
    <string name="privacy_dialog_title">Microphone &amp; Camera</string>
    <string name="privacy_dialog_title">Microphone, Camera &amp; Location</string>
    <!-- Subtitle of the privacy dialog, shown for active / recent app usage of some phone sensors [CHAR LIMIT=NONE] -->
    <string name="privacy_dialog_summary">Recent app use</string>
    <!-- Label of the secondary button of the privacy dialog, used to check recent app usage of phone sensors [CHAR LIMIT=30] -->
+12 −0
Original line number Diff line number Diff line
@@ -267,6 +267,12 @@ constructor(
        return true
    }

    /**
     * Returns true if the package is a system app.
     *
     * <p>TODO(b/422799135): refactor isSystemApp() and isBackgroundApp(). Before this is fixed,
     * make sure to update PermissionUsageHelper when changing this method.
     */
    private fun isSystemApp(item: AppOpItem): Boolean {
        val user = UserHandle.getUserHandleForUid(item.uid)

@@ -299,6 +305,12 @@ constructor(
        }
    }

    /**
     * Returns true if it is a background app
     *
     * <p>TODO(b/422799135): refactor isSystemApp() and isBackgroundApp(). Before this is fixed,
     * make sure to update PermissionUsageHelper when changing this method.
     */
    private fun isBackgroundApp(item: AppOpItem): Boolean {
        for (processInfo in activityManager.runningAppProcesses) {
            if (processInfo.uid == item.uid) {