Background optimization has flag checkProfiles as true,
performDexOptLI check profile is updated with checkProfiles.
(isProfileUpdated() -> mergeProfiles -> analyze_profiles())
analyze_profiles decides if it is need to compile and clear
the profile or not. But analyze_profiles and profman merge
only based on existing profiles. Eventhough checksum of
application dex was changed, profman only check the profile
can be merge or not.
With below TC, the return value of profman is PROFMAN_BIN_
RETURN_CODE_SKIP_COMPILATION(1). Because current profile
has not enough informations than reference profile.
I think ProcessProfilesInternal should consider change
of dex checksum, If there are mismatch checksum of dex
between profiles and dex, then profman should return with
PROFMAN_BIN_RETURN_CODE_BAD_PROFILES (2).
After that analyze_profiles can reset profiles with
PROFMAN_BIN_RETURN_CODE_BAD_PROFILES.
But profman does not have that implemtation for verify
the profile based on checksum. So, It is need to drop
the profile based on change of application version.
Test: System update
1. Factory Image with system application. (vendor, system app)
2. Use Sample application to generage current profile.
3. BackgroundDexOptService optimize with speed-profile.
4. Use Sample application to generage current profile.
5. There are small size of current profile and large size
of reference profile.
6. System update with application change.
7. Reboot.
8. Next background optimization would be fail permanently.
Bug:
77839992
Change-Id: Iac575ae5906498a59b750df0b281fab01df57b3e
}
/**
+ * Clear the package profile if this was an upgrade and the package
+ * version was updated.
+ */
+ private void maybeClearProfilesForUpgradesLI(
+ @Nullable PackageSetting originalPkgSetting,
+ @NonNull PackageParser.Package currentPkg) {
+ if (originalPkgSetting == null || !isUpgrade()) {
+ return;
+ }
+ if (originalPkgSetting.versionCode == currentPkg.mVersionCode) {
+ return;
+ }
+
+ clearAppProfilesLIF(currentPkg, UserHandle.USER_ALL);
+ if (DEBUG_INSTALL) {
+ Slog.d(TAG, originalPkgSetting.name
+ + " clear profile due to version change "
+ + originalPkgSetting.versionCode + " != "
+ + currentPkg.mVersionCode);
+ }
+ }
+
+ /**
* Traces a package scan.
* @see #scanPackageLI(File, int, int, long, UserHandle)
*/
(forceCollect && canSkipFullPackageVerification(pkg));
collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
+ // Reset profile if the application version is changed
+ maybeClearProfilesForUpgradesLI(pkgSetting, pkg);
+
+ /*
+ * A new system app appeared, but we already had a non-system one of the
+ * same name installed earlier.
+ */
boolean shouldHideSystemApp = false;
// A new application appeared on /system, but, we already have a copy of
// the application installed on /data.