diff options
author | 2021-05-11 00:08:23 +0000 | |
---|---|---|
committer | 2021-05-11 00:11:38 +0000 | |
commit | f2795645474eef73df24c332049555ea0083e815 (patch) | |
tree | 0450faa4bc709e520471c61901e917257b53b1e6 | |
parent | f3ab17da088fe5c4253abe202dc36a9db0e3fc99 (diff) |
Add timestamp to permission apps screen
Bug: 176902658
Test: manually tested on Sargo DVT
Change-Id: I40f14bf124cedbd3760a643fe304df85bc02b444
3 files changed, 170 insertions, 45 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java index 49aee7e08..786757d27 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java @@ -23,11 +23,13 @@ import static com.android.permissioncontroller.PermissionControllerStatsLog.APP_ import static com.android.permissioncontroller.PermissionControllerStatsLog.APP_PERMISSIONS_FRAGMENT_VIEWED__CATEGORY__ALLOWED_FOREGROUND; import static com.android.permissioncontroller.PermissionControllerStatsLog.APP_PERMISSIONS_FRAGMENT_VIEWED__CATEGORY__DENIED; import static com.android.permissioncontroller.permission.ui.handheld.UtilsKt.pressBack; +import static com.android.permissioncontroller.permission.utils.Utils.LAST_24H_CONTENT_PROVIDER; +import static com.android.permissioncontroller.permission.utils.Utils.LAST_24H_SENSOR_TODAY; +import static com.android.permissioncontroller.permission.utils.Utils.LAST_24H_SENSOR_YESTERDAY; +import static com.android.permissioncontroller.permission.utils.Utils.NOT_IN_LAST_24H; -import static java.lang.annotation.RetentionPolicy.SOURCE; import static java.util.concurrent.TimeUnit.DAYS; -import android.Manifest; import android.app.ActionBar; import android.app.Activity; import android.content.ActivityNotFoundException; @@ -42,7 +44,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.provider.Settings; -import android.text.format.DateFormat; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -52,7 +53,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Toast; -import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.lifecycle.ViewModelProvider; @@ -74,10 +74,8 @@ import com.android.permissioncontroller.permission.utils.KotlinUtils; import com.android.permissioncontroller.permission.utils.Utils; import com.android.settingslib.HelpUtils; -import java.lang.annotation.Retention; import java.text.Collator; import java.time.Instant; -import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -85,6 +83,8 @@ import java.util.Map; import java.util.Objects; import java.util.Random; +import kotlin.Pair; + /** * Show and manage permission groups for an app. * @@ -93,15 +93,6 @@ import java.util.Random; public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader implements PermissionUsages.PermissionsUsagesChangeCallback { - @Retention(SOURCE) - @IntDef(value = {LAST_24H_SENSOR_TODAY, LAST_24H_SENSOR_YESTERDAY, - LAST_24H_CONTENT_PROVIDER, NOT_IN_LAST_24H}) - @interface AppPermsLastAccessType {} - static final int LAST_24H_SENSOR_TODAY = 1; - static final int LAST_24H_SENSOR_YESTERDAY = 2; - static final int LAST_24H_CONTENT_PROVIDER = 3; - static final int NOT_IN_LAST_24H = 4; - private static final String LOG_TAG = AppPermissionGroupsFragment.class.getSimpleName(); private static final String IS_SYSTEM_PERMS_SCREEN = "_is_system_screen"; private static final String AUTO_REVOKE_CATEGORY_KEY = "_AUTO_REVOKE_KEY"; @@ -112,12 +103,6 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i private static final String ASSISTANT_MIC_SUMMARY_KEY = "_ASSISTANT_MIC_SUMMARY_KEY"; private static final int AGGREGATE_DATA_FILTER_BEGIN_DAYS = 1; - private static final List<String> SENSOR_DATA_PERMISSIONS = List.of( - Manifest.permission_group.LOCATION, - Manifest.permission_group.CAMERA, - Manifest.permission_group.MICROPHONE - ); - static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton"; private AppPermissionGroupsViewModel mViewModel; @@ -331,7 +316,6 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i Map<String, Long> groupUsageLastAccessTime = new HashMap<>(); extractGroupUsageLastAccessTime(groupUsageLastAccessTime); - long midnightToday = Instant.now().truncatedTo(ChronoUnit.DAYS).toEpochMilli(); findPreference(Category.ALLOWED_FOREGROUND.getCategoryName()).setVisible(false); @@ -359,20 +343,10 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i for (GroupUiInfo groupInfo : groupMap.get(grantCategory)) { String groupName = groupInfo.getGroupName(); Long lastAccessTime = groupUsageLastAccessTime.get(groupName); - boolean isLastAccessToday = lastAccessTime != null - && midnightToday <= lastAccessTime; - String lastAccessTimeFormatted = ""; - @AppPermsLastAccessType int lastAccessType = NOT_IN_LAST_24H; - - if (lastAccessTime != null) { - lastAccessTimeFormatted = DateFormat.getTimeFormat(context) - .format(lastAccessTime); - - lastAccessType = !SENSOR_DATA_PERMISSIONS.contains(groupName) - ? LAST_24H_CONTENT_PROVIDER : isLastAccessToday - ? LAST_24H_SENSOR_TODAY : - LAST_24H_SENSOR_YESTERDAY; - } + Pair<String, Integer> summaryTimestamp = Utils + .getPermissionLastAccessSummaryTimestamp( + lastAccessTime, context, groupName); + @Utils.AppPermsLastAccessType int lastAccessType = summaryTimestamp.getSecond(); PermissionControlPreference preference = new PermissionControlPreference(context, mPackageName, groupName, mUser, AppPermissionGroupsFragment.class.getName(), @@ -391,12 +365,12 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i preference.setSummary( getString( R.string.app_perms_24h_access_background, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case LAST_24H_SENSOR_YESTERDAY: preference.setSummary(getString( R.string.app_perms_24h_access_yest_background, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case NOT_IN_LAST_24H: default: @@ -415,13 +389,13 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i preference.setSummary( getString( R.string.app_perms_24h_access_media_only, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case LAST_24H_SENSOR_YESTERDAY: preference.setSummary( getString( R.string.app_perms_24h_access_yest_media_only, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case NOT_IN_LAST_24H: default: @@ -439,13 +413,13 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i preference.setSummary( getString( R.string.app_perms_24h_access_all_files, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case LAST_24H_SENSOR_YESTERDAY: preference.setSummary( getString( R.string.app_perms_24h_access_yest_all_files, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case NOT_IN_LAST_24H: default: @@ -464,12 +438,12 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i case LAST_24H_SENSOR_TODAY: preference.setSummary( getString(R.string.app_perms_24h_access, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case LAST_24H_SENSOR_YESTERDAY: preference.setSummary( getString(R.string.app_perms_24h_access_yest, - lastAccessTimeFormatted)); + summaryTimestamp.getFirst())); break; case NOT_IN_LAST_24H: default: diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java index 7c9c46b5b..fff27e49c 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java @@ -28,6 +28,12 @@ import static com.android.permissioncontroller.permission.ui.Category.ALLOWED_FO import static com.android.permissioncontroller.permission.ui.Category.ASK; import static com.android.permissioncontroller.permission.ui.Category.DENIED; import static com.android.permissioncontroller.permission.ui.handheld.UtilsKt.pressBack; +import static com.android.permissioncontroller.permission.utils.Utils.LAST_24H_CONTENT_PROVIDER; +import static com.android.permissioncontroller.permission.utils.Utils.LAST_24H_SENSOR_TODAY; +import static com.android.permissioncontroller.permission.utils.Utils.LAST_24H_SENSOR_YESTERDAY; +import static com.android.permissioncontroller.permission.utils.Utils.NOT_IN_LAST_24H; + +import static java.util.concurrent.TimeUnit.DAYS; import android.Manifest; import android.app.ActionBar; @@ -52,6 +58,8 @@ import androidx.preference.PreferenceCategory; import com.android.permissioncontroller.PermissionControllerStatsLog; import com.android.permissioncontroller.R; +import com.android.permissioncontroller.permission.debug.PermissionUsages; +import com.android.permissioncontroller.permission.model.AppPermissionUsage; import com.android.permissioncontroller.permission.ui.Category; import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity; import com.android.permissioncontroller.permission.ui.model.PermissionAppsViewModel; @@ -62,6 +70,9 @@ import com.android.settingslib.HelpUtils; import com.android.settingslib.utils.applications.AppUtils; import java.text.Collator; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; @@ -73,7 +84,8 @@ import kotlin.Pair; * * <p>Shows a list of apps which request at least on permission of this group. */ -public final class PermissionAppsFragment extends SettingsWithLargeHeader { +public final class PermissionAppsFragment extends SettingsWithLargeHeader implements + PermissionUsages.PermissionsUsagesChangeCallback { private static final String KEY_SHOW_SYSTEM_PREFS = "_showSystem"; private static final String CREATION_LOGGED_SYSTEM_PREFS = "_creationLogged"; @@ -83,6 +95,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { private static final String STORAGE_ALLOWED_FULL = "allowed_storage_full"; private static final String STORAGE_ALLOWED_SCOPED = "allowed_storage_scoped"; private static final int SHOW_LOAD_DELAY_MS = 200; + private static final int AGGREGATE_DATA_FILTER_BEGIN_DAYS = 1; private static final int MENU_PERMISSION_USAGE = MENU_HIDE_SYSTEM + 1; @@ -105,6 +118,8 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { private String mPermGroupName; private Collator mCollator; private PermissionAppsViewModel mViewModel; + private @NonNull PermissionUsages mPermissionUsages; + private @NonNull List<AppPermissionUsage> mAppPermissionUsages = new ArrayList<>(); @Override public void onCreate(Bundle savedInstanceState) { @@ -142,6 +157,28 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { if (ab != null) { ab.setDisplayHomeAsUpEnabled(true); } + + Context context = getPreferenceManager().getContext(); + mPermissionUsages = new PermissionUsages(context); + long filterTimeBeginMillis = Math.max(System.currentTimeMillis() + - DAYS.toMillis(AGGREGATE_DATA_FILTER_BEGIN_DAYS), Instant.EPOCH.toEpochMilli()); + mPermissionUsages.load(null, null, filterTimeBeginMillis, Long.MAX_VALUE, + PermissionUsages.USAGE_FLAG_LAST, getActivity().getLoaderManager(), + false, false, this, false); + } + + @Override + public void onPermissionUsagesChanged() { + if (mPermissionUsages.getUsages().isEmpty()) { + return; + } + if (getContext() == null) { + // Async result has come in after our context is gone. + return; + } + + mAppPermissionUsages = new ArrayList<>(mPermissionUsages.getUsages()); + onPackagesLoaded(mViewModel.getCategorizedAppsLiveData().getValue()); } @Override @@ -259,6 +296,10 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { } } + // A mapping of user + packageName to their last access timestamps for the permission group. + Map<String, Long> groupUsageLastAccessTime = new HashMap<>(); + extractGroupUsageLastAccessTime(groupUsageLastAccessTime); + for (Category grantCategory : categories.keySet()) { List<Pair<String, UserHandle>> packages = categories.get(grantCategory); PreferenceCategory category = findPreference(grantCategory.getCategoryName()); @@ -293,6 +334,11 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { String key = user + packageName; + Long lastAccessTime = groupUsageLastAccessTime.get(key); + Pair<String, Integer> summaryTimestamp = Utils + .getPermissionLastAccessSummaryTimestamp( + lastAccessTime, context, mPermGroupName); + if (isStorage && grantCategory.equals(ALLOWED)) { category = mViewModel.packageHasFullStorage(packageName, user) ? findPreference(STORAGE_ALLOWED_FULL) @@ -301,6 +347,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { Preference existingPref = existingPrefs.get(key); if (existingPref != null) { + updatePreferenceSummary(existingPref, summaryTimestamp); category.addPreference(existingPref); continue; } @@ -321,6 +368,8 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { pref.setTitleContentDescription(AppUtils.getAppContentDescription(context, packageName, user.getIdentifier())); + updatePreferenceSummary(pref, summaryTimestamp); + category.addPreference(pref); if (!mViewModel.getCreationLogged()) { logPermissionAppsFragmentCreated(packageName, user, viewIdForLogging, @@ -359,6 +408,60 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader { setLoading(false /* loading */, true /* animate */); } + private void updatePreferenceSummary(Preference preference, + Pair<String, Integer> summaryTimestamp) { + @Utils.AppPermsLastAccessType int lastAccessType = summaryTimestamp.getSecond(); + + switch (lastAccessType) { + case LAST_24H_CONTENT_PROVIDER: + preference.setSummary( + R.string.app_perms_content_provider); + break; + case LAST_24H_SENSOR_TODAY: + preference.setSummary( + getString(R.string.app_perms_24h_access, + summaryTimestamp.getFirst())); + break; + case LAST_24H_SENSOR_YESTERDAY: + preference.setSummary( + getString(R.string.app_perms_24h_access_yest, + summaryTimestamp.getFirst())); + break; + case NOT_IN_LAST_24H: + default: + } + } + + private void extractGroupUsageLastAccessTime(Map<String, Long> accessTime) { + accessTime.clear(); + long filterTimeBeginMillis = Math.max(System.currentTimeMillis() + - DAYS.toMillis(AGGREGATE_DATA_FILTER_BEGIN_DAYS), Instant.EPOCH.toEpochMilli()); + + int numApps = mAppPermissionUsages.size(); + for (int appIndex = 0; appIndex < numApps; appIndex++) { + AppPermissionUsage appUsage = mAppPermissionUsages.get(appIndex); + String packageName = appUsage.getPackageName(); + + List<AppPermissionUsage.GroupUsage> appGroups = appUsage.getGroupUsages(); + int numGroups = appGroups.size(); + for (int groupIndex = 0; groupIndex < numGroups; groupIndex++) { + AppPermissionUsage.GroupUsage groupUsage = appGroups.get(groupIndex); + String groupName = groupUsage.getGroup().getName(); + if (!mPermGroupName.equals(groupName)) { + continue; + } + + long lastAccessTime = groupUsage.getLastAccessTime(); + if (lastAccessTime == 0 || lastAccessTime < filterTimeBeginMillis) { + continue; + } + + String key = groupUsage.getGroup().getUser() + packageName; + accessTime.put(key, lastAccessTime); + } + } + } + private int comparePreference(Preference lhs, Preference rhs) { int result = mCollator.compare(lhs.getTitle().toString(), rhs.getTitle().toString()); diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java index 4537d9c13..cd937600f 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java @@ -41,6 +41,8 @@ import static android.os.UserHandle.myUserId; import static com.android.permissioncontroller.Constants.INVALID_SESSION_ID; +import static java.lang.annotation.RetentionPolicy.SOURCE; + import android.Manifest; import android.app.AppOpsManager; import android.app.Application; @@ -79,6 +81,7 @@ import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; +import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; @@ -93,6 +96,9 @@ import com.android.permissioncontroller.PermissionControllerApplication; import com.android.permissioncontroller.R; import com.android.permissioncontroller.permission.model.AppPermissionGroup; +import java.lang.annotation.Retention; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; @@ -102,8 +108,25 @@ import java.util.Locale; import java.util.Random; import java.util.Set; +import kotlin.Pair; + public final class Utils { + @Retention(SOURCE) + @IntDef(value = {LAST_24H_SENSOR_TODAY, LAST_24H_SENSOR_YESTERDAY, + LAST_24H_CONTENT_PROVIDER, NOT_IN_LAST_24H}) + public @interface AppPermsLastAccessType {} + public static final int LAST_24H_SENSOR_TODAY = 1; + public static final int LAST_24H_SENSOR_YESTERDAY = 2; + public static final int LAST_24H_CONTENT_PROVIDER = 3; + public static final int NOT_IN_LAST_24H = 4; + + private static final List<String> SENSOR_DATA_PERMISSIONS = List.of( + Manifest.permission_group.LOCATION, + Manifest.permission_group.CAMERA, + Manifest.permission_group.MICROPHONE + ); + private static final String LOG_TAG = "Utils"; public static final String OS_PKG = "android"; @@ -1178,4 +1201,29 @@ public final class Utils { return exemptedPackages; } + + /** + * Get the timestamp and lastAccessType for the summary text + * in app permission groups and permission apps screens + */ + public static Pair<String, Integer> getPermissionLastAccessSummaryTimestamp( + Long lastAccessTime, Context context, String groupName) { + long midnightToday = Instant.now().truncatedTo(ChronoUnit.DAYS).toEpochMilli(); + boolean isLastAccessToday = lastAccessTime != null + && midnightToday <= lastAccessTime; + String lastAccessTimeFormatted = ""; + @AppPermsLastAccessType int lastAccessType = NOT_IN_LAST_24H; + + if (lastAccessTime != null) { + lastAccessTimeFormatted = DateFormat.getTimeFormat(context) + .format(lastAccessTime); + + lastAccessType = !SENSOR_DATA_PERMISSIONS.contains(groupName) + ? LAST_24H_CONTENT_PROVIDER : isLastAccessToday + ? LAST_24H_SENSOR_TODAY : + LAST_24H_SENSOR_YESTERDAY; + } + + return new Pair<>(lastAccessTimeFormatted, lastAccessType); + } } |