diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/DexOptHelper.java | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java index 8c33dd935822..f1296e0cd7b0 100644 --- a/services/core/java/com/android/server/pm/DexOptHelper.java +++ b/services/core/java/com/android/server/pm/DexOptHelper.java @@ -29,7 +29,9 @@ import static com.android.server.pm.PackageManagerService.TAG; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter; import static com.android.server.pm.PackageManagerServiceUtils.REMOVE_IF_NULL_PKG; +import android.Manifest; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.AppGlobals; import android.content.Intent; @@ -42,6 +44,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; +import android.provider.DeviceConfig; import android.util.ArraySet; import android.util.Log; import android.util.Slog; @@ -250,10 +253,60 @@ final class DexOptHelper { numberOfPackagesFailed}; } + /** + * Checks if system UI package (typically "com.android.systemui") needs to be re-compiled, and + * compiles it if needed. + */ + private void checkAndDexOptSystemUi() { + Computer snapshot = mPm.snapshotComputer(); + String sysUiPackageName = + mPm.mContext.getString(com.android.internal.R.string.config_systemUi); + AndroidPackage pkg = snapshot.getPackage(sysUiPackageName); + if (pkg == null) { + Log.w(TAG, "System UI package " + sysUiPackageName + " is not found for dexopting"); + return; + } + + boolean useProfileForDexopt = false; + File profileFile = new File(getPrebuildProfilePath(pkg)); + // Copy the profile to the reference profile path if it exists. Installd can only use a + // profile at the reference profile path for dexopt. + if (profileFile.exists()) { + try { + synchronized (mPm.mInstallLock) { + if (mPm.mInstaller.copySystemProfile(profileFile.getAbsolutePath(), + pkg.getUid(), pkg.getPackageName(), + ArtManager.getProfileName(null))) { + useProfileForDexopt = true; + } else { + Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath()); + } + } + } catch (Exception e) { + Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath(), e); + } + } + + // It could also be after mainline update, but we're not introducing a new reason just for + // this special case. + performDexOptTraced(new DexoptOptions(pkg.getPackageName(), REASON_BOOT_AFTER_OTA, + useProfileForDexopt ? "speed-profile" : "speed", null /* splitName */, + 0 /* dexoptFlags */)); + } + + @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) public void performPackageDexOptUpgradeIfNeeded() { PackageManagerServiceUtils.enforceSystemOrRoot( "Only the system can request package update"); + // The default is "true". + if (!"false".equals(DeviceConfig.getProperty("runtime", "dexopt_system_ui_on_boot"))) { + // System UI is important to user experience, so we check it on every boot. It may need + // to be re-compiled after a mainline update or an OTA. + // TODO(b/227310505): Only do this after a mainline update or an OTA. + checkAndDexOptSystemUi(); + } + // We need to re-extract after an OTA. boolean causeUpgrade = mPm.isDeviceUpgrading(); |