summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--api/test-current.txt2
-rw-r--r--core/java/android/content/pm/PackageManager.java5
-rw-r--r--core/java/android/content/pm/PackageStats.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java38
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java414
7 files changed, 119 insertions, 353 deletions
diff --git a/api/current.txt b/api/current.txt
index f8c2615c519e..4b3acb18c3b8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10704,7 +10704,7 @@ package android.content.pm {
ctor public PackageManager.NameNotFoundException(java.lang.String);
}
- public class PackageStats implements android.os.Parcelable {
+ public deprecated class PackageStats implements android.os.Parcelable {
ctor public PackageStats(java.lang.String);
ctor public PackageStats(android.os.Parcel);
ctor public PackageStats(android.content.pm.PackageStats);
diff --git a/api/system-current.txt b/api/system-current.txt
index b3d1a894c4e8..876b00b29052 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -11424,7 +11424,7 @@ package android.content.pm {
public static abstract class PackageManager.PermissionFlags implements java.lang.annotation.Annotation {
}
- public class PackageStats implements android.os.Parcelable {
+ public deprecated class PackageStats implements android.os.Parcelable {
ctor public PackageStats(java.lang.String);
ctor public PackageStats(android.os.Parcel);
ctor public PackageStats(android.content.pm.PackageStats);
diff --git a/api/test-current.txt b/api/test-current.txt
index f581171eb994..7299f8dc8c42 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -10740,7 +10740,7 @@ package android.content.pm {
ctor public PackageManager.NameNotFoundException(java.lang.String);
}
- public class PackageStats implements android.os.Parcelable {
+ public deprecated class PackageStats implements android.os.Parcelable {
ctor public PackageStats(java.lang.String);
ctor public PackageStats(android.os.Parcel);
ctor public PackageStats(android.content.pm.PackageStats);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 664e76b91479..3a875bc79aa8 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -34,6 +34,7 @@ import android.annotation.XmlRes;
import android.app.PackageDeleteObserver;
import android.app.PackageInstallObserver;
import android.app.admin.DevicePolicyManager;
+import android.app.usage.StorageStatsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -5466,8 +5467,10 @@ public abstract class PackageManager {
* the status of the operation. observer may be null to indicate that
* no callback is desired.
*
+ * @deprecated use {@link StorageStatsManager} instead.
* @hide
*/
+ @Deprecated
public abstract void getPackageSizeInfoAsUser(String packageName, @UserIdInt int userId,
IPackageStatsObserver observer);
@@ -5475,8 +5478,10 @@ public abstract class PackageManager {
* Like {@link #getPackageSizeInfoAsUser(String, int, IPackageStatsObserver)}, but
* returns the size for the calling user.
*
+ * @deprecated use {@link StorageStatsManager} instead.
* @hide
*/
+ @Deprecated
public void getPackageSizeInfo(String packageName, IPackageStatsObserver observer) {
getPackageSizeInfoAsUser(packageName, UserHandle.myUserId(), observer);
}
diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java
index c746af4c9ea3..27b3506f49a7 100644
--- a/core/java/android/content/pm/PackageStats.java
+++ b/core/java/android/content/pm/PackageStats.java
@@ -16,6 +16,7 @@
package android.content.pm;
+import android.app.usage.StorageStatsManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
@@ -24,9 +25,13 @@ import android.text.TextUtils;
import java.util.Objects;
/**
- * implementation of PackageStats associated with a
- * application package.
+ * implementation of PackageStats associated with a application package.
+ *
+ * @deprecated this class is an orphan that could never be obtained from a valid
+ * public API. If you need package storage statistics use the new
+ * {@link StorageStatsManager} APIs.
*/
+@Deprecated
public class PackageStats implements Parcelable {
/** Name of the package to which this stats applies. */
public String packageName;
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index fda3914d1fc0..8f7efb59d8c4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -19,6 +19,8 @@ package com.android.settingslib.applications;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.Application;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -92,6 +94,7 @@ public class ApplicationsState {
final PackageManager mPm;
final IPackageManager mIpm;
final UserManager mUm;
+ final StorageStatsManager mStats;
final int mAdminRetrieveFlags;
final int mRetrieveFlags;
PackageIntentReceiver mPackageIntentReceiver;
@@ -111,6 +114,7 @@ public class ApplicationsState {
final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>();
List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();
long mCurId = 1;
+ String mCurComputingSizeUuid;
String mCurComputingSizePkg;
int mCurComputingSizeUserId;
boolean mSessionsChanged;
@@ -126,7 +130,8 @@ public class ApplicationsState {
mContext = app;
mPm = mContext.getPackageManager();
mIpm = AppGlobals.getPackageManager();
- mUm = (UserManager) app.getSystemService(Context.USER_SERVICE);
+ mUm = mContext.getSystemService(UserManager.class);
+ mStats = mContext.getSystemService(StorageStatsManager.class);
for (int userId : mUm.getProfileIdsWithDisabled(UserHandle.myUserId())) {
mEntriesMap.put(userId, new HashMap<String, AppEntry>());
}
@@ -328,7 +333,18 @@ public class ApplicationsState {
synchronized (mEntriesMap) {
AppEntry entry = mEntriesMap.get(userId).get(packageName);
if (entry != null) {
- mPm.getPackageSizeInfoAsUser(packageName, userId, mBackgroundHandler.mStatsObserver);
+ mBackgroundHandler.post(() -> {
+ final StorageStats stats = mStats.queryStatsForPackage(entry.info.volumeUuid,
+ packageName, UserHandle.of(userId));
+ final PackageStats legacyStats = new PackageStats(packageName, userId);
+ legacyStats.codeSize = stats.getCodeBytes();
+ legacyStats.dataSize = stats.getDataBytes();
+ legacyStats.cacheSize = stats.getCacheBytes();
+ try {
+ mBackgroundHandler.mStatsObserver.onGetStatsCompleted(legacyStats, true);
+ } catch (RemoteException ignored) {
+ }
+ });
}
if (DEBUG_LOCKING) Log.v(TAG, "...requestSize releasing lock");
}
@@ -958,10 +974,24 @@ public class ApplicationsState {
mMainHandler.sendMessage(m);
}
entry.sizeLoadStart = now;
+ mCurComputingSizeUuid = entry.info.volumeUuid;
mCurComputingSizePkg = entry.info.packageName;
mCurComputingSizeUserId = UserHandle.getUserId(entry.info.uid);
- mPm.getPackageSizeInfoAsUser(mCurComputingSizePkg,
- mCurComputingSizeUserId, mStatsObserver);
+
+ mBackgroundHandler.post(() -> {
+ final StorageStats stats = mStats.queryStatsForPackage(
+ mCurComputingSizeUuid, mCurComputingSizePkg,
+ UserHandle.of(mCurComputingSizeUserId));
+ final PackageStats legacyStats = new PackageStats(
+ mCurComputingSizePkg, mCurComputingSizeUserId);
+ legacyStats.codeSize = stats.getCodeBytes();
+ legacyStats.dataSize = stats.getDataBytes();
+ legacyStats.cacheSize = stats.getCacheBytes();
+ try {
+ mStatsObserver.onGetStatsCompleted(legacyStats, true);
+ } catch (RemoteException ignored) {
+ }
+ });
}
if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: now computing");
return;
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index e520319c1eb7..953dda29d7c4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -16,22 +16,14 @@
package com.android.settingslib.deviceinfo;
-import android.app.ActivityManager;
-import android.content.ComponentName;
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageStats;
import android.content.pm.UserInfo;
+import android.os.AsyncTask;
import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageVolume;
@@ -40,93 +32,54 @@ import android.util.Log;
import android.util.SparseArray;
import android.util.SparseLongArray;
-import com.android.internal.app.IMediaContainerService;
-import com.android.internal.util.ArrayUtils;
-import com.google.android.collect.Sets;
-
-import java.io.File;
import java.lang.ref.WeakReference;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.Objects;
-import java.util.Set;
/**
* Utility for measuring the disk usage of internal storage or a physical
- * {@link StorageVolume}. Connects with a remote {@link IMediaContainerService}
- * and delivers results to {@link MeasurementReceiver}.
+ * {@link StorageVolume}.
*/
public class StorageMeasurement {
private static final String TAG = "StorageMeasurement";
- private static final boolean LOCAL_LOGV = false;
- static final boolean LOGV = LOCAL_LOGV && Log.isLoggable(TAG, Log.VERBOSE);
-
- private static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
-
- public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
- DEFAULT_CONTAINER_PACKAGE, "com.android.defcontainer.DefaultContainerService");
-
- /** Media types to measure on external storage. */
- private static final Set<String> sMeasureMediaTypes = Sets.newHashSet(
- Environment.DIRECTORY_DCIM, Environment.DIRECTORY_MOVIES,
- Environment.DIRECTORY_PICTURES, Environment.DIRECTORY_MUSIC,
- Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
- Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS,
- Environment.DIRECTORY_DOWNLOADS, Environment.DIRECTORY_ANDROID);
-
public static class MeasurementDetails {
+ /** Size of storage device. */
public long totalSize;
+ /** Size of available space. */
public long availSize;
+ /** Size of all cached data. */
+ public long cacheSize;
/**
- * Total apps disk usage per profiles of the current user.
- * <p>
- * When measuring internal storage, this value includes the code size of
- * all apps (regardless of install status for the given profile), and
- * internal disk used by the profile's apps. When the device
- * emulates external storage, this value also includes emulated storage
- * used by the profile's apps.
- * <p>
- * When measuring a physical {@link StorageVolume}, this value includes
- * usage by all apps on that volume and only for the primary profile.
+ * Total disk space used by everything.
* <p>
* Key is {@link UserHandle}.
*/
- public SparseLongArray appsSize = new SparseLongArray();
+ public SparseLongArray usersSize = new SparseLongArray();
/**
- * Total cache disk usage by apps (over all users and profiles).
+ * Total disk space used by apps.
+ * <p>
+ * Key is {@link UserHandle}.
*/
- public long cacheSize;
+ public SparseLongArray appsSize = new SparseLongArray();
/**
- * Total media disk usage, categorized by types such as
- * {@link Environment#DIRECTORY_MUSIC} for every user profile of the current user.
- * <p>
- * When measuring internal storage, this reflects media on emulated
- * storage for the respective profile.
+ * Total disk space used by media on shared storage.
* <p>
- * When measuring a physical {@link StorageVolume}, this reflects media
- * on that volume.
- * <p>
- * Key of the {@link SparseArray} is {@link UserHandle}.
+ * First key is {@link UserHandle}. Second key is media type, such as
+ * {@link Environment#DIRECTORY_PICTURES}.
*/
public SparseArray<HashMap<String, Long>> mediaSize = new SparseArray<>();
/**
- * Misc external disk usage for the current user's profiles, unaccounted in
- * {@link #mediaSize}. Key is {@link UserHandle}.
+ * Total disk space used by non-media on shared storage.
+ * <p>
+ * Key is {@link UserHandle}.
*/
public SparseLongArray miscSize = new SparseLongArray();
- /**
- * Total disk usage for users, which is only meaningful for emulated
- * internal storage. Key is {@link UserHandle}.
- */
- public SparseLongArray usersSize = new SparseLongArray();
-
@Override
public String toString() {
return "MeasurementDetails: [totalSize: " + totalSize + " availSize: " + availSize
@@ -142,25 +95,19 @@ public class StorageMeasurement {
private WeakReference<MeasurementReceiver> mReceiver;
private final Context mContext;
+ private final UserManager mUser;
+ private final StorageStatsManager mStats;
private final VolumeInfo mVolume;
private final VolumeInfo mSharedVolume;
- private final MainHandler mMainHandler;
- private final MeasurementHandler mMeasurementHandler;
-
public StorageMeasurement(Context context, VolumeInfo volume, VolumeInfo sharedVolume) {
mContext = context.getApplicationContext();
+ mUser = mContext.getSystemService(UserManager.class);
+ mStats = mContext.getSystemService(StorageStatsManager.class);
mVolume = volume;
mSharedVolume = sharedVolume;
-
- // Start the thread that will measure the disk usage.
- final HandlerThread handlerThread = new HandlerThread("MemoryMeasurement");
- handlerThread.start();
-
- mMainHandler = new MainHandler();
- mMeasurementHandler = new MeasurementHandler(handlerThread.getLooper());
}
public void setReceiver(MeasurementReceiver receiver) {
@@ -170,315 +117,94 @@ public class StorageMeasurement {
}
public void forceMeasure() {
- invalidate();
measure();
}
public void measure() {
- if (!mMeasurementHandler.hasMessages(MeasurementHandler.MSG_MEASURE)) {
- mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_MEASURE);
- }
+ new MeasureTask().execute();
}
public void onDestroy() {
mReceiver = null;
- mMeasurementHandler.removeMessages(MeasurementHandler.MSG_MEASURE);
- mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_DISCONNECT);
}
- private void invalidate() {
- mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_INVALIDATE);
- }
-
- private static class StatsObserver extends IPackageStatsObserver.Stub {
- private final boolean mIsPrivate;
- private final MeasurementDetails mDetails;
- private final int mCurrentUser;
- private final Message mFinished;
-
- private int mRemaining;
-
- public StatsObserver(boolean isPrivate, MeasurementDetails details, int currentUser,
- List<UserInfo> profiles, Message finished, int remaining) {
- mIsPrivate = isPrivate;
- mDetails = details;
- mCurrentUser = currentUser;
- if (isPrivate) {
- // Add the profile ids as keys to detail's app sizes.
- for (UserInfo userInfo : profiles) {
- mDetails.appsSize.put(userInfo.id, 0);
- }
- }
- mFinished = finished;
- mRemaining = remaining;
- }
-
+ private class MeasureTask extends AsyncTask<Void, Void, MeasurementDetails> {
@Override
- public void onGetStatsCompleted(PackageStats stats, boolean succeeded) {
- synchronized (mDetails) {
- if (succeeded) {
- addStatsLocked(stats);
- }
- if (--mRemaining == 0) {
- mFinished.sendToTarget();
- }
- }
+ protected MeasurementDetails doInBackground(Void... params) {
+ return measureExactStorage();
}
- private void addStatsLocked(PackageStats stats) {
- if (mIsPrivate) {
- long codeSize = stats.codeSize;
- long dataSize = stats.dataSize;
- long cacheSize = stats.cacheSize;
- if (Environment.isExternalStorageEmulated()) {
- // Include emulated storage when measuring internal. OBB is
- // shared on emulated storage, so treat as code.
- codeSize += stats.externalCodeSize + stats.externalObbSize;
- dataSize += stats.externalDataSize + stats.externalMediaSize;
- cacheSize += stats.externalCacheSize;
- }
-
- // Count code and data for current user's profiles (keys prepared in constructor)
- addValueIfKeyExists(mDetails.appsSize, stats.userHandle, codeSize + dataSize);
-
- // User summary only includes data (code is only counted once
- // for the current user)
- addValue(mDetails.usersSize, stats.userHandle, dataSize);
-
- // Include cache for all users
- mDetails.cacheSize += cacheSize;
-
- } else {
- // Physical storage; only count external sizes
- addValue(mDetails.appsSize, mCurrentUser,
- stats.externalCodeSize + stats.externalDataSize
- + stats.externalMediaSize + stats.externalObbSize);
- mDetails.cacheSize += stats.externalCacheSize;
- }
- }
- }
-
- private class MainHandler extends Handler {
@Override
- public void handleMessage(Message msg) {
- final MeasurementDetails details = (MeasurementDetails) msg.obj;
+ protected void onPostExecute(MeasurementDetails result) {
final MeasurementReceiver receiver = (mReceiver != null) ? mReceiver.get() : null;
if (receiver != null) {
- receiver.onDetailsChanged(details);
+ receiver.onDetailsChanged(result);
}
}
}
- private class MeasurementHandler extends Handler {
- public static final int MSG_MEASURE = 1;
- public static final int MSG_CONNECTED = 2;
- public static final int MSG_DISCONNECT = 3;
- public static final int MSG_COMPLETED = 4;
- public static final int MSG_INVALIDATE = 5;
-
- private Object mLock = new Object();
+ private MeasurementDetails measureExactStorage() {
+ final List<UserInfo> users = mUser.getUsers();
- private IMediaContainerService mDefaultContainer;
+ final long start = SystemClock.elapsedRealtime();
- private volatile boolean mBound = false;
-
- private MeasurementDetails mCached;
-
- private final ServiceConnection mDefContainerConn = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- final IMediaContainerService imcs = IMediaContainerService.Stub.asInterface(
- service);
- mDefaultContainer = imcs;
- mBound = true;
- sendMessage(obtainMessage(MSG_CONNECTED, imcs));
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mBound = false;
- removeMessages(MSG_CONNECTED);
- }
- };
-
- public MeasurementHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_MEASURE: {
- if (mCached != null) {
- mMainHandler.obtainMessage(0, mCached).sendToTarget();
- break;
- }
-
- synchronized (mLock) {
- if (mBound) {
- removeMessages(MSG_DISCONNECT);
- sendMessage(obtainMessage(MSG_CONNECTED, mDefaultContainer));
- } else {
- Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
- mContext.bindServiceAsUser(service, mDefContainerConn,
- Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
- }
- }
- break;
- }
- case MSG_CONNECTED: {
- final IMediaContainerService imcs = (IMediaContainerService) msg.obj;
- measureExactStorage(imcs);
- break;
- }
- case MSG_DISCONNECT: {
- synchronized (mLock) {
- if (mBound) {
- mBound = false;
- mContext.unbindService(mDefContainerConn);
- }
- }
- break;
- }
- case MSG_COMPLETED: {
- mCached = (MeasurementDetails) msg.obj;
- mMainHandler.obtainMessage(0, mCached).sendToTarget();
- break;
- }
- case MSG_INVALIDATE: {
- mCached = null;
- break;
- }
- }
- }
- }
+ final MeasurementDetails details = new MeasurementDetails();
+ if (mVolume == null) return details;
- private void measureExactStorage(IMediaContainerService imcs) {
- final UserManager userManager = mContext.getSystemService(UserManager.class);
- final PackageManager packageManager = mContext.getPackageManager();
+ details.totalSize = mStats.getTotalBytes(mVolume.fsUuid);
+ details.availSize = mStats.getFreeBytes(mVolume.fsUuid);
- final List<UserInfo> users = userManager.getUsers();
- final List<UserInfo> currentProfiles = userManager.getEnabledProfiles(
- ActivityManager.getCurrentUser());
+ final long finishTotal = SystemClock.elapsedRealtime();
+ Log.d(TAG, "Measured total storage in " + (finishTotal - start) + "ms");
- final MeasurementDetails details = new MeasurementDetails();
- final Message finished = mMeasurementHandler.obtainMessage(MeasurementHandler.MSG_COMPLETED,
- details);
+ if (mSharedVolume != null && mSharedVolume.isMountedReadable()) {
+ for (UserInfo user : users) {
+ final HashMap<String, Long> mediaMap = new HashMap<>();
+ details.mediaSize.put(user.id, mediaMap);
- if (mVolume == null || !mVolume.isMountedReadable()) {
- finished.sendToTarget();
- return;
- }
+ final ExternalStorageStats stats = mStats
+ .queryExternalStatsForUser(mSharedVolume.fsUuid, UserHandle.of(user.id));
- if (mSharedVolume != null && mSharedVolume.isMountedReadable()) {
- for (UserInfo currentUserInfo : currentProfiles) {
- final int userId = currentUserInfo.id;
- final File basePath = mSharedVolume.getPathForUser(userId);
- HashMap<String, Long> mediaMap = new HashMap<>(sMeasureMediaTypes.size());
- details.mediaSize.put(userId, mediaMap);
-
- // Measure media types for emulated storage, or for primary physical
- // external volume
- for (String type : sMeasureMediaTypes) {
- final File path = new File(basePath, type);
- final long size = getDirectorySize(imcs, path);
- mediaMap.put(type, size);
- }
+ addValue(details.usersSize, user.id, stats.getTotalBytes());
- // Measure misc files not counted under media
- addValue(details.miscSize, userId, measureMisc(imcs, basePath));
- }
+ // Track detailed data types
+ mediaMap.put(Environment.DIRECTORY_MUSIC, stats.getAudioBytes());
+ mediaMap.put(Environment.DIRECTORY_MOVIES, stats.getVideoBytes());
+ mediaMap.put(Environment.DIRECTORY_PICTURES, stats.getImageBytes());
- if (mSharedVolume.getType() == VolumeInfo.TYPE_EMULATED) {
- // Measure total emulated storage of all users; internal apps data
- // will be spliced in later
- for (UserInfo user : users) {
- final File userPath = mSharedVolume.getPathForUser(user.id);
- final long size = getDirectorySize(imcs, userPath);
- addValue(details.usersSize, user.id, size);
- }
+ final long miscBytes = stats.getTotalBytes() - stats.getAudioBytes()
+ - stats.getVideoBytes() - stats.getImageBytes();
+ addValue(details.miscSize, user.id, miscBytes);
}
}
- final File file = mVolume.getPath();
- if (file != null) {
- details.totalSize = file.getTotalSpace();
- details.availSize = file.getFreeSpace();
- }
+ final long finishShared = SystemClock.elapsedRealtime();
+ Log.d(TAG, "Measured shared storage in " + (finishShared - finishTotal) + "ms");
- // Measure all apps hosted on this volume for all users
- if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE) {
- final List<ApplicationInfo> apps = packageManager.getInstalledApplications(
- PackageManager.MATCH_ANY_USER
- | PackageManager.MATCH_DISABLED_COMPONENTS);
+ if ((mVolume.getType() == VolumeInfo.TYPE_PRIVATE) && mVolume.isMountedReadable()) {
+ for (UserInfo user : users) {
+ final StorageStats stats = mStats.queryStatsForUser(mVolume.fsUuid,
+ UserHandle.of(user.id));
- final List<ApplicationInfo> volumeApps = new ArrayList<>();
- for (ApplicationInfo app : apps) {
- if (Objects.equals(app.volumeUuid, mVolume.getFsUuid())) {
- volumeApps.add(app);
+ // Only count code once against current user
+ if (user.id == UserHandle.myUserId()) {
+ addValue(details.usersSize, user.id, stats.getCodeBytes());
}
- }
- final int count = users.size() * volumeApps.size();
- if (count == 0) {
- finished.sendToTarget();
- return;
- }
+ addValue(details.usersSize, user.id, stats.getDataBytes());
+ addValue(details.appsSize, user.id, stats.getCodeBytes() + stats.getDataBytes());
- final StatsObserver observer = new StatsObserver(true, details,
- ActivityManager.getCurrentUser(), currentProfiles, finished, count);
- for (UserInfo user : users) {
- for (ApplicationInfo app : volumeApps) {
- packageManager.getPackageSizeInfoAsUser(app.packageName, user.id, observer);
- }
+ details.cacheSize += stats.getCacheBytes();
}
-
- } else {
- finished.sendToTarget();
- return;
}
- }
-
- private static long getDirectorySize(IMediaContainerService imcs, File path) {
- try {
- final long size = imcs.calculateDirectorySize(path.toString());
- if (LOGV) Log.v(TAG, "getDirectorySize(" + path + ") returned " + size);
- return size;
- } catch (Exception e) {
- Log.w(TAG, "Could not read memory from default container service for " + path, e);
- return 0;
- }
- }
-
- private long measureMisc(IMediaContainerService imcs, File dir) {
- final File[] files = dir.listFiles();
- if (ArrayUtils.isEmpty(files)) return 0;
- // Get sizes of all top level nodes except the ones already computed
- long miscSize = 0;
- for (File file : files) {
- final String name = file.getName();
- if (sMeasureMediaTypes.contains(name)) {
- continue;
- }
+ final long finishPrivate = SystemClock.elapsedRealtime();
+ Log.d(TAG, "Measured private storage in " + (finishPrivate - finishShared) + "ms");
- if (file.isFile()) {
- miscSize += file.length();
- } else if (file.isDirectory()) {
- miscSize += getDirectorySize(imcs, file);
- }
- }
- return miscSize;
+ return details;
}
private static void addValue(SparseLongArray array, int key, long value) {
array.put(key, array.get(key) + value);
}
-
- private static void addValueIfKeyExists(SparseLongArray array, int key, long value) {
- final int index = array.indexOfKey(key);
- if (index >= 0) {
- array.put(key, array.valueAt(index) + value);
- }
- }
}