summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKevin Han <kevhan@google.com>2021-06-04 23:35:55 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-06-04 23:35:55 +0000
commit603cd6c44c9a292d16f8606110d1eddc624a5b94 (patch)
treead4464724051e159a33e9087ea54509afd5effb1 /src
parent4a0a03f0e4430850a0cf4ed5e4ce785a2ab2402b (diff)
parent8df22e7cd9c28d46b60fa345c45297cec9d8c05b (diff)
downloadpackages_apps_Settings-603cd6c44c9a292d16f8606110d1eddc624a5b94.tar.gz
packages_apps_Settings-603cd6c44c9a292d16f8606110d1eddc624a5b94.tar.bz2
packages_apps_Settings-603cd6c44c9a292d16f8606110d1eddc624a5b94.zip
Merge "Move unused apps count calculation to bg thread" into sc-dev
Diffstat (limited to 'src')
-rw-r--r--src/com/android/settings/applications/AppDashboardFragment.java4
-rw-r--r--src/com/android/settings/applications/HibernatedAppsPreferenceController.java93
2 files changed, 90 insertions, 7 deletions
diff --git a/src/com/android/settings/applications/AppDashboardFragment.java b/src/com/android/settings/applications/AppDashboardFragment.java
index 65f2b61cdd..ff1259571f 100644
--- a/src/com/android/settings/applications/AppDashboardFragment.java
+++ b/src/com/android/settings/applications/AppDashboardFragment.java
@@ -69,6 +69,10 @@ public class AppDashboardFragment extends DashboardFragment {
use(SpecialAppAccessPreferenceController.class).setSession(getSettingsLifecycle());
mAppsPreferenceController = use(AppsPreferenceController.class);
mAppsPreferenceController.setFragment(this /* fragment */);
+
+ final HibernatedAppsPreferenceController hibernatedAppsPreferenceController =
+ use(HibernatedAppsPreferenceController.class);
+ getSettingsLifecycle().addObserver(hibernatedAppsPreferenceController);
}
@Override
diff --git a/src/com/android/settings/applications/HibernatedAppsPreferenceController.java b/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
index 8d128112ad..bf12b86c00 100644
--- a/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
+++ b/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
@@ -30,40 +30,111 @@ import android.content.pm.PackageManager;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
+import androidx.annotation.NonNull;
+import androidx.annotation.WorkerThread;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
+import com.google.common.annotations.VisibleForTesting;
+
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* A preference controller handling the logic for updating summary of hibernated apps.
*/
-public final class HibernatedAppsPreferenceController extends BasePreferenceController {
+public final class HibernatedAppsPreferenceController extends BasePreferenceController
+ implements LifecycleObserver {
private static final String TAG = "HibernatedAppsPrefController";
private static final String PROPERTY_HIBERNATION_UNUSED_THRESHOLD_MILLIS =
"auto_revoke_unused_threshold_millis2";
private static final long DEFAULT_UNUSED_THRESHOLD_MS = TimeUnit.DAYS.toMillis(90);
+ private PreferenceScreen mScreen;
+ private int mUnusedCount = 0;
+ private boolean mLoadingUnusedApps;
+ private final Executor mBackgroundExecutor;
+ private final Executor mMainExecutor;
public HibernatedAppsPreferenceController(Context context, String preferenceKey) {
+ this(context, preferenceKey, Executors.newSingleThreadExecutor(),
+ context.getMainExecutor());
+ }
+
+ @VisibleForTesting
+ HibernatedAppsPreferenceController(Context context, String preferenceKey,
+ Executor bgExecutor, Executor mainExecutor) {
super(context, preferenceKey);
+ mBackgroundExecutor = bgExecutor;
+ mMainExecutor = mainExecutor;
}
@Override
public int getAvailabilityStatus() {
- return isHibernationEnabled() && getNumHibernated() > 0
+ return isHibernationEnabled() && mUnusedCount > 0
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
- final int numHibernated = getNumHibernated();
return mContext.getResources().getQuantityString(
- R.plurals.unused_apps_summary, numHibernated, numHibernated);
+ R.plurals.unused_apps_summary, mUnusedCount, mUnusedCount);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mScreen = screen;
+ }
+
+ /**
+ * On lifecycle resume event.
+ */
+ @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
+ public void onResume() {
+ updatePreference();
}
- private int getNumHibernated() {
+ private void updatePreference() {
+ if (mScreen == null) {
+ return;
+ }
+ if (!mLoadingUnusedApps) {
+ loadUnusedCount(unusedCount -> {
+ mUnusedCount = unusedCount;
+ mLoadingUnusedApps = false;
+ mMainExecutor.execute(() -> {
+ super.displayPreference(mScreen);
+ Preference pref = mScreen.findPreference(mPreferenceKey);
+ refreshSummary(pref);
+ });
+ });
+ mLoadingUnusedApps = true;
+ }
+ }
+
+ /**
+ * Asynchronously load the count of unused apps.
+ *
+ * @param callback callback to call when the number of unused apps is calculated
+ */
+ private void loadUnusedCount(@NonNull UnusedCountLoadedCallback callback) {
+ mBackgroundExecutor.execute(() -> {
+ final int unusedCount = getUnusedCount();
+ callback.onUnusedCountLoaded(unusedCount);
+ });
+ }
+
+ @WorkerThread
+ private int getUnusedCount() {
// TODO(b/187465752): Find a way to export this logic from PermissionController module
final PackageManager pm = mContext.getPackageManager();
final AppHibernationManager ahm = mContext.getSystemService(AppHibernationManager.class);
@@ -71,6 +142,7 @@ public final class HibernatedAppsPreferenceController extends BasePreferenceCont
int numHibernated = hibernatedPackages.size();
// Also need to count packages that are auto revoked but not hibernated.
+ int numAutoRevoked = 0;
final UsageStatsManager usm = mContext.getSystemService(UsageStatsManager.class);
final long now = System.currentTimeMillis();
final long unusedThreshold = DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS,
@@ -97,17 +169,24 @@ public final class HibernatedAppsPreferenceController extends BasePreferenceCont
for (String perm : pi.requestedPermissions) {
if ((pm.getPermissionFlags(perm, packageName, mContext.getUser())
& PackageManager.FLAG_PERMISSION_AUTO_REVOKED) != 0) {
- numHibernated++;
+ numAutoRevoked++;
break;
}
}
}
}
- return numHibernated;
+ return numHibernated + numAutoRevoked;
}
private static boolean isHibernationEnabled() {
return DeviceConfig.getBoolean(
NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED, false);
}
+
+ /**
+ * Callback for when we've determined the number of unused apps.
+ */
+ private interface UnusedCountLoadedCallback {
+ void onUnusedCountLoaded(int unusedCount);
+ }
}