Merge "Rebind to the remote service if AppPrediction is restarted or updated" into qt-qpr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
edafb21d84
@@ -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;
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
@@ -605,6 +636,20 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
||||
if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user