Add API to start pendingIntent for attribution from client App.

Bug: 150321630
Test: manual verification
Change-Id: I99f8529c94ef0cc8721d58af7f3c57ae43f4b6dd
diff --git a/api/system-current.txt b/api/system-current.txt
index e9bfdad..359c68f 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9642,6 +9642,7 @@
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method @Nullable public android.os.Bundle onGetInlineSuggestionsRendererInfo();
     method @Nullable public android.view.View onRenderSuggestion(@NonNull android.service.autofill.InlinePresentation, int, int);
+    method public final void startIntentSender(@NonNull android.content.IntentSender);
     field public static final String SERVICE_INTERFACE = "android.service.autofill.InlineSuggestionRenderService";
   }
 
diff --git a/api/test-current.txt b/api/test-current.txt
index 4704c0b..87169e0 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3169,6 +3169,7 @@
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method @Nullable public android.os.Bundle onGetInlineSuggestionsRendererInfo();
     method @Nullable public android.view.View onRenderSuggestion(@NonNull android.service.autofill.InlinePresentation, int, int);
+    method public final void startIntentSender(@NonNull android.content.IntentSender);
     field public static final String SERVICE_INTERFACE = "android.service.autofill.InlineSuggestionRenderService";
   }
 
diff --git a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
index 1bcc76b..bed4302 100644
--- a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
+++ b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
@@ -16,6 +16,7 @@
 
 package android.service.autofill;
 
+import android.content.IntentSender;
 import android.os.IBinder;
 import android.view.SurfaceControlViewHost;
 
@@ -30,4 +31,5 @@
     void onContent(in SurfaceControlViewHost.SurfacePackage surface);
     void onError();
     void onTransferTouchFocusToImeWindow(in IBinder sourceInputToken, int displayId);
+    void onStartIntentSender(in IntentSender intentSender);
 }
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index 7fbc309..0d4be58 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -24,6 +24,7 @@
 import android.app.Service;
 import android.app.slice.Slice;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.graphics.PixelFormat;
 import android.os.Bundle;
 import android.os.Handler;
@@ -60,6 +61,8 @@
 
     private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
 
+    private IInlineSuggestionUiCallback mCallback;
+
     private void handleRenderSuggestion(IInlineSuggestionUiCallback callback,
             InlinePresentation presentation, int width, int height, IBinder hostInputToken,
             int displayId) {
@@ -84,6 +87,7 @@
                 }
                 return;
             }
+            mCallback = callback;
 
             final InlineSuggestionRoot suggestionRoot = new InlineSuggestionRoot(this, callback);
             suggestionRoot.addView(suggestionView);
