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

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

Merge "Only coalesce entries if they have the same timestamp."

parents 6d3337a3 70ffb3af
Loading
Loading
Loading
Loading
+12 −3
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView;


import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceGroup;
@@ -41,13 +42,12 @@ public class ExpandablePreferenceGroup extends PreferenceGroup {
    private @NonNull List<Integer> mSummaryIcons;
    private @NonNull List<Integer> mSummaryIcons;
    private boolean mExpanded;
    private boolean mExpanded;


    public ExpandablePreferenceGroup(@NonNull Context context,
    public ExpandablePreferenceGroup(@NonNull Context context) {
            @NonNull List<Integer> summaryIcons) {
        super(context, null);
        super(context, null);


        mContext = context;
        mContext = context;
        mPreferences = new ArrayList<>();
        mPreferences = new ArrayList<>();
        mSummaryIcons = summaryIcons;
        mSummaryIcons = new ArrayList<>();
        mExpanded = false;
        mExpanded = false;


        setLayoutResource(R.layout.preference_usage);
        setLayoutResource(R.layout.preference_usage);
@@ -111,4 +111,13 @@ public class ExpandablePreferenceGroup extends PreferenceGroup {
        mPreferences.add(preference);
        mPreferences.add(preference);
        return true;
        return true;
    }
    }

    /**
     * Show the given icon next to this preference's summary.
     *
     * @param resId the the resourceId of the drawable to use as the icon.
     */
    public void addSummaryIcon(@DrawableRes int resId) {
        mSummaryIcons.add(resId);
    }
}
}
+110 −203
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@ import android.text.format.DateFormat;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Log;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuInflater;
@@ -48,7 +49,6 @@ import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.DialogFragment;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceScreen;


