From f4eb70c96edcdb368efd05d9f6895438d742079e Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Thu, 10 Sep 2020 12:05:19 -0700 Subject: [PATCH] Setup logging pipeline for search results Bug: 168121204 Test: Manual Change-Id: I4abb6c75aa0f22416616a713733bef2802b703d1 --- .../allapps/AllAppsContainerView.java | 28 +++--- .../launcher3/allapps/AllAppsGridAdapter.java | 99 ++++++++++++++++--- .../search/AllAppsSearchBarController.java | 5 - .../launcher3/views/HeroSearchResultView.java | 57 ++++++++++- .../views/SearchResultPeopleView.java | 44 +++++++-- .../launcher3/views/SearchResultPlayItem.java | 21 +++- .../launcher3/views/SearchResultShortcut.java | 30 ++++-- .../views/SearchSettingsRowView.java | 21 +++- .../systemui/plugins/AllAppsSearchPlugin.java | 5 +- .../plugins/shared/SearchTargetEvent.java | 15 +-- 10 files changed, 264 insertions(+), 61 deletions(-) diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 1f515669a6..5079469f4a 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -67,6 +67,9 @@ import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.Themes; import com.android.launcher3.views.RecyclerViewFastScroller; import com.android.launcher3.views.SpringRelativeLayout; +import com.android.systemui.plugins.shared.SearchTargetEvent; + +import java.util.function.IntConsumer; /** * The all apps view container. @@ -538,34 +541,35 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo * Handles selection on focused view and returns success */ public boolean selectFocusedView(View v) { - ItemInfo itemInfo = getHighlightedItemInfo(); - if (itemInfo != null) { - return mLauncher.startActivitySafely(v, itemInfo.getIntent(), itemInfo); + ItemInfo headerItem = getHighlightedItemFromHeader(); + if (headerItem != null) { + return mLauncher.startActivitySafely(v, headerItem.getIntent(), headerItem); } AdapterItem focusedItem = getActiveRecyclerView().getApps().getFocusedChild(); if (focusedItem instanceof AdapterItemWithPayload) { - Runnable onSelection = ((AdapterItemWithPayload) focusedItem).getSelectionHandler(); + IntConsumer onSelection = + ((AdapterItemWithPayload) focusedItem).getSelectionHandler(); if (onSelection != null) { - onSelection.run(); + onSelection.accept(SearchTargetEvent.QUICK_SELECT); return true; } } + if (focusedItem.appInfo != null) { + ItemInfo itemInfo = focusedItem.appInfo; + return mLauncher.startActivitySafely(v, itemInfo.getIntent(), itemInfo); + } return false; } /** - * Returns the ItemInfo of a view that is in focus, ready to be launched by an IME. + * Returns the ItemInfo of a focused view inside {@link FloatingHeaderView} */ - public ItemInfo getHighlightedItemInfo() { + public ItemInfo getHighlightedItemFromHeader() { View view = getFloatingHeaderView().getFocusedChild(); if (view != null && view.getTag() instanceof ItemInfo) { return ((ItemInfo) view.getTag()); } - if (getActiveRecyclerView().getApps().getFocusedChild() != null) { - // TODO: when new pipelines are included, getSearchResults - // should be supported at recycler view level and not apps list level. - return getActiveRecyclerView().getApps().getFocusedChild().appInfo; - } + return null; } diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index 4e801a7cc8..f077173c0a 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.net.Uri; +import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -54,8 +55,13 @@ import com.android.launcher3.allapps.search.SearchSectionInfo; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.util.PackageManagerHelper; +import com.android.launcher3.views.HeroSearchResultView; +import com.android.systemui.plugins.AllAppsSearchPlugin; +import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; import java.util.List; +import java.util.function.IntConsumer; /** * The grid view adapter of all the apps. @@ -196,18 +202,28 @@ public class AllAppsGridAdapter extends */ public static class AdapterItemWithPayload extends AdapterItem { private T mPayload; - private Runnable mSelectionHandler; + private AllAppsSearchPlugin mPlugin; + private IntConsumer mSelectionHandler; - public AdapterItemWithPayload(T payload, int type) { - mPayload = payload; - viewType = type; + public AllAppsSearchPlugin getPlugin() { + return mPlugin; } - public void setSelectionHandler(Runnable runnable) { + public void setPlugin(AllAppsSearchPlugin plugin) { + mPlugin = plugin; + } + + public AdapterItemWithPayload(T payload, int type, AllAppsSearchPlugin plugin) { + mPayload = payload; + viewType = type; + mPlugin = plugin; + } + + public void setSelectionHandler(IntConsumer runnable) { mSelectionHandler = runnable; } - public Runnable getSelectionHandler() { + public IntConsumer getSelectionHandler() { return mSelectionHandler; } @@ -396,10 +412,12 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_ICON: BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate( R.layout.all_apps_icon, parent, false); - icon.setOnClickListener(mOnIconClickListener); - icon.setOnLongClickListener(mOnIconLongClickListener); icon.setLongPressTimeoutFactor(1f); icon.setOnFocusChangeListener(mIconFocusListener); + if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) { + icon.setOnClickListener(mOnIconClickListener); + icon.setOnLongClickListener(mOnIconLongClickListener); + } // Ensure the all apps icon height matches the workspace icons in portrait mode. icon.getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx; @@ -419,7 +437,6 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_CORPUS_TITLE: return new ViewHolder( mLayoutInflater.inflate(R.layout.search_section_title, parent, false)); - case VIEW_TYPE_SEARCH_HERO_APP: return new ViewHolder(mLayoutInflater.inflate( R.layout.search_result_hero_app, parent, false)); @@ -447,10 +464,36 @@ public class AllAppsGridAdapter extends public void onBindViewHolder(ViewHolder holder, int position) { switch (holder.getItemViewType()) { case VIEW_TYPE_ICON: - AppInfo info = mApps.getAdapterItems().get(position).appInfo; + AdapterItem adapterItem = mApps.getAdapterItems().get(position); + AppInfo info = adapterItem.appInfo; BubbleTextView icon = (BubbleTextView) holder.itemView; icon.reset(); icon.applyFromApplicationInfo(info); + if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) { + break; + } + //TODO: replace with custom TopHitBubbleTextView with support for both shortcut + // and apps + if (adapterItem instanceof AdapterItemWithPayload) { + AdapterItemWithPayload withPayload = (AdapterItemWithPayload) adapterItem; + IntConsumer selectionHandler = type -> { + SearchTargetEvent e = new SearchTargetEvent(SearchTarget.ItemType.APP, + type); + e.bundle = HeroSearchResultView.getAppBundle(info); + if (withPayload.getPlugin() != null) { + withPayload.getPlugin().notifySearchTargetEvent(e); + } + }; + icon.setOnClickListener(view -> { + selectionHandler.accept(SearchTargetEvent.SELECT); + mOnIconClickListener.onClick(view); + }); + icon.setOnLongClickListener(view -> { + selectionHandler.accept(SearchTargetEvent.LONG_PRESS); + return mOnIconLongClickListener.onLongClick(view); + }); + withPayload.setSelectionHandler(selectionHandler); + } break; case VIEW_TYPE_EMPTY_SEARCH: TextView emptyViewText = (TextView) holder.itemView; @@ -468,11 +511,22 @@ public class AllAppsGridAdapter extends break; case VIEW_TYPE_SEARCH_SLICE: SliceView sliceView = (SliceView) holder.itemView; - Uri uri = ((AdapterItemWithPayload) mApps.getAdapterItems().get(position)) - .getPayload(); + AdapterItemWithPayload item = + (AdapterItemWithPayload) mApps.getAdapterItems().get(position); + sliceView.setOnSliceActionListener((info1, s) -> { + if (item.getPlugin() != null) { + SearchTargetEvent searchTargetEvent = new SearchTargetEvent( + SearchTarget.ItemType.SETTINGS_SLICE, + SearchTargetEvent.CHILD_SELECT); + searchTargetEvent.bundle = new Bundle(); + searchTargetEvent.bundle.putParcelable("uri", item.getPayload()); + item.getPlugin().notifySearchTargetEvent(searchTargetEvent); + } + }); try { - LiveData liveData = SliceLiveData.fromUri(mLauncher, uri); + LiveData liveData = SliceLiveData.fromUri(mLauncher, item.getPayload()); liveData.observe(this::getLifecycle, sliceView); + sliceView.setTag(liveData); } catch (Exception ignored) { } break; @@ -492,6 +546,25 @@ public class AllAppsGridAdapter extends } } + @Override + public void onViewRecycled(@NonNull ViewHolder holder) { + super.onViewRecycled(holder); + if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) return; + if (holder.itemView instanceof BubbleTextView) { + BubbleTextView icon = (BubbleTextView) holder.itemView; + icon.setOnClickListener(mOnIconClickListener); + icon.setOnLongClickListener(mOnIconLongClickListener); + } else if (holder.itemView instanceof SliceView) { + SliceView sliceView = (SliceView) holder.itemView; + sliceView.setOnSliceActionListener(null); + if (sliceView.getTag() instanceof LiveData) { + LiveData sliceLiveData = (LiveData) sliceView.getTag(); + sliceLiveData.removeObservers(this::getLifecycle); + } + } + } + + @Override public boolean onFailedToRecycleView(ViewHolder holder) { // Always recycle and we will reset the view when it is bound diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index 29e340480d..3320189a1d 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -115,11 +115,6 @@ public class AllAppsSearchBarController if (actionId == EditorInfo.IME_ACTION_SEARCH) { // selectFocusedView should return SearchTargetEvent that is passed onto onClick if (Launcher.getLauncher(mLauncher).getAppsView().selectFocusedView(v)) { - if (mSearchAlgorithm instanceof PluginWrapper) { - ((PluginWrapper) mSearchAlgorithm).runOnPluginIfConnected(plugin -> { - plugin.onClick(false, null); - }); - } return true; } } diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java index 761ef0d639..a8e1c6b30c 100644 --- a/src/com/android/launcher3/views/HeroSearchResultView.java +++ b/src/com/android/launcher3/views/HeroSearchResultView.java @@ -18,7 +18,9 @@ package com.android.launcher3.views; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS; import android.content.Context; +import android.content.Intent; import android.graphics.Point; +import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -41,6 +43,9 @@ import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; import com.android.launcher3.touch.ItemLongClickListener; +import com.android.systemui.plugins.AllAppsSearchPlugin; +import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; import java.util.List; @@ -54,6 +59,7 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, BubbleTextView mBubbleTextView; View mIconView; BubbleTextView[] mDeepShortcutTextViews = new BubbleTextView[2]; + AllAppsSearchPlugin mPlugin; public HeroSearchResultView(Context context) { super(context); @@ -79,7 +85,10 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, mBubbleTextView = findViewById(R.id.bubble_text); - mBubbleTextView.setOnClickListener(launcher.getItemOnClickListener()); + mBubbleTextView.setOnClickListener(view -> { + handleSelection(SearchTargetEvent.SELECT); + launcher.getItemOnClickListener().onClick(view); + }); mBubbleTextView.setOnLongClickListener(new HeroItemDragHandler(getContext(), this)); setLayoutParams( new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, grid.allAppsCellHeightPx)); @@ -91,7 +100,18 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, bubbleTextView.setLayoutParams( new LinearLayout.LayoutParams(grid.allAppsIconSizePx, grid.allAppsIconSizePx)); - bubbleTextView.setOnClickListener(launcher.getItemOnClickListener()); + bubbleTextView.setOnClickListener(view -> { + WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag(); + SearchTargetEvent event = new SearchTargetEvent( + SearchTarget.ItemType.APP_HERO, + SearchTargetEvent.CHILD_SELECT); + event.bundle = getAppBundle(itemInfo); + event.bundle.putString("shortcut_id", itemInfo.getDeepShortcutId()); + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(event); + } + launcher.getItemOnClickListener().onClick(view); + }); } } @@ -110,6 +130,8 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, mDeepShortcutTextViews[i].applyFromItemInfoWithIcon(shorcutInfos.get(i)); } } + mPlugin = adapterItem.getPlugin(); + adapterItem.setSelectionHandler(this::handleSelection); } @Override @@ -147,7 +169,38 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, mLauncher.getWorkspace().beginDragShared(mContainer.mBubbleTextView, draggableView, mContainer, itemInfo, previewProvider, new DragOptions()); + SearchTargetEvent event = new SearchTargetEvent( + SearchTarget.ItemType.APP_HERO, SearchTargetEvent.LONG_PRESS); + event.bundle = getAppBundle(itemInfo); + if (mContainer.mPlugin != null) { + mContainer.mPlugin.notifySearchTargetEvent(event); + } + return false; } } + + private void handleSelection(int eventType) { + ItemInfo itemInfo = (ItemInfo) mBubbleTextView.getTag(); + if (itemInfo == null) return; + Launcher launcher = Launcher.getLauncher(getContext()); + launcher.startActivitySafely(this, itemInfo.getIntent(), itemInfo); + + SearchTargetEvent event = new SearchTargetEvent( + SearchTarget.ItemType.APP_HERO, eventType); + event.bundle = getAppBundle(itemInfo); + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(event); + } + } + + /** + * Helper method to generate {@link SearchTargetEvent} bundle from {@link ItemInfo} + */ + public static Bundle getAppBundle(ItemInfo itemInfo) { + Bundle b = new Bundle(); + b.putParcelable(Intent.EXTRA_COMPONENT_NAME, itemInfo.getTargetComponent()); + b.putParcelable(Intent.EXTRA_USER, itemInfo.user); + return b; + } } diff --git a/src/com/android/launcher3/views/SearchResultPeopleView.java b/src/com/android/launcher3/views/SearchResultPeopleView.java index d1e34fa65f..78e9841d36 100644 --- a/src/com/android/launcher3/views/SearchResultPeopleView.java +++ b/src/com/android/launcher3/views/SearchResultPeopleView.java @@ -45,6 +45,9 @@ import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsGridAdapter; import com.android.launcher3.allapps.search.AllAppsSearchBarController; import com.android.launcher3.util.Themes; +import com.android.systemui.plugins.AllAppsSearchPlugin; +import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; import java.net.URISyntaxException; import java.util.ArrayList; @@ -58,9 +61,12 @@ public class SearchResultPeopleView extends LinearLayout implements private final int mIconSize; private final int mButtonSize; private final PackageManager mPackageManager; - View mIconView; - TextView mTitleView; - ImageButton[] mProviderButtons = new ImageButton[3]; + private View mIconView; + private TextView mTitleView; + private ImageButton[] mProviderButtons = new ImageButton[3]; + private AllAppsSearchPlugin mPlugin; + private Uri mContactUri; + public SearchResultPeopleView(Context context) { this(context, null, 0); @@ -93,14 +99,14 @@ public class SearchResultPeopleView extends LinearLayout implements button.getLayoutParams().width = mButtonSize; button.getLayoutParams().height = mButtonSize; } - setOnClickListener(v -> handleSelection()); + setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT)); } @Override public void applyAdapterInfo( AllAppsGridAdapter.AdapterItemWithPayload adapterItemWithPayload) { - Launcher launcher = Launcher.getLauncher(getContext()); Bundle payload = adapterItemWithPayload.getPayload(); + mPlugin = adapterItemWithPayload.getPlugin(); mTitleView.setText(payload.getString("title")); mContactUri = payload.getParcelable("contact_uri"); Bitmap icon = payload.getParcelable("icon"); @@ -122,8 +128,8 @@ public class SearchResultPeopleView extends LinearLayout implements 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); String pkg = provider.getString("package_name"); - button.setOnClickListener(b -> launcher.startActivitySafely(b, intent, null)); UI_HELPER_EXECUTOR.post(() -> { try { ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo( @@ -144,13 +150,35 @@ public class SearchResultPeopleView extends LinearLayout implements adapterItemWithPayload.setSelectionHandler(this::handleSelection); } - Uri mContactUri; + private void setupProviderButton(ImageButton button, Bundle provider, Intent intent) { + Launcher launcher = Launcher.getLauncher(getContext()); + button.setOnClickListener(b -> { + launcher.startActivitySafely(b, intent, null); + SearchTargetEvent searchTargetEvent = new SearchTargetEvent( + SearchTarget.ItemType.PEOPLE, + SearchTargetEvent.CHILD_SELECT); + searchTargetEvent.bundle = new Bundle(); + searchTargetEvent.bundle.putParcelable("contact_uri", mContactUri); + searchTargetEvent.bundle.putBundle("provider", provider); + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(searchTargetEvent); + } + }); + } - private void handleSelection() { + + private void handleSelection(int eventType) { if (mContactUri != null) { 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.bundle = new Bundle(); + searchTargetEvent.bundle.putParcelable("contact_uri", mContactUri); + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(searchTargetEvent); + } } } } diff --git a/src/com/android/launcher3/views/SearchResultPlayItem.java b/src/com/android/launcher3/views/SearchResultPlayItem.java index 19a4c5d84c..8624609f80 100644 --- a/src/com/android/launcher3/views/SearchResultPlayItem.java +++ b/src/com/android/launcher3/views/SearchResultPlayItem.java @@ -38,6 +38,9 @@ import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; import com.android.launcher3.allapps.search.AllAppsSearchBarController; +import com.android.systemui.plugins.AllAppsSearchPlugin; +import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; import java.io.IOException; import java.net.URL; @@ -54,6 +57,7 @@ public class SearchResultPlayItem extends LinearLayout implements private Button mPreviewButton; private String mPackageName; private boolean mIsInstantGame; + private AllAppsSearchPlugin mPlugin; public SearchResultPlayItem(Context context) { this(context, null, 0); @@ -84,13 +88,14 @@ public class SearchResultPlayItem extends LinearLayout implements ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams(); iconParams.height = mDeviceProfile.allAppsIconSizePx; iconParams.width = mDeviceProfile.allAppsIconSizePx; - setOnClickListener(view -> handleSelection()); + setOnClickListener(view -> handleSelection(SearchTargetEvent.SELECT)); } @Override public void applyAdapterInfo(AdapterItemWithPayload adapterItemWithPayload) { Bundle bundle = adapterItemWithPayload.getPayload(); + mPlugin = adapterItemWithPayload.getPlugin(); adapterItemWithPayload.setSelectionHandler(this::handleSelection); if (bundle.getString("package", "").equals(mPackageName)) { return; @@ -129,13 +134,14 @@ public class SearchResultPlayItem extends LinearLayout implements } } - private void handleSelection() { + private void handleSelection(int eventType) { if (mPackageName == null) return; Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse( "https://play.google.com/store/apps/details?id=" + mPackageName)); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getContext().startActivity(i); + logSearchEvent(eventType); } private void launchInstantGame() { @@ -150,5 +156,16 @@ public class SearchResultPlayItem extends LinearLayout implements intent.putExtra("callerId", getContext().getPackageName()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getContext().startActivity(intent); + logSearchEvent(SearchTargetEvent.CHILD_SELECT); + } + + private void logSearchEvent(int eventType) { + SearchTargetEvent searchTargetEvent = new SearchTargetEvent( + SearchTarget.ItemType.PLAY_RESULTS, eventType); + searchTargetEvent.bundle = new Bundle(); + searchTargetEvent.bundle.putString("package_name", mPackageName); + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(searchTargetEvent); + } } } diff --git a/src/com/android/launcher3/views/SearchResultShortcut.java b/src/com/android/launcher3/views/SearchResultShortcut.java index a402719e76..307cf34c7d 100644 --- a/src/com/android/launcher3/views/SearchResultShortcut.java +++ b/src/com/android/launcher3/views/SearchResultShortcut.java @@ -36,7 +36,9 @@ import com.android.launcher3.allapps.AllAppsGridAdapter; import com.android.launcher3.allapps.search.AllAppsSearchBarController; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.touch.ItemClickHandler; +import com.android.systemui.plugins.AllAppsSearchPlugin; import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; /** * A view representing a stand alone shortcut search result @@ -44,8 +46,10 @@ import com.android.systemui.plugins.shared.SearchTarget; public class SearchResultShortcut extends FrameLayout implements AllAppsSearchBarController.PayloadResultHandler { - BubbleTextView mBubbleTextView; - View mIconView; + private BubbleTextView mBubbleTextView; + private View mIconView; + private ShortcutInfo mShortcutInfo; + private AllAppsSearchPlugin mPlugin; public SearchResultShortcut(@NonNull Context context) { super(context); @@ -71,28 +75,36 @@ public class SearchResultShortcut extends FrameLayout implements iconParams.height = grid.allAppsIconSizePx; iconParams.width = grid.allAppsIconSizePx; mBubbleTextView = findViewById(R.id.bubble_text); - setOnClickListener(v -> handleSelection()); + setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT)); } @Override public void applyAdapterInfo( AllAppsGridAdapter.AdapterItemWithPayload adapterItemWithPayload) { SearchTarget payload = adapterItemWithPayload.getPayload(); - ShortcutInfo si = payload.shortcuts.get(0); - WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(si, getContext()); + mPlugin = adapterItemWithPayload.getPlugin(); + mShortcutInfo = payload.shortcuts.get(0); + WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(mShortcutInfo, getContext()); mBubbleTextView.applyFromWorkspaceItem(workspaceItemInfo); mIconView.setBackground(mBubbleTextView.getIcon()); LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext()); MODEL_EXECUTOR.execute(() -> { - launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, si); + launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, mShortcutInfo); mBubbleTextView.applyFromWorkspaceItem(workspaceItemInfo); mIconView.setBackground(mBubbleTextView.getIcon()); }); adapterItemWithPayload.setSelectionHandler(this::handleSelection); } - private void handleSelection() { - ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) mBubbleTextView.getTag(), - Launcher.getLauncher(getContext())); + 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.shortcut = mShortcutInfo; + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(searchTargetEvent); + } } } diff --git a/src/com/android/launcher3/views/SearchSettingsRowView.java b/src/com/android/launcher3/views/SearchSettingsRowView.java index 08c78ffc3a..93bcee2585 100644 --- a/src/com/android/launcher3/views/SearchSettingsRowView.java +++ b/src/com/android/launcher3/views/SearchSettingsRowView.java @@ -31,6 +31,9 @@ import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsGridAdapter; import com.android.launcher3.allapps.search.AllAppsSearchBarController; +import com.android.systemui.plugins.AllAppsSearchPlugin; +import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; import java.util.ArrayList; @@ -44,6 +47,7 @@ public class SearchSettingsRowView extends LinearLayout implements private TextView mDescriptionView; private TextView mBreadcrumbsView; private Intent mIntent; + private AllAppsSearchPlugin mPlugin; public SearchSettingsRowView(@NonNull Context context) { super(context); @@ -72,6 +76,7 @@ public class SearchSettingsRowView extends LinearLayout implements public void applyAdapterInfo( AllAppsGridAdapter.AdapterItemWithPayload adapterItemWithPayload) { Bundle bundle = adapterItemWithPayload.getPayload(); + mPlugin = adapterItemWithPayload.getPlugin(); mIntent = bundle.getParcelable("intent"); showIfAvailable(mTitleView, bundle.getString("title")); showIfAvailable(mDescriptionView, bundle.getString("description")); @@ -79,7 +84,7 @@ public class SearchSettingsRowView extends LinearLayout implements //TODO: implement RTL friendly breadcrumbs view showIfAvailable(mBreadcrumbsView, breadcrumbs != null ? String.join(" > ", breadcrumbs) : null); - adapterItemWithPayload.setSelectionHandler(() -> onClick(this)); + adapterItemWithPayload.setSelectionHandler(this::handleSelection); } private void showIfAvailable(TextView view, @Nullable String string) { @@ -93,10 +98,22 @@ public class SearchSettingsRowView extends LinearLayout implements @Override public void onClick(View view) { + handleSelection(SearchTargetEvent.SELECT); + } + + private void handleSelection(int eventType) { if (mIntent == null) return; // TODO: create ItemInfo object and then use it to call startActivityForResult for proper // WW logging - Launcher launcher = Launcher.getLauncher(view.getContext()); + Launcher launcher = Launcher.getLauncher(getContext()); launcher.startActivityForResult(mIntent, 0); + + SearchTargetEvent searchTargetEvent = new SearchTargetEvent( + SearchTarget.ItemType.SETTINGS_ROW, eventType); + searchTargetEvent.bundle = new Bundle(); + searchTargetEvent.bundle.putParcelable("intent", mIntent); + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(searchTargetEvent); + } } } diff --git a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java index 9949678458..437cf3cfe5 100644 --- a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java +++ b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java @@ -47,7 +47,10 @@ public interface AllAppsSearchPlugin extends Plugin { */ void performSearch(String query, Consumer> results); - void onClick(boolean isTouch, SearchTargetEvent event); + /** + * Send over search target interaction events to Plugin + */ + void notifySearchTargetEvent(SearchTargetEvent event); /** * Send signal when user exits all apps. diff --git a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java index 00aacd0543..ac4bc333c6 100644 --- a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java +++ b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java @@ -22,18 +22,19 @@ import android.os.Bundle; * Event used for the feedback loop to the plugin. (and future aiai) */ public class SearchTargetEvent { + public static final int SELECT = 0; + public static final int QUICK_SELECT = 1; + public static final int LONG_PRESS = 2; + public static final int CHILD_SELECT = 3; + public SearchTarget.ItemType type; public ShortcutInfo shortcut; + public int eventType; public Bundle bundle; public float score; - public SearchTargetEvent(SearchTarget.ItemType itemType, - ShortcutInfo shortcut, - Bundle bundle, - float score) { + public SearchTargetEvent(SearchTarget.ItemType itemType, int eventType) { this.type = itemType; - this.shortcut = shortcut; - this.bundle = bundle; - this.score = score; + this.eventType = eventType; } }