@@ -155,6 +159,20 @@
     }
 
     /**
+     * Starts the {@link IntentSender} from the client app.
+     *
+     * @param intentSender the {@link IntentSender} to start the attribution UI from the client app.
+     */
+    public final void startIntentSender(@NonNull IntentSender intentSender) {
+        if (mCallback == null) return;
+        try {
+            mCallback.onStartIntentSender(intentSender);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      *  Returns the metadata about the renderer. Returns {@code null} if no metadata is provided.
      */
     @Nullable
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index b4b0641..8b50b01 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -28,6 +28,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
@@ -250,23 +251,31 @@
         final InlineSuggestionsResponse inlineSuggestionsResponse =
                 InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(
                         request, inlineSuggestionsData, focusedId,
-                        dataset -> {
-                            mCallbacks.logAugmentedAutofillSelected(sessionId,
-                                    dataset.getId());
-                            try {
-                                final ArrayList<AutofillId> fieldIds = dataset.getFieldIds();
-                                final int size = fieldIds.size();
-                                final boolean hideHighlight = size == 1
-                                        && fieldIds.get(0).equals(focusedId);
-                                if (dataset.getAuthentication() != null) {
-                                    client.startIntentSender(dataset.getAuthentication(),
-                                            new Intent());
-                                } else {
+                        new InlineSuggestionFactory.InlineSuggestionUiCallback() {
+                            @Override
+                            public void autofill(Dataset dataset) {
+                                mCallbacks.logAugmentedAutofillSelected(sessionId,
+                                        dataset.getId());
+                                try {
+                                    final ArrayList<AutofillId> fieldIds = dataset.getFieldIds();
+                                    final int size = fieldIds.size();
+                                    final boolean hideHighlight = size == 1
+                                            && fieldIds.get(0).equals(focusedId);
                                     client.autofill(sessionId, fieldIds, dataset.getFieldValues(),
                                             hideHighlight);
+                                } catch (RemoteException e) {
+                                    Slog.w(TAG, "Encounter exception autofilling the values");
                                 }
-                            } catch (RemoteException e) {
-                                Slog.w(TAG, "Encounter exception autofilling the values");
+                            }
+
+                            @Override
+                            public void startIntentSender(IntentSender intentSender,
+                                    Intent intent) {
+                                try {
+                                    client.startIntentSender(intentSender, intent);
+                                } catch (RemoteException e) {
+                                    Slog.w(TAG, "RemoteException starting intent sender");
+                                }
                             }
                         }, onErrorCallback, remoteRenderService);
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
index 71d4ace..cb09bf5 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
@@ -21,6 +21,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.service.autofill.Dataset;
@@ -49,6 +51,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.BiConsumer;
+import java.util.function.Consumer;
 import java.util.regex.Pattern;
 
 public final class InlineSuggestionFactory {
@@ -62,6 +65,11 @@
          * Callback to autofill a dataset to the client app.
          */
         void autofill(@NonNull Dataset dataset);
+
+        /**
+         * Callback to start Intent in client app.
+         */
+        void startIntentSender(@NonNull IntentSender intentSender, @NonNull Intent intent);
     }
 
     /**
@@ -94,7 +102,8 @@
                 response.getAuthentication() == null ? null : response.getInlinePresentation();
         return createInlineSuggestionsResponseInternal(/* isAugmented= */ false, request,
                 response.getDatasets(), filterText, inlineAuthentication, autofillId,
-                onErrorCallback, onClickFactory, remoteRenderService);
+                onErrorCallback, onClickFactory, (intentSender) ->
+                        client.startIntentSender(intentSender, new Intent()), remoteRenderService);
     }
 
     /**
@@ -111,8 +120,12 @@
         if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
         return createInlineSuggestionsResponseInternal(/* isAugmented= */ true, request,
                 datasets, /* filterText= */ null, /* inlineAuthentication= */ null,
-                autofillId, onErrorCallback, (dataset, datasetIndex) ->
-                        inlineSuggestionUiCallback.autofill(dataset), remoteRenderService);
+                autofillId, onErrorCallback,
+                (dataset, datasetIndex) ->
+                        inlineSuggestionUiCallback.autofill(dataset),
+                (intentSender) ->
+                        inlineSuggestionUiCallback.startIntentSender(intentSender, new Intent()),
+                remoteRenderService);
     }
 
     @Nullable
@@ -121,12 +134,13 @@
             @Nullable List<Dataset> datasets, @Nullable String filterText,
             @Nullable InlinePresentation inlineAuthentication, @NonNull AutofillId autofillId,
             @NonNull Runnable onErrorCallback, @NonNull BiConsumer<Dataset, Integer> onClickFactory,
+            @NonNull Consumer<IntentSender> intentSenderConsumer,
             @Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
 
         final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
         if (inlineAuthentication != null) {
             InlineSuggestion inlineAuthSuggestion = createInlineAuthSuggestion(inlineAuthentication,
-                    remoteRenderService, onClickFactory, onErrorCallback,
+                    remoteRenderService, onClickFactory, onErrorCallback, intentSenderConsumer,
                     request.getHostInputToken(), request.getHostDisplayId());
             inlineSuggestions.add(inlineAuthSuggestion);
 
@@ -157,7 +171,7 @@
             InlineSuggestion inlineSuggestion = createInlineSuggestion(isAugmented, dataset,
                     datasetIndex,
                     mergedInlinePresentation(request, datasetIndex, inlinePresentation),
-                    onClickFactory, remoteRenderService, onErrorCallback,
+                    onClickFactory, remoteRenderService, onErrorCallback, intentSenderConsumer,
                     request.getHostInputToken(), request.getHostDisplayId());
 
             inlineSuggestions.add(inlineSuggestion);
@@ -201,7 +215,8 @@
             @NonNull InlinePresentation inlinePresentation,
             @NonNull BiConsumer<Dataset, Integer> onClickFactory,
             @NonNull RemoteInlineSuggestionRenderService remoteRenderService,
-            @NonNull Runnable onErrorCallback, @Nullable IBinder hostInputToken,
+            @NonNull Runnable onErrorCallback, @NonNull Consumer<IntentSender> intentSenderConsumer,
+            @Nullable IBinder hostInputToken,
             int displayId) {
         final String suggestionSource = isAugmented ? InlineSuggestionInfo.SOURCE_PLATFORM
                 : InlineSuggestionInfo.SOURCE_AUTOFILL;
@@ -216,7 +231,7 @@
         final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
                 createInlineContentProvider(inlinePresentation,
                         () -> onClickFactory.accept(dataset, datasetIndex), onErrorCallback,
-                        remoteRenderService, hostInputToken, displayId));
+                        intentSenderConsumer, remoteRenderService, hostInputToken, displayId));
 
         return inlineSuggestion;
     }
@@ -225,6 +240,7 @@
             @NonNull InlinePresentation inlinePresentation,
             @NonNull RemoteInlineSuggestionRenderService remoteRenderService,
             @NonNull BiConsumer<Dataset, Integer> onClickFactory, @NonNull Runnable onErrorCallback,
+            @NonNull Consumer<IntentSender> intentSenderConsumer,
             @Nullable IBinder hostInputToken, int displayId) {
         final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
                 inlinePresentation.getInlinePresentationSpec(),
@@ -235,7 +251,8 @@
                 createInlineContentProvider(inlinePresentation,
                         () -> onClickFactory.accept(null,
                                 AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED),
-                        onErrorCallback, remoteRenderService, hostInputToken, displayId));
+                        onErrorCallback, intentSenderConsumer, remoteRenderService, hostInputToken,
+                        displayId));
     }
 
     /**
@@ -261,6 +278,7 @@
     private static IInlineContentProvider.Stub createInlineContentProvider(
             @NonNull InlinePresentation inlinePresentation, @Nullable Runnable onClickAction,
             @NonNull Runnable onErrorCallback,
+            @NonNull Consumer<IntentSender> intentSenderConsumer,
             @Nullable RemoteInlineSuggestionRenderService remoteRenderService,
             @Nullable IBinder hostInputToken,
             int displayId) {
@@ -269,7 +287,7 @@
             public void provideContent(int width, int height, IInlineContentCallback callback) {
                 UiThread.getHandler().post(() -> {
                     final IInlineSuggestionUiCallback uiCallback = createInlineSuggestionUiCallback(
-                            callback, onClickAction, onErrorCallback);
+                            callback, onClickAction, onErrorCallback, intentSenderConsumer);
 
                     if (remoteRenderService == null) {
                         Slog.e(TAG, "RemoteInlineSuggestionRenderService is null");
@@ -285,7 +303,8 @@
 
     private static IInlineSuggestionUiCallback.Stub createInlineSuggestionUiCallback(
             @NonNull IInlineContentCallback callback, @NonNull Runnable onAutofillCallback,
-            @NonNull Runnable onErrorCallback) {
+            @NonNull Runnable onErrorCallback,
+            @NonNull Consumer<IntentSender> intentSenderConsumer) {
         return new IInlineSuggestionUiCallback.Stub() {
             @Override
             public void onClick() throws RemoteException {
@@ -321,6 +340,11 @@
                     onErrorCallback.run();
                 }
             }
+
+            @Override
+            public void onStartIntentSender(IntentSender intentSender) {
+                intentSenderConsumer.accept(intentSender);
+            }
         };
     }