summaryrefslogtreecommitdiff
path: root/services/usage/java
diff options
context:
space:
mode:
author Daniel Nishi <dhnishi@google.com> 2017-01-23 14:33:42 -0800
committer Daniel Nishi <dhnishi@google.com> 2017-02-17 10:26:16 -0800
commitcf9d19e030830fd808d59f1c97edf65e66f675d6 (patch)
tree7d27e4f71ff44e24ce8aa36038dc5e88b4eb8a70 /services/usage/java
parentceb250424a32ef45549fa728adcd766cb7c35b54 (diff)
First pass at adding the cache quota suggestions.
This currently integrates with installd, but not with any framework API to expose this information to apps. The first pass, as per the design doc, adds a service which polls for large changes in the file system free space. If enough spaces changes, it begins a recalculation of the cache quotas and pipes the information down to installd. This calculation is done in the updateable ExtServices. Further enhancements in later patches include integrating this to listen to package install and removal events, caching the last computed quota values into an XML file on disk to load on boot, and exposing the information to apps. Bug: 33965858 Test: ExtServices unit test Change-Id: Ie39f228b73532cb6ce2f98529f7c5df0839202ae
Diffstat (limited to 'services/usage/java')
-rw-r--r--services/usage/java/com/android/server/usage/StorageStatsService.java74
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java7
2 files changed, 81 insertions, 0 deletions
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 68269751efc1..96907c33ca45 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -20,6 +20,7 @@ import android.app.AppOpsManager;
import android.app.usage.ExternalStorageStats;
import android.app.usage.IStorageStatsManager;
import android.app.usage.StorageStats;
+import android.app.usage.UsageStatsManagerInternal;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -28,25 +29,35 @@ import android.content.pm.PackageStats;
import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.StatFs;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
+import android.text.format.DateUtils;
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
+import com.android.server.IoThread;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
+import com.android.server.storage.CacheQuotaStrategy;
public class StorageStatsService extends IStorageStatsManager.Stub {
private static final String TAG = "StorageStatsService";
private static final String PROP_VERIFY_STORAGE = "fw.verify_storage";
+ private static final long DELAY_IN_MILLIS = 30 * DateUtils.SECOND_IN_MILLIS;
+
public static class Lifecycle extends SystemService {
private StorageStatsService mService;
@@ -68,6 +79,7 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
private final StorageManager mStorage;
private final Installer mInstaller;
+ private final H mHandler;
public StorageStatsService(Context context) {
mContext = Preconditions.checkNotNull(context);
@@ -80,6 +92,9 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
mInstaller.onStart();
invalidateMounts();
+ mHandler = new H(IoThread.get().getLooper());
+ mHandler.sendEmptyMessageDelayed(H.MSG_CHECK_STORAGE_DELTA, DELAY_IN_MILLIS);
+
mStorage.registerListener(new StorageEventListener() {
@Override
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
@@ -274,4 +289,63 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
res.cacheBytes = stats.cacheSize + stats.externalCacheSize;
return res;
}
+
+ private class H extends Handler {
+ private static final int MSG_CHECK_STORAGE_DELTA = 100;
+ /**
+ * By only triggering a re-calculation after the storage has changed sizes, we can avoid
+ * recalculating quotas too often. Minimum change delta defines the percentage of change
+ * we need to see before we recalculate.
+ */
+ private static final double MINIMUM_CHANGE_DELTA = 0.05;
+ private static final boolean DEBUG = false;
+
+ private final StatFs mStats;
+ private long mPreviousBytes;
+ private double mMinimumThresholdBytes;
+
+ public H(Looper looper) {
+ super(looper);
+ // TODO: Handle all private volumes.
+ mStats = new StatFs(Environment.getDataDirectory().getAbsolutePath());
+ mPreviousBytes = mStats.getFreeBytes();
+ mMinimumThresholdBytes = mStats.getTotalBytes() * MINIMUM_CHANGE_DELTA;
+ // TODO: Load cache quotas from a file to avoid re-doing work.
+ }
+
+ public void handleMessage(Message msg) {
+ if (DEBUG) {
+ Slog.v(TAG, ">>> handling " + msg.what);
+ }
+ switch (msg.what) {
+ case MSG_CHECK_STORAGE_DELTA: {
+ long bytesDelta = Math.abs(mPreviousBytes - mStats.getFreeBytes());
+ if (bytesDelta > mMinimumThresholdBytes) {
+ mPreviousBytes = mStats.getFreeBytes();
+ recalculateQuotas();
+ }
+ sendEmptyMessageDelayed(MSG_CHECK_STORAGE_DELTA, DELAY_IN_MILLIS);
+ break;
+ }
+ default:
+ if (DEBUG) {
+ Slog.v(TAG, ">>> default message case ");
+ }
+ return;
+ }
+ }
+
+ private void recalculateQuotas() {
+ if (DEBUG) {
+ Slog.v(TAG, ">>> recalculating quotas ");
+ }
+
+ UsageStatsManagerInternal usageStatsManager =
+ LocalServices.getService(UsageStatsManagerInternal.class);
+ CacheQuotaStrategy strategy = new CacheQuotaStrategy(
+ mContext, usageStatsManager, mInstaller);
+ // TODO: Save cache quotas to an XML file.
+ strategy.recalculateQuotas();
+ }
+ }
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 7a69803c8463..3c743b5cb355 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1603,5 +1603,12 @@ public class UsageStatsService extends SystemService implements
userStats.applyRestoredPayload(key, payload);
}
}
+
+ @Override
+ public List<UsageStats> queryUsageStatsForUser(
+ int userId, int intervalType, long beginTime, long endTime) {
+ return UsageStatsService.this.queryUsageStats(
+ userId, intervalType, beginTime, endTime);
+ }
}
}