import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
@@ -357,13 +357,45 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
        }
        }
        screen.removeAll();
        screen.removeAll();


        // Update bar chart
        mHasSystemApps = false;

        List<Pair<AppPermissionUsage, GroupUsage>> usages = new ArrayList<>();
        int numApps = appPermissionUsages.size();
        for (int appNum = 0; appNum < numApps; appNum++) {
            AppPermissionUsage appUsage = appPermissionUsages.get(appNum);
            List<GroupUsage> appGroups = appUsage.getGroupUsages();
            int numGroups = appGroups.size();
            for (int groupNum = 0; groupNum < numGroups; groupNum++) {
                GroupUsage groupUsage = appGroups.get(groupNum);

                if (groupUsage.getAccessCount() <= 0) {
                    continue;
                }
                final boolean isSystemApp = Utils.isSystem(appUsage.getApp(), mLauncherPkgs);
                if (!mHasSystemApps) {
                    if (isSystemApp) {
                        mHasSystemApps = true;
                        getActivity().invalidateOptionsMenu();
                    }
                }
                if (isSystemApp && !mShowSystem) {
                    continue;
                }
                // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away.
                if (groupUsage.getGroup().getLabel().equals("Storage")) {
                    continue;
                }

                usages.add(Pair.create(appUsage, appGroups.get(groupNum)));
            }
        }

        // Update bar chart.
        final TimeFilterItem timeFilterItem = getSelectedFilterItem();
        final TimeFilterItem timeFilterItem = getSelectedFilterItem();
        final BarChartPreference barChart = createBarChart(appPermissionUsages,
        final BarChartPreference barChart = createBarChart(usages, timeFilterItem, context);
                timeFilterItem, context);
        screen.addPreference(barChart);
        screen.addPreference(barChart);


        // Add the preferences.
        // Add the preference header.
        PreferenceCategory category = new PreferenceCategory(context);
        PreferenceCategory category = new PreferenceCategory(context);
        screen.addPreference(category);
        screen.addPreference(category);
        if (timeFilterItem != null) {
        if (timeFilterItem != null) {
@@ -372,63 +404,32 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements


        // Sort the apps.
        // Sort the apps.
        final int sortOption = getSelectedSortOption();
        final int sortOption = getSelectedSortOption();
        if (sortOption == SORT_MOST_PERMISSIONS) {
        if (sortOption == SORT_RECENT) {
            appPermissionUsages.sort(PermissionUsageFragment::compareAccessUsage);
            usages.sort(PermissionUsageFragment::compareAccessRecency);
        } else if (sortOption == SORT_MOST_PERMISSIONS) {
            usages.sort(PermissionUsageFragment::compareAccessUsage);
        } else if (sortOption == SORT_MOST_ACCESSES) {
        } else if (sortOption == SORT_MOST_ACCESSES) {
            appPermissionUsages.sort(PermissionUsageFragment::compareAccessCount);
            usages.sort(PermissionUsageFragment::compareAccessCount);
        } else if (sortOption == SORT_RECENT) {
            appPermissionUsages.sort(PermissionUsageFragment::compareAccessRecency);
        } else {
        } else {
            Log.w(LOG_TAG, "Unexpected sort option: " + sortOption);
            Log.w(LOG_TAG, "Unexpected sort option: " + sortOption);
        }
        }


        mHasSystemApps = false;

        java.text.DateFormat timeFormat = DateFormat.getTimeFormat(context);
        java.text.DateFormat timeFormat = DateFormat.getTimeFormat(context);
        java.text.DateFormat dateFormat = DateFormat.getMediumDateFormat(context);
        java.text.DateFormat dateFormat = DateFormat.getMediumDateFormat(context);


        final int numApps = appPermissionUsages.size();
        ExpandablePreferenceGroup parent = null;
        for (int appNum = 0; appNum < numApps; appNum++) {
        AppPermissionUsage lastAppPermissionUsage = null;
            final AppPermissionUsage appPermissionUsage = appPermissionUsages.get(appNum);

            if (appPermissionUsage.getAccessCount() <= 0) {
                continue;
            }

            final boolean isSystemApp = Utils.isSystem(appPermissionUsage.getApp(),
                    mLauncherPkgs);
            if (!mHasSystemApps) {
                if (isSystemApp) {
                    mHasSystemApps = true;
                    getActivity().invalidateOptionsMenu();
                }
            }
            if (isSystemApp && !mShowSystem) {
                continue;
            }

            if (sortOption == SORT_MOST_ACCESSES) {
                appPermissionUsage.getGroupUsages().sort(
                        PermissionUsageFragment::compareAccessCount);
            } else {
                appPermissionUsage.getGroupUsages().sort(
                        PermissionUsageFragment::compareAccessTime);
            }


            final List<GroupUsage> appGroups = appPermissionUsage.getGroupUsages();
        final int numUsages = usages.size();
        for (int usageNum = 0; usageNum < numUsages; usageNum++) {
            final Pair<AppPermissionUsage, GroupUsage> usage = usages.get(usageNum);
            AppPermissionUsage appPermissionUsage = usage.first;
            GroupUsage groupUsage = usage.second;


            final List<PermissionControlPreference> permissionPrefs = new ArrayList<>();
            final int numGroups = appGroups.size();
            for (int groupNum = 0; groupNum < numGroups; groupNum++) {
                final GroupUsage groupUsage = appGroups.get(groupNum);
            if (mFilterGroup != null && !mFilterGroup.equals(groupUsage.getGroup().getName())) {
            if (mFilterGroup != null && !mFilterGroup.equals(groupUsage.getGroup().getName())) {
                continue;
                continue;
            }
            }
                // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away.

                if (groupUsage.getGroup().getLabel().equals("Storage")) {
                    continue;
                }
                if (groupUsage.getAccessCount() > 0) {
            String accessTimeString = null;
            String accessTimeString = null;
            if (isToday(groupUsage.getLastAccessTime())) {
            if (isToday(groupUsage.getLastAccessTime())) {
                accessTimeString = timeFormat.format(groupUsage.getLastAccessTime());
                accessTimeString = timeFormat.format(groupUsage.getLastAccessTime());
@@ -436,27 +437,17 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
                accessTimeString = dateFormat.format(groupUsage.getLastAccessTime());
                accessTimeString = dateFormat.format(groupUsage.getLastAccessTime());
            }
            }


                    permissionPrefs.add(createPermissionUsagePreference(context,
            if (lastAppPermissionUsage != appPermissionUsage) {
                            appPermissionUsage, groupUsage, accessTimeString));
                }
            }

            if (permissionPrefs.isEmpty()) {
                continue;
            }

                // Add a "parent" entry for the app that will expand to the individual entries.
                // Add a "parent" entry for the app that will expand to the individual entries.
            PreferenceGroup parent = createExpandablePreferenceGroup(context, appPermissionUsage);
                parent = createExpandablePreferenceGroup(context, appPermissionUsage,
                        sortOption == SORT_RECENT ? accessTimeString : null);
                category.addPreference(parent);
                category.addPreference(parent);

                lastAppPermissionUsage = appPermissionUsage;
            final int permissionPrefCount = permissionPrefs.size();
            for (int i = 0; i < permissionPrefCount; i++) {
                final PermissionControlPreference permissionPref = permissionPrefs.get(i);
                if (permissionPrefs.size() == 1) {
                    permissionPref.setIcon(appPermissionUsage.getApp().getIcon());
                }
                parent.addPreference(permissionPrefs.get(i));
            }
            }

            parent.addPreference(createPermissionUsagePreference(context, appPermissionUsage,
                    groupUsage, accessTimeString));
            parent.addSummaryIcon(groupUsage.getGroup().getIconResId());
        }
        }
    }
    }


