diff options
| author | 2019-03-19 17:31:37 +0000 | |
|---|---|---|
| committer | 2019-03-19 17:31:37 +0000 | |
| commit | c384395d1a0028f366ba8efbced1429852c6531a (patch) | |
| tree | 769d9a3aa1c0c053123805e528fa705b4903ea0a | |
| parent | 117b108506f3e18d9658176a600038cb66c88d8f (diff) | |
| parent | 234030a0c58828b48d36639e7ca5ad7b144b478a (diff) | |
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.
5 files changed, 128 insertions, 11 deletions
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java index 19e216a72d07..34ced177fed1 100644 --- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java +++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java @@ -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; diff --git a/core/java/android/service/autofill/augmented/IFillCallback.aidl b/core/java/android/service/autofill/augmented/IFillCallback.aidl index 2b0726649759..88baa878f118 100644 --- a/core/java/android/service/autofill/augmented/IFillCallback.aidl +++ b/core/java/android/service/autofill/augmented/IFillCallback.aidl @@ -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(); } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 604cce52d5bd..8f1896d76b9c 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -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]; diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java index eb881def5d67..5c144d3b5752 100644 --- a/core/java/com/android/internal/infra/AbstractRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractRemoteService.java @@ -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; + } + } } /** diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java index aaba1edc73d6..3c17ac35f624 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java @@ -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 |