OSDN Git Service

Add a command to print package dexopt status.
authorNarayan Kamath <narayan@google.com>
Mon, 2 May 2016 13:44:31 +0000 (14:44 +0100)
committerNarayan Kamath <narayan@google.com>
Tue, 10 May 2016 08:51:56 +0000 (08:51 +0000)
Can be invoked like so :

$adb shell dumpsys package dexopt
$adb shell dumpsys package dexopt <packageName>

bug: 27494108
Change-Id: Ie91f744aeac772e0e22abc9c805df9290a4e2418

services/core/java/com/android/server/pm/PackageDexOptimizer.java
services/core/java/com/android/server/pm/PackageManagerService.java

index f134e40..89747b5 100644 (file)
@@ -28,6 +28,7 @@ import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.os.InstallerConnection.InstallerException;
+import com.android.internal.util.IndentingPrintWriter;
 
 import java.io.File;
 import java.io.IOException;
@@ -122,6 +123,32 @@ class PackageDexOptimizer {
         return dexoptFlags;
     }
 
+    /**
+     * Dumps the dexopt state of the given package {@code pkg} to the given {@code PrintWriter}.
+     */
+    void dumpDexoptState(IndentingPrintWriter pw, PackageParser.Package pkg) {
+        final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
+        final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
+
+        final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
+
+        for (String instructionSet : dexCodeInstructionSets) {
+             pw.println("Instruction Set: " + instructionSet);
+             pw.increaseIndent();
+             for (String path : paths) {
+                  String status = null;
+                  try {
+                      status = DexFile.getDexFileStatus(path, instructionSet);
+                  } catch (IOException ioe) {
+                      status = "[Exception]: " + ioe.getMessage();
+                  }
+                  pw.println("path: " + path);
+                  pw.println("status: " + status);
+             }
+             pw.decreaseIndent();
+        }
+    }
+
     private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
             String[] targetInstructionSets, boolean checkProfiles, String targetCompilerFilter) {
         final String[] instructionSets = targetInstructionSets != null ?
index d7693b0..96bfe4a 100644 (file)
@@ -17782,6 +17782,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
         public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
         public static final int DUMP_FROZEN = 1 << 19;
+        public static final int DUMP_DEXOPT = 1 << 20;
 
         public static final int OPTION_SHOW_FILTERS = 1 << 0;
 
@@ -17898,6 +17899,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                 pw.println("    write: write current settings now");
                 pw.println("    installs: details about install sessions");
                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
+                pw.println("    dexopt: dump dexopt state");
                 pw.println("    <package.name>: info about given package");
                 return;
             } else if ("--checkin".equals(opt)) {
@@ -18017,6 +18019,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                 dumpState.setDump(DumpState.DUMP_INSTALLS);
             } else if ("frozen".equals(cmd)) {
                 dumpState.setDump(DumpState.DUMP_FROZEN);
+            } else if ("dexopt".equals(cmd)) {
+                dumpState.setDump(DumpState.DUMP_DEXOPT);
             } else if ("write".equals(cmd)) {
                 synchronized (mPackages) {
                     mSettings.writeLPr();
@@ -18374,6 +18378,11 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                 ipw.decreaseIndent();
             }
 
+            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
+                if (dumpState.onTitlePrinted()) pw.println();
+                dumpDexoptStateLPr(pw, packageName);
+            }
+
             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
                 if (dumpState.onTitlePrinted()) pw.println();
                 mSettings.dumpReadMessagesLPr(pw, dumpState);
@@ -18412,6 +18421,32 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
         }
     }
 
+    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
+        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
+        ipw.println();
+        ipw.println("Dexopt state:");
+        ipw.increaseIndent();
+        Collection<PackageParser.Package> packages = null;
+        if (packageName != null) {
+            PackageParser.Package targetPackage = mPackages.get(packageName);
+            if (targetPackage != null) {
+                packages = Collections.singletonList(targetPackage);
+            } else {
+                ipw.println("Unable to find package: " + packageName);
+                return;
+            }
+        } else {
+            packages = mPackages.values();
+        }
+
+        for (PackageParser.Package pkg : packages) {
+            ipw.println("[" + pkg.packageName + "]");
+            ipw.increaseIndent();
+            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
+            ipw.decreaseIndent();
+        }
+    }
+
     private String dumpDomainString(String packageName) {
         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
                 .getList();