From f107a23ff165bbb7f0ae145f9ac85ddca8b43ed7 Mon Sep 17 00:00:00 2001 From: Carmen Jackson Date: Tue, 16 May 2017 10:37:26 -0700 Subject: [PATCH] Re-run pinner service on camera app update and dex optimization. When the camera app updates or the dex files are optimized, the files that have been pinned by the pinner service fall out of date. The next time they're used, they will be paged in like normal. This change un-pins and re-pins the Camera app when the user's camera app updates, as well as when background dex optimization finishes. Bug: 33168521 Test: Manual. Here's a logcat of PinnerService activity while I ran the following commands: $ flashall -w $ adb install -r -d --force-sdk [new camera app].apk Success $ adb root restarting adbd as root $ adb shell cmd package bg-dexopt-job SystemServer: PinnerService SystemServiceManager: Starting com.android.server.PinnerService PinnerService: Starting PinnerService SystemServerTiming: PinnerService took to complete: 2ms PinnerService: Pinned file = /system/framework/arm64/boot-framework.oat PinnerService: Pinned file = /system/framework/arm64/boot-framework.vdex PinnerService: Pinned file = /system/framework/oat/arm64/services.odex PinnerService: Pinned file = /system/framework/oat/arm64/services.vdex PinnerService: Pinned file = /system/framework/arm64/boot.oat PinnerService: Pinned file = /system/framework/arm64/boot.vdex PinnerService: Pinned file = /system/framework/arm64/boot-core-libart.oat PinnerService: Pinned file = /system/framework/arm64/boot-core-libart.vdex PinnerService: Pinned /system/app/GoogleCamera/GoogleCamera.apk PinnerService: Pinned /data/dalvik-cache/arm64/system@app@GoogleCamera@GoogleCamera.apk@classes.dex PinnerService: Updating pinned files. PinnerService: Unpinned file /system/app/GoogleCamera/GoogleCamera.apk PinnerService: Unpinned file /data/dalvik-cache/arm64/system@app@GoogleCamera@GoogleCamera.apk@classes.dex PinnerService: Pinned /data/app/com.google.android.GoogleCamera-vVji3RQcPHS1Lzqh1WjY1g==/base.apk PinnerService: Pinned /data/app/com.google.android.GoogleCamera-vVji3RQcPHS1Lzqh1WjY1g==/oat/arm64/base.odex PinnerService: Updating pinned files. PinnerService: Unpinned file /data/app/com.google.android.GoogleCamera-vVji3RQcPHS1Lzqh1WjY1g==/base.apk PinnerService: Unpinned file /data/app/com.google.android.GoogleCamera-vVji3RQcPHS1Lzqh1WjY1g==/oat/arm64/base.odex PinnerService: Pinned /data/app/com.google.android.GoogleCamera-vVji3RQcPHS1Lzqh1WjY1g==/base.apk PinnerService: Pinned /data/app/com.google.android.GoogleCamera-vVji3RQcPHS1Lzqh1WjY1g==/oat/arm64/base.odex Change-Id: I10d72d6a3d1717773324913362a638f199d49bc9 --- .../com/android/server/PinnerService.java | 42 ++++++++++++++++--- .../server/pm/BackgroundDexOptService.java | 15 ++++++- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java index e3ebf4d3a7ee2..f8baf17664e22 100644 --- a/services/core/java/com/android/server/PinnerService.java +++ b/services/core/java/com/android/server/PinnerService.java @@ -16,12 +16,15 @@ package com.android.server; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Handler; @@ -68,6 +71,19 @@ public final class PinnerService extends SystemService { private PinnerHandler mPinnerHandler = null; + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + // 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(); + } + } + } + }; public PinnerService(Context context) { super(context); @@ -76,6 +92,11 @@ public final class PinnerService extends SystemService { mShouldPinCamera = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerCameraApp); mPinnerHandler = new PinnerHandler(BackgroundThread.get().getLooper()); + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_PACKAGE_REPLACED); + filter.addDataScheme("package"); + mContext.registerReceiver(mBroadcastReceiver, filter); } @Override @@ -85,6 +106,7 @@ public final class PinnerService extends SystemService { } mBinderService = new BinderService(); publishBinderService("pinner", mBinderService); + publishLocalService(PinnerService.class, this); mPinnerHandler.obtainMessage(PinnerHandler.PIN_ONSTART_MSG).sendToTarget(); mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, UserHandle.USER_SYSTEM, 0) @@ -102,6 +124,17 @@ public final class PinnerService extends SystemService { mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, userHandle, 0).sendToTarget(); } + /** + * Update the currently pinned files. + * 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(); + } + /** * Handler for on start pinning message */ @@ -202,13 +235,10 @@ public final class PinnerService extends SystemService { return cameraResolveInfo.activityInfo.applicationInfo; } + /** + * If the camera app is already pinned, unpin and repin it. + */ private boolean pinCamera(int userHandle){ - //we may have already pinned a camera app. If we've pinned this - //camera app, we're done. otherwise, unpin and pin the new app - if (alreadyPinned(userHandle)){ - return true; - } - ApplicationInfo cameraInfo = getCameraInfo(userHandle); if (cameraInfo == null) { return false; diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index d364d17fa764d..484cd4ea84338 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -36,6 +36,8 @@ import android.util.ArraySet; import android.util.Log; import com.android.server.pm.dex.DexManager; +import com.android.server.LocalServices; +import com.android.server.PinnerService; import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; @@ -366,11 +368,20 @@ public class BackgroundDexOptService extends JobService { return false; } + boolean result; if (params.getJobId() == JOB_POST_BOOT_UPDATE) { - return runPostBootUpdate(params, pm, pkgs); + result = runPostBootUpdate(params, pm, pkgs); } else { - return runIdleOptimization(params, pm, pkgs); + 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; } @Override