From 23e044d09dc5002af27df3add4d0537604a10404 Mon Sep 17 00:00:00 2001 From: Mehdi Alizadeh Date: Fri, 23 Aug 2019 14:44:50 -0700 Subject: [PATCH] Rebind to the remote service if AppPrediction is restarted or updated Rebind to the remote AppPredictionService when the service package is updated. Also adds new restart policy flags in AbstractMasterSystemService to be able to keep per-user instances in the cache when service restarts as a result of package data getting cleared, so that we can revive the existing sessions. This would potentially fix the issue for other services that try to keep the sessions over data resets. Bug: 139445447 Test: Reinstall the AiAi package and verify that suggested apps in launcher are getting updated Test: Clear data for Device Personalization Services and verify that suggested apps in launcher are getting updated Test: atest CtsAppPredictionServiceTestCases CtsContentCaptureServiceTestCases Change-Id: Ie835cb159faa9c0718cd63a3045251444b89e505 --- .../AppPredictionManagerService.java | 20 ++- .../AppPredictionPerUserService.java | 34 ++++ .../RemoteAppPredictionService.java | 7 + .../infra/AbstractMasterSystemService.java | 156 ++++++++++++++---- 4 files changed, 185 insertions(+), 32 deletions(-) diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java index d7e68f896c6cb..5844f98730013 100644 --- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java +++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java @@ -23,6 +23,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionSessionId; import android.app.prediction.AppTargetEvent; @@ -61,7 +62,8 @@ public class AppPredictionManagerService extends public AppPredictionManagerService(Context context) { super(context, new FrameworkResourcesServiceNameResolver(context, - com.android.internal.R.string.config_defaultAppPredictionService), null); + com.android.internal.R.string.config_defaultAppPredictionService), null, + PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH); mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class); } @@ -80,6 +82,22 @@ public class AppPredictionManagerService extends getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG); } + @Override // from AbstractMasterSystemService + protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { + final AppPredictionPerUserService service = peekServiceForUserLocked(userId); + if (service != null) { + service.onPackageUpdatedLocked(); + } + } + + @Override // from AbstractMasterSystemService + protected void onServicePackageRestartedLocked(@UserIdInt int userId) { + final AppPredictionPerUserService service = peekServiceForUserLocked(userId); + if (service != null) { + service.onPackageRestartedLocked(); + } + } + @Override protected int getMaximumTemporaryServiceDurationMs() { return MAX_TEMP_SERVICE_DURATION_MS; diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java index 03c4542a50d45..4f49fb7578a13 100644 --- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java +++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java @@ -251,6 +251,40 @@ public class AppPredictionPerUserService extends // Do nothing, eventually the system will bind to the remote service again... } + void onPackageUpdatedLocked() { + if (isDebug()) { + Slog.v(TAG, "onPackageUpdatedLocked()"); + } + destroyAndRebindRemoteService(); + } + + void onPackageRestartedLocked() { + if (isDebug()) { + Slog.v(TAG, "onPackageRestartedLocked()"); + } + destroyAndRebindRemoteService(); + } + + private void destroyAndRebindRemoteService() { + if (mRemoteService == null) { + return; + } + + if (isDebug()) { + Slog.d(TAG, "Destroying the old remote service."); + } + mRemoteService.destroy(); + mRemoteService = null; + + mRemoteService = getRemoteServiceLocked(); + if (mRemoteService != null) { + if (isDebug()) { + Slog.d(TAG, "Rebinding to the new remote service."); + } + mRemoteService.reconnect(); + } + } + /** * Called after the remote service connected, it's used to restore state from a 'zombie' * service (i.e., after it died). diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java index c82e7a012ffff..04e0e7f7102f5 100644 --- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java +++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java @@ -134,6 +134,13 @@ public class RemoteAppPredictionService extends scheduleAsyncRequest((s) -> s.onDestroyPredictionSession(sessionId)); } + /** + * Schedules a request to bind to the remote service. + */ + public void reconnect() { + super.scheduleBind(); + } + /** * Failure callback */ diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index 9782f30d30743..259527a5f2173 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -79,7 +79,7 @@ public abstract class AbstractMasterSystemService> extends SystemService { /** On a package update, does not refresh the per-user service in the cache. */ - public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0; + public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0x00000001; /** * On a package update, removes any existing per-user services in the cache. @@ -87,20 +87,40 @@ public abstract class AbstractMasterSystemServiceThis does not immediately recreate these services. It is assumed they will be recreated * for the next user request. */ - public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1; + public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 0x00000002; /** * On a package update, removes and recreates any existing per-user services in the cache. */ - public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2; + public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 0x00000004; - @IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = { + /** On a package restart, does not refresh the per-user service in the cache. */ + public static final int PACKAGE_RESTART_POLICY_NO_REFRESH = 0x00000010; + + /** + * On a package restart, removes any existing per-user services in the cache. + * + *

This does not immediately recreate these services. It is assumed they will be recreated + * for the next user request. + */ + public static final int PACKAGE_RESTART_POLICY_REFRESH_LAZY = 0x00000020; + + /** + * On a package restart, removes and recreates any existing per-user services in the cache. + */ + public static final int PACKAGE_RESTART_POLICY_REFRESH_EAGER = 0x00000040; + + @IntDef(flag = true, prefix = { "PACKAGE_" }, value = { PACKAGE_UPDATE_POLICY_NO_REFRESH, PACKAGE_UPDATE_POLICY_REFRESH_LAZY, - PACKAGE_UPDATE_POLICY_REFRESH_EAGER + PACKAGE_UPDATE_POLICY_REFRESH_EAGER, + PACKAGE_RESTART_POLICY_NO_REFRESH, + PACKAGE_RESTART_POLICY_REFRESH_LAZY, + PACKAGE_RESTART_POLICY_REFRESH_EAGER }) + @Retention(RetentionPolicy.SOURCE) - public @interface PackageUpdatePolicy {} + public @interface ServicePackagePolicyFlags {} /** * Log tag @@ -153,12 +173,10 @@ public abstract class AbstractMasterSystemService mServicesCache = new SparseArray<>(); /** - * Whether the per-user service should be removed from the cache when its apk is updated. - * - *

One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, - * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}. + * Value that determines whether the per-user service should be removed from the cache when its + * apk is updated or restarted. */ - private final @PackageUpdatePolicy int mPackageUpdatePolicy; + private final @ServicePackagePolicyFlags int mServicePackagePolicyFlags; /** * Name of the service packages whose APK are being updated, keyed by user id. @@ -184,11 +202,11 @@ public abstract class AbstractMasterSystemServiceNOTE: you'll also need to add it to * {@code UserRestrictionsUtils.USER_RESTRICTIONS}. - * @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the - * {@link AbstractPerUserSystemService} is removed from the cache when the service - * package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the - * {@link AbstractPerUserSystemService} is removed from the cache and immediately - * re-added when the service package is updated; when - * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update. + * @param servicePackagePolicyFlags a combination of + * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, + * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, + * {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, + * {@link #PACKAGE_RESTART_POLICY_NO_REFRESH}, + * {@link #PACKAGE_RESTART_POLICY_REFRESH_LAZY} or + * {@link #PACKAGE_RESTART_POLICY_REFRESH_EAGER} */ protected AbstractMasterSystemService(@NonNull Context context, - @Nullable ServiceNameResolver serviceNameResolver, - @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) { + @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty, + @ServicePackagePolicyFlags int servicePackagePolicyFlags) { super(context); - mPackageUpdatePolicy = packageUpdatePolicy; + final int updatePolicyMask = PACKAGE_UPDATE_POLICY_NO_REFRESH + | PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_UPDATE_POLICY_REFRESH_EAGER; + if ((servicePackagePolicyFlags & updatePolicyMask) == 0) { + // If the package update policy is not set, add the default flag + servicePackagePolicyFlags |= PACKAGE_UPDATE_POLICY_REFRESH_LAZY; + } + final int restartPolicyMask = PACKAGE_RESTART_POLICY_NO_REFRESH + | PACKAGE_RESTART_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_EAGER; + if ((servicePackagePolicyFlags & restartPolicyMask) == 0) { + // If the package restart policy is not set, add the default flag + servicePackagePolicyFlags |= PACKAGE_RESTART_POLICY_REFRESH_LAZY; + } + mServicePackagePolicyFlags = servicePackagePolicyFlags; mServiceNameResolver = serviceNameResolver; if (mServiceNameResolver != null) { @@ -605,6 +636,20 @@ public abstract class AbstractMasterSystemService