Merge changes I2ef3737f,If080281f
am: bb3de35e5f

Change-Id: Ibe1af669d200057f1d91142299055694b55b5660
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 6d8b811..2fd2521 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -546,12 +546,13 @@
         for (String classPathElement : classPathElements) {
             // System server is fully AOTed and never profiled
             // for profile guided compilation.
-            // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
+            String systemServerFilter = SystemProperties.get(
+                    "dalvik.vm.systemservercompilerfilter", "speed");
 
             int dexoptNeeded;
             try {
                 dexoptNeeded = DexFile.getDexOptNeeded(
-                    classPathElement, instructionSet, "speed",
+                    classPathElement, instructionSet, systemServerFilter,
                     false /* newProfile */, false /* downgrade */);
             } catch (FileNotFoundException ignored) {
                 // Do not add to the classpath.
@@ -570,7 +571,7 @@
                 final String packageName = "*";
                 final String outputPath = null;
                 final int dexFlags = 0;
-                final String compilerFilter = "speed";
+                final String compilerFilter = systemServerFilter;
                 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
                 final String seInfo = null;
                 try {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index a43f8af..60d7c95 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -321,6 +321,10 @@
                 mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName),
                 true /* bootComplete */);
 
+        mPackageManagerService.getDexManager().dexoptSecondaryDex(pkg.packageName,
+                getCompilerFilterForReason(compilationReason),
+                false /* force */,
+                false /* compileOnlySharedDex */);
         return commands;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index da1df78..1934b79 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9392,24 +9392,39 @@
             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
             // trade-off worth doing to save boot time work.
-            int dexOptStatus = performDexOptTraced(pkg.packageName,
+            int primaryDexOptStaus = performDexOptTraced(pkg.packageName,
                     false /* checkProfiles */,
                     compilerFilter,
                     false /* force */,
                     bootComplete);
-            switch (dexOptStatus) {
-                case PackageDexOptimizer.DEX_OPT_PERFORMED:
-                    numberOfPackagesOptimized++;
-                    break;
-                case PackageDexOptimizer.DEX_OPT_SKIPPED:
-                    numberOfPackagesSkipped++;
-                    break;
-                case PackageDexOptimizer.DEX_OPT_FAILED:
-                    numberOfPackagesFailed++;
-                    break;
-                default:
-                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
-                    break;
+
+            boolean secondaryDexOptStatus = true;
+            if (pkg.isSystemApp()) {
+                // Only dexopt shared secondary dex files belonging to system apps to not slow down
+                // too much boot after an OTA.
+                secondaryDexOptStatus = mDexManager.dexoptSecondaryDex(pkg.packageName,
+                        compilerFilter,
+                        false /* force */,
+                        true /* compileOnlySharedDex */);
+            }
+
+            if (secondaryDexOptStatus) {
+                switch (primaryDexOptStaus) {
+                    case PackageDexOptimizer.DEX_OPT_PERFORMED:
+                        numberOfPackagesOptimized++;
+                        break;
+                    case PackageDexOptimizer.DEX_OPT_SKIPPED:
+                        numberOfPackagesSkipped++;
+                        break;
+                    case PackageDexOptimizer.DEX_OPT_FAILED:
+                        numberOfPackagesFailed++;
+                        break;
+                    default:
+                        Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
+                        break;
+                }
+            } else {
+                numberOfPackagesFailed++;
             }
         }
 
@@ -9611,8 +9626,8 @@
         } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
             return false;
         }
-        mDexManager.reconcileSecondaryDexFiles(packageName);
-        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
+        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force,
+                /* compileOnlySharedDex*/ false);
     }
 
     public boolean performDexOptSecondary(String packageName, int compileReason,
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index be50eee..db2d30f 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -307,7 +307,7 @@
     public boolean dexoptSecondaryDex(String packageName, int compilerReason, boolean force) {
         return dexoptSecondaryDex(packageName,
                 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(compilerReason),
-                force);
+                force, /* compileOnlySharedDex */ false);
     }
 
     /**
@@ -315,7 +315,8 @@
      * @return true if all secondary dex files were processed successfully (compiled or skipped
      *         because they don't need to be compiled)..
      */
-    public boolean dexoptSecondaryDex(String packageName, String compilerFilter, boolean force) {
+    public boolean dexoptSecondaryDex(String packageName, String compilerFilter, boolean force,
+            boolean compileOnlySharedDex) {
         // Select the dex optimizer based on the force parameter.
         // Forced compilation is done through ForcedUpdatePackageDexOptimizer which will adjust
         // the necessary dexopt flags to make sure that compilation is not skipped. This avoid
@@ -337,6 +338,9 @@
         for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
             String dexPath = entry.getKey();
             DexUseInfo dexUseInfo = entry.getValue();
+            if (compileOnlySharedDex && !dexUseInfo.isUsedByOtherApps()) {
+                continue;
+            }
             PackageInfo pkg = null;
             try {
                 pkg = mPackageManager.getPackageInfo(packageName, /*flags*/0,