Re-pin camera odex/vdex files only if they have changed

Test: Camera is re-pinned after
adb shell cmd package compile -f -m extract
com.google.android.GoogleCamera
adb shell cmd package bg-dexopt-job

Bug: 33168521
Change-Id: I5c5e76d1e40b6d433c9a0beba463c86f79ad437e
This commit is contained in:
Calin Juravle
2017-05-22 17:49:01 -07:00
parent f107a23ff1
commit 31ce3a8a56
3 changed files with 56 additions and 25 deletions

View File

@@ -36,6 +36,7 @@ import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.system.StructStat;
import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.app.ResolverActivity;
@@ -77,10 +78,10 @@ public final class PinnerService extends SystemService {
// If this user's camera app has been updated, update pinned files accordingly.
if (intent.getAction() == Intent.ACTION_PACKAGE_REPLACED) {
Uri packageUri = intent.getData();
ApplicationInfo cameraInfo = getCameraInfo(UserHandle.USER_SYSTEM);
if (cameraInfo.packageName == packageUri.getSchemeSpecificPart()) {
update();
}
String packageName = packageUri.getSchemeSpecificPart();
ArraySet<String> updatedPackages = new ArraySet<>();
updatedPackages.add(packageName);
update(updatedPackages);
}
}
};
@@ -129,10 +130,13 @@ public final class PinnerService extends SystemService {
* Specifically, this only updates camera pinning.
* The other files pinned in onStart will not need to be updated.
*/
public void update() {
Slog.i(TAG, "Updating pinned files.");
mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, UserHandle.USER_SYSTEM, 0)
.sendToTarget();
public void update(ArraySet<String> updatedPackages) {
ApplicationInfo cameraInfo = getCameraInfo(UserHandle.USER_SYSTEM);
if (cameraInfo != null && updatedPackages.contains(cameraInfo.packageName)) {
Slog.i(TAG, "Updating pinned files.");
mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, UserHandle.USER_SYSTEM, 0)
.sendToTarget();
}
}
/**

View File

@@ -177,6 +177,7 @@ public class BackgroundDexOptService extends JobService {
mAbortPostBootUpdate.set(false);
ArraySet<String> updatedPackages = new ArraySet<>();
for (String pkg : pkgs) {
if (mAbortPostBootUpdate.get()) {
// JobScheduler requested an early abort.
@@ -210,11 +211,15 @@ public class BackgroundDexOptService extends JobService {
// 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);
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);
}
@@ -267,6 +272,7 @@ public class BackgroundDexOptService extends JobService {
private int optimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
long lowStorageThreshold, boolean is_for_primary_dex,
ArraySet<String> failedPackageNames) {
ArraySet<String> updatedPackages = new ArraySet<>();
for (String pkg : pkgs) {
int abort_code = abortIdleOptimizations(lowStorageThreshold);
if (abort_code != OPTIMIZE_CONTINUE) {
@@ -286,14 +292,21 @@ public class BackgroundDexOptService extends JobService {
// 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)
: 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);
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) {
@@ -301,6 +314,7 @@ public class BackgroundDexOptService extends JobService {
}
}
}
notifyPinService(updatedPackages);
return OPTIMIZE_PROCESSED;
}
@@ -375,12 +389,6 @@ public class BackgroundDexOptService extends JobService {
result = runIdleOptimization(params, pm, pkgs);
}
PinnerService pinnerService = (PinnerService) LocalServices.getService(PinnerService.class);
if (pinnerService != null) {
Log.i(TAG, "Pinning optimized code");
pinnerService.update();
}
return result;
}
@@ -397,4 +405,12 @@ public class BackgroundDexOptService extends JobService {
}
return false;
}
private void notifyPinService(ArraySet<String> updatedPackages) {
PinnerService pinnerService = LocalServices.getService(PinnerService.class);
if (pinnerService != null) {
Log.i(TAG, "Pinning optimized code " + updatedPackages);
pinnerService.update(updatedPackages);
}
}
}

View File

@@ -8925,9 +8925,20 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean performDexOpt(String packageName,
boolean checkProfiles, int compileReason, boolean force) {
int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
return performDexOptWithStatus(packageName, checkProfiles, compileReason, force) !=
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) {
return performDexOptTraced(packageName, checkProfiles,
getCompilerFilterForReason(compileReason), force);
return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
}
@Override