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

Commit 883ff1a6 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Automatically unbind for AbstractRemoteService

No need for services to think about unbinding anymore. Now the
AbstractRemoteService counts how many requests are not yet finished and
once the number of unfinished requests drops to zero, schedules an
unbind.

Bug: 117779333
Test: - Started settings which makes many calls to
        PermissionControllerManager. Saw the automatic unbind to eventually
        happen.
      - atest CtsContentCaptureServiceTestCases (with content capture
        enabled and with content capture disabled)
      - atest CtsAutoFillServiceTestCases (4 tests out of WebViewActivityTest fail without and with this change)
Change-Id: Ief2f3512df5a1c55694c0c6b449079a49089bcde
parent d01084eb
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.internal.annotations.GuardedBy;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;

/**
 * Base class representing a remote service.
@@ -93,6 +94,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
    // Used just for debugging purposes (on dump)
    private long mNextUnbind;

    /** Requests that have been scheduled, but that are not finished yet */
    private final ArrayList<PendingRequest<S, I>> mUnfinishedRequests = new ArrayList<>();

    /**
     * Callback called when the service dies.
     *
@@ -229,6 +233,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
                .append(mComponentName.flattenToString()).println();
        pw.append(prefix).append(tab).append("destroyed=")
                .append(String.valueOf(mDestroyed)).println();
        pw.append(prefix).append(tab).append("numUnfinishedRequests=")
                .append(String.valueOf(mUnfinishedRequests.size()));
        final boolean bound = handleIsBound();
        pw.append(prefix).append(tab).append("bound=")
                .append(String.valueOf(bound));
@@ -257,15 +263,30 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
     * <p>This request must be responded by the service somehow (typically using a callback),
     * othewise it will trigger a {@link PendingRequest#onTimeout(AbstractRemoteService)} if the
     * service doesn't respond.
     *
     * <p><b>NOTE: </b>this request is responsible for calling {@link #scheduleUnbind()}.
     */
    protected void scheduleRequest(@NonNull PendingRequest<S, I> pendingRequest) {
        cancelScheduledUnbind();
        mHandler.sendMessage(obtainMessage(
                AbstractRemoteService::handlePendingRequest, this, pendingRequest));
    }

    /**
     * Marks a pendingRequest as finished.
     *
     * @param finshedRequest The request that is finished
     */
    void finishRequest(@NonNull PendingRequest<S, I> finshedRequest) {
        mHandler.sendMessage(
                obtainMessage(AbstractRemoteService::handleFinishRequest, this, finshedRequest));
    }

    private void handleFinishRequest(@NonNull PendingRequest<S, I> finshedRequest) {
        mUnfinishedRequests.remove(finshedRequest);

        if (mUnfinishedRequests.isEmpty()) {
            scheduleUnbind();
        }
    }

    /**
     * Schedules an async request.
     *
@@ -273,7 +294,6 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
     * a simple {@link Runnable}.
     */
    protected void scheduleAsyncRequest(@NonNull AsyncRequest<I> request) {
        scheduleUnbind();
        // TODO(b/117779333): fix generics below
        @SuppressWarnings({"unchecked", "rawtypes"})
        final MyAsyncPendingRequest<S, I> asyncRequest = new MyAsyncPendingRequest(this, request);
@@ -341,6 +361,10 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
            handleEnsureBound();
        } else {
            if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);

            mUnfinishedRequests.add(pendingRequest);
            cancelScheduledUnbind();

            pendingRequest.run();
            if (pendingRequest.isFinal()) {
                mCompleted = true;
@@ -504,6 +528,12 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
                }
                mCompleted = true;
            }

            S service = mWeakService.get();
            if (service != null) {
                service.finishRequest(this);
            }

            mServiceHandler.removeCallbacks(mTimeoutTrigger);
            return true;
        }
+0 −3
Original line number Diff line number Diff line
@@ -139,9 +139,6 @@ final class RemoteFillService
        if (mPendingRequest == pendingRequest) {
            mPendingRequest = null;
        }
        if (mPendingRequest == null) {
            scheduleUnbind();
        }
        return true;
    }