@@ -497,13 +488,14 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
    /**
    /**
     * Create a bar chart showing the permissions that are used by the most apps.
     * Create a bar chart showing the permissions that are used by the most apps.
     *
     *
     * @param appPermissionUsages app permission usages
     * @param usages the usages
     * @param timeFilterItem the time filter, or null if no filter is set
     * @param timeFilterItem the time filter, or null if no filter is set
     * @param context the context
     * @param context the context
     *
     *
     * @return the Preference representing the bar chart
     * @return the Preference representing the bar chart
     */
     */
    private BarChartPreference createBarChart(@NonNull List<AppPermissionUsage> appPermissionUsages,
    private BarChartPreference createBarChart(
            @NonNull List<Pair<AppPermissionUsage, GroupUsage>> usages,
            @Nullable TimeFilterItem timeFilterItem, @NonNull Context context) {
            @Nullable TimeFilterItem timeFilterItem, @NonNull Context context) {
        BarChartInfo.Builder builder = new BarChartInfo.Builder();
        BarChartInfo.Builder builder = new BarChartInfo.Builder();
        BarChartPreference barChart = new BarChartPreference(context, null);
        BarChartPreference barChart = new BarChartPreference(context, null);
@@ -521,21 +513,10 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements


        final ArrayList<AppPermissionGroup> groups = new ArrayList<>();
        final ArrayList<AppPermissionGroup> groups = new ArrayList<>();
        final ArrayMap<String, Integer> groupToAppCount = new ArrayMap<>();
        final ArrayMap<String, Integer> groupToAppCount = new ArrayMap<>();
        final int appCount = appPermissionUsages.size();
        final int usageCount = usages.size();
        for (int i = 0; i < appCount; i++) {
        for (int i = 0; i < usageCount; i++) {
            final AppPermissionUsage appPermissionUsage = appPermissionUsages.get(i);
            final Pair<AppPermissionUsage, GroupUsage> usage = usages.get(i);
            final List<AppPermissionUsage.GroupUsage> groupUsages =
            GroupUsage groupUsage = usage.second;
                    appPermissionUsage.getGroupUsages();
            final int groupCount = groupUsages.size();
            for (int j = 0; j < groupCount; j++) {
                final GroupUsage groupUsage = groupUsages.get(j);
                if (groupUsage.getAccessCount() <= 0) {
                    continue;
                }
                // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away.
                if (groupUsage.getGroup().getLabel().equals("Storage")) {
                    continue;
                }
            final Integer count = groupToAppCount.get(groupUsage.getGroup().getName());
            final Integer count = groupToAppCount.get(groupUsage.getGroup().getName());
            if (count == null) {
            if (count == null) {
                groups.add(groupUsage.getGroup());
                groups.add(groupUsage.getGroup());
@@ -544,7 +525,6 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
                groupToAppCount.put(groupUsage.getGroup().getName(), count + 1);
                groupToAppCount.put(groupUsage.getGroup().getName(), count + 1);
            }
            }
        }
        }
        }


        groups.sort((x, y) -> {
        groups.sort((x, y) -> {
            final int usageDiff = compareLong(groupToAppCount.get(x.getName()),
            final int usageDiff = compareLong(groupToAppCount.get(x.getName()),
@@ -586,24 +566,14 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
     *
     *
     * @return the expandable preference group.
     * @return the expandable preference group.
     */
     */
    private PreferenceGroup createExpandablePreferenceGroup(@NonNull Context context,
    private ExpandablePreferenceGroup createExpandablePreferenceGroup(@NonNull Context context,
            @NonNull AppPermissionUsage appPermissionUsage) {
            @NonNull AppPermissionUsage appPermissionUsage, @Nullable String summaryString) {
        final List<GroupUsage> groupUsages = appPermissionUsage.getGroupUsages();
        ExpandablePreferenceGroup preference = new ExpandablePreferenceGroup(context);
        final List<Integer> permissionIcons = new ArrayList<>(groupUsages.size());
        final int permissionUsageCount = groupUsages.size();
        for (int i = 0; i < permissionUsageCount; i++) {
            final AppPermissionUsage.GroupUsage groupUsage = groupUsages.get(i);
            // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away.
            if (groupUsage.getGroup().getLabel().equals("Storage")) {
                continue;
            }
            if (groupUsage.getAccessCount() > 0) {
                permissionIcons.add(groupUsage.getGroup().getIconResId());
            }
        }
        PreferenceGroup preference = new ExpandablePreferenceGroup(context, permissionIcons);
        preference.setTitle(appPermissionUsage.getApp().getLabel());
        preference.setTitle(appPermissionUsage.getApp().getLabel());
        preference.setIcon(appPermissionUsage.getApp().getIcon());
        preference.setIcon(appPermissionUsage.getApp().getIcon());
        if (summaryString != null) {
            preference.setSummary(summaryString);
        }
        return preference;
        return preference;
    }
    }


@@ -643,22 +613,24 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
    }
    }


    /**
    /**
     * Compare two AppPermissionUsage by their permission usage.
     * Compare two usages by the number of apps that accessed each group.
     *
     *
     * Can be used as a {@link java.util.Comparator}.
     * Can be used as a {@link java.util.Comparator}.
     *
     *
     * @param x an AppPermissionUsage.
     * We ignore the GroupUsage here to ensure that we keep all usages by the same app together.
     * @param y an AppPermissionUsage.
     *
     * @param x a usage.
     * @param y a usage.
     *
     *
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     */
     */
    private static int compareAccessUsage(@NonNull AppPermissionUsage x,
    private static int compareAccessUsage(@NonNull Pair<AppPermissionUsage, GroupUsage> x,
            @NonNull AppPermissionUsage y) {
            @NonNull Pair<AppPermissionUsage, GroupUsage> y) {
        final int groupDiff = getAccessedGroupCount(y) - getAccessedGroupCount(x);
        final int groupDiff = getAccessedGroupCount(y.first) - getAccessedGroupCount(x.first);
        if (groupDiff != 0) {
        if (groupDiff != 0) {
            return groupDiff;
            return groupDiff;
        }
        }
        return compareAccessTime(x, y);
        return compareAccessTime(x.first, y.first);
    }
    }


    /**
    /**
@@ -685,18 +657,19 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
    }
    }


    /**
    /**
     * Compare two AppPermissionUsage by their access time.
     * Compare two usages by their access time.
     *
     *
     * Can be used as a {@link java.util.Comparator}.
     * Can be used as a {@link java.util.Comparator}.
     *
     *
     * @param x an AppPermissionUsage.
     * @param x a usage.
     * @param y an AppPermissionUsage.
     * @param y a usage.
     *
     *
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     */
     */
    private static int compareAccessTime(@NonNull AppPermissionUsage.GroupUsage x,
    private static int compareAccessTime(@NonNull Pair<AppPermissionUsage, GroupUsage> x,
            @NonNull AppPermissionUsage.GroupUsage y) {
            @NonNull Pair<AppPermissionUsage, GroupUsage> y) {
        final int timeDiff = compareLong(x.getLastAccessTime(), y.getLastAccessTime());
        final int timeDiff = compareLong(x.second.getLastAccessTime(),
                y.second.getLastAccessTime());
        if (timeDiff != 0) {
        if (timeDiff != 0) {
            return timeDiff;
            return timeDiff;
        }
        }
@@ -716,7 +689,7 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
     */
     */
    private static int compareAccessTime(@NonNull AppPermissionUsage x,
    private static int compareAccessTime(@NonNull AppPermissionUsage x,
            @NonNull AppPermissionUsage y) {
            @NonNull AppPermissionUsage y) {
        final int timeDiff = compareLong(getLastAccessTime(x), getLastAccessTime(y));
        final int timeDiff = compareLong(x.getLastAccessTime(), y.getLastAccessTime());
        if (timeDiff != 0) {
        if (timeDiff != 0) {
            return timeDiff;
            return timeDiff;
        }
        }
@@ -725,90 +698,24 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
    }
    }


    /**
    /**
     * Gets the last time the given app used a permission.
     * Compare two usages by their access count.
     *
     * @param appPermissionUsage The app permission usage.
     *
     * @return The last access time.
     */
    private static long getLastAccessTime(@NonNull AppPermissionUsage appPermissionUsage) {
        long lastAccessTime = 0;
        final List<GroupUsage> groupUsages = appPermissionUsage.getGroupUsages();
        final int groupCount = groupUsages.size();
        for (int i = 0; i < groupCount; i++) {
            final GroupUsage groupUsage = groupUsages.get(i);
            // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away.
            // We can replace this with AppPermissionUsage.getLastAccessTime then.
            if (groupUsage.getGroup().getLabel().equals("Storage")) {
                continue;
            }
            lastAccessTime = Math.max(lastAccessTime, groupUsage.getLastAccessTime());
        }
        return lastAccessTime;
    }

    /**
     * Compare two AppPermissionUsage by their access count.
     *
     *
     * Can be used as a {@link java.util.Comparator}.
     * Can be used as a {@link java.util.Comparator}.
     *
     *
     * @param x an AppPermissionUsage.
     * @param x a usage.
     * @param y an AppPermissionUsage.
     * @param y a usage.
     *
     *
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     */
     */
    private static int compareAccessCount(@NonNull AppPermissionUsage x,
    private static int compareAccessCount(@NonNull Pair<AppPermissionUsage, GroupUsage> x,
            @NonNull AppPermissionUsage y) {
            @NonNull Pair<AppPermissionUsage, GroupUsage> y) {
        final int accessDiff = compareLong(getAccessCount(x), getAccessCount(y));
        final int accessDiff = compareLong(x.second.getAccessCount(), y.second.getAccessCount());
        if (accessDiff != 0) {
        if (accessDiff != 0) {
            return accessDiff;
            return accessDiff;
        }
        }
        return compareAccessTime(x, y);
        return compareAccessTime(x, y);
    }
    }


    /**
     * Compare two AppPermissionUsage by their access count.
     *
     * Can be used as a {@link java.util.Comparator}.
     *
     * @param x an AppPermissionUsage.
     * @param y an AppPermissionUsage.
     *
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     */
    private static int compareAccessCount(@NonNull AppPermissionUsage.GroupUsage x,
            @NonNull GroupUsage y) {
        final int accessDiff = compareLong(x.getAccessCount(), y.getAccessCount());
        if (accessDiff != 0) {
            return accessDiff;
        }
        // Make sure we lose no data if same
        return y.hashCode() - x.hashCode();
    }

    /**
     * Gets the number of permission usages.
     *
     * @param appPermissionUsage The app permission usage.
     *
     * @return The number of permission usages.
     */
    private static long getAccessCount(@NonNull AppPermissionUsage appPermissionUsage) {
        long accessCount = 0;
        final List<GroupUsage> groupUsages = appPermissionUsage.getGroupUsages();
        final int groupCount = groupUsages.size();
        for (int i = 0; i < groupCount; i++) {
            final GroupUsage groupUsage = groupUsages.get(i);
            // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away.
            // We can replace this with AppPermissionUsage.getAccessCount then.
            if (groupUsage.getGroup().getLabel().equals("Storage")) {
                continue;
            }
            accessCount += groupUsage.getAccessCount();
        }
        return accessCount;
    }

    /**
    /**
     * Compare two longs.
     * Compare two longs.
     *
     *
@@ -829,17 +736,17 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements
    }
    }


    /**
    /**
     * Compare two AppPermissionUsage by recency of access.
     * Compare two usages by recency of access.
     *
     *
     * Can be used as a {@link java.util.Comparator}.
     * Can be used as a {@link java.util.Comparator}.
     *
     *
     * @param x an AppPermissionUsage.
     * @param x a usage.
     * @param y an AppPermissionUsage.
     * @param y a usage.
     *
     *
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     * @return see {@link java.util.Comparator#compare(Object, Object)}.
     */
     */
    private static int compareAccessRecency(@NonNull AppPermissionUsage x,
    private static int compareAccessRecency(@NonNull Pair<AppPermissionUsage, GroupUsage> x,
            @NonNull AppPermissionUsage y) {
            @NonNull Pair<AppPermissionUsage, GroupUsage> y) {
        final int timeDiff = compareAccessTime(x, y);
        final int timeDiff = compareAccessTime(x, y);
        if (timeDiff != 0) {
        if (timeDiff != 0) {
            return timeDiff;
            return timeDiff;