Merge "BGDexopt: Have a single run for primary and secondary dexes" am: 39673f91fa am: 181177d87d am: 454f7b59c5 am: fc61fe97a6
am: 0f2c8f5243

Change-Id: I89448d93d7dd1692627846ee788ba0e25881c92d
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 984f22f..c712431 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -281,20 +281,7 @@
         mAbortIdleOptimization.set(false);
 
         long lowStorageThreshold = getLowStorageThreshold(context);
-        // Optimize primary apks.
-        int result = optimizePackages(pm, pkgs, lowStorageThreshold,
-            /*isForPrimaryDex=*/ true);
-        if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
-            return result;
-        }
-        if (supportSecondaryDex()) {
-            result = reconcileSecondaryDexFiles(pm.getDexManager());
-            if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
-                return result;
-            }
-            result = optimizePackages(pm, pkgs, lowStorageThreshold,
-                /*isForPrimaryDex=*/ false);
-        }
+        int result = idleOptimizePackages(pm, pkgs, lowStorageThreshold);
         return result;
     }
 
@@ -342,11 +329,20 @@
         return 0;
     }
 
-    private int optimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
-            long lowStorageThreshold, boolean isForPrimaryDex) {
+    private int idleOptimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
+            long lowStorageThreshold) {
         ArraySet<String> updatedPackages = new ArraySet<>();
 
         try {
+            final boolean supportSecondaryDex = supportSecondaryDex();
+
+            if (supportSecondaryDex) {
+                int result = reconcileSecondaryDexFiles(pm.getDexManager());
+                if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
+                    return result;
+                }
+            }
+
             // Only downgrade apps when space is low on device.
             // Threshold is selected above the lowStorageThreshold so that we can pro-actively clean
             // up disk before user hits the actual lowStorageThreshold.
@@ -359,43 +355,61 @@
                         pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
                 Log.d(TAG, "Unsused Packages " +  String.join(",", unusedPackages));
 
-                for (String pkg : unusedPackages) {
-                    int abortCode = abortIdleOptimizations(/*lowStorageThreshold*/ -1);
-                    if (abortCode != OPTIMIZE_CONTINUE) {
-                        // Should be aborted by the scheduler.
-                        return abortCode;
-                    }
-                    if (downgradePackage(pm, pkg, isForPrimaryDex)) {
-                        updatedPackages.add(pkg);
-                    }
-                }
-
                 if (!unusedPackages.isEmpty()) {
+                    for (String pkg : unusedPackages) {
+                        int abortCode = abortIdleOptimizations(/*lowStorageThreshold*/ -1);
+                        if (abortCode != OPTIMIZE_CONTINUE) {
+                            // Should be aborted by the scheduler.
+                            return abortCode;
+                        }
+                        if (downgradePackage(pm, pkg, /*isForPrimaryDex*/ true)) {
+                            updatedPackages.add(pkg);
+                        }
+                        if (supportSecondaryDex) {
+                            downgradePackage(pm, pkg, /*isForPrimaryDex*/ false);
+                        }
+                    }
+
                     pkgs = new ArraySet<>(pkgs);
                     pkgs.removeAll(unusedPackages);
                 }
             }
 
-            for (String pkg : pkgs) {
-                int abortCode = abortIdleOptimizations(lowStorageThreshold);
-                if (abortCode != OPTIMIZE_CONTINUE) {
-                    // Either aborted by the scheduler or no space left.
-                    return abortCode;
-                }
-
-                boolean dexOptPerformed = optimizePackage(pm, pkg, isForPrimaryDex);
-                if (dexOptPerformed) {
-                    updatedPackages.add(pkg);
-                }
+            int primaryResult = optimizePackages(pm, pkgs, lowStorageThreshold,
+                    /*isForPrimaryDex*/ true, updatedPackages);
+            if (primaryResult != OPTIMIZE_PROCESSED) {
+                return primaryResult;
             }
 
-            return OPTIMIZE_PROCESSED;
+            if (!supportSecondaryDex) {
+                return OPTIMIZE_PROCESSED;
+            }
+
+            int secondaryResult = optimizePackages(pm, pkgs, lowStorageThreshold,
+                    /*isForPrimaryDex*/ false, updatedPackages);
+            return secondaryResult;
         } finally {
             // Always let the pinner service know about changes.
             notifyPinService(updatedPackages);
         }
     }
 
+    private int optimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
+            long lowStorageThreshold, boolean isForPrimaryDex, ArraySet<String> updatedPackages) {
+        for (String pkg : pkgs) {
+            int abortCode = abortIdleOptimizations(lowStorageThreshold);
+            if (abortCode != OPTIMIZE_CONTINUE) {
+                // Either aborted by the scheduler or no space left.
+                return abortCode;
+            }
+
+            boolean dexOptPerformed = optimizePackage(pm, pkg, isForPrimaryDex);
+            if (dexOptPerformed) {
+                updatedPackages.add(pkg);
+            }
+        }
+        return OPTIMIZE_PROCESSED;
+    }
 
     /**
      * Try to downgrade the package to a smaller compilation filter.