From 373d01766f27476e81a174727dcfeee406742417 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 22 Feb 2017 15:47:27 -0700 Subject: Add queryStatsForPackage() API. This gives developers a way to collect package-level stats, even if it means we have to use manual calculation for sharedUserId apps. Also round size of storage devices to nice power-of-two values so we do a better job of matching retail packaging. Test: builds, boots Bug: 35294241 Change-Id: I24946c443bb9dc4b0411a8149a0656702ac1fd24 --- .../android/server/usage/StorageStatsService.java | 43 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'services/usage/java') diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java index a44860e4441d..d65afc18e79b 100644 --- a/services/usage/java/com/android/server/usage/StorageStatsService.java +++ b/services/usage/java/com/android/server/usage/StorageStatsService.java @@ -29,6 +29,7 @@ import android.content.pm.PackageStats; import android.content.pm.UserInfo; import android.os.Binder; import android.os.Environment; +import android.os.FileUtils; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -145,11 +146,10 @@ public class StorageStatsService extends IStorageStatsManager.Stub { enforcePermission(Binder.getCallingUid(), callingPackage); if (volumeUuid == StorageManager.UUID_PRIVATE_INTERNAL) { - // TODO: round total size to nearest power of two - return mStorage.getPrimaryStorageSize(); + return FileUtils.roundStorageSize(mStorage.getPrimaryStorageSize()); } else { final VolumeInfo vol = mStorage.findVolumeByUuid(volumeUuid); - return vol.disk.size; + return FileUtils.roundStorageSize(vol.disk.size); } } @@ -171,6 +171,43 @@ public class StorageStatsService extends IStorageStatsManager.Stub { } } + @Override + public StorageStats queryStatsForPackage(String volumeUuid, String packageName, int userId, + String callingPackage) { + enforcePermission(Binder.getCallingUid(), callingPackage); + if (userId != UserHandle.getCallingUserId()) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.INTERACT_ACROSS_USERS, TAG); + } + + final ApplicationInfo appInfo; + try { + appInfo = mPackage.getApplicationInfoAsUser(packageName, 0, userId); + } catch (NameNotFoundException e) { + throw new IllegalStateException(e); + } + + if (mPackage.getPackagesForUid(appInfo.uid).length == 1) { + // Only one package inside UID means we can fast-path + return queryStatsForUid(volumeUuid, appInfo.uid, callingPackage); + } else { + // Multiple packages means we need to go manual + final int appId = UserHandle.getUserId(appInfo.uid); + final String[] packageNames = new String[] { packageName }; + final long[] ceDataInodes = new long[1]; + final String[] codePaths = new String[] { appInfo.getCodePath() }; + + final PackageStats stats = new PackageStats(TAG); + try { + mInstaller.getAppSize(volumeUuid, packageNames, userId, 0, + appId, ceDataInodes, codePaths, stats); + } catch (InstallerException e) { + throw new IllegalStateException(e); + } + return translate(stats); + } + } + @Override public StorageStats queryStatsForUid(String volumeUuid, int uid, String callingPackage) { enforcePermission(Binder.getCallingUid(), callingPackage); -- cgit v1.2.3-59-g8ed1b