Track search results with position and search Identifier

Bug: 169087008
Test: Manual
Change-Id: I54c74093b90e5aea03a7810f55fcc32f0ddf8dda
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 0abf84a..f01f90b 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -200,6 +200,7 @@
      */
     public static class AdapterItemWithPayload<T> extends AdapterItem {
         private T mPayload;
+        private String mSearchSessionId;
         private AllAppsSearchPlugin mPlugin;
         private IntConsumer mSelectionHandler;
 
@@ -221,6 +222,14 @@
             mSelectionHandler = runnable;
         }
 
+        public void setSearchSessionId(String searchSessionId) {
+            mSearchSessionId = searchSessionId;
+        }
+
+        public String getSearchSessionId() {
+            return mSearchSessionId;
+        }
+
         public IntConsumer getSelectionHandler() {
             return mSelectionHandler;
         }
@@ -228,6 +237,8 @@
         public T getPayload() {
             return mPayload;
         }
+
+
     }
 
     /**
@@ -476,24 +487,23 @@
                 //TODO: replace with custom TopHitBubbleTextView with support for both shortcut
                 // and apps
                 if (adapterItem instanceof AdapterItemWithPayload) {
-                    AdapterItemWithPayload withPayload = (AdapterItemWithPayload) adapterItem;
-                    IntConsumer selectionHandler = type -> {
+                    AdapterItemWithPayload item = (AdapterItemWithPayload) adapterItem;
+                    item.setSelectionHandler(type -> {
                         SearchTargetEvent e = new SearchTargetEvent(SearchTarget.ItemType.APP,
-                                type);
+                                type, item.position, item.getSearchSessionId());
                         e.bundle = HeroSearchResultView.getAppBundle(info);
-                        if (withPayload.getPlugin() != null) {
-                            withPayload.getPlugin().notifySearchTargetEvent(e);
+                        if (item.getPlugin() != null) {
+                            item.getPlugin().notifySearchTargetEvent(e);
                         }
-                    };
+                    });
                     icon.setOnClickListener(view -> {
-                        selectionHandler.accept(SearchTargetEvent.SELECT);
+                        item.getSelectionHandler().accept(SearchTargetEvent.SELECT);
                         mOnIconClickListener.onClick(view);
                     });
                     icon.setOnLongClickListener(view -> {
-                        selectionHandler.accept(SearchTargetEvent.LONG_PRESS);
+                        item.getSelectionHandler().accept(SearchTargetEvent.SELECT);
                         return mOnIconLongClickListener.onLongClick(view);
                     });
-                    withPayload.setSelectionHandler(selectionHandler);
                 }
                 else {
                     icon.setOnClickListener(mOnIconClickListener);
@@ -516,20 +526,22 @@
                 break;
             case VIEW_TYPE_SEARCH_SLICE:
                 SliceView sliceView = (SliceView) holder.itemView;
-                AdapterItemWithPayload<Uri> item =
+                AdapterItemWithPayload<Uri> slicePayload =
                         (AdapterItemWithPayload<Uri>) mApps.getAdapterItems().get(position);
                 sliceView.setOnSliceActionListener((info1, s) -> {
-                    if (item.getPlugin() != null) {
+                    if (slicePayload.getPlugin() != null) {
                         SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
                                 SearchTarget.ItemType.SETTINGS_SLICE,
-                                SearchTargetEvent.CHILD_SELECT);
+                                SearchTargetEvent.CHILD_SELECT, slicePayload.position,
+                                slicePayload.getSearchSessionId());
                         searchTargetEvent.bundle = new Bundle();
-                        searchTargetEvent.bundle.putParcelable("uri", item.getPayload());
-                        item.getPlugin().notifySearchTargetEvent(searchTargetEvent);
+                        searchTargetEvent.bundle.putParcelable("uri", slicePayload.getPayload());
+                        slicePayload.getPlugin().notifySearchTargetEvent(searchTargetEvent);
                     }
                 });
                 try {
-                    LiveData<Slice> liveData = SliceLiveData.fromUri(mLauncher, item.getPayload());
+                    LiveData<Slice> liveData = SliceLiveData.fromUri(mLauncher,
+                            slicePayload.getPayload());
                     liveData.observe((Launcher) mLauncher, sliceView);
                     sliceView.setTag(liveData);
                 } catch (Exception ignored) {
@@ -542,9 +554,10 @@
             case VIEW_TYPE_SEARCH_SHORTCUT:
             case VIEW_TYPE_SEARCH_PEOPLE:
             case VIEW_TYPE_SEARCH_THUMBNAIL:
+                AdapterItemWithPayload item =
+                        (AdapterItemWithPayload) mApps.getAdapterItems().get(position);
                 PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView;
-                payloadResultView.applyAdapterInfo(
-                        (AdapterItemWithPayload) mApps.getAdapterItems().get(position));
+                payloadResultView.setup(item);
                 break;
             case VIEW_TYPE_ALL_APPS_DIVIDER:
                 // nothing to do
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index 3320189..d7fa5bc 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -35,6 +35,8 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.systemui.plugins.AllAppsSearchPlugin;
+import com.android.systemui.plugins.shared.SearchTarget;
+import com.android.systemui.plugins.shared.SearchTargetEvent;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -213,6 +215,44 @@
         /**
          * Updates View using Adapter's payload
          */
