summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageStats.java30
-rw-r--r--services/core/java/com/android/server/storage/AppCollector.java46
-rw-r--r--services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java83
3 files changed, 61 insertions, 98 deletions
diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java
index cb9039b046ee..c746af4c9ea3 100644
--- a/core/java/android/content/pm/PackageStats.java
+++ b/core/java/android/content/pm/PackageStats.java
@@ -19,6 +19,9 @@ package android.content.pm;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
+import android.text.TextUtils;
+
+import java.util.Objects;
/**
* implementation of PackageStats associated with a
@@ -173,4 +176,31 @@ public class PackageStats implements Parcelable {
dest.writeLong(externalMediaSize);
dest.writeLong(externalObbSize);
}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof PackageStats)) {
+ return false;
+ }
+
+ final PackageStats otherStats = (PackageStats) obj;
+ return ((TextUtils.equals(packageName, otherStats.packageName))
+ && userHandle == otherStats.userHandle
+ && codeSize == otherStats.codeSize
+ && dataSize == otherStats.dataSize
+ && cacheSize == otherStats.cacheSize
+ && externalCodeSize == otherStats.externalCodeSize
+ && externalDataSize == otherStats.externalDataSize
+ && externalCacheSize == otherStats.externalCacheSize
+ && externalMediaSize == otherStats.externalMediaSize
+ && externalObbSize == otherStats.externalObbSize);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(packageName, userHandle, codeSize, dataSize,
+ cacheSize, externalCodeSize, externalDataSize, externalCacheSize, externalMediaSize,
+ externalObbSize);
+ }
+
}
diff --git a/services/core/java/com/android/server/storage/AppCollector.java b/services/core/java/com/android/server/storage/AppCollector.java
index ee9c5bf2775d..25880fb90496 100644
--- a/services/core/java/com/android/server/storage/AppCollector.java
+++ b/services/core/java/com/android/server/storage/AppCollector.java
@@ -17,6 +17,8 @@
package com.android.server.storage;
import android.annotation.NonNull;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageStatsObserver;
@@ -64,7 +66,8 @@ public class AppCollector {
mBackgroundHandler = new BackgroundHandler(BackgroundThread.get().getLooper(),
volume,
context.getPackageManager(),
- (UserManager) context.getSystemService(Context.USER_SERVICE));
+ (UserManager) context.getSystemService(Context.USER_SERVICE),
+ (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE));
}
/**
@@ -93,39 +96,20 @@ public class AppCollector {
return value;
}
- private class StatsObserver extends IPackageStatsObserver.Stub {
- private AtomicInteger mCount;
- private final ArrayList<PackageStats> mPackageStats;
-
- public StatsObserver(int count) {
- mCount = new AtomicInteger(count);
- mPackageStats = new ArrayList<>(count);
- }
-
- @Override
- public void onGetStatsCompleted(PackageStats packageStats, boolean succeeded)
- throws RemoteException {
- if (succeeded) {
- mPackageStats.add(packageStats);
- }
-
- if (mCount.decrementAndGet() == 0) {
- mStats.complete(mPackageStats);
- }
- }
- }
-
private class BackgroundHandler extends Handler {
static final int MSG_START_LOADING_SIZES = 0;
private final VolumeInfo mVolume;
private final PackageManager mPm;
private final UserManager mUm;
+ private final StorageStatsManager mStorageStatsManager;
- BackgroundHandler(Looper looper, @NonNull VolumeInfo volume, PackageManager pm, UserManager um) {
+ BackgroundHandler(Looper looper, @NonNull VolumeInfo volume,
+ PackageManager pm, UserManager um, StorageStatsManager storageStatsManager) {
super(looper);
mVolume = volume;
mPm = pm;
mUm = um;
+ mStorageStatsManager = storageStatsManager;
}
@Override
@@ -149,14 +133,20 @@ public class AppCollector {
mStats.complete(new ArrayList<>());
}
- // Kick off the async package size query for all apps.
- final StatsObserver observer = new StatsObserver(count);
+ List<PackageStats> stats = new ArrayList<>();
for (UserInfo user : users) {
for (ApplicationInfo app : volumeApps) {
- mPm.getPackageSizeInfoAsUser(app.packageName, user.id,
- observer);
+ PackageStats packageStats = new PackageStats(app.packageName, user.id);
+ StorageStats storageStats = mStorageStatsManager.queryStatsForPackage(
+ app.volumeUuid, app.packageName, user.getUserHandle());
+ packageStats.cacheSize = storageStats.getCacheBytes();
+ packageStats.codeSize = storageStats.getCodeBytes();
+ packageStats.dataSize = storageStats.getDataBytes();
+ stats.add(packageStats);
}
}
+
+ mStats.complete(stats);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java b/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java
index 29185e92d5ed..8cf7c8a62039 100644
--- a/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java
@@ -16,12 +16,15 @@
package com.android.server.storage;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.pm.UserInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
+import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.VolumeInfo;
import android.test.AndroidTestCase;
@@ -53,6 +56,7 @@ public class AppCollectorTest extends AndroidTestCase {
@Mock private Context mContext;
@Mock private PackageManager mPm;
@Mock private UserManager mUm;
+ @Mock private StorageStatsManager mSsm;
private List<ApplicationInfo> mApps;
private List<UserInfo> mUsers;
@@ -63,6 +67,7 @@ public class AppCollectorTest extends AndroidTestCase {
mApps = new ArrayList<>();
when(mContext.getPackageManager()).thenReturn(mPm);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm);
+ when(mContext.getSystemService(Context.STORAGE_STATS_SERVICE)).thenReturn(mSsm);
// Set up the app list.
when(mPm.getInstalledApplications(anyInt())).thenReturn(mApps);
@@ -100,39 +105,9 @@ public class AppCollectorTest extends AndroidTestCase {
AppCollector collector = new AppCollector(mContext, volume);
PackageStats stats = new PackageStats("com.test.app");
- // Set up this to handle the asynchronous call to the PackageManager. This returns the
- // package info for the specified package.
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) {
- try {
- ((IPackageStatsObserver.Stub) invocation.getArguments()[2])
- .onGetStatsCompleted(stats, true);
- } catch (Exception e) {
- // We fail instead of just letting the exception fly because throwing
- // out of the callback like this on the background thread causes the test
- // runner to crash, rather than reporting the failure.
- fail();
- }
- return null;
- }
- }).when(mPm).getPackageSizeInfoAsUser(eq("com.test.app"), eq(0), any());
-
-
- // Because getPackageStats is a blocking call, we block execution of the test until the
- // call finishes. In order to finish the call, we need the above answer to execute.
- List<PackageStats> myStats = new ArrayList<>();
- CountDownLatch latch = new CountDownLatch(1);
- new Thread(new Runnable() {
- @Override
- public void run() {
- myStats.addAll(collector.getPackageStats(TIMEOUT));
- latch.countDown();
- }
- }).start();
- latch.await();
-
- assertThat(myStats).containsExactly(stats);
+ when(mSsm.queryStatsForPackage(eq("testuuid"),
+ eq("com.test.app"), eq(UserHandle.of(0)))).thenReturn(new StorageStats());
+ assertThat(collector.getPackageStats(TIMEOUT)).containsExactly(stats);
}
@Test
@@ -151,43 +126,11 @@ public class AppCollectorTest extends AndroidTestCase {
PackageStats otherStats = new PackageStats("com.test.app");
otherStats.userHandle = 1;
- // Set up this to handle the asynchronous call to the PackageManager. This returns the
- // package info for our packages.
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) {
- try {
- ((IPackageStatsObserver.Stub) invocation.getArguments()[2])
- .onGetStatsCompleted(stats, true);
-
- // Now callback for the other uid.
- ((IPackageStatsObserver.Stub) invocation.getArguments()[2])
- .onGetStatsCompleted(otherStats, true);
- } catch (Exception e) {
- // We fail instead of just letting the exception fly because throwing
- // out of the callback like this on the background thread causes the test
- // runner to crash, rather than reporting the failure.
- fail();
- }
- return null;
- }
- }).when(mPm).getPackageSizeInfoAsUser(eq("com.test.app"), eq(0), any());
-
-
- // Because getPackageStats is a blocking call, we block execution of the test until the
- // call finishes. In order to finish the call, we need the above answer to execute.
- List<PackageStats> myStats = new ArrayList<>();
- CountDownLatch latch = new CountDownLatch(1);
- new Thread(new Runnable() {
- @Override
- public void run() {
- myStats.addAll(collector.getPackageStats(TIMEOUT));
- latch.countDown();
- }
- }).start();
- latch.await();
-
- assertThat(myStats).containsAllOf(stats, otherStats);
+ when(mSsm.queryStatsForPackage(eq("testuuid"),
+ eq("com.test.app"), eq(UserHandle.of(0)))).thenReturn(new StorageStats());
+ when(mSsm.queryStatsForPackage(eq("testuuid"),
+ eq("com.test.app"), eq(UserHandle.of(1)))).thenReturn(new StorageStats());
+ assertThat(collector.getPackageStats(TIMEOUT)).containsExactly(stats, otherStats);
}
@Test(expected=NullPointerException.class)