OSDN Git Service

Re-run pinner service on camera app update and dex optimization.
authorCarmen Jackson <carmenjackson@google.com>
Tue, 16 May 2017 17:37:26 +0000 (10:37 -0700)
committerCalin Juravle <calin@google.com>
Tue, 23 May 2017 00:09:49 +0000 (17:09 -0700)
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

services/core/java/com/android/server/PinnerService.java
services/core/java/com/android/server/pm/BackgroundDexOptService.java

index e3ebf4d..f8baf17 100644 (file)
 
 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)
@@ -103,6 +125,17 @@ public final class PinnerService extends SystemService {
     }
 
     /**
+     * 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
      */
     private void handlePinOnStart() {
@@ -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;
index d364d17..484cd4e 100644 (file)
@@ -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