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

Commit c384395d authored by Adam He's avatar Adam He Committed by Android (Google) Code Review
Browse files

Merge changes from topics "aa_fill_ui", "aa_cancellation"

* changes:
  Don't show fill ui if fillrequest times out.
  Implemented CancellationSignal for augmented autofill requests.
parents 117b1085 234030a0
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.graphics.Rect;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -201,18 +202,26 @@ public abstract class AugmentedAutofillService extends Service {
        if (mAutofillProxies == null) {
            mAutofillProxies = new SparseArray<>();
        }

        final ICancellationSignal transport = CancellationSignal.createTransport();
        final CancellationSignal cancellationSignal = CancellationSignal.fromTransport(transport);
        AutofillProxy proxy = mAutofillProxies.get(sessionId);
        if (proxy == null) {
            proxy = new AutofillProxy(sessionId, client, taskId, componentName, focusedId,
                    focusedValue, requestTime, callback);
                    focusedValue, requestTime, callback, cancellationSignal);
            mAutofillProxies.put(sessionId,  proxy);
        } else {
            // TODO(b/123099468): figure out if it's ok to reuse the proxy; add logging
            if (DEBUG) Log.d(TAG, "Reusing proxy for session " + sessionId);
            proxy.update(focusedId, focusedValue, callback);
        }
        // TODO(b/123101711): set cancellation signal
        final CancellationSignal cancellationSignal = null;

        try {
            callback.onCancellable(transport);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }

        onFillRequest(new FillRequest(proxy), cancellationSignal, new FillController(proxy),
                new FillCallback(proxy));
    }
@@ -329,18 +338,21 @@ public abstract class AugmentedAutofillService extends Service {
        @GuardedBy("mLock")
        private FillWindow mFillWindow;

        private CancellationSignal mCancellationSignal;

        private AutofillProxy(int sessionId, @NonNull IBinder client, int taskId,
                @NonNull ComponentName componentName, @NonNull AutofillId focusedId,
                @Nullable AutofillValue focusedValue, long requestTime,
                @NonNull IFillCallback callback) {
                @NonNull IFillCallback callback, @NonNull CancellationSignal cancellationSignal) {
            mSessionId = sessionId;
            mClient = IAugmentedAutofillManagerClient.Stub.asInterface(client);
            mCallback = callback;
            this.taskId = taskId;
            this.componentName = componentName;
            this.mFocusedId = focusedId;
            this.mFocusedValue = focusedValue;
            this.mFirstRequestTime = requestTime;
            mFocusedId = focusedId;
            mFocusedValue = focusedValue;
            mFirstRequestTime = requestTime;
            mCancellationSignal = cancellationSignal;
            // TODO(b/123099468): linkToDeath
        }

@@ -394,6 +406,12 @@ public abstract class AugmentedAutofillService extends Service {

        public void requestShowFillUi(int width, int height, Rect anchorBounds,
                IAutofillWindowPresenter presenter) throws RemoteException {
            if (mCancellationSignal.isCanceled()) {
                if (VERBOSE) {
                    Log.v(TAG, "requestShowFillUi() not showing because request is cancelled");
                }
                return;
            }
            mClient.requestShowFillUi(mSessionId, mFocusedId, width, height, anchorBounds,
                    presenter);
        }
@@ -408,8 +426,13 @@ public abstract class AugmentedAutofillService extends Service {
                mFocusedId = focusedId;
                mFocusedValue = focusedValue;
                if (mCallback != null) {
                    // TODO(b/123101711): we need to check whether the previous request was
                    //  completed or not, and if not, cancel it first.
                    try {
                        if (mCallback.isCompleted()) {
                            mCallback.cancel();
                        }
                    } catch (RemoteException e) {
                        Slog.e(TAG, "failed to check current pending request status", e);
                    }
                    Slog.d(TAG, "mCallback is updated.");
                }
                mCallback = callback;
+3 −2
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ import android.os.ICancellationSignal;
 * @hide
 */
interface IFillCallback {
    // TODO(b/123101711): add cancellation (after we have CTS tests, so we can test it)
//    void onCancellable(in ICancellationSignal cancellation);
    void onCancellable(in ICancellationSignal cancellation);
    void onSuccess();
    boolean isCompleted();
    void cancel();
}
+4 −0
Original line number Diff line number Diff line
@@ -3146,6 +3146,10 @@ public final class AutofillManager {
            if (afm == null) return null;

            final View view = afm.getClient().autofillClientFindViewByAutofillIdTraversal(id);
            if (view == null) {
                Log.w(TAG, "getViewCoordinates(" + id + "): could not find view");
                return null;
            }
            final Rect windowVisibleDisplayFrame = new Rect();
            view.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame);
            final int[] location = new int[2];
+6 −0
Original line number Diff line number Diff line
@@ -577,6 +577,12 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
        protected boolean isFinal() {
            return false;
        }

        protected boolean isRequestCompleted() {
            synchronized (mLock) {
                return mCompleted;
            }
        }
    }

    /**
+83 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.autofill;

import static com.android.server.autofill.Helper.sDebug;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -26,6 +28,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.os.SystemClock;
import android.service.autofill.augmented.AugmentedAutofillService;
@@ -142,6 +145,16 @@ final class RemoteAugmentedAutofillService
        scheduleAsyncRequest((s) -> s.onDestroyAllFillWindowsRequest());
    }

    private void dispatchOnFillTimeout(@NonNull ICancellationSignal cancellation) {
        mHandler.post(() -> {
            try {
                cancellation.cancel();
            } catch (RemoteException e) {
                Slog.w(mTag, "Error calling cancellation signal: " + e);
            }
        });
    }

    // TODO(b/123100811): inline into PendingAutofillRequest if it doesn't have any other subclass
    private abstract static class MyPendingRequest
            extends PendingRequest<RemoteAugmentedAutofillService, IAugmentedAutofillService> {
@@ -161,6 +174,7 @@ final class RemoteAugmentedAutofillService
        private final int mTaskId;
        private final long mRequestTime = SystemClock.elapsedRealtime();
        private final @NonNull IFillCallback mCallback;
        private ICancellationSignal mCancellation;

        protected PendingAutofillRequest(@NonNull RemoteAugmentedAutofillService service,
                int sessionId, @NonNull IAutoFillManagerClient client, int taskId,
@@ -178,11 +192,55 @@ final class RemoteAugmentedAutofillService
                    if (!finish()) return;
                    // NOTE: so far we don't need notify RemoteAugmentedAutofillServiceCallbacks
                }

                @Override
                public void onCancellable(ICancellationSignal cancellation) {
                    synchronized (mLock) {
                        final boolean cancelled;
                        synchronized (mLock) {
                            mCancellation = cancellation;
                            cancelled = isCancelledLocked();
                        }
                        if (cancelled) {
                            try {
                                cancellation.cancel();
                            } catch (RemoteException e) {
                                Slog.e(mTag, "Error requesting a cancellation", e);
                            }
                        }
                    }
                }

                @Override
                public boolean isCompleted() {
                    return isRequestCompleted();
                }

                @Override
                public void cancel() {
                    synchronized (mLock) {
                        final boolean cancelled = isCancelledLocked();
                        final ICancellationSignal cancellation = mCancellation;
                        if (!cancelled) {
                            try {
                                cancellation.cancel();
                            } catch (RemoteException e) {
                                Slog.e(mTag, "Error requesting a cancellation", e);
                            }
                        }
                    }
                }
            };
        }

        @Override
        public void run() {
            synchronized (mLock) {
                if (isCancelledLocked()) {
                    if (sDebug) Slog.d(mTag, "run() called after canceled");
                    return;
                }
            }
            final RemoteAugmentedAutofillService remoteService = getService();
            if (remoteService == null) return;

@@ -215,8 +273,33 @@ final class RemoteAugmentedAutofillService
            Slog.w(TAG, "PendingAutofillRequest timed out (" + remoteService.mRequestTimeoutMs
                    + "ms) for " + remoteService);
            // NOTE: so far we don't need notify RemoteAugmentedAutofillServiceCallbacks
            final ICancellationSignal cancellation;
            synchronized (mLock) {
                cancellation = mCancellation;
            }
            if (cancellation != null) {
                remoteService.dispatchOnFillTimeout(cancellation);
            }
            finish();
        }

        @Override
        public boolean cancel() {
            if (!super.cancel()) return false;

            final ICancellationSignal cancellation;
            synchronized (mLock) {
                cancellation = mCancellation;
            }
            if (cancellation != null) {
                try {
                    cancellation.cancel();
                } catch (RemoteException e) {
                    Slog.e(mTag, "Error cancelling a fill request", e);
                }
            }
            return true;
        }
    }

    public interface RemoteAugmentedAutofillServiceCallbacks