Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92aa0dd0 authored by Haiping Yang's avatar Haiping Yang Committed by Android (Google) Code Review
Browse files

Merge "Add dumpsys entry point for package storageStats." into main

parents 6195149f 6bf31f49
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -136,6 +136,18 @@ flag {
    bug: "314815969"
}

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
+104 −0
Original line number Diff line number Diff line
@@ -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("");