+
+        default void setup(AdapterItemWithPayload<T> adapterItemWithPayload) {
+            Object[] targetInfo = getTargetInfo();
+            if (targetInfo != null) {
+                targetInfo[0] = adapterItemWithPayload.getSearchSessionId();
+                targetInfo[1] = adapterItemWithPayload.position;
+            }
+            applyAdapterInfo(adapterItemWithPayload);
+        }
+
         void applyAdapterInfo(AdapterItemWithPayload<T> adapterItemWithPayload);
+
+        /**
+         * Gets object created by {@link PayloadResultHandler#createTargetInfo()}
+         */
+        Object[] getTargetInfo();
+
+        /**
+         * Creates a wrapper object to hold searchSessionId and item position
+         */
+        default Object[] createTargetInfo() {
+            return new Object[2];
+        }
+
+        /**
+         * Generates a SearchTargetEvent object for a PayloadHandlerView
+         */
+        default SearchTargetEvent getSearchTargetEvent(SearchTarget.ItemType itemType,
+                int eventType) {
+            Object[] targetInfo = getTargetInfo();
+            if (targetInfo == null) return null;
+
+            String searchSessionId = (String) targetInfo[0];
+            int position = (int) targetInfo[1];
+            return new SearchTargetEvent(itemType, eventType,
+                    position, searchSessionId);
+        }
     }
+
+
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java
index 845c6de..94b9ca1 100644
--- a/src/com/android/launcher3/views/HeroSearchResultView.java
+++ b/src/com/android/launcher3/views/HeroSearchResultView.java
@@ -61,6 +61,7 @@
         PayloadResultHandler<List<Pair<ShortcutInfo, ItemInfoWithIcon>>> {
 
     public static final int MAX_SHORTCUTS_COUNT = 2;
+    private final Object[] mTargetInfo = createTargetInfo();
     BubbleTextView mBubbleTextView;
     View mIconView;
     BubbleTextView[] mDeepShortcutTextViews = new BubbleTextView[2];
@@ -107,7 +108,7 @@
                             grid.allAppsIconSizePx));
             bubbleTextView.setOnClickListener(view -> {
                 WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
-                SearchTargetEvent event = new SearchTargetEvent(
+                SearchTargetEvent event = getSearchTargetEvent(
                         SearchTarget.ItemType.APP_HERO,
                         SearchTargetEvent.CHILD_SELECT);
                 event.bundle = getAppBundle(itemInfo);
@@ -150,6 +151,11 @@
     }
 
     @Override
+    public Object[] getTargetInfo() {
+        return mTargetInfo;
+    }
+
+    @Override
     public void onDropCompleted(View target, DropTarget.DragObject d, boolean success) {
         mBubbleTextView.setVisibility(VISIBLE);
         mBubbleTextView.setIconVisible(true);
@@ -184,7 +190,7 @@
             mLauncher.getWorkspace().beginDragShared(mContainer.mBubbleTextView,
                     draggableView, mContainer, itemInfo, previewProvider, new DragOptions());
 
-            SearchTargetEvent event = new SearchTargetEvent(
+            SearchTargetEvent event = mContainer.getSearchTargetEvent(
                     SearchTarget.ItemType.APP_HERO, SearchTargetEvent.LONG_PRESS);
             event.bundle = getAppBundle(itemInfo);
             if (mContainer.mPlugin != null) {
@@ -201,7 +207,7 @@
         Launcher launcher = Launcher.getLauncher(getContext());
         launcher.startActivitySafely(this, itemInfo.getIntent(), itemInfo);
 
-        SearchTargetEvent event = new SearchTargetEvent(
+        SearchTargetEvent event = getSearchTargetEvent(
                 SearchTarget.ItemType.APP_HERO, eventType);
         event.bundle = getAppBundle(itemInfo);
         if (mPlugin != null) {
diff --git a/src/com/android/launcher3/views/SearchResultPeopleView.java b/src/com/android/launcher3/views/SearchResultPeopleView.java
index 6e45e88..eacc095 100644
--- a/src/com/android/launcher3/views/SearchResultPeopleView.java
+++ b/src/com/android/launcher3/views/SearchResultPeopleView.java
@@ -67,7 +67,7 @@
     private ImageButton[] mProviderButtons = new ImageButton[3];
     private AllAppsSearchPlugin mPlugin;
     private Uri mContactUri;
-
+    private final Object[] mTargetInfo = createTargetInfo();
 
     public SearchResultPeopleView(Context context) {
         this(context, null, 0);
@@ -129,14 +129,14 @@
                     Bundle provider = providers.get(i);
                     Intent intent = Intent.parseUri(provider.getString("intent_uri_str"),
                             URI_ANDROID_APP_SCHEME | URI_ALLOW_UNSAFE);
-                    setupProviderButton(button, provider, intent);
+                    setupProviderButton(button, provider, intent, adapterItemWithPayload);
                     String pkg = provider.getString("package_name");
                     UI_HELPER_EXECUTOR.post(() -> {
                         try {
                             ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(
                                     pkg, 0);
                             Drawable appIcon = applicationInfo.loadIcon(mPackageManager);
-                            MAIN_EXECUTOR.post(()-> button.setImageDrawable(appIcon));
+                            MAIN_EXECUTOR.post(() -> button.setImageDrawable(appIcon));
                         } catch (PackageManager.NameNotFoundException ignored) {
                         }
 
@@ -151,11 +151,17 @@
         adapterItemWithPayload.setSelectionHandler(this::handleSelection);
     }
 
-    private void setupProviderButton(ImageButton button, Bundle provider, Intent intent) {
+    @Override
+    public Object[] getTargetInfo() {
+        return mTargetInfo;
+    }
+
+    private void setupProviderButton(ImageButton button, Bundle provider, Intent intent,
+            AllAppsGridAdapter.AdapterItem adapterItem) {
         Launcher launcher = Launcher.getLauncher(getContext());
         button.setOnClickListener(b -> {
             launcher.startActivitySafely(b, intent, null);
-            SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
+            SearchTargetEvent searchTargetEvent = getSearchTargetEvent(
                     SearchTarget.ItemType.PEOPLE,
                     SearchTargetEvent.CHILD_SELECT);
             searchTargetEvent.bundle = new Bundle();
@@ -173,8 +179,8 @@
             Launcher launcher = Launcher.getLauncher(getContext());
             launcher.startActivitySafely(this, new Intent(Intent.ACTION_VIEW, mContactUri).setFlags(
                     Intent.FLAG_ACTIVITY_NEW_TASK), null);
-            SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
-                    SearchTarget.ItemType.PEOPLE, eventType);
+            SearchTargetEvent searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.PEOPLE,
+                    eventType);
             searchTargetEvent.bundle = new Bundle();
             searchTargetEvent.bundle.putParcelable("contact_uri", mContactUri);
             if (mPlugin != null) {
diff --git a/src/com/android/launcher3/views/SearchResultPlayItem.java b/src/com/android/launcher3/views/SearchResultPlayItem.java
index 8624609..ff3ecc8 100644
--- a/src/com/android/launcher3/views/SearchResultPlayItem.java
+++ b/src/com/android/launcher3/views/SearchResultPlayItem.java
@@ -58,6 +58,8 @@
     private String mPackageName;
     private boolean mIsInstantGame;
     private AllAppsSearchPlugin mPlugin;
+    private final Object[] mTargetInfo = createTargetInfo();
+
 
     public SearchResultPlayItem(Context context) {
         this(context, null, 0);
@@ -125,6 +127,11 @@
         });
     }
 
+    @Override
+    public Object[] getTargetInfo() {
+        return mTargetInfo;
+    }
+
     private void showIfNecessary(TextView textView, @Nullable String string) {
         if (string == null || string.isEmpty()) {
             textView.setVisibility(GONE);
@@ -160,7 +167,7 @@
     }
 
     private void logSearchEvent(int eventType) {
-        SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
+        SearchTargetEvent searchTargetEvent = getSearchTargetEvent(
                 SearchTarget.ItemType.PLAY_RESULTS, eventType);
         searchTargetEvent.bundle = new Bundle();
         searchTargetEvent.bundle.putString("package_name", mPackageName);
diff --git a/src/com/android/launcher3/views/SearchResultShortcut.java b/src/com/android/launcher3/views/SearchResultShortcut.java
index 307cf34..a409f08 100644
--- a/src/com/android/launcher3/views/SearchResultShortcut.java
+++ b/src/com/android/launcher3/views/SearchResultShortcut.java
@@ -50,6 +50,8 @@
     private View mIconView;
     private ShortcutInfo mShortcutInfo;
     private AllAppsSearchPlugin mPlugin;
+    private final Object[] mTargetInfo = createTargetInfo();
+
 
     public SearchResultShortcut(@NonNull Context context) {
         super(context);
@@ -96,12 +98,17 @@
         adapterItemWithPayload.setSelectionHandler(this::handleSelection);
     }
 
+    @Override
+    public Object[] getTargetInfo() {
+        return mTargetInfo;
+    }
+
     private void handleSelection(int eventType) {
         WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) mBubbleTextView.getTag();
         ItemClickHandler.onClickAppShortcut(this, itemInfo, Launcher.getLauncher(getContext()));
 
-        SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
-                SearchTarget.ItemType.SHORTCUT, eventType);
+        SearchTargetEvent searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.SHORTCUT,
+                eventType);
         searchTargetEvent.shortcut = mShortcutInfo;
         if (mPlugin != null) {
             mPlugin.notifySearchTargetEvent(searchTargetEvent);
diff --git a/src/com/android/launcher3/views/SearchSectionHeaderView.java b/src/com/android/launcher3/views/SearchSectionHeaderView.java
index d439ee3..0fe0a43 100644
--- a/src/com/android/launcher3/views/SearchSectionHeaderView.java
+++ b/src/com/android/launcher3/views/SearchSectionHeaderView.java
@@ -52,4 +52,9 @@
             setVisibility(INVISIBLE);
         }
     }
+
+    @Override
+    public Object[] getTargetInfo() {
+        return null;
+    }
 }
diff --git a/src/com/android/launcher3/views/SearchSettingsRowView.java b/src/com/android/launcher3/views/SearchSettingsRowView.java
index 93bcee2..a1a0172 100644
--- a/src/com/android/launcher3/views/SearchSettingsRowView.java
+++ b/src/com/android/launcher3/views/SearchSettingsRowView.java
@@ -48,6 +48,8 @@
     private TextView mBreadcrumbsView;
     private Intent mIntent;
     private AllAppsSearchPlugin mPlugin;
+    private final Object[] mTargetInfo = createTargetInfo();
+
 
     public SearchSettingsRowView(@NonNull Context context) {
         super(context);
@@ -87,6 +89,11 @@
         adapterItemWithPayload.setSelectionHandler(this::handleSelection);
     }
 
+    @Override
+    public Object[] getTargetInfo() {
+        return mTargetInfo;
+    }
+
     private void showIfAvailable(TextView view, @Nullable String string) {
         if (TextUtils.isEmpty(string)) {
             view.setVisibility(GONE);
@@ -108,7 +115,7 @@
         Launcher launcher = Launcher.getLauncher(getContext());
         launcher.startActivityForResult(mIntent, 0);
 
-        SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
+        SearchTargetEvent searchTargetEvent = getSearchTargetEvent(
                 SearchTarget.ItemType.SETTINGS_ROW, eventType);
         searchTargetEvent.bundle = new Bundle();
         searchTargetEvent.bundle.putParcelable("intent", mIntent);
diff --git a/src/com/android/launcher3/views/ThumbnailSearchResultView.java b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
index decc861..1d58a06 100644
--- a/src/com/android/launcher3/views/ThumbnailSearchResultView.java
+++ b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
@@ -39,8 +39,10 @@
 public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppCompatImageView
         implements AllAppsSearchBarController.PayloadResultHandler<Bundle> {
 
+    private final Object[] mTargetInfo = createTargetInfo();
     Intent mIntent;
     AllAppsSearchPlugin mPlugin;
+    int mPosition;
 
     public ThumbnailSearchResultView(Context context) {
         super(context);
@@ -58,7 +60,7 @@
         Launcher launcher = Launcher.getLauncher(getContext());
         launcher.startActivitySafely(this, mIntent, null);
 
-        SearchTargetEvent event = new SearchTargetEvent(
+        SearchTargetEvent event = getSearchTargetEvent(
                 SearchTarget.ItemType.SCREENSHOT, eventType);
         if (mPlugin != null) {
             mPlugin.notifySearchTargetEvent(event);
@@ -67,6 +69,7 @@
 
     @Override
     public void applyAdapterInfo(AdapterItemWithPayload<Bundle> adapterItem) {
+        mPosition = adapterItem.position;
         RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(null,
                 (Bitmap) adapterItem.getPayload().getParcelable("bitmap"));
         drawable.setCornerRadius(Themes.getDialogCornerRadius(getContext()));
@@ -78,4 +81,9 @@
         mPlugin = adapterItem.getPlugin();
         adapterItem.setSelectionHandler(this::handleSelection);
     }
+
+    @Override
+    public Object[] getTargetInfo() {
+        return mTargetInfo;
+    }
 }
diff --git a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
index 48369a4..aa3ab8f 100644
--- a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
@@ -32,7 +32,7 @@
 @ProvidesInterface(action = AllAppsSearchPlugin.ACTION, version = AllAppsSearchPlugin.VERSION)
 public interface AllAppsSearchPlugin extends Plugin {
     String ACTION = "com.android.systemui.action.PLUGIN_ALL_APPS_SEARCH_ACTIONS";
-    int VERSION = 6;
+    int VERSION = 7;
 
     void setup(Activity activity, View view);
 
diff --git a/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java b/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
index 9144976..fb8dd72 100644
--- a/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
+++ b/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
@@ -122,6 +122,7 @@
     public List<ShortcutInfo> shortcuts;
     public Bundle bundle;
     public float score;
+    public String mSessionId;
 
     /**
      * Constructor to create the search target. Bundle is currently temporary to hold
@@ -130,11 +131,12 @@
      *
      */
     public SearchTarget(ItemType itemType, List<ShortcutInfo> shortcuts,
-            Bundle bundle, float score) {
+            Bundle bundle, float score, String sessionId) {
         this.type = itemType;
         this.shortcuts = shortcuts;
         this.bundle = bundle;
         this.score = score;
+        this.mSessionId = sessionId;
     }
 
     @Override
diff --git a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
index ac4bc33..00a78de 100644
--- a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
+++ b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
@@ -31,10 +31,14 @@
     public ShortcutInfo shortcut;
     public int eventType;
     public Bundle bundle;
-    public float score;
+    public int index;
+    public String sessionIdentifier;
 
-    public SearchTargetEvent(SearchTarget.ItemType itemType, int eventType) {
+    public SearchTargetEvent(SearchTarget.ItemType itemType, int eventType, int index,
+            String sessionId) {
         this.type = itemType;
         this.eventType = eventType;
+        this.index = index;
+        this.sessionIdentifier = sessionId;
     }
 }