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

Commit 05675bc0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Made AbstractRemoteService.getRemoteRequestMillis() optional."

parents 1f6b9850 81299d0d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -519,7 +519,7 @@ public final class PermissionControllerManager {
        }

        @Override
        public void scheduleRequest(@NonNull PendingRequest<RemoteService,
        public void scheduleRequest(@NonNull BasePendingRequest<RemoteService,
                IPermissionController> pendingRequest) {
            super.scheduleRequest(pendingRequest);
        }
+2 −2
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ public abstract class AbstractMultiplePendingRequestsRemoteService<S

    private final int mInitialCapacity;

    protected ArrayList<PendingRequest<S, I>> mPendingRequests;
    protected ArrayList<BasePendingRequest<S, I>> mPendingRequests;

    public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
            @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
@@ -85,7 +85,7 @@ public abstract class AbstractMultiplePendingRequestsRemoteService<S
    }

    @Override // from AbstractRemoteService
    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S, I> pendingRequest) {
    void handlePendingRequestWhileUnBound(@NonNull BasePendingRequest<S, I> pendingRequest) {
        if (mPendingRequests == null) {
            mPendingRequests = new ArrayList<>(mInitialCapacity);
        }
+99 −56
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
    private long mNextUnbind;

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

    /**
     * Callback called when the service dies.
@@ -183,8 +183,15 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I

    /**
     * Defines how long after we make a remote request to a fill service we timeout.
     *
     * <p>Just need to be overridden by subclasses that uses sync {@link PendingRequest}s.
     *
     * @throws UnsupportedOperationException if called when not overridden.
     *
     */
    protected abstract long getRemoteRequestMillis();
    protected long getRemoteRequestMillis() {
        throw new UnsupportedOperationException("not implemented by " + getClass());
    }

    /**
     * Gets the currently registered service interface or {@code null} if the service is not
@@ -243,7 +250,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
        pw.append(prefix).append(tab).append("destroyed=")
                .append(String.valueOf(mDestroyed)).println();
        pw.append(prefix).append(tab).append("numUnfinishedRequests=")
                .append(String.valueOf(mUnfinishedRequests.size()));
                .append(String.valueOf(mUnfinishedRequests.size())).println();
        final boolean bound = handleIsBound();
        pw.append(prefix).append(tab).append("bound=")
                .append(String.valueOf(bound));
@@ -260,9 +267,13 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
        pw.println();
        pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
        pw.append(prefix).append("idleTimeout=")
            .append(Long.toString(idleTimeout / 1000)).append("s").println();
        pw.append(prefix).append("requestTimeout=")
            .append(Long.toString(getRemoteRequestMillis() / 1000)).append("s").println();
            .append(Long.toString(idleTimeout / 1000)).append("s\n");
        pw.append(prefix).append("requestTimeout=");
        try {
            pw.append(Long.toString(getRemoteRequestMillis() / 1000)).append("s\n");
        } catch (UnsupportedOperationException e) {
            pw.append("not supported\n");
        }
        pw.println();
    }

@@ -273,7 +284,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
     * othewise it will trigger a {@link PendingRequest#onTimeout(AbstractRemoteService)} if the
     * service doesn't respond.
     */
    protected void scheduleRequest(@NonNull PendingRequest<S, I> pendingRequest) {
    protected void scheduleRequest(@NonNull BasePendingRequest<S, I> pendingRequest) {
        mHandler.sendMessage(obtainMessage(
                AbstractRemoteService::handlePendingRequest, this, pendingRequest));
    }
@@ -283,12 +294,12 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
     *
     * @param finshedRequest The request that is finished
     */
    void finishRequest(@NonNull PendingRequest<S, I> finshedRequest) {
    void finishRequest(@NonNull BasePendingRequest<S, I> finshedRequest) {
        mHandler.sendMessage(
                obtainMessage(AbstractRemoteService::handleFinishRequest, this, finshedRequest));
    }

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

        if (mUnfinishedRequests.isEmpty()) {
@@ -361,7 +372,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
     * Handles a request, either processing it right now when bound, or saving it to be handled when
     * bound.
     */
    protected final void handlePendingRequest(@NonNull PendingRequest<S, I> pendingRequest) {
    protected final void handlePendingRequest(@NonNull BasePendingRequest<S, I> pendingRequest) {
        if (checkIfDestroyed() || mCompleted) return;

        if (!handleIsBound()) {
@@ -384,7 +395,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
    /**
     * Defines what to do with a request that arrives while not bound to the service.
     */
    abstract void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S, I> pendingRequest);
    abstract void handlePendingRequestWhileUnBound(
            @NonNull BasePendingRequest<S, I> pendingRequest);

    private boolean handleIsBound() {
        return mService != null;
@@ -471,50 +483,28 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
    /**
     * Base class for the requests serviced by the remote service.
     *
     * <p><b>NOTE: </b> this class is typically used when the service needs to use a callback to
     * communicate back with the system server. For cases where that's not needed, you should use
     * {@link AbstractRemoteService#scheduleAsyncRequest(AsyncRequest)} instead.
     * <p><b>NOTE: </b> this class is not used directly, you should either override
     * {@link com.android.internal.infra.AbstractRemoteService.PendingRequest} for sync requests, or
     * use {@link AbstractRemoteService#scheduleAsyncRequest(AsyncRequest)} for async requests.
     *
     * @param <S> the remote service class
     * @param <I> the interface of the binder service
     */
    public abstract static class PendingRequest<S extends AbstractRemoteService<S, I>,
    public abstract static class BasePendingRequest<S extends AbstractRemoteService<S, I>,
            I extends IInterface> implements Runnable {
        protected final String mTag = getClass().getSimpleName();
        protected final Object mLock = new Object();

        private final WeakReference<S> mWeakService;
        private final Runnable mTimeoutTrigger;
        private final Handler mServiceHandler;
        final WeakReference<S> mWeakService;

        @GuardedBy("mLock")
        private boolean mCancelled;
        boolean mCancelled;

        @GuardedBy("mLock")
        private boolean mCompleted;
        boolean mCompleted;

        protected PendingRequest(@NonNull S service) {
        BasePendingRequest(@NonNull S service) {
            mWeakService = new WeakReference<>(service);
            mServiceHandler = service.mHandler;
            mTimeoutTrigger = () -> {
                synchronized (mLock) {
                    if (mCancelled) {
                        return;
                    }
                    mCompleted = true;
                }

                final S remoteService = mWeakService.get();
                if (remoteService != null) {
                    // TODO(b/117779333): we should probably ignore it if service is destroyed.
                    Slog.w(mTag, "timed out after " + service.getRemoteRequestMillis() + " ms");
                    onTimeout(remoteService);
                } else {
                    Slog.w(mTag, "timed out (no service)");
                }
            };
            mServiceHandler.postAtTime(mTimeoutTrigger,
                    SystemClock.uptimeMillis() + service.getRemoteRequestMillis());
        }

        /**
@@ -543,10 +533,13 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
                service.finishRequest(this);
            }

            mServiceHandler.removeCallbacks(mTimeoutTrigger);
            onFinished();

            return true;
        }

        void onFinished() { }

        /**
         * Checks whether this request was cancelled.
         */
@@ -568,15 +561,11 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
                mCancelled = true;
            }

            mServiceHandler.removeCallbacks(mTimeoutTrigger);
            onCancel();
            return true;
        }

        /**
         * Called by the self-destruct timeout when the remote service didn't reply to the
         * request on time.
         */
        protected abstract void onTimeout(S remoteService);
        void onCancel() {}

        /**
         * Checks whether this request leads to a final state where no other requests can be made.
@@ -586,6 +575,67 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
        }
    }

    /**
     * Base class for the requests serviced by the remote service.
     *
     * <p><b>NOTE: </b> this class is typically used when the service needs to use a callback to
     * communicate back with the system server. For cases where that's not needed, you should use
     * {@link AbstractRemoteService#scheduleAsyncRequest(AsyncRequest)} instead.
     *
     * <p><b>NOTE: </b> you must override {@link AbstractRemoteService#getRemoteRequestMillis()},
     * otherwise the constructor will throw an {@link UnsupportedOperationException}.
     *
     * @param <S> the remote service class
     * @param <I> the interface of the binder service
     */
    public abstract static class PendingRequest<S extends AbstractRemoteService<S, I>,
            I extends IInterface> extends BasePendingRequest<S, I> {

        private final Runnable mTimeoutTrigger;
        private final Handler mServiceHandler;

        protected PendingRequest(S service) {
            super(service);
            mServiceHandler = service.mHandler;

            mTimeoutTrigger = () -> {
                synchronized (mLock) {
                    if (mCancelled) {
                        return;
                    }
                    mCompleted = true;
                }

                final S remoteService = mWeakService.get();
                if (remoteService != null) {
                    // TODO(b/117779333): we should probably ignore it if service is destroyed.
                    Slog.w(mTag, "timed out after " + service.getRemoteRequestMillis() + " ms");
                    onTimeout(remoteService);
                } else {
                    Slog.w(mTag, "timed out (no service)");
                }
            };
            mServiceHandler.postAtTime(mTimeoutTrigger,
                    SystemClock.uptimeMillis() + service.getRemoteRequestMillis());
        }

        @Override
        final void onFinished() {
            mServiceHandler.removeCallbacks(mTimeoutTrigger);
        }

        @Override
        final void onCancel() {
            mServiceHandler.removeCallbacks(mTimeoutTrigger);
        }

        /**
         * Called by the self-destruct timeout when the remote service didn't reply to the
         * request on time.
         */
        protected abstract void onTimeout(S remoteService);
    }

    /**
     * Represents a request that does not expect a callback from the remote service.
     *
@@ -600,7 +650,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
    }

    private static final class MyAsyncPendingRequest<S extends AbstractRemoteService<S, I>,
            I extends IInterface> extends PendingRequest<S, I> {
            I extends IInterface> extends BasePendingRequest<S, I> {
        private static final String TAG = MyAsyncPendingRequest.class.getSimpleName();

        private final AsyncRequest<I> mRequest;
@@ -623,12 +673,5 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
                finish();
            }
        }

        @Override
        protected void onTimeout(S remoteService) {
            // TODO(b/117779333): should not happen because we called finish() on run(), although
            // currently it might be called if the service is destroyed while showing it.
            Slog.w(TAG, "AsyncPending requested timed out");
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ public abstract class AbstractSinglePendingRequestRemoteService<S
        extends AbstractSinglePendingRequestRemoteService<S, I>, I extends IInterface>
        extends AbstractRemoteService<S, I> {

    protected PendingRequest<S, I> mPendingRequest;
    protected BasePendingRequest<S, I> mPendingRequest;

    public AbstractSinglePendingRequestRemoteService(@NonNull Context context,
            @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
@@ -51,7 +51,7 @@ public abstract class AbstractSinglePendingRequestRemoteService<S
    @Override // from AbstractRemoteService
    void handlePendingRequests() {
        if (mPendingRequest != null) {
            final PendingRequest<S, I> pendingRequest = mPendingRequest;
            final BasePendingRequest<S, I> pendingRequest = mPendingRequest;
            mPendingRequest = null;
            handlePendingRequest(pendingRequest);
        }
@@ -73,7 +73,7 @@ public abstract class AbstractSinglePendingRequestRemoteService<S
    }

    @Override // from AbstractRemoteService
    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S, I> pendingRequest) {
    void handlePendingRequestWhileUnBound(@NonNull BasePendingRequest<S, I> pendingRequest) {
        if (mPendingRequest != null) {
            if (mVerbose) {
                Slog.v(mTag, "handlePendingRequestWhileUnBound(): cancelling " + mPendingRequest
+0 −9
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.os.IBinder;
import android.service.contentcapture.IContentCaptureService;
import android.service.contentcapture.IContentCaptureServiceCallback;
import android.service.contentcapture.SnapshotData;
import android.text.format.DateUtils;
import android.util.Slog;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.UserDataRemovalRequest;
@@ -38,8 +37,6 @@ final class RemoteContentCaptureService
        extends AbstractMultiplePendingRequestsRemoteService<RemoteContentCaptureService,
        IContentCaptureService> {

    private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS;

    private final IBinder mServerCallback;

    RemoteContentCaptureService(Context context, String serviceInterface,
@@ -65,12 +62,6 @@ final class RemoteContentCaptureService
        return PERMANENT_BOUND_TIMEOUT_MS;
    }

    @Override // from AbstractRemoteService
    protected long getRemoteRequestMillis() {
        // TODO(b/111276913): read from Settings so it can be changed in the field
        return TIMEOUT_REMOTE_REQUEST_MILLIS;
    }

    @Override // from RemoteService
    protected void handleOnConnectedStateChanged(boolean state) {
        if (state && getTimeoutIdleBindMillis() != PERMANENT_BOUND_TIMEOUT_MS) {