Merge "Add an API to allow AugmentedAutofillService to request an autofill."

This commit is contained in:
TreeHugger Robot
2020-02-16 08:45:18 +00:00
committed by Android (Google) Code Review
5 changed files with 88 additions and 7 deletions

View File

@@ -10203,6 +10203,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";
}

View File

@@ -3205,6 +3205,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";
}

View File

@@ -89,6 +89,8 @@ public abstract class AugmentedAutofillService extends Service {
private SparseArray<AutofillProxy> 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.
*
* <p> 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.
*
* <p> 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) {

View File

@@ -3366,14 +3366,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();
@@ -3414,5 +3408,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;
}
}
}

View File

@@ -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);
}