summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMehdi Alizadeh <mett@google.com>2019-08-23 14:44:50 -0700
committerMehdi Alizadeh <mett@google.com>2019-08-28 20:21:49 +0000
commit23e044d09dc5002af27df3add4d0537604a10404 (patch)
tree9bc433399caaf5f58b83ac495717887af1b35019
parenta58013ae18dbeb87cf3b103d4764428e76a87efe (diff)
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
-rw-r--r--services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java20
-rw-r--r--services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java34
-rw-r--r--services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java7
-rw-r--r--services/core/java/com/android/server/infra/AbstractMasterSystemService.java156
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 d7e68f896c6c..5844f9873001 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 03c4542a50d4..4f49fb7578a1 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 c82e7a012fff..04e0e7f7102f 100644
--- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
+++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
@@ -135,6 +135,13 @@ public class RemoteAppPredictionService extends
}
/**
+ * Schedules a request to bind to the remote service.
+ */
+ public void reconnect() {
+ super.scheduleBind();
+ }
+
+ /**
* Failure callback
*/
public interface RemoteAppPredictionServiceCallbacks
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 9782f30d3074..259527a5f217 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<M extends AbstractMasterSystem
S extends AbstractPerUserSystemService<S, M>> 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 AbstractMasterSystemService<M extends AbstractMasterSystem
* <p>This 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.
+ *
+ * <p>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<M extends AbstractMasterSystem
private final SparseArray<S> mServicesCache = new SparseArray<>();
/**
- * Whether the per-user service should be removed from the cache when its apk is updated.
- *
- * <p>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 AbstractMasterSystemService<M extends AbstractMasterSystem
@Nullable ServiceNameResolver serviceNameResolver,
@Nullable String disallowProperty) {
this(context, serviceNameResolver, disallowProperty,
- /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY);
+ PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_LAZY);
}
/**
- * Full constructor.
+ * Full Constructor.
*
* @param context system context.
* @param serviceNameResolver resolver for
@@ -197,19 +215,32 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
* @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
* disables the service. <b>NOTE: </b> 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) {
@@ -606,6 +637,20 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
}
/**
+ * Called after the package data that provides the service for the given user is cleared.
+ */
+ protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
+ }
+
+ /**
+ * Called after the package that provides the service for the given user is restarted.
+ */
+ protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
+ }
+
+ /**
* Called after the service is removed from the cache.
*/
@SuppressWarnings("unused")
@@ -677,7 +722,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
final int size = mServicesCache.size();
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
pw.print(" Verbose: "); pw.println(realVerbose);
- pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy);
+ pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags);
if (mUpdatingPackageNames != null) {
pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
}
@@ -733,7 +778,12 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
}
mUpdatingPackageNames.put(userId, packageName);
onServicePackageUpdatingLocked(userId);
- if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) {
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being updated");
+ }
+ } else {
if (debug) {
Slog.d(mTag, "Removing service for user " + userId
+ " because package " + activePackageName
@@ -741,18 +791,14 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
}
removeCachedServiceLocked(userId);
- if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) {
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
+ != 0) {
if (debug) {
Slog.d(mTag, "Eagerly recreating service for user "
+ userId);
}
getServiceForUserLocked(userId);
}
- } else {
- if (debug) {
- Slog.d(mTag, "Holding service for user " + userId + " while package "
- + activePackageName + " is being updated");
- }
}
}
}
@@ -804,7 +850,13 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
if (!doit) {
return true;
}
- removeCachedServiceLocked(getChangingUserId());
+ final String action = intent.getAction();
+ final int userId = getChangingUserId();
+ if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
+ handleActiveServiceRestartedLocked(activePackageName, userId);
+ } else {
+ removeCachedServiceLocked(userId);
+ }
} else {
handlePackageUpdateLocked(pkg);
}
@@ -813,6 +865,23 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
return false;
}
+ @Override
+ public void onPackageDataCleared(String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName);
+ final int userId = getChangingUserId();
+ synchronized (mLock) {
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ final ComponentName componentName = service.getServiceComponentName();
+ if (componentName != null) {
+ if (packageName.equals(componentName.getPackageName())) {
+ onServicePackageDataClearedLocked(userId);
+ }
+ }
+ }
+ }
+ }
+
private void handleActiveServiceRemoved(@UserIdInt int userId) {
synchronized (mLock) {
removeCachedServiceLocked(userId);
@@ -824,6 +893,31 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
}
}
+ private void handleActiveServiceRestartedLocked(String activePackageName,
+ @UserIdInt int userId) {
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being restarted");
+ }
+ } else {
+ if (debug) {
+ Slog.d(mTag, "Removing service for user " + userId
+ + " because package " + activePackageName
+ + " is being restarted");
+ }
+ removeCachedServiceLocked(userId);
+
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Eagerly recreating service for user " + userId);
+ }
+ getServiceForUserLocked(userId);
+ }
+ }
+ onServicePackageRestartedLocked(userId);
+ }
+
private String getActiveServicePackageNameLocked() {
final int userId = getChangingUserId();
final S service = peekServiceForUserLocked(userId);