Merge "Add support for multiple fill contexts" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
41200eac71
@@ -37052,8 +37052,10 @@ package android.service.autofill {
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public void onConnected();
|
||||
method public void onDisconnected();
|
||||
method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
|
||||
method public void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public abstract deprecated void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
|
||||
method public abstract deprecated void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
|
||||
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
|
||||
field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
|
||||
}
|
||||
@@ -37078,6 +37080,25 @@ package android.service.autofill {
|
||||
method public void onSuccess(android.service.autofill.FillResponse);
|
||||
}
|
||||
|
||||
public final class FillContext implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getRequestId();
|
||||
method public android.app.assist.AssistStructure getStructure();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
|
||||
}
|
||||
|
||||
public final class FillRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public int getFlags();
|
||||
method public int getId();
|
||||
method public android.app.assist.AssistStructure getStructure();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillRequest> CREATOR;
|
||||
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
}
|
||||
|
||||
public final class FillResponse implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
@@ -37089,7 +37110,8 @@ package android.service.autofill {
|
||||
method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
|
||||
method public android.service.autofill.FillResponse build();
|
||||
method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
|
||||
method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
|
||||
method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
|
||||
method public deprecated android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
|
||||
method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
|
||||
}
|
||||
|
||||
@@ -37118,6 +37140,14 @@ package android.service.autofill {
|
||||
method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
|
||||
}
|
||||
|
||||
public final class SaveRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public java.util.List<android.service.autofill.FillContext> getFillContexts();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveRequest> CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.service.carrier {
|
||||
@@ -47813,7 +47843,7 @@ package android.view.autofill {
|
||||
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
|
||||
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
|
||||
field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
|
||||
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
field public static final deprecated int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
}
|
||||
|
||||
public static abstract class AutofillManager.AutofillCallback {
|
||||
|
||||
@@ -40169,8 +40169,10 @@ package android.service.autofill {
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public void onConnected();
|
||||
method public void onDisconnected();
|
||||
method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
|
||||
method public void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public abstract deprecated void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
|
||||
method public abstract deprecated void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
|
||||
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
|
||||
field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
|
||||
}
|
||||
@@ -40195,6 +40197,25 @@ package android.service.autofill {
|
||||
method public void onSuccess(android.service.autofill.FillResponse);
|
||||
}
|
||||
|
||||
public final class FillContext implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getRequestId();
|
||||
method public android.app.assist.AssistStructure getStructure();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
|
||||
}
|
||||
|
||||
public final class FillRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public int getFlags();
|
||||
method public int getId();
|
||||
method public android.app.assist.AssistStructure getStructure();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillRequest> CREATOR;
|
||||
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
}
|
||||
|
||||
public final class FillResponse implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
@@ -40206,7 +40227,8 @@ package android.service.autofill {
|
||||
method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
|
||||
method public android.service.autofill.FillResponse build();
|
||||
method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
|
||||
method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
|
||||
method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
|
||||
method public deprecated android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
|
||||
method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
|
||||
}
|
||||
|
||||
@@ -40235,6 +40257,14 @@ package android.service.autofill {
|
||||
method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
|
||||
}
|
||||
|
||||
public final class SaveRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public java.util.List<android.service.autofill.FillContext> getFillContexts();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveRequest> CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.service.carrier {
|
||||
@@ -51397,7 +51427,7 @@ package android.view.autofill {
|
||||
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
|
||||
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
|
||||
field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
|
||||
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
field public static final deprecated int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
}
|
||||
|
||||
public static abstract class AutofillManager.AutofillCallback {
|
||||
|
||||
@@ -37205,8 +37205,10 @@ package android.service.autofill {
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public void onConnected();
|
||||
method public void onDisconnected();
|
||||
method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
|
||||
method public void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public abstract deprecated void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
|
||||
method public void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
|
||||
method public abstract deprecated void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
|
||||
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
|
||||
field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
|
||||
}
|
||||
@@ -37231,6 +37233,25 @@ package android.service.autofill {
|
||||
method public void onSuccess(android.service.autofill.FillResponse);
|
||||
}
|
||||
|
||||
public final class FillContext implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getRequestId();
|
||||
method public android.app.assist.AssistStructure getStructure();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
|
||||
}
|
||||
|
||||
public final class FillRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public int getFlags();
|
||||
method public int getId();
|
||||
method public android.app.assist.AssistStructure getStructure();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillRequest> CREATOR;
|
||||
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
}
|
||||
|
||||
public final class FillResponse implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
@@ -37242,7 +37263,8 @@ package android.service.autofill {
|
||||
method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
|
||||
method public android.service.autofill.FillResponse build();
|
||||
method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
|
||||
method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
|
||||
method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
|
||||
method public deprecated android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
|
||||
method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
|
||||
}
|
||||
|
||||
@@ -37271,6 +37293,14 @@ package android.service.autofill {
|
||||
method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
|
||||
}
|
||||
|
||||
public final class SaveRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public java.util.List<android.service.autofill.FillContext> getFillContexts();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveRequest> CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.service.carrier {
|
||||
@@ -48191,7 +48221,7 @@ package android.view.autofill {
|
||||
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
|
||||
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
|
||||
field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
|
||||
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
field public static final deprecated int FLAG_MANUAL_REQUEST = 1; // 0x1
|
||||
}
|
||||
|
||||
public static abstract class AutofillManager.AutofillCallback {
|
||||
|
||||
@@ -34,6 +34,8 @@ import android.view.autofill.AutofillManager;
|
||||
|
||||
import com.android.internal.os.SomeArgs;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the
|
||||
//life-cycle (and how state could be maintained on server-side) is well documented.
|
||||
|
||||
@@ -103,24 +105,22 @@ public abstract class AutofillService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFillRequest(AssistStructure structure, Bundle extras,
|
||||
IFillCallback callback, int flags) {
|
||||
public void onFillRequest(FillRequest request, IFillCallback callback) {
|
||||
ICancellationSignal transport = CancellationSignal.createTransport();
|
||||
try {
|
||||
callback.onCancellable(transport);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
mHandlerCaller.obtainMessageIIOOOO(MSG_ON_FILL_REQUEST, flags, UNUSED_ARG, structure,
|
||||
CancellationSignal.fromTransport(transport), extras, callback)
|
||||
mHandlerCaller.obtainMessageOOO(MSG_ON_FILL_REQUEST, request,
|
||||
CancellationSignal.fromTransport(transport), callback)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveRequest(AssistStructure structure, Bundle extras,
|
||||
ISaveCallback callback) {
|
||||
mHandlerCaller.obtainMessageOOO(MSG_ON_SAVE_REQUEST, structure,
|
||||
extras, callback).sendToTarget();
|
||||
public void onSaveRequest(SaveRequest request, ISaveCallback callback) {
|
||||
mHandlerCaller.obtainMessageOO(MSG_ON_SAVE_REQUEST, request,
|
||||
callback).sendToTarget();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -131,23 +131,20 @@ public abstract class AutofillService extends Service {
|
||||
break;
|
||||
} case MSG_ON_FILL_REQUEST: {
|
||||
final SomeArgs args = (SomeArgs) msg.obj;
|
||||
final AssistStructure structure = (AssistStructure) args.arg1;
|
||||
final FillRequest request = (FillRequest) args.arg1;
|
||||
final CancellationSignal cancellation = (CancellationSignal) args.arg2;
|
||||
final Bundle extras = (Bundle) args.arg3;
|
||||
final IFillCallback callback = (IFillCallback) args.arg4;
|
||||
final FillCallback fillCallback = new FillCallback(callback);
|
||||
final int flags = msg.arg1;
|
||||
final IFillCallback callback = (IFillCallback) args.arg3;
|
||||
final FillCallback fillCallback = new FillCallback(callback, request.getId());
|
||||
args.recycle();
|
||||
onFillRequest(structure, extras, flags, cancellation, fillCallback);
|
||||
onFillRequest(request, cancellation, fillCallback);
|
||||
break;
|
||||
} case MSG_ON_SAVE_REQUEST: {
|
||||
final SomeArgs args = (SomeArgs) msg.obj;
|
||||
final AssistStructure structure = (AssistStructure) args.arg1;
|
||||
final Bundle extras = (Bundle) args.arg2;
|
||||
final ISaveCallback callback = (ISaveCallback) args.arg3;
|
||||
final SaveRequest request = (SaveRequest) args.arg1;
|
||||
final ISaveCallback callback = (ISaveCallback) args.arg2;
|
||||
final SaveCallback saveCallback = new SaveCallback(callback);
|
||||
args.recycle();
|
||||
onSaveRequest(structure, extras, saveCallback);
|
||||
onSaveRequest(request, saveCallback);
|
||||
break;
|
||||
} case MSG_DISCONNECT: {
|
||||
onDisconnected();
|
||||
@@ -189,6 +186,28 @@ public abstract class AutofillService extends Service {
|
||||
public void onConnected() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the Android system do decide if an {@link Activity} can be autofilled by the
|
||||
* service.
|
||||
*
|
||||
* <p>Service must call one of the {@link FillCallback} methods (like
|
||||
* {@link FillCallback#onSuccess(FillResponse)}
|
||||
* or {@link FillCallback#onFailure(CharSequence)})
|
||||
* to notify the result of the request.
|
||||
*
|
||||
* @param request the {@link FillRequest request} to handle.
|
||||
* See {@link FillResponse} for examples of multiple-sections requests.
|
||||
* @param cancellationSignal signal for observing cancellation requests. The system will use
|
||||
* this to notify you that the fill result is no longer needed and you should stop
|
||||
* handling this fill request in order to save resources.
|
||||
* @param callback object used to notify the result of the request.
|
||||
*/
|
||||
public void onFillRequest(@NonNull FillRequest request,
|
||||
@NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback) {
|
||||
onFillRequest(request.getStructure(), request.getClientState(), request.getFlags(),
|
||||
cancellationSignal, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the Android system do decide if an {@link Activity} can be autofilled by the
|
||||
* service.
|
||||
@@ -211,10 +230,28 @@ public abstract class AutofillService extends Service {
|
||||
* handling this fill request in order to save resources.
|
||||
* @param callback object used to notify the result of the request.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
|
||||
int flags, @NonNull CancellationSignal cancellationSignal,
|
||||
@NonNull FillCallback callback);
|
||||
|
||||
/**
|
||||
* Called when user requests service to save the fields of an {@link Activity}.
|
||||
*
|
||||
* <p>Service must call one of the {@link SaveCallback} methods (like
|
||||
* {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
|
||||
* to notify the result of the request.
|
||||
*
|
||||
* @param request the {@link SaveRequest request} to handle.
|
||||
* See {@link FillResponse} for examples of multiple-sections requests.
|
||||
* @param callback object used to notify the result of the request.
|
||||
*/
|
||||
public void onSaveRequest(@NonNull SaveRequest request, @NonNull SaveCallback callback) {
|
||||
List<FillContext> contexts = request.getFillContexts();
|
||||
onSaveRequest(contexts.get(contexts.size() - 1).getStructure(),
|
||||
request.getClientState(), callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when user requests service to save the fields of an {@link Activity}.
|
||||
*
|
||||
@@ -231,6 +268,7 @@ public abstract class AutofillService extends Service {
|
||||
* See {@link FillResponse} for examples of multiple-sections requests.
|
||||
* @param callback object used to notify the result of the request.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
|
||||
@NonNull SaveCallback callback);
|
||||
|
||||
|
||||
@@ -27,11 +27,13 @@ import android.os.RemoteException;
|
||||
*/
|
||||
public final class FillCallback {
|
||||
private final IFillCallback mCallback;
|
||||
private final int mRequestId;
|
||||
private boolean mCalled;
|
||||
|
||||
/** @hide */
|
||||
public FillCallback(IFillCallback callback) {
|
||||
public FillCallback(IFillCallback callback, int requestId) {
|
||||
mCallback = callback;
|
||||
mRequestId = requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +49,7 @@ public final class FillCallback {
|
||||
assertNotCalled();
|
||||
mCalled = true;
|
||||
try {
|
||||
mCallback.onSuccess(response);
|
||||
mCallback.onSuccess(response, mRequestId);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
|
||||
96
core/java/android/service/autofill/FillContext.java
Normal file
96
core/java/android/service/autofill/FillContext.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.assist.AssistStructure;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* This class represents a context for each fill request made via {@link
|
||||
* AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)}.
|
||||
* It contains a snapshot of the UI state, the view ids that were returned by
|
||||
* the {@link AutofillService autofill service} as both required to trigger a save
|
||||
* and optional that can be saved, and the id of the corresponding {@link
|
||||
* FillRequest}.
|
||||
* <p>
|
||||
* This context allows you to inspect the values for the interesting views
|
||||
* in the context they appeared. Also a reference to the corresponding fill
|
||||
* request is useful to store meta-data in the client state bundle passed
|
||||
* to {@link FillResponse.Builder#setClientState(Bundle)} to avoid interpreting
|
||||
* the UI state again while saving.
|
||||
*/
|
||||
public final class FillContext implements Parcelable {
|
||||
private final int mRequestId;
|
||||
private final @NonNull AssistStructure mStructure;
|
||||
|
||||
/** @hide */
|
||||
public FillContext(int requestId, @NonNull AssistStructure structure) {
|
||||
mRequestId = requestId;
|
||||
mStructure = structure;
|
||||
}
|
||||
|
||||
private FillContext(Parcel parcel) {
|
||||
this(parcel.readInt(), parcel.readParcelable(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of the {@link FillRequest fill request} this context
|
||||
* corresponds to. This is useful to associate your custom client
|
||||
* state with every request to avoid reinterpreting the UI when saving
|
||||
* user data.
|
||||
*
|
||||
* @return The request id.
|
||||
*/
|
||||
public int getRequestId() {
|
||||
return mRequestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The screen content.
|
||||
*/
|
||||
public AssistStructure getStructure() {
|
||||
return mStructure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeInt(mRequestId);
|
||||
parcel.writeParcelable(mStructure, flags);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<FillContext> CREATOR =
|
||||
new Parcelable.Creator<FillContext>() {
|
||||
@Override
|
||||
public FillContext createFromParcel(Parcel parcel) {
|
||||
return new FillContext(parcel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FillContext[] newArray(int size) {
|
||||
return new FillContext[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
19
core/java/android/service/autofill/FillRequest.aidl
Normal file
19
core/java/android/service/autofill/FillRequest.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2017, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
parcelable FillRequest;
|
||||
144
core/java/android/service/autofill/FillRequest.java
Normal file
144
core/java/android/service/autofill/FillRequest.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.assist.AssistStructure;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* This class represents a request to an {@link AutofillService autofill provider}
|
||||
* to interpret the screen and provide information to the system which views are
|
||||
* interesting for saving and what are the possible ways to fill the inputs on
|
||||
* the screen if applicable.
|
||||
*
|
||||
* @see AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)
|
||||
*/
|
||||
public final class FillRequest implements Parcelable {
|
||||
private static AtomicInteger sIdCounter = new AtomicInteger();
|
||||
|
||||
/**
|
||||
* Indicates autofill was explicitly requested by the user.
|
||||
*/
|
||||
public static final int FLAG_MANUAL_REQUEST = 0x1;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(
|
||||
flag = true,
|
||||
value = {FLAG_MANUAL_REQUEST})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface RequestFlags{}
|
||||
|
||||
private final int mId;
|
||||
private final @RequestFlags int mFlags;
|
||||
private final @NonNull AssistStructure mStructure;
|
||||
private final @Nullable Bundle mClientState;
|
||||
|
||||
/** @hide */
|
||||
public FillRequest(@NonNull AssistStructure structure,
|
||||
@Nullable Bundle clientState, @RequestFlags int flags) {
|
||||
this(sIdCounter.incrementAndGet(), structure, clientState, flags);
|
||||
}
|
||||
|
||||
private FillRequest(@NonNull Parcel parcel) {
|
||||
mId = parcel.readInt();
|
||||
mStructure = parcel.readParcelable(null);
|
||||
mClientState = parcel.readBundle();
|
||||
mFlags = parcel.readInt();
|
||||
}
|
||||
|
||||
private FillRequest(int id, @NonNull AssistStructure structure,
|
||||
@Nullable Bundle clientState, @RequestFlags int flags) {
|
||||
mId = id;
|
||||
mFlags = Preconditions.checkFlagsArgument(flags, FLAG_MANUAL_REQUEST);
|
||||
mStructure = Preconditions.checkNotNull(structure, "structure");
|
||||
mClientState = clientState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The unique id of this request.
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The flags associated with this request.
|
||||
*
|
||||
* @see #FLAG_MANUAL_REQUEST
|
||||
*/
|
||||
public @RequestFlags int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The structure capturing the UI state.
|
||||
*/
|
||||
public @NonNull AssistStructure getStructure() {
|
||||
return mStructure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extra client state returned from the last {@link
|
||||
* AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)
|
||||
* fill request}.
|
||||
* <p>
|
||||
* Once a {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)
|
||||
* save request} is made the client state is cleared.
|
||||
*
|
||||
* @return The client state.
|
||||
*/
|
||||
public @Nullable Bundle getClientState() {
|
||||
return mClientState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeInt(mId);
|
||||
parcel.writeParcelable(mStructure, flags);
|
||||
parcel.writeBundle(mClientState);
|
||||
parcel.writeInt(mFlags);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<FillRequest> CREATOR =
|
||||
new Parcelable.Creator<FillRequest>() {
|
||||
@Override
|
||||
public FillRequest createFromParcel(Parcel parcel) {
|
||||
return new FillRequest(parcel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FillRequest[] newArray(int size) {
|
||||
return new FillRequest[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -132,25 +132,25 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public final class FillResponse implements Parcelable {
|
||||
|
||||
private final ArrayList<Dataset> mDatasets;
|
||||
private final SaveInfo mSaveInfo;
|
||||
private final Bundle mExtras;
|
||||
private final RemoteViews mPresentation;
|
||||
private final IntentSender mAuthentication;
|
||||
private AutofillId[] mAuthenticationIds;
|
||||
private final @Nullable ArrayList<Dataset> mDatasets;
|
||||
private final @Nullable SaveInfo mSaveInfo;
|
||||
private final @Nullable Bundle mClientState;
|
||||
private final @Nullable RemoteViews mPresentation;
|
||||
private final @Nullable IntentSender mAuthentication;
|
||||
private final @Nullable AutofillId[] mAuthenticationIds;
|
||||
|
||||
private FillResponse(@NonNull Builder builder) {
|
||||
mDatasets = builder.mDatasets;
|
||||
mSaveInfo = builder.mSaveInfo;
|
||||
mExtras = builder.mExtras;
|
||||
mClientState = builder.mCLientState;
|
||||
mPresentation = builder.mPresentation;
|
||||
mAuthentication = builder.mAuthentication;
|
||||
mAuthenticationIds = builder.mAuthenticationIds;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public @Nullable Bundle getExtras() {
|
||||
return mExtras;
|
||||
public @Nullable Bundle getClientState() {
|
||||
return mClientState;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -185,7 +185,7 @@ public final class FillResponse implements Parcelable {
|
||||
public static final class Builder {
|
||||
private ArrayList<Dataset> mDatasets;
|
||||
private SaveInfo mSaveInfo;
|
||||
private Bundle mExtras;
|
||||
private Bundle mCLientState;
|
||||
private RemoteViews mPresentation;
|
||||
private IntentSender mAuthentication;
|
||||
private AutofillId[] mAuthenticationIds;
|
||||
@@ -289,23 +289,35 @@ public final class FillResponse implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Builder setExtras(@Nullable Bundle extras) {
|
||||
throwIfDestroyed();
|
||||
mCLientState = extras;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a {@link Bundle} that will be passed to subsequent APIs that
|
||||
* Sets a {@link Bundle state} that will be passed to subsequent APIs that
|
||||
* manipulate this response. For example, they are passed to subsequent
|
||||
* calls to {@link AutofillService#onFillRequest(
|
||||
* android.app.assist.AssistStructure, Bundle, int,
|
||||
* android.os.CancellationSignal, FillCallback)} and {@link AutofillService#onSaveRequest(
|
||||
* android.app.assist.AssistStructure, Bundle, SaveCallback)}.
|
||||
* android.app.assist.AssistStructure, Bundle, SaveCallback)}. You can use
|
||||
* this to store intermediate state that is persistent across multiple
|
||||
* fill requests and the subsequent save request.
|
||||
*
|
||||
* <p>If this method is called on multiple {@link FillResponse} objects for the same
|
||||
* activity, just the latest bundle is passed back to the service.
|
||||
*
|
||||
* @param extras The response extras.
|
||||
* <p>Once a {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)
|
||||
* save request} is made the client state is cleared.
|
||||
*
|
||||
* @param clientState The custom client state.
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setExtras(Bundle extras) {
|
||||
public Builder setClientState(@Nullable Bundle clientState) {
|
||||
throwIfDestroyed();
|
||||
mExtras = extras;
|
||||
mCLientState = clientState;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -344,7 +356,7 @@ public final class FillResponse implements Parcelable {
|
||||
return new StringBuilder(
|
||||
"FillResponse: [datasets=").append(mDatasets)
|
||||
.append(", saveInfo=").append(mSaveInfo)
|
||||
.append(", hasExtras=").append(mExtras != null)
|
||||
.append(", clientState=").append(mClientState != null)
|
||||
.append(", hasPresentation=").append(mPresentation != null)
|
||||
.append(", hasAuthentication=").append(mAuthentication != null)
|
||||
.append(", authenticationSize=").append(mAuthenticationIds != null
|
||||
@@ -365,7 +377,7 @@ public final class FillResponse implements Parcelable {
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeTypedArrayList(mDatasets, flags);
|
||||
parcel.writeParcelable(mSaveInfo, flags);
|
||||
parcel.writeParcelable(mExtras, flags);
|
||||
parcel.writeParcelable(mClientState, flags);
|
||||
parcel.writeParcelableArray(mAuthenticationIds, flags);
|
||||
parcel.writeParcelable(mAuthentication, flags);
|
||||
parcel.writeParcelable(mPresentation, flags);
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
import android.app.assist.AssistStructure;
|
||||
import android.os.Bundle;
|
||||
import android.service.autofill.FillRequest;
|
||||
import android.service.autofill.IFillCallback;
|
||||
import android.service.autofill.ISaveCallback;
|
||||
import android.service.autofill.SaveRequest;
|
||||
import com.android.internal.os.IResultReceiver;
|
||||
|
||||
/**
|
||||
@@ -29,8 +29,6 @@ import com.android.internal.os.IResultReceiver;
|
||||
*/
|
||||
oneway interface IAutoFillService {
|
||||
void onConnectedStateChanged(boolean connected);
|
||||
void onFillRequest(in AssistStructure structure, in Bundle extras,
|
||||
in IFillCallback callback, int flags);
|
||||
void onSaveRequest(in AssistStructure structure, in Bundle extras,
|
||||
in ISaveCallback callback);
|
||||
void onFillRequest(in FillRequest request, in IFillCallback callback);
|
||||
void onSaveRequest(in SaveRequest request, in ISaveCallback callback);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,6 @@ import android.service.autofill.FillResponse;
|
||||
*/
|
||||
interface IFillCallback {
|
||||
void onCancellable(in ICancellationSignal cancellation);
|
||||
void onSuccess(in FillResponse response);
|
||||
void onSuccess(in FillResponse response, int requestId);
|
||||
void onFailure(CharSequence message);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,19 @@ public final class SaveInfo implements Parcelable {
|
||||
*/
|
||||
public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 0x10;
|
||||
|
||||
private final int mType;
|
||||
/** @hide */
|
||||
@IntDef(
|
||||
flag = true,
|
||||
value = {
|
||||
SAVE_DATA_TYPE_GENERIC,
|
||||
SAVE_DATA_TYPE_PASSWORD,
|
||||
SAVE_DATA_TYPE_ADDRESS,
|
||||
SAVE_DATA_TYPE_CREDIT_CARD,
|
||||
SAVE_DATA_TYPE_EMAIL_ADDRESS})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface SaveDataType{}
|
||||
|
||||
private final @SaveDataType int mType;
|
||||
private final CharSequence mNegativeActionTitle;
|
||||
private final IntentSender mNegativeActionListener;
|
||||
private final AutofillId[] mRequiredIds;
|
||||
@@ -177,7 +189,7 @@ public final class SaveInfo implements Parcelable {
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public int getType() {
|
||||
public @SaveDataType int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
@@ -191,7 +203,7 @@ public final class SaveInfo implements Parcelable {
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
private final int mType;
|
||||
private final @SaveDataType int mType;
|
||||
private CharSequence mNegativeActionTitle;
|
||||
private IntentSender mNegativeActionListener;
|
||||
// TODO(b/33197203): make mRequiredIds final once addSavableIds() is gone
|
||||
@@ -215,7 +227,7 @@ public final class SaveInfo implements Parcelable {
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code requiredIds} is {@code null} or empty.
|
||||
*/
|
||||
public Builder(int type, @NonNull AutofillId[] requiredIds) {
|
||||
public Builder(@SaveDataType int type, @NonNull AutofillId[] requiredIds) {
|
||||
if (false) {// TODO(b/33197203): re-move when clients use it
|
||||
Preconditions.checkArgument(requiredIds != null && requiredIds.length > 0,
|
||||
"must have at least one required id: " + Arrays.toString(requiredIds));
|
||||
@@ -230,7 +242,7 @@ public final class SaveInfo implements Parcelable {
|
||||
* // TODO(b/33197203): make sure is removed when clients migrated
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder(int type) {
|
||||
public Builder(@SaveDataType int type) {
|
||||
this(type, null);
|
||||
}
|
||||
|
||||
|
||||
19
core/java/android/service/autofill/SaveRequest.aidl
Normal file
19
core/java/android/service/autofill/SaveRequest.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2017, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
parcelable SaveRequest;
|
||||
92
core/java/android/service/autofill/SaveRequest.java
Normal file
92
core/java/android/service/autofill/SaveRequest.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class represents a request to an {@link AutofillService
|
||||
* autofill provider} to save applicable data entered by the user.
|
||||
*
|
||||
* @see AutofillService#onSaveRequest(SaveRequest, SaveCallback)
|
||||
*/
|
||||
public final class SaveRequest implements Parcelable {
|
||||
private final @NonNull ArrayList<FillContext> mFillContexts;
|
||||
private final @Nullable Bundle mClientState;
|
||||
|
||||
/** @hide */
|
||||
public SaveRequest(@NonNull ArrayList<FillContext> fillContexts,
|
||||
@Nullable Bundle clientState) {
|
||||
mFillContexts = Preconditions.checkNotNull(fillContexts, "fillContexts");
|
||||
mClientState = clientState;
|
||||
}
|
||||
|
||||
private SaveRequest(@NonNull Parcel parcel) {
|
||||
this(parcel.readTypedArrayList(null), parcel.readBundle());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The contexts associated with each previous fill request.
|
||||
*/
|
||||
public @NonNull List<FillContext> getFillContexts() {
|
||||
return mFillContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extra client state returned from the last {@link
|
||||
* AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)}
|
||||
* fill request}.
|
||||
*
|
||||
* @return The client state.
|
||||
*/
|
||||
public @Nullable Bundle getClientState() {
|
||||
return mClientState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeTypedArrayList(mFillContexts, flags);
|
||||
parcel.writeBundle(mClientState);
|
||||
}
|
||||
|
||||
public static final Creator<SaveRequest> CREATOR =
|
||||
new Creator<SaveRequest>() {
|
||||
@Override
|
||||
public SaveRequest createFromParcel(Parcel parcel) {
|
||||
return new SaveRequest(parcel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaveRequest[] newArray(int size) {
|
||||
return new SaveRequest[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -101,7 +101,10 @@ public final class AutofillManager {
|
||||
// Public flags start from the lowest bit
|
||||
/**
|
||||
* Indicates autofill was explicitly requested by the user.
|
||||
*
|
||||
* @deprecated Use {@link android.service.autofill.FillRequest#FLAG_MANUAL_REQUEST}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int FLAG_MANUAL_REQUEST = 0x1;
|
||||
|
||||
// Private flags start from the highest bit
|
||||
|
||||
@@ -48,6 +48,7 @@ import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.autofill.AutofillService;
|
||||
import android.service.autofill.AutofillServiceInfo;
|
||||
import android.service.autofill.FillRequest;
|
||||
import android.service.autofill.IAutoFillService;
|
||||
import android.text.TextUtils;
|
||||
import android.util.LocalLog;
|
||||
@@ -169,7 +170,8 @@ final class AutofillManagerServiceImpl {
|
||||
structure.sanitizeForParceling(true);
|
||||
|
||||
// TODO(b/33197203): Need to pipe the bundle
|
||||
session.mRemoteFillService.onFillRequest(structure, null, session.mFlags);
|
||||
FillRequest request = new FillRequest(structure, null, session.mFlags);
|
||||
session.mRemoteFillService.onFillRequest(request);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,12 +20,10 @@ import static com.android.server.autofill.Helper.DEBUG;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.assist.AssistStructure;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.IBinder.DeathRecipient;
|
||||
import android.os.ICancellationSignal;
|
||||
@@ -33,10 +31,12 @@ import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.service.autofill.AutofillService;
|
||||
import android.service.autofill.FillRequest;
|
||||
import android.service.autofill.FillResponse;
|
||||
import android.service.autofill.IAutoFillService;
|
||||
import android.service.autofill.IFillCallback;
|
||||
import android.service.autofill.ISaveCallback;
|
||||
import android.service.autofill.SaveRequest;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -88,7 +88,7 @@ final class RemoteFillService implements DeathRecipient {
|
||||
|
||||
public interface FillServiceCallbacks {
|
||||
void onFillRequestSuccess(@Nullable FillResponse response,
|
||||
@NonNull String servicePackageName);
|
||||
@NonNull String servicePackageName, int requestId);
|
||||
void onFillRequestFailure(@Nullable CharSequence message,
|
||||
@NonNull String servicePackageName);
|
||||
void onSaveRequestSuccess(@NonNull String servicePackageName);
|
||||
@@ -134,17 +134,16 @@ final class RemoteFillService implements DeathRecipient {
|
||||
mCallbacks.onServiceDied(this);
|
||||
}
|
||||
|
||||
public void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle extras,
|
||||
int flags) {
|
||||
public void onFillRequest(@NonNull FillRequest request) {
|
||||
cancelScheduledUnbind();
|
||||
final PendingFillRequest request = new PendingFillRequest(structure, extras, this, flags);
|
||||
mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
|
||||
final PendingFillRequest pendingRequest = new PendingFillRequest(request, this);
|
||||
mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, pendingRequest).sendToTarget();
|
||||
}
|
||||
|
||||
public void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle extras) {
|
||||
public void onSaveRequest(@NonNull SaveRequest request) {
|
||||
cancelScheduledUnbind();
|
||||
final PendingSaveRequest request = new PendingSaveRequest(structure, extras, this);
|
||||
mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
|
||||
final PendingSaveRequest pendingRequest = new PendingSaveRequest(request, this);
|
||||
mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, pendingRequest).sendToTarget();
|
||||
}
|
||||
|
||||
// Note: we are dumping without a lock held so this is a bit racy but
|
||||
@@ -253,10 +252,11 @@ final class RemoteFillService implements DeathRecipient {
|
||||
}
|
||||
|
||||
private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
|
||||
FillResponse response) {
|
||||
FillResponse response, int requestId) {
|
||||
mHandler.getHandler().post(() -> {
|
||||
if (handleResponseCallbackCommon(pendingRequest)) {
|
||||
mCallbacks.onFillRequestSuccess(response, mComponentName.getPackageName());
|
||||
mCallbacks.onFillRequestSuccess(response, mComponentName.getPackageName(),
|
||||
requestId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -392,18 +392,13 @@ final class RemoteFillService implements DeathRecipient {
|
||||
private static final class PendingFillRequest extends PendingRequest {
|
||||
private final Object mLock = new Object();
|
||||
private final WeakReference<RemoteFillService> mWeakService;
|
||||
private final AssistStructure mStructure;
|
||||
private final Bundle mExtras;
|
||||
private final FillRequest mRequest;
|
||||
private final IFillCallback mCallback;
|
||||
private ICancellationSignal mCancellation;
|
||||
private boolean mCancelled;
|
||||
private int mFlags;
|
||||
|
||||
public PendingFillRequest(AssistStructure structure,
|
||||
Bundle extras, RemoteFillService service, int flags) {
|
||||
mStructure = structure;
|
||||
mExtras = extras;
|
||||
mFlags = flags;
|
||||
public PendingFillRequest(FillRequest request, RemoteFillService service) {
|
||||
mRequest = request;
|
||||
mWeakService = new WeakReference<>(service);
|
||||
mCallback = new IFillCallback.Stub() {
|
||||
@Override
|
||||
@@ -425,11 +420,11 @@ final class RemoteFillService implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(FillResponse response) {
|
||||
public void onSuccess(FillResponse response, int requestId) {
|
||||
RemoteFillService remoteService = mWeakService.get();
|
||||
if (remoteService != null) {
|
||||
remoteService.dispatchOnFillRequestSuccess(
|
||||
PendingFillRequest.this, response);
|
||||
PendingFillRequest.this, response, requestId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,8 +444,7 @@ final class RemoteFillService implements DeathRecipient {
|
||||
RemoteFillService remoteService = mWeakService.get();
|
||||
if (remoteService != null) {
|
||||
try {
|
||||
remoteService.mAutoFillService.onFillRequest(mStructure,
|
||||
mExtras, mCallback, mFlags);
|
||||
remoteService.mAutoFillService.onFillRequest(mRequest, mCallback);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(LOG_TAG, "Error calling on fill request", e);
|
||||
cancel();
|
||||
@@ -481,14 +475,12 @@ final class RemoteFillService implements DeathRecipient {
|
||||
|
||||
private static final class PendingSaveRequest extends PendingRequest {
|
||||
private final WeakReference<RemoteFillService> mWeakService;
|
||||
private final AssistStructure mStructure;
|
||||
private final Bundle mExtras;
|
||||
private final SaveRequest mRequest;
|
||||
private final ISaveCallback mCallback;
|
||||
|
||||
public PendingSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle extras,
|
||||
public PendingSaveRequest(@NonNull SaveRequest request,
|
||||
@NonNull RemoteFillService service) {
|
||||
mStructure = structure;
|
||||
mExtras = extras;
|
||||
mRequest = request;
|
||||
mWeakService = new WeakReference<>(service);
|
||||
mCallback = new ISaveCallback.Stub() {
|
||||
@Override
|
||||
@@ -516,7 +508,7 @@ final class RemoteFillService implements DeathRecipient {
|
||||
final RemoteFillService service = mWeakService.get();
|
||||
if (service != null) {
|
||||
try {
|
||||
service.mAutoFillService.onSaveRequest(mStructure, mExtras, mCallback);
|
||||
service.mAutoFillService.onSaveRequest(mRequest, mCallback);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(LOG_TAG, "Error calling on save request", e);
|
||||
}
|
||||
|
||||
@@ -44,11 +44,15 @@ import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.service.autofill.AutofillService;
|
||||
import android.service.autofill.Dataset;
|
||||
import android.service.autofill.FillContext;
|
||||
import android.service.autofill.FillRequest;
|
||||
import android.service.autofill.FillResponse;
|
||||
import android.service.autofill.SaveInfo;
|
||||
import android.service.autofill.SaveRequest;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.DebugUtils;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillManager;
|
||||
import android.view.autofill.AutofillValue;
|
||||
@@ -125,7 +129,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
RemoteFillService mRemoteFillService;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private ArrayList<FillResponse> mResponses;
|
||||
private SparseArray<FillResponse> mResponses;
|
||||
|
||||
/**
|
||||
* Response that requires a service authentitcation request.
|
||||
@@ -156,7 +160,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
* and used on subsequent {@code onFillRequest()} and {@code onSaveRequest()} calls.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private Bundle mExtras;
|
||||
private Bundle mClientState;
|
||||
|
||||
/**
|
||||
* Flags used to start the session.
|
||||
@@ -222,7 +226,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
// FillServiceCallbacks
|
||||
@Override
|
||||
public void onFillRequestSuccess(@Nullable FillResponse response,
|
||||
@NonNull String servicePackageName) {
|
||||
@NonNull String servicePackageName, int requestId) {
|
||||
if (response == null) {
|
||||
if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
|
||||
getUiForShowing().showError(R.string.autofill_error_cannot_autofill);
|
||||
@@ -243,7 +247,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
// TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
|
||||
mResponseWaitingAuth = response;
|
||||
}
|
||||
processResponseLocked(response);
|
||||
processResponseLocked(response, requestId);
|
||||
}
|
||||
|
||||
final LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
|
||||
@@ -394,12 +398,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
AutofillManager.EXTRA_AUTHENTICATION_RESULT);
|
||||
if (result instanceof FillResponse) {
|
||||
mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
|
||||
final int requestIndex = mResponses.indexOfValue(mResponseWaitingAuth);
|
||||
mResponseWaitingAuth = null;
|
||||
processResponseLocked((FillResponse) result);
|
||||
if (requestIndex >= 0) {
|
||||
final int requestId = mResponses.keyAt(requestIndex);
|
||||
processResponseLocked((FillResponse) result, requestId);
|
||||
} else {
|
||||
Slog.e(TAG, "Error cannot find id for auth response");
|
||||
}
|
||||
} else if (result instanceof Dataset) {
|
||||
final Dataset dataset = (Dataset) result;
|
||||
for (int i = 0; i < mResponses.size(); i++) {
|
||||
final FillResponse response = mResponses.get(i);
|
||||
final FillResponse response = mResponses.valueAt(i);
|
||||
final int index = response.getDatasets().indexOf(mDatasetWaitingAuth);
|
||||
if (index >= 0) {
|
||||
response.getDatasets().set(index, dataset);
|
||||
@@ -440,12 +450,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
return true;
|
||||
}
|
||||
|
||||
final FillResponse response = mResponses.get(mResponses.size() - 1);
|
||||
final int lastResponseIdx = getLastResponseIndex();
|
||||
if (lastResponseIdx < 0) {
|
||||
Slog.d(TAG, "showSaveLocked(): mResponses=" + mResponses
|
||||
+ ", mViewStates=" + mViewStates);
|
||||
return true;
|
||||
}
|
||||
|
||||
final FillResponse response = mResponses.valueAt(lastResponseIdx);
|
||||
final SaveInfo saveInfo = response.getSaveInfo();
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG,
|
||||
"showSaveLocked(): mResponses=" + mResponses + ", mViewStates=" + mViewStates);
|
||||
Slog.d(TAG, "showSaveLocked(): mResponses=" + mResponses
|
||||
+ ", mViewStates=" + mViewStates);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -572,7 +588,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
mStructure.dump();
|
||||
}
|
||||
|
||||
mRemoteFillService.onSaveRequest(mStructure, mExtras);
|
||||
// TODO(b/33197203): Implement partitioning properly
|
||||
final int lastResponseIdx = getLastResponseIndex();
|
||||
final int requestId = mResponses.keyAt(lastResponseIdx);
|
||||
final FillContext fillContext = new FillContext(requestId, mStructure);
|
||||
final ArrayList fillContexts = new ArrayList(1);
|
||||
fillContexts.add(fillContext);
|
||||
|
||||
final SaveRequest saveRequest = new SaveRequest(fillContexts, mClientState);
|
||||
mRemoteFillService.onSaveRequest(saveRequest);
|
||||
}
|
||||
|
||||
void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
|
||||
@@ -686,7 +710,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
overlay.focused = id.equals(viewState.id);
|
||||
node.setAutofillOverlay(overlay);
|
||||
}
|
||||
mRemoteFillService.onFillRequest(mStructure, mExtras, 0);
|
||||
|
||||
FillRequest request = new FillRequest(mStructure, mClientState, 0);
|
||||
mRemoteFillService.onFillRequest(request);
|
||||
|
||||
return newViewState;
|
||||
}
|
||||
@@ -723,17 +749,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
}
|
||||
|
||||
private void processResponseLocked(FillResponse response) {
|
||||
private void processResponseLocked(FillResponse response, int requestId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
|
||||
}
|
||||
|
||||
if (mResponses == null) {
|
||||
mResponses = new ArrayList<>(4);
|
||||
mResponses = new SparseArray<>(4);
|
||||
}
|
||||
mResponses.add(response);
|
||||
mResponses.put(requestId, response);
|
||||
if (response != null) {
|
||||
mExtras = response.getExtras();
|
||||
mClientState = response.getClientState();
|
||||
}
|
||||
|
||||
setViewStatesLocked(response, ViewState.STATE_FILLABLE);
|
||||
@@ -884,7 +910,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
}
|
||||
pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
|
||||
pw.print(prefix); pw.print("mExtras: "); pw.println(Helper.bundleToString(mExtras));
|
||||
pw.print(prefix); pw.print("mClientState: "); pw.println(
|
||||
Helper.bundleToString(mClientState));
|
||||
mRemoteFillService.dump(prefix, pw);
|
||||
}
|
||||
|
||||
@@ -961,4 +988,20 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
destroyLocked();
|
||||
mService.removeSessionLocked(id);
|
||||
}
|
||||
|
||||
private int getLastResponseIndex() {
|
||||
// The response ids are monotonically increasing so
|
||||
// we just find the largest id which is the last. We
|
||||
// do not rely on the internal ordering in sparse
|
||||
// array to avoid - wow this stopped working!?
|
||||
int lastResponseIdx = -1;
|
||||
int lastResponseId = -1;
|
||||
final int responseCount = mResponses.size();
|
||||
for (int i = 0; i < responseCount; i++) {
|
||||
if (mResponses.keyAt(i) > lastResponseId) {
|
||||
lastResponseIdx = i;
|
||||
}
|
||||
}
|
||||
return lastResponseIdx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,8 @@ public final class AutoFillUI {
|
||||
log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL);
|
||||
hideFillUiUiThread();
|
||||
if (mCallback != null) {
|
||||
mCallback.authenticate(response.getAuthentication(), response.getExtras());
|
||||
mCallback.authenticate(response.getAuthentication(),
|
||||
response.getClientState());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user