Add support for multiple fill contexts

When saving data filled by the user the platform provides to
an autofill provider the state of the UI allowing the provider
to interpret this state and store relevant information.

A limitation of the current design is that the fill provider
needs to interpret the screen content twice, once handling a
fill request and once handling a save request. To address this
we are introducing a id for each fill request allowing the
autofill provider to associate arbitrary state with each fill
request and store it in the client data bundle later passed
to save.

Another limitation of the current design is that if the screen
changes dynamically while the user interacts with the app the
UI state passed on save represents a static snapshot, therefore
it is not possible to the autofill provider to determine the
context in which the data in the UI was filled. We could
keep the views and have deltas for views being removed/added
/moved/changed but this is not enough as the fill provider
needs to know not only what changed but what changed for every
fill request and in one session there could be multiple fill
requests. To address this we provide a list of fill contexts
on save each of which has the id of the corresponding fill
request. This allows the fill provider to know the exact context
in which the data was popuplated and also use its custom client
state for this fill request if desired.

This change deprecates the old APIs and the new ones delegate
to the old ones. Once the clients migrate to the new APIs we
will remove the old ones.

Test: all autofill CTS tests pass

Change-Id: Idcebcc671aa3c078a305d8c358e225274fccc588
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index a4d3fb2..5e49b8f 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -34,6 +34,8 @@
 
 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 @@
         }
 
         @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 @@
                 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();
@@ -198,6 +195,28 @@
      * 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.
+     *
+     * <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 structure {@link Activity}'s view structure.
      * @param data bundle containing data passed by the service in a last call to
      *        {@link FillResponse.Builder#setExtras(Bundle)}, if any. This bundle allows your
@@ -211,6 +230,7 @@
      *     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);
@@ -222,6 +242,23 @@
      * {@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}.
+     *
+     * <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 structure {@link Activity}'s view structure.
      * @param data bundle containing data passed by the service in a last call to
      *        {@link FillResponse.Builder#setExtras(Bundle)}, if any. This bundle allows your
@@ -231,6 +268,7 @@
      *        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);