From 0fd5641dd7dd526e2694a30ab73f972b62b8f20d Mon Sep 17 00:00:00 2001 From: Feng Cao Date: Thu, 13 Feb 2020 19:58:30 -0800 Subject: [PATCH] Add an API to allow AugmentedAutofillService to request an autofill. Test: manual verification Bug: 149531989 Change-Id: I3b7ade5fb57da344379378b4c50e67b4cbad213c --- api/system-current.txt | 1 + api/test-current.txt | 1 + .../augmented/AugmentedAutofillService.java | 42 +++++++++++++++++ .../view/autofill/AutofillManager.java | 45 ++++++++++++++++--- .../IAugmentedAutofillManagerClient.aidl | 6 +++ 5 files changed, 88 insertions(+), 7 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index 55460bbfefd5d..1de1c8900a6c0 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10187,6 +10187,7 @@ package android.service.autofill.augmented { method public void onConnected(); method public void onDisconnected(); method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback); + method public final boolean requestAutofill(@NonNull android.content.ComponentName, @NonNull android.view.autofill.AutofillId); field public static final String SERVICE_INTERFACE = "android.service.autofill.augmented.AugmentedAutofillService"; } diff --git a/api/test-current.txt b/api/test-current.txt index 4c8bb0290caef..66f877057b3a0 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -3188,6 +3188,7 @@ package android.service.autofill.augmented { method public void onConnected(); method public void onDisconnected(); method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback); + method public final boolean requestAutofill(@NonNull android.content.ComponentName, @NonNull android.view.autofill.AutofillId); field public static final String SERVICE_INTERFACE = "android.service.autofill.augmented.AugmentedAutofillService"; } diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java index 79852d3c0fcad..672b501bbc414 100644 --- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java +++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java @@ -89,6 +89,8 @@ public abstract class AugmentedAutofillService extends Service { private SparseArray mAutofillProxies; + private AutofillProxy mAutofillProxyForLastRequest; + // Used for metrics / debug only private ComponentName mServiceComponentName; @@ -157,6 +159,38 @@ public abstract class AugmentedAutofillService extends Service { public void onConnected() { } + /** + * The child class of the service can call this method to initiate an Autofill flow. + * + *

The request would be respected only if the previous augmented autofill request was + * made for the same {@code activityComponent} and {@code autofillId}, and the field is + * currently on focus. + * + *

The request would start a new autofill flow. It doesn't guarantee that the + * {@link AutofillManager} will proceed with the request. + * + * @param activityComponent the client component for which the autofill is requested for + * @param autofillId the client field id for which the autofill is requested for + * @return true if the request makes the {@link AutofillManager} start a new Autofill flow, + * false otherwise. + */ + public final boolean requestAutofill(@NonNull ComponentName activityComponent, + @NonNull AutofillId autofillId) { + // TODO(b/149531989): revisit this. The request should start a new autofill session + // rather than reusing the existing session. + final AutofillProxy proxy = mAutofillProxyForLastRequest; + if (proxy == null || !proxy.mComponentName.equals(activityComponent) + || !proxy.mFocusedId.equals(autofillId)) { + return false; + } + try { + return proxy.requestAutofill(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + return false; + } + /** * Asks the service to handle an "augmented" autofill request. * @@ -241,6 +275,7 @@ public abstract class AugmentedAutofillService extends Service { } catch (RemoteException e) { e.rethrowFromSystemServer(); } + mAutofillProxyForLastRequest = proxy; onFillRequest(new FillRequest(proxy, inlineSuggestionsRequest), cancellationSignal, new FillController(proxy), new FillCallback(proxy)); } @@ -268,6 +303,7 @@ public abstract class AugmentedAutofillService extends Service { proxy.destroy(); } mAutofillProxies.clear(); + mAutofillProxyForLastRequest = null; } } @@ -287,6 +323,7 @@ public abstract class AugmentedAutofillService extends Service { } } mAutofillProxies = null; + mAutofillProxyForLastRequest = null; } @Override @@ -481,6 +518,11 @@ public abstract class AugmentedAutofillService extends Service { mClient.requestHideFillUi(mSessionId, mFocusedId); } + + private boolean requestAutofill() throws RemoteException { + return mClient.requestAutofill(mSessionId, mFocusedId); + } + private void update(@NonNull AutofillId focusedId, @NonNull AutofillValue focusedValue, @NonNull IFillCallback callback, @NonNull CancellationSignal cancellationSignal) { synchronized (mLock) { diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index c159f89cf2ac5..734556d720a9d 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -3363,14 +3363,8 @@ public final class AutofillManager { final AutofillManager afm = mAfm.get(); if (afm == null) return null; - final AutofillClient client = afm.getClient(); - if (client == null) { - Log.w(TAG, "getViewCoordinates(" + id + "): no autofill client"); - return null; - } - final View view = client.autofillClientFindViewByAutofillIdTraversal(id); + final View view = getView(afm, id); if (view == null) { - Log.w(TAG, "getViewCoordinates(" + id + "): could not find view"); return null; } final Rect windowVisibleDisplayFrame = new Rect(); @@ -3411,5 +3405,42 @@ public final class AutofillManager { afm.post(() -> afm.requestHideFillUi(id, false)); } } + + @Override + public boolean requestAutofill(int sessionId, AutofillId id) { + final AutofillManager afm = mAfm.get(); + if (afm == null || afm.mSessionId != sessionId) { + if (sDebug) { + Slog.d(TAG, "Autofill not available or sessionId doesn't match"); + } + return false; + } + final View view = getView(afm, id); + if (view == null || !view.isFocused()) { + if (sDebug) { + Slog.d(TAG, "View not available or is not on focus"); + } + return false; + } + if (sVerbose) { + Log.v(TAG, "requestAutofill() by AugmentedAutofillService."); + } + afm.post(() -> afm.requestAutofill(view)); + return true; + } + + @Nullable + private View getView(@NonNull AutofillManager afm, @NonNull AutofillId id) { + final AutofillClient client = afm.getClient(); + if (client == null) { + Log.w(TAG, "getView(" + id + "): no autofill client"); + return null; + } + View view = client.autofillClientFindViewByAutofillIdTraversal(id); + if (view == null) { + Log.w(TAG, "getView(" + id + "): could not find view"); + } + return view; + } } } diff --git a/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl b/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl index 140507c80ed02..03054dfdc7eab 100644 --- a/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl +++ b/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl @@ -50,4 +50,10 @@ interface IAugmentedAutofillManagerClient { * Requests hiding the fill UI. */ void requestHideFillUi(int sessionId, in AutofillId id); + + /** + * Requests to start a new autofill flow. Returns true if the autofill request is made to + * {@link AutofillManager#requestAutofill(View)}. + */ + boolean requestAutofill(int sessionId, in AutofillId id); }