diff options
| author | 2024-04-20 05:40:52 +0000 | |
|---|---|---|
| committer | 2024-05-08 05:24:53 +0000 | |
| commit | 6bf31f4966a6a78721b0345fedb8dbe9c393548f (patch) | |
| tree | 3dae9f81d7fd56357fa75506e4351dfd431a82e5 | |
| parent | e25101a2a23af1a2a3cc536fe40b7994ff970007 (diff) | |
Add dumpsys entry point for package storageStats.
Flag: android.content.pm.Flags.get_package_storage_stats
Bug:332905331
Test: adb shell pm get-package-storage-stats com.google.android.youtube
sample output:
code: 151909888 bytes (144.87 Mb)
data: 8081408 bytes (7.71 Mb)
cache: 6602752 bytes (6.30 Mb)
apk: 110509971 bytes (105.39 Mb)
lib: 0 bytes
dm: 1282352 bytes (1.22 Mb)
dexopt artifacts: 40149956 bytes (38.29 Mb)
current profile : 18094 bytes (17.67 Kb)
reference profile: 98524 bytes (96.21 Kb)
external cache: 6279168 bytes (5.99 Mb)
Change-Id: I19083664f29756f3e3918de74d48b44b81a254dc
| -rw-r--r-- | core/java/android/content/pm/flags.aconfig | 12 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerShellCommand.java | 104 |
2 files changed, 116 insertions, 0 deletions
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig index cde565b3f66e..added33ba35a 100644 --- a/core/java/android/content/pm/flags.aconfig +++ b/core/java/android/content/pm/flags.aconfig @@ -136,6 +136,18 @@ flag { } flag { + name: "get_package_storage_stats" + namespace: "system_performance" + is_exported: true + description: "Add dumpsys entry point for package StorageStats" + bug: "332905331" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "provide_info_of_apk_in_apex" is_exported: true namespace: "package_manager_service" diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 179379487aba..7a36f6dabe06 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -35,6 +35,8 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.role.RoleManager; +import android.app.usage.StorageStats; +import android.app.usage.StorageStatsManager; import android.content.ComponentName; import android.content.Context; import android.content.IIntentReceiver; @@ -136,6 +138,7 @@ import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URISyntaxException; import java.security.SecureRandom; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; @@ -275,6 +278,8 @@ class PackageManagerShellCommand extends ShellCommand { return runClear(); case "get-archived-package-metadata": return runGetArchivedPackageMetadata(); + case "get-package-storage-stats": + return runGetPackageStorageStats(); case "install-archived": return runArchivedInstall(); case "enable": @@ -1861,6 +1866,103 @@ class PackageManagerShellCommand extends ShellCommand { return 0; } + /** + * Returns a string that shows the number of bytes in b, Kb, Mb or Gb. + */ + protected static String getFormattedBytes(long size) { + double k = size/1024.0; + double m = size/1048576.0; + double g = size/1073741824.0; + + DecimalFormat dec = new DecimalFormat("0.00"); + if (g > 1) { + return dec.format(g).concat(" Gb"); + } else if (m > 1) { + return dec.format(m).concat(" Mb"); + } else if (k > 1) { + return dec.format(k).concat(" Kb"); + } + return ""; + } + + /** + * Return the string that displays the data size. + */ + private String getDataSizeDisplay(long size) { + String formattedOutput = getFormattedBytes(size); + if (!formattedOutput.isEmpty()) { + formattedOutput = " (" + formattedOutput + ")"; + } + return Long.toString(size) + " bytes" + formattedOutput; + } + + /** + * Display storage stats of the specified package. + * + * Usage: get-package-storage-stats [--usr USER_ID] PACKAGE + */ + private int runGetPackageStorageStats() throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + if (!android.content.pm.Flags.getPackageStorageStats()) { + pw.println("Error: get_package_storage_stats flag is not enabled"); + return 1; + } + if (!android.app.usage.Flags.getAppBytesByDataTypeApi()) { + pw.println("Error: get_app_bytes_by_data_type_api flag is not enabled"); + return 1; + } + int userId = UserHandle.USER_CURRENT; + + String opt; + while ((opt = getNextOption()) != null) { + switch (opt) { + case "--user": + userId = UserHandle.parseUserArg(getNextArgRequired()); + break; + default: + pw.println("Error: Unknown option: " + opt); + return 1; + } + } + + final String packageName = getNextArg(); + if (packageName == null) { + pw.println("Error: package name not specified"); + return 1; + } + try { + StorageStatsManager storageStatsManager = + mContext.getSystemService(StorageStatsManager.class); + final int translatedUserId = translateUserId(userId, UserHandle.USER_NULL, + "runGetPackageStorageStats"); + StorageStats stats = + storageStatsManager.queryStatsForPackage(StorageManager.UUID_DEFAULT, + packageName, UserHandle.of(translatedUserId)); + + pw.println("code: " + getDataSizeDisplay(stats.getAppBytes())); + pw.println("data: " + getDataSizeDisplay(stats.getDataBytes())); + pw.println("cache: " + getDataSizeDisplay(stats.getCacheBytes())); + pw.println("apk: " + getDataSizeDisplay(stats.getAppBytesByDataType( + StorageStats.APP_DATA_TYPE_FILE_TYPE_APK))); + pw.println("lib: " + getDataSizeDisplay( + stats.getAppBytesByDataType(StorageStats.APP_DATA_TYPE_LIB))); + pw.println("dm: " + getDataSizeDisplay(stats.getAppBytesByDataType( + StorageStats.APP_DATA_TYPE_FILE_TYPE_DM))); + pw.println("dexopt artifacts: " + getDataSizeDisplay(stats.getAppBytesByDataType( + StorageStats.APP_DATA_TYPE_FILE_TYPE_DEXOPT_ARTIFACT))); + pw.println("current profile : " + getDataSizeDisplay(stats.getAppBytesByDataType( + StorageStats.APP_DATA_TYPE_FILE_TYPE_CURRENT_PROFILE))); + pw.println("reference profile: " + getDataSizeDisplay(stats.getAppBytesByDataType( + StorageStats.APP_DATA_TYPE_FILE_TYPE_REFERENCE_PROFILE))); + pw.println("external cache: " + getDataSizeDisplay(stats.getExternalCacheBytes())); + } catch (Exception e) { + getErrPrintWriter().println("Failed to get storage stats, reason: " + e); + pw.println("Failure [failed to get storage stats], reason: " + e); + return -1; + } + return 0; + } + private int runInstallExisting() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); int userId = UserHandle.USER_CURRENT; @@ -4869,6 +4971,8 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" Displays the component name of the domain verification agent on device."); pw.println(" If the component isn't enabled, an error message will be displayed."); pw.println(" --user: return the agent of the given user (SYSTEM_USER if unspecified)"); + pw.println(" get-package-storage-stats [--user <USER_ID>] <PACKAGE>"); + pw.println(" Return the storage stats for the given app, if present"); pw.println(""); printArtServiceHelp(); pw.println(""); |