OSDN Git Service

resolve merge conflicts of 255b69aca02f to oc-dev-plus-aosp
authorNicolas Geoffray <ngeoffray@google.com>
Fri, 26 May 2017 08:47:18 +0000 (09:47 +0100)
committerNicolas Geoffray <ngeoffray@google.com>
Fri, 26 May 2017 10:03:19 +0000 (11:03 +0100)
Test: I solemnly swear I tested this conflict resolution.
Change-Id: I9caf7542f11b0b322da063a5a08140384eba0ce0

1  2 
core/java/android/content/pm/IPackageManager.aidl
services/core/java/com/android/server/pm/BackgroundDexOptService.java
services/core/java/com/android/server/pm/OtaDexoptService.java
services/core/java/com/android/server/pm/PackageDexOptimizer.java
services/core/java/com/android/server/pm/PackageManagerService.java
services/core/java/com/android/server/pm/PackageManagerShellCommand.java

@@@ -211,15 -208,12 +211,16 @@@ public class BackgroundDexOptService ex
              // 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.
 -            pm.performDexOpt(pkg,
 +            int result = pm.performDexOptWithStatus(pkg,
                      /* checkProfiles */ false,
                      PackageManagerService.REASON_BOOT,
-                     /* force */ false);
+                     /* force */ false,
+                     /* bootComplete */ true);
 +            if (result == PackageDexOptimizer.DEX_OPT_PERFORMED)  {
 +                updatedPackages.add(pkg);
 +            }
          }
 +        notifyPinService(updatedPackages);
          // Ran to completion, so we abandon our timeslice and do not reschedule.
          jobFinished(jobParams, /* reschedule */ false);
      }
  
              // Optimize package if needed. Note that there can be no race between
              // concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
 -            boolean success = is_for_primary_dex
 -                    ? pm.performDexOpt(pkg,
 -                            /* checkProfiles */ true,
 -                            PackageManagerService.REASON_BACKGROUND_DEXOPT,
 -                            /* force */ false,
 -                            /* bootComplete */ true)
 -                    : pm.performDexOptSecondary(pkg,
 -                            PackageManagerService.REASON_BACKGROUND_DEXOPT,
 -                            /* force */ false);
 +            boolean success;
 +            if (is_for_primary_dex) {
 +                int result = pm.performDexOptWithStatus(pkg,
 +                        /* checkProfiles */ true,
 +                        PackageManagerService.REASON_BACKGROUND_DEXOPT,
-                         /* force */ false);
++                        /* force */ false,
++                        /* bootComplete */ true);
 +                success = result != PackageDexOptimizer.DEX_OPT_FAILED;
 +                if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) {
 +                    updatedPackages.add(pkg);
 +                }
 +            } else {
 +                success = pm.performDexOptSecondary(pkg,
 +                        PackageManagerService.REASON_BACKGROUND_DEXOPT,
 +                        /* force */ false);
 +            }
              if (success) {
                  // Dexopt succeeded, remove package from the list of failing ones.
                  synchronized (failedPackageNames) {
@@@ -118,12 -110,21 +119,12 @@@ public class PackageDexOptimizer 
              return DEX_OPT_SKIPPED;
          }
          synchronized (mInstallLock) {
 -            // During boot the system doesn't need to instantiate and obtain a wake lock.
 -            // PowerManager might not be ready, but that doesn't mean that we can't proceed with
 -            // dexopt.
 -            final boolean useLock = mSystemReady;
 -            if (useLock) {
 -                mDexoptWakeLock.setWorkSource(new WorkSource(pkg.applicationInfo.uid));
 -                mDexoptWakeLock.acquire();
 -            }
 +            final long acquireTime = acquireWakeLockLI(pkg.applicationInfo.uid);
              try {
                  return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
-                         targetCompilationFilter, packageStats, isUsedByOtherApps);
+                         targetCompilationFilter, packageStats, isUsedByOtherApps, bootComplete);
              } finally {
 -                if (useLock) {
 -                    mDexoptWakeLock.release();
 -                }
 +                releaseWakeLockLI(acquireTime);
              }
          }
      }
          final boolean profileUpdated = checkForProfileUpdates &&
                  isProfileUpdated(pkg, sharedGid, compilerFilter);
  
 -        // TODO(calin,jeffhao): shared library paths should be adjusted to include previous code
 -        // paths (b/34169257).
 -        String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries);
 +        final String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries);
          // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
-         final int dexoptFlags = getDexFlags(pkg, compilerFilter);
+         final int dexoptFlags = getDexFlags(pkg, compilerFilter, bootComplete);
 +        // Get the dependencies of each split in the package. For each code path in the package,
 +        // this array contains the relative paths of each split it depends on, separated by colons.
 +        String[] splitDependencies = getSplitDependencies(pkg);
  
          int result = DEX_OPT_SKIPPED;
 -        // TODO: Iterate based on dependency hierarchy (currently alphabetically by name)
 -        // (b/37480811).
 -        String basePathCheck = null;
 -        for (String path : paths) {
 +        for (int i = 0; i < paths.size(); i++) {
 +            // Skip paths that have no code.
 +            if ((i == 0 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) ||
 +                    (i != 0 && (pkg.splitFlags[i - 1] & ApplicationInfo.FLAG_HAS_CODE) == 0)) {
 +                continue;
 +            }
 +            // Append shared libraries with split dependencies for this split.
 +            String path = paths.get(i);
 +            String sharedLibrariesPathWithSplits;
 +            if (sharedLibrariesPath != null && splitDependencies[i] != null) {
 +                sharedLibrariesPathWithSplits = sharedLibrariesPath + ":" + splitDependencies[i];
 +            } else {
 +                sharedLibrariesPathWithSplits =
 +                        splitDependencies[i] != null ? splitDependencies[i] : sharedLibrariesPath;
 +            }
              for (String dexCodeIsa : dexCodeInstructionSets) {
                  int newResult = dexOptPath(pkg, path, dexCodeIsa, compilerFilter, profileUpdated,
 -                        sharedLibrariesPath, dexoptFlags, sharedGid, packageStats);
 +                        sharedLibrariesPathWithSplits, dexoptFlags, sharedGid, packageStats);
                  // The end result is:
                  //  - FAILED if any path failed,
                  //  - PERFORMED if at least one path needed compilation,
      @GuardedBy("mInstallLock")
      private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, Set<String> isas,
              String compilerFilter, boolean isUsedByOtherApps) {
-         int dexoptFlags = getDexFlags(info, compilerFilter) | DEXOPT_SECONDARY_DEX;
 +        compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps);
 +        // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
+         // Secondary dex files are currently not compiled at boot.
+         int dexoptFlags = getDexFlags(info, compilerFilter, /* bootComplete */ true)
+                 | DEXOPT_SECONDARY_DEX;
          // Check the app storage and add the appropriate flags.
 -        if (info.dataDir.equals(info.deviceProtectedDataDir)) {
 +        if (info.deviceProtectedDataDir != null &&
 +                FileUtils.contains(info.deviceProtectedDataDir, path)) {
              dexoptFlags |= DEXOPT_STORAGE_DE;
 -        } else if (info.dataDir.equals(info.credentialProtectedDataDir)) {
 +        } else if (info.credentialProtectedDataDir != null &&
 +                FileUtils.contains(info.credentialProtectedDataDir, path)) {
              dexoptFlags |= DEXOPT_STORAGE_CE;
          } else {
              Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
@@@ -2940,10 -2644,43 +2940,9 @@@ public class PackageManagerService exte
              ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
  
              // can downgrade to reader
 +            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
              mSettings.writeLPr();
 -
 -            // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
 -            // early on (before the package manager declares itself as early) because other
 -            // components in the system server might ask for package contexts for these apps.
 -            //
 -            // Note that "onlyCore" in this context means the system is encrypted or encrypting
 -            // (i.e, that the data partition is unavailable).
 -            if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
 -                long start = System.nanoTime();
 -                List<PackageParser.Package> coreApps = new ArrayList<>();
 -                for (PackageParser.Package pkg : mPackages.values()) {
 -                    if (pkg.coreApp) {
 -                        coreApps.add(pkg);
 -                    }
 -                }
 -
 -                int[] stats = performDexOptUpgrade(coreApps, false,
 -                        getCompilerFilterForReason(REASON_CORE_APP), /* bootComplete */ false);
 -
 -                final int elapsedTimeSeconds =
 -                        (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
 -                MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
 -
 -                if (DEBUG_DEXOPT) {
 -                    Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
 -                            stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
 -                }
 -
 -
 -                // TODO: Should we log these stats to tron too ?
 -                // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
 -                // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
 -                // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
 -                // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
 -            }
 -
 +            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
              EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                      SystemClock.uptimeMillis());
  
  
      @Override
      public boolean performDexOpt(String packageName,
-             boolean checkProfiles, int compileReason, boolean force) {
-         return performDexOptWithStatus(packageName, checkProfiles, compileReason, force) !=
-                 PackageDexOptimizer.DEX_OPT_FAILED;
+             boolean checkProfiles, int compileReason, boolean force, boolean bootComplete) {
 -        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
++        int dexoptStatus = performDexOptWithStatus(
++              packageName, checkProfiles, compileReason, force, bootComplete);
++        return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
 +    }
 +
 +    /**
 +     * Perform dexopt on the given package and return one of following result:
 +     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
 +     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
 +     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
 +     */
 +    /* package */ int performDexOptWithStatus(String packageName,
-             boolean checkProfiles, int compileReason, boolean force) {
++            boolean checkProfiles, int compileReason, boolean force, boolean bootComplete) {
 +        return performDexOptTraced(packageName, checkProfiles,
-                 getCompilerFilterForReason(compileReason), force);
+                 getCompilerFilterForReason(compileReason), force, bootComplete);
 -        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
      }
  
      @Override
      public boolean performDexOptMode(String packageName,
-             boolean checkProfiles, String targetCompilerFilter, boolean force) {
+             boolean checkProfiles, String targetCompilerFilter, boolean force,
+             boolean bootComplete) {
 +        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
 +            return false;
 +        }
          int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
-                 targetCompilerFilter, force);
+                 targetCompilerFilter, force, bootComplete);
          return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
      }
  
          if (!deps.isEmpty()) {
              for (PackageParser.Package depPackage : deps) {
                  // TODO: Analyze and investigate if we (should) profile libraries.
 -                // Currently this will do a full compilation of the library by default.
                  pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
                          false /* checkProfiles */,
 -                        getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
 +                        targetCompilerFilter,
                          getOrCreateCompilerPackageStats(depPackage),
-                         true /* isUsedByOtherApps */);
 -                        mDexManager.isUsedByOtherApps(p.packageName),
++                        true /* isUsedByOtherApps */,
+                         bootComplete);
              }
          }
          return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
          synchronized (mInstallLock) {
              Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
  
 -            // Whoever is calling forceDexOpt wants a fully compiled package.
 +            // Whoever is calling forceDexOpt wants a compiled package.
              // Don't use profiles since that may cause compilation to be skipped.
              final int res = performDexOptInternalWithDependenciesLI(pkg,
 -                    false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
 +                    false /* checkProfiles */, getDefaultCompilerFilter(),
-                     true /* force */);
+                     true /* force */,
+                     true /* bootComplete */);
  
              Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
              if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
              // Shared libraries for the package need to be updated.
              synchronized (mPackages) {
                  try {
 -                    updateSharedLibrariesLPw(pkg, null);
 +                    updateSharedLibrariesLPr(pkg, null);
                  } catch (PackageManagerException e) {
 -                    Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage());
 +                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
                  }
              }
 -            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
 -            // Do not run PackageDexOptimizer through the local performDexOpt
 -            // method because `pkg` may not be in `mPackages` yet.
 -            //
 -            // Also, don't fail application installs if the dexopt step fails.
 -            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
 -                    null /* instructionSets */, false /* checkProfiles */,
 -                    getCompilerFilterForReason(REASON_INSTALL),
 -                    getOrCreateCompilerPackageStats(pkg),
 -                    mDexManager.isUsedByOtherApps(pkg.packageName),
 -                    true /* bootComplete */);
 -            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 +
 +            // dexopt can take some time to complete, so, for instant apps, we skip this
 +            // step during installation. Instead, we'll take extra time the first time the
 +            // instant app starts. It's preferred to do it this way to provide continuous
 +            // progress to the user instead of mysteriously blocking somewhere in the
 +            // middle of running an instant app.
 +            if (!instantApp) {
 +                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
 +                // Do not run PackageDexOptimizer through the local performDexOpt
 +                // method because `pkg` may not be in `mPackages` yet.
 +                //
 +                // Also, don't fail application installs if the dexopt step fails.
 +                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
 +                        null /* instructionSets */, false /* checkProfiles */,
 +                        getCompilerFilterForReason(REASON_INSTALL),
 +                        getOrCreateCompilerPackageStats(pkg),
-                         mDexManager.isUsedByOtherApps(pkg.packageName));
++                        mDexManager.isUsedByOtherApps(pkg.packageName),
++                        true /* bootComplete */);
 +                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 +            }
  
              // Notify BackgroundDexOptService that the package has been changed.
              // If this is an update of a package which used to fail to compile,