Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92bb6f9a authored by Mehdi Alizadeh's avatar Mehdi Alizadeh Committed by android-build-merger
Browse files

Merge "Rebind to the remote service if AppPrediction is restarted or updated" into qt-qpr1-dev

am: edafb21d

Change-Id: I27bcca7460cc6207391e00f7afd13d9dfb425d2e
parents 2f9d78a8 edafb21d
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -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;
+34 −0
Original line number Diff line number Diff line
@@ -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).
+7 −0
Original line number Diff line number Diff line
@@ -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
     */
+125 −31
Original line number Diff line number Diff line
@@ -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);