diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 75ab00a7dd..5d5e017372 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -16,7 +16,7 @@ package com.android.launcher3.allapps; import static com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem; -import static com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; +import static com.android.launcher3.allapps.AllAppsGridAdapter.SearchAdapterItem; import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION; import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION; import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED; @@ -57,6 +57,7 @@ import com.android.launcher3.Insettable; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.allapps.search.SearchEventTracker; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.keyboard.FocusedItemDecorator; import com.android.launcher3.model.data.AppInfo; @@ -67,9 +68,7 @@ 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; +import com.android.systemui.plugins.shared.SearchTarget; /** * The all apps view container. @@ -546,13 +545,9 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo return mLauncher.startActivitySafely(v, headerItem.getIntent(), headerItem); } AdapterItem focusedItem = getActiveRecyclerView().getApps().getFocusedChild(); - if (focusedItem instanceof AdapterItemWithPayload) { - IntConsumer onSelection = - ((AdapterItemWithPayload) focusedItem).getSelectionHandler(); - if (onSelection != null) { - onSelection.accept(SearchTargetEvent.QUICK_SELECT); - return true; - } + if (focusedItem instanceof SearchAdapterItem) { + SearchTarget searchTarget = ((SearchAdapterItem) focusedItem).getSearchTarget(); + SearchEventTracker.INSTANCE.get(getContext()).quickSelect(searchTarget); } if (focusedItem.appInfo != null) { ItemInfo itemInfo = focusedItem.appInfo; @@ -585,6 +580,10 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo int padding = mHeader.getMaxTranslation(); for (int i = 0; i < mAH.length; i++) { mAH[i].padding.top = padding; + if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && mUsingTabs) { + //add extra space between tabs and recycler view + mAH[i].padding.top += mLauncher.getDeviceProfile().edgeMarginPx; + } mAH[i].applyPadding(); } } diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index 8bc8e53af3..603e9df16c 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -20,8 +20,6 @@ import static com.android.launcher3.touch.ItemLongClickListener.INSTANCE_ALL_APP 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; @@ -37,29 +35,25 @@ import androidx.annotation.Nullable; import androidx.core.view.accessibility.AccessibilityEventCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityRecordCompat; -import androidx.lifecycle.LiveData; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.slice.Slice; -import androidx.slice.widget.SliceLiveData; import androidx.slice.widget.SliceView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.BubbleTextView; -import com.android.launcher3.Launcher; import com.android.launcher3.R; -import com.android.launcher3.allapps.search.AllAppsSearchBarController.PayloadResultHandler; +import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler; +import com.android.launcher3.allapps.search.SearchEventTracker; 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.launcher3.views.SearchSliceWrapper; 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. @@ -201,28 +195,13 @@ public class AllAppsGridAdapter extends * * @param Play load Type */ - public static class AdapterItemWithPayload extends AdapterItem { - private T mPayload; + public static class SearchAdapterItem extends AdapterItem { + private SearchTarget mSearchTarget; private String mSearchSessionId; - private AllAppsSearchPlugin mPlugin; - private IntConsumer mSelectionHandler; - public AllAppsSearchPlugin getPlugin() { - return mPlugin; - } - - public void setPlugin(AllAppsSearchPlugin plugin) { - mPlugin = plugin; - } - - public AdapterItemWithPayload(T payload, int type, AllAppsSearchPlugin plugin) { - mPayload = payload; + public SearchAdapterItem(SearchTarget searchTarget, int type) { + mSearchTarget = searchTarget; viewType = type; - mPlugin = plugin; - } - - public void setSelectionHandler(IntConsumer runnable) { - mSelectionHandler = runnable; } public void setSearchSessionId(String searchSessionId) { @@ -233,15 +212,9 @@ public class AllAppsGridAdapter extends return mSearchSessionId; } - public IntConsumer getSelectionHandler() { - return mSelectionHandler; + public SearchTarget getSearchTarget() { + return mSearchTarget; } - - public T getPayload() { - return mPayload; - } - - } /** @@ -492,26 +465,35 @@ public class AllAppsGridAdapter extends } //TODO: replace with custom TopHitBubbleTextView with support for both shortcut // and apps - if (adapterItem instanceof AdapterItemWithPayload) { - AdapterItemWithPayload item = (AdapterItemWithPayload) adapterItem; - item.setSelectionHandler(type -> { - SearchTargetEvent e = new SearchTargetEvent(SearchTarget.ItemType.APP, - type, item.position, item.getSearchSessionId()); - e.bundle = HeroSearchResultView.getAppBundle(info); - if (item.getPlugin() != null) { - item.getPlugin().notifySearchTargetEvent(e); + if (adapterItem instanceof SearchAdapterItem) { + SearchAdapterItem item = (SearchAdapterItem) adapterItem; + SearchTargetHandler searchTargetHandler = new SearchTargetHandler() { + @Override + public void applySearchTarget(SearchTarget searchTarget) { + // Does nothing } - }); + + @Override + public void handleSelection(int type) { + SearchTargetEvent e = new SearchTargetEvent(SearchTarget.ItemType.APP, + type, item.position, item.getSearchSessionId()); + e.bundle = HeroSearchResultView.getAppBundle(info); + SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(e); + } + }; + SearchEventTracker.INSTANCE.get(mLauncher).registerWeakHandler( + ((SearchAdapterItem) adapterItem).getSearchTarget(), + searchTargetHandler); + icon.setOnClickListener(view -> { - item.getSelectionHandler().accept(SearchTargetEvent.SELECT); + searchTargetHandler.handleSelection(SearchTargetEvent.SELECT); mOnIconClickListener.onClick(view); }); icon.setOnLongClickListener(view -> { - item.getSelectionHandler().accept(SearchTargetEvent.SELECT); + searchTargetHandler.handleSelection(SearchTargetEvent.LONG_PRESS); return mOnIconLongClickListener.onLongClick(view); }); - } - else { + } else { icon.setOnClickListener(mOnIconClickListener); icon.setOnLongClickListener(mOnIconLongClickListener); } @@ -532,26 +514,12 @@ public class AllAppsGridAdapter extends break; case VIEW_TYPE_SEARCH_SLICE: SliceView sliceView = (SliceView) holder.itemView; - AdapterItemWithPayload slicePayload = - (AdapterItemWithPayload) mApps.getAdapterItems().get(position); - sliceView.setOnSliceActionListener((info1, s) -> { - if (slicePayload.getPlugin() != null) { - SearchTargetEvent searchTargetEvent = new SearchTargetEvent( - SearchTarget.ItemType.SETTINGS_SLICE, - SearchTargetEvent.CHILD_SELECT, slicePayload.position, - slicePayload.getSearchSessionId()); - searchTargetEvent.bundle = new Bundle(); - searchTargetEvent.bundle.putParcelable("uri", slicePayload.getPayload()); - slicePayload.getPlugin().notifySearchTargetEvent(searchTargetEvent); - } - }); - try { - LiveData liveData = SliceLiveData.fromUri(mLauncher, - slicePayload.getPayload()); - liveData.observe((Launcher) mLauncher, sliceView); - sliceView.setTag(liveData); - } catch (Exception ignored) { - } + SearchAdapterItem slicePayload = (SearchAdapterItem) mApps.getAdapterItems().get( + position); + SearchTarget searchTarget = slicePayload.getSearchTarget(); + sliceView.setTag(new SearchSliceWrapper(mLauncher, sliceView, searchTarget, + slicePayload.getSearchSessionId(), slicePayload.position)); + break; case VIEW_TYPE_SEARCH_CORPUS_TITLE: case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON: @@ -561,9 +529,9 @@ public class AllAppsGridAdapter extends case VIEW_TYPE_SEARCH_PEOPLE: case VIEW_TYPE_SEARCH_THUMBNAIL: case VIEW_TYPE_SEARCH_SUGGEST: - AdapterItemWithPayload item = - (AdapterItemWithPayload) mApps.getAdapterItems().get(position); - PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView; + SearchAdapterItem item = + (SearchAdapterItem) mApps.getAdapterItems().get(position); + SearchTargetHandler payloadResultView = (SearchTargetHandler) holder.itemView; payloadResultView.setup(item); break; case VIEW_TYPE_ALL_APPS_DIVIDER: @@ -582,11 +550,10 @@ public class AllAppsGridAdapter extends icon.setOnLongClickListener(null); } 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((Launcher) mLauncher); + if (sliceView.getTag() instanceof SearchSliceWrapper) { + ((SearchSliceWrapper) sliceView.getTag()).destroy(); } + sliceView.setTag(null); } } diff --git a/src/com/android/launcher3/allapps/AllAppsPagedView.java b/src/com/android/launcher3/allapps/AllAppsPagedView.java index eae9c0a6b6..e2550f597a 100644 --- a/src/com/android/launcher3/allapps/AllAppsPagedView.java +++ b/src/com/android/launcher3/allapps/AllAppsPagedView.java @@ -25,11 +25,11 @@ import com.android.launcher3.config.FeatureFlags; public class AllAppsPagedView extends PagedView { - final static float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6; - final static float MAX_SWIPE_ANGLE = (float) Math.PI / 3; - final static float TOUCH_SLOP_DAMPING_FACTOR = 4; + static final float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6; + static final float MAX_SWIPE_ANGLE = (float) Math.PI / 3; + static final float TOUCH_SLOP_DAMPING_FACTOR = 4; - public AllAppsPagedView(Context context) { + public AllAppsPagedView(Context context) { this(context, null); } @@ -42,6 +42,7 @@ public class AllAppsPagedView extends PagedView { int topPadding = FeatureFlags.ENABLE_DEVICE_SEARCH.get() ? 0 : context.getResources().getDimensionPixelOffset( R.dimen.all_apps_header_top_padding); + setPadding(0, topPadding, 0, 0); } @Override diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index 82c4db4da3..6ba0421d57 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -31,7 +31,7 @@ import com.android.launcher3.ExtendedEditText; import com.android.launcher3.Launcher; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.AllAppsGridAdapter; -import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; +import com.android.launcher3.allapps.AllAppsGridAdapter.SearchAdapterItem; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.PackageManagerHelper; import com.android.systemui.plugins.AllAppsSearchPlugin; @@ -211,26 +211,31 @@ public class AllAppsSearchBarController * * @param Type of payload */ - public interface PayloadResultHandler { + public interface SearchTargetHandler { /** * Updates View using Adapter's payload */ - default void setup(AdapterItemWithPayload adapterItemWithPayload) { + default void setup(SearchAdapterItem searchAdapterItem) { Object[] targetInfo = getTargetInfo(); if (targetInfo != null) { - targetInfo[0] = adapterItemWithPayload.getSearchSessionId(); - targetInfo[1] = adapterItemWithPayload.position; + targetInfo[0] = searchAdapterItem.getSearchSessionId(); + targetInfo[1] = searchAdapterItem.position; } - applyAdapterInfo(adapterItemWithPayload); + applySearchTarget(searchAdapterItem.getSearchTarget()); } - void applyAdapterInfo(AdapterItemWithPayload adapterItemWithPayload); + /** + * Update view using values from {@link SearchTarget} + */ + void applySearchTarget(SearchTarget searchTarget); /** - * Gets object created by {@link PayloadResultHandler#createTargetInfo()} + * Gets object created by {@link SearchTargetHandler#createTargetInfo()} */ - Object[] getTargetInfo(); + default Object[] getTargetInfo() { + return null; + } /** * Creates a wrapper object to hold searchSessionId and item position @@ -252,6 +257,13 @@ public class AllAppsSearchBarController return new SearchTargetEvent(itemType, eventType, position, searchSessionId); } + + /** + * Handles selection of SearchTarget + */ + default void handleSelection(int eventType) { + } + } diff --git a/src/com/android/launcher3/allapps/search/SearchEventTracker.java b/src/com/android/launcher3/allapps/search/SearchEventTracker.java new file mode 100644 index 0000000000..6bcde6c53b --- /dev/null +++ b/src/com/android/launcher3/allapps/search/SearchEventTracker.java @@ -0,0 +1,91 @@ +/* + * 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 com.android.launcher3.allapps.search; + +import android.content.Context; + +import androidx.annotation.Nullable; + +import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler; +import com.android.launcher3.util.MainThreadInitializedObject; +import com.android.systemui.plugins.AllAppsSearchPlugin; +import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; + +import java.util.WeakHashMap; + +/** + * A singleton class to track and report search events to search provider + */ +public class SearchEventTracker { + @Nullable + private AllAppsSearchPlugin mPlugin; + private final WeakHashMap + mCallbacks = new WeakHashMap<>(); + + public static final MainThreadInitializedObject INSTANCE = + new MainThreadInitializedObject<>(SearchEventTracker::new); + + private SearchEventTracker(Context context) { + } + + /** + * Returns instance of SearchEventTracker + */ + public static SearchEventTracker getInstance(Context context) { + return SearchEventTracker.INSTANCE.get(context); + } + + /** + * Sets current connected plugin for event reporting + */ + public void setPlugin(@Nullable AllAppsSearchPlugin plugin) { + mPlugin = plugin; + } + + /** + * Sends SearchTargetEvent to search provider + */ + public void notifySearchTargetEvent(SearchTargetEvent searchTargetEvent) { + if (mPlugin != null) { + mPlugin.notifySearchTargetEvent(searchTargetEvent); + } + } + + /** + * Registers a {@link SearchTargetHandler} to handle quick launch for specified SearchTarget. + */ + public void registerWeakHandler(SearchTarget searchTarget, SearchTargetHandler targetHandler) { + mCallbacks.put(searchTarget, targetHandler); + } + + /** + * Handles quick select for SearchTarget + */ + public void quickSelect(SearchTarget searchTarget) { + SearchTargetHandler searchTargetHandler = mCallbacks.get(searchTarget); + if (searchTargetHandler != null) { + searchTargetHandler.handleSelection(SearchTargetEvent.QUICK_SELECT); + } + } + + /** + * flushes all registered quick select handlers + */ + public void clearHandlers() { + mCallbacks.clear(); + } +} diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java index 91337ba824..9e56e00d60 100644 --- a/src/com/android/launcher3/views/HeroSearchResultView.java +++ b/src/com/android/launcher3/views/HeroSearchResultView.java @@ -19,11 +19,13 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APP import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.graphics.Point; import android.os.Bundle; +import android.os.UserHandle; import android.util.AttributeSet; import android.util.Pair; import android.view.View; @@ -37,8 +39,9 @@ import com.android.launcher3.DropTarget; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; -import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; -import com.android.launcher3.allapps.search.AllAppsSearchBarController.PayloadResultHandler; +import com.android.launcher3.allapps.AllAppsStore; +import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler; +import com.android.launcher3.allapps.search.SearchEventTracker; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DraggableView; import com.android.launcher3.graphics.DragPreviewProvider; @@ -48,24 +51,25 @@ 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.launcher3.util.ComponentKey; import com.android.systemui.plugins.shared.SearchTarget; import com.android.systemui.plugins.shared.SearchTargetEvent; -import java.util.List; +import java.util.ArrayList; /** * A view representing a high confidence app search result that includes shortcuts */ -public class HeroSearchResultView extends LinearLayout implements DragSource, - PayloadResultHandler>> { +public class HeroSearchResultView extends LinearLayout implements DragSource, SearchTargetHandler { public static final int MAX_SHORTCUTS_COUNT = 2; + public static final String SHORTCUTS_KEY = "shortcut_infos"; + + private final Object[] mTargetInfo = createTargetInfo(); BubbleTextView mBubbleTextView; View mIconView; BubbleTextView[] mDeepShortcutTextViews = new BubbleTextView[2]; - AllAppsSearchPlugin mPlugin; public HeroSearchResultView(Context context) { super(context); @@ -111,30 +115,35 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, SearchTargetEvent.CHILD_SELECT); event.bundle = getAppBundle(itemInfo); event.bundle.putString("shortcut_id", itemInfo.getDeepShortcutId()); - if (mPlugin != null) { - mPlugin.notifySearchTargetEvent(event); - } launcher.getItemOnClickListener().onClick(view); }); } } - /** - * Apply {@link ItemInfo} for appIcon and shortcut Icons - */ @Override - public void applyAdapterInfo( - AdapterItemWithPayload>> adapterItem) { - mBubbleTextView.applyFromApplicationInfo(adapterItem.appInfo); + public void applySearchTarget(SearchTarget searchTarget) { + AppInfo appInfo = getAppInfo(searchTarget.bundle); +// TODO: replace this with searchTarget.shortcuts + ArrayList infos = searchTarget.bundle.getParcelableArrayList( + SHORTCUTS_KEY); + + ArrayList> shortcuts = new ArrayList<>(); + for (int i = 0; infos != null && i < infos.size() && i < MAX_SHORTCUTS_COUNT; i++) { + ShortcutInfo shortcutInfo = infos.get(i); + ItemInfoWithIcon si = new WorkspaceItemInfo(shortcutInfo, getContext()); + shortcuts.add(new Pair<>(shortcutInfo, si)); + } + + + mBubbleTextView.applyFromApplicationInfo(appInfo); mIconView.setBackground(mBubbleTextView.getIcon()); - mIconView.setTag(adapterItem.appInfo); - List> shortcutDetails = adapterItem.getPayload(); + mIconView.setTag(appInfo); LauncherAppState appState = LauncherAppState.getInstance(getContext()); for (int i = 0; i < mDeepShortcutTextViews.length; i++) { BubbleTextView shortcutView = mDeepShortcutTextViews[i]; - mDeepShortcutTextViews[i].setVisibility(shortcutDetails.size() > i ? VISIBLE : GONE); - if (i < shortcutDetails.size()) { - Pair p = shortcutDetails.get(i); + mDeepShortcutTextViews[i].setVisibility(shortcuts.size() > i ? VISIBLE : GONE); + if (i < shortcuts.size()) { + Pair p = shortcuts.get(i); //apply ItemInfo and prepare view shortcutView.applyFromWorkspaceItem((WorkspaceItemInfo) p.second); MODEL_EXECUTOR.execute(() -> { @@ -144,8 +153,14 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, }); } } - mPlugin = adapterItem.getPlugin(); - adapterItem.setSelectionHandler(this::handleSelection); + SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this); + } + + private AppInfo getAppInfo(Bundle bundle) { + AllAppsStore apps = Launcher.getLauncher(getContext()).getAppsView().getAppsStore(); + ComponentName cn = bundle.getParcelable("component_name"); + UserHandle userHandle = bundle.getParcelable("user_handle"); + return (cn != null) ? apps.getApp(new ComponentKey(cn, userHandle)) : null; } @Override @@ -191,15 +206,13 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, SearchTargetEvent event = mContainer.getSearchTargetEvent( SearchTarget.ItemType.APP_HERO, SearchTargetEvent.LONG_PRESS); event.bundle = getAppBundle(itemInfo); - if (mContainer.mPlugin != null) { - mContainer.mPlugin.notifySearchTargetEvent(event); - } - + SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(event); return false; } } - private void handleSelection(int eventType) { + @Override + public void handleSelection(int eventType) { ItemInfo itemInfo = (ItemInfo) mBubbleTextView.getTag(); if (itemInfo == null) return; Launcher launcher = Launcher.getLauncher(getContext()); @@ -208,9 +221,7 @@ public class HeroSearchResultView extends LinearLayout implements DragSource, SearchTargetEvent event = getSearchTargetEvent( SearchTarget.ItemType.APP_HERO, eventType); event.bundle = getAppBundle(itemInfo); - if (mPlugin != null) { - mPlugin.notifySearchTargetEvent(event); - } + SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(event); } /** diff --git a/src/com/android/launcher3/views/SearchResultIconRow.java b/src/com/android/launcher3/views/SearchResultIconRow.java index 6d9c86a9a7..ddeefaff3a 100644 --- a/src/com/android/launcher3/views/SearchResultIconRow.java +++ b/src/com/android/launcher3/views/SearchResultIconRow.java @@ -35,8 +35,8 @@ import androidx.annotation.Nullable; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; -import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; import com.android.launcher3.allapps.search.AllAppsSearchBarController; +import com.android.launcher3.allapps.search.SearchEventTracker; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.model.data.ItemInfo; @@ -44,7 +44,6 @@ import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.RemoteActionItemInfo; 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.SearchTarget.ItemType; import com.android.systemui.plugins.shared.SearchTargetEvent; @@ -53,15 +52,13 @@ import com.android.systemui.plugins.shared.SearchTargetEvent; * A view representing a stand alone shortcut search result */ public class SearchResultIconRow extends DoubleShadowBubbleTextView implements - AllAppsSearchBarController.PayloadResultHandler { + AllAppsSearchBarController.SearchTargetHandler { private final Object[] mTargetInfo = createTargetInfo(); private final int mCustomIconResId; private final boolean mMatchesInset; private ShortcutInfo mShortcutInfo; - private AllAppsSearchPlugin mPlugin; - private AdapterItemWithPayload mAdapterItem; public SearchResultIconRow(@NonNull Context context) { @@ -100,26 +97,18 @@ public class SearchResultIconRow extends DoubleShadowBubbleTextView implements } } - @Override - public void applyAdapterInfo(AdapterItemWithPayload adapterItemWithPayload) { - if (mAdapterItem != null) { - mAdapterItem.setSelectionHandler(null); - } - mAdapterItem = adapterItemWithPayload; - SearchTarget payload = adapterItemWithPayload.getPayload(); - mPlugin = adapterItemWithPayload.getPlugin(); - - if (payload.mRemoteAction != null) { - prepareUsingRemoteAction(payload.mRemoteAction, - payload.bundle.getString(SearchTarget.REMOTE_ACTION_TOKEN), - payload.bundle.getBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START), - payload.type == ItemType.ACTION); + public void applySearchTarget(SearchTarget searchTarget) { + if (searchTarget.mRemoteAction != null) { + prepareUsingRemoteAction(searchTarget.mRemoteAction, + searchTarget.bundle.getString(SearchTarget.REMOTE_ACTION_TOKEN), + searchTarget.bundle.getBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START), + searchTarget.type == ItemType.ACTION); } else { - prepareUsingShortcutInfo(payload.shortcuts.get(0)); + prepareUsingShortcutInfo(searchTarget.shortcuts.get(0)); } setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT)); - adapterItemWithPayload.setSelectionHandler(this::handleSelection); + SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this); } private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) { @@ -179,7 +168,8 @@ public class SearchResultIconRow extends DoubleShadowBubbleTextView implements return mTargetInfo; } - private void handleSelection(int eventType) { + @Override + public void handleSelection(int eventType) { ItemInfo itemInfo = (ItemInfo) getTag(); Launcher launcher = Launcher.getLauncher(getContext()); final SearchTargetEvent searchTargetEvent; @@ -200,8 +190,6 @@ public class SearchResultIconRow extends DoubleShadowBubbleTextView implements searchTargetEvent.bundle.putString(SearchTarget.REMOTE_ACTION_TOKEN, remoteItemInfo.getToken()); } - if (mPlugin != null) { - mPlugin.notifySearchTargetEvent(searchTargetEvent); - } + SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(searchTargetEvent); } } diff --git a/src/com/android/launcher3/views/SearchResultPeopleView.java b/src/com/android/launcher3/views/SearchResultPeopleView.java index f20b08016f..18bc99a3f9 100644 --- a/src/com/android/launcher3/views/SearchResultPeopleView.java +++ b/src/com/android/launcher3/views/SearchResultPeopleView.java @@ -42,11 +42,10 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.launcher3.DeviceProfile; 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.launcher3.allapps.search.SearchEventTracker; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.LauncherIcons; -import com.android.systemui.plugins.AllAppsSearchPlugin; import com.android.systemui.plugins.shared.SearchTarget; import com.android.systemui.plugins.shared.SearchTargetEvent; @@ -56,7 +55,7 @@ import java.util.ArrayList; * A view representing a single people search result in all apps */ public class SearchResultPeopleView extends LinearLayout implements - AllAppsSearchBarController.PayloadResultHandler { + AllAppsSearchBarController.SearchTargetHandler { private final int mIconSize; private final int mButtonSize; @@ -64,7 +63,6 @@ public class SearchResultPeopleView extends LinearLayout implements private View mIconView; private TextView mTitleView; private ImageButton[] mProviderButtons = new ImageButton[3]; - private AllAppsSearchPlugin mPlugin; private Intent mIntent; private final Object[] mTargetInfo = createTargetInfo(); @@ -103,10 +101,8 @@ public class SearchResultPeopleView extends LinearLayout implements } @Override - public void applyAdapterInfo( - AllAppsGridAdapter.AdapterItemWithPayload adapterItemWithPayload) { - Bundle payload = adapterItemWithPayload.getPayload(); - mPlugin = adapterItemWithPayload.getPlugin(); + public void applySearchTarget(SearchTarget searchTarget) { + Bundle payload = searchTarget.bundle; mTitleView.setText(payload.getString("title")); mIntent = payload.getParcelable("intent"); Bitmap contactIcon = payload.getParcelable("icon"); @@ -125,7 +121,7 @@ public class SearchResultPeopleView extends LinearLayout implements if (providers != null && i < providers.size()) { Bundle provider = providers.get(i); Intent intent = provider.getParcelable("intent"); - setupProviderButton(button, provider, intent, adapterItemWithPayload); + setupProviderButton(button, provider, intent); UI_HELPER_EXECUTOR.post(() -> { String pkg = provider.getString("package_name"); Drawable appIcon = getAppIcon(pkg); @@ -138,13 +134,13 @@ public class SearchResultPeopleView extends LinearLayout implements button.setVisibility(GONE); } } - adapterItemWithPayload.setSelectionHandler(this::handleSelection); + SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this); } /** - * Normalizes the bitmap to look like rounded App Icon - * TODO(b/170234747) to support styling, generate adaptive icon drawable and generate - * bitmap from it. + * Normalizes the bitmap to look like rounded App Icon + * TODO(b/170234747) to support styling, generate adaptive icon drawable and generate + * bitmap from it. */ private Bitmap roundBitmap(Bitmap icon) { final RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(getResources(), icon); @@ -185,37 +181,32 @@ public class SearchResultPeopleView extends LinearLayout implements return mTargetInfo; } - private void setupProviderButton(ImageButton button, Bundle provider, Intent intent, - AllAppsGridAdapter.AdapterItem adapterItem) { + private void setupProviderButton(ImageButton button, Bundle provider, Intent intent) { Launcher launcher = Launcher.getLauncher(getContext()); button.setOnClickListener(b -> { launcher.startActivitySafely(b, intent, null); - SearchTargetEvent searchTargetEvent = getSearchTargetEvent( + SearchTargetEvent event = getSearchTargetEvent( SearchTarget.ItemType.PEOPLE, SearchTargetEvent.CHILD_SELECT); - searchTargetEvent.bundle = new Bundle(); - searchTargetEvent.bundle.putParcelable("intent", intent); - searchTargetEvent.bundle.putString("title", mTitleView.getText().toString()); - searchTargetEvent.bundle.putBundle("provider", provider); - if (mPlugin != null) { - mPlugin.notifySearchTargetEvent(searchTargetEvent); - } + event.bundle = new Bundle(); + event.bundle.putParcelable("intent", intent); + event.bundle.putString("title", mTitleView.getText().toString()); + event.bundle.putBundle("provider", provider); + SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(event); }); } - - private void handleSelection(int eventType) { + @Override + public void handleSelection(int eventType) { if (mIntent != null) { Launcher launcher = Launcher.getLauncher(getContext()); launcher.startActivitySafely(this, mIntent, null); - SearchTargetEvent searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.PEOPLE, + SearchTargetEvent event = getSearchTargetEvent(SearchTarget.ItemType.PEOPLE, eventType); - searchTargetEvent.bundle = new Bundle(); - searchTargetEvent.bundle.putParcelable("intent", mIntent); - searchTargetEvent.bundle.putString("title", mTitleView.getText().toString()); - if (mPlugin != null) { - mPlugin.notifySearchTargetEvent(searchTargetEvent); - } + event.bundle = new Bundle(); + event.bundle.putParcelable("intent", mIntent); + event.bundle.putString("title", mTitleView.getText().toString()); + SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(event); } } } diff --git a/src/com/android/launcher3/views/SearchResultPlayItem.java b/src/com/android/launcher3/views/SearchResultPlayItem.java index c7133fd8d8..39a83045e4 100644 --- a/src/com/android/launcher3/views/SearchResultPlayItem.java +++ b/src/com/android/launcher3/views/SearchResultPlayItem.java @@ -41,11 +41,10 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; 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.launcher3.allapps.search.SearchEventTracker; import com.android.launcher3.icons.BitmapRenderer; 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; @@ -57,22 +56,19 @@ import java.net.URLConnection; * A View representing a PlayStore item. */ public class SearchResultPlayItem extends LinearLayout implements - AllAppsSearchBarController.PayloadResultHandler { + AllAppsSearchBarController.SearchTargetHandler { private static final int BITMAP_CROP_MASK_COLOR = 0xff424242; - + final Paint mIconPaint = new Paint(); + final Rect mTempRect = new Rect(); private final DeviceProfile mDeviceProfile; + private final Object[] mTargetInfo = createTargetInfo(); private View mIconView; private TextView mTitleView; private TextView[] mDetailViews = new TextView[3]; private Button mPreviewButton; private String mPackageName; private boolean mIsInstantGame; - private AllAppsSearchPlugin mPlugin; - private final Object[] mTargetInfo = createTargetInfo(); - - final Paint mIconPaint = new Paint(); - final Rect mTempRect = new Rect(); public SearchResultPlayItem(Context context) { @@ -108,11 +104,32 @@ public class SearchResultPlayItem extends LinearLayout implements } + + private Bitmap getRoundedBitmap(Bitmap bitmap) { + final int iconSize = bitmap.getWidth(); + final float radius = Themes.getDialogCornerRadius(getContext()); + + Bitmap output = BitmapRenderer.createHardwareBitmap(iconSize, iconSize, (canvas) -> { + mTempRect.set(0, 0, iconSize, iconSize); + final RectF rectF = new RectF(mTempRect); + + mIconPaint.setAntiAlias(true); + mIconPaint.reset(); + canvas.drawARGB(0, 0, 0, 0); + mIconPaint.setColor(BITMAP_CROP_MASK_COLOR); + canvas.drawRoundRect(rectF, radius, radius, mIconPaint); + + mIconPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + canvas.drawBitmap(bitmap, mTempRect, mTempRect, mIconPaint); + }); + return output; + } + + @Override - public void applyAdapterInfo(AdapterItemWithPayload adapterItemWithPayload) { - Bundle bundle = adapterItemWithPayload.getPayload(); - mPlugin = adapterItemWithPayload.getPlugin(); - adapterItemWithPayload.setSelectionHandler(this::handleSelection); + public void applySearchTarget(SearchTarget searchTarget) { + Bundle bundle = searchTarget.bundle; + SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this); if (bundle.getString("package", "").equals(mPackageName)) { return; } @@ -143,28 +160,6 @@ public class SearchResultPlayItem extends LinearLayout implements }); } - - private Bitmap getRoundedBitmap(Bitmap bitmap) { - final int iconSize = bitmap.getWidth(); - final float radius = Themes.getDialogCornerRadius(getContext()); - - Bitmap output = BitmapRenderer.createHardwareBitmap(iconSize, iconSize, (canvas) -> { - mTempRect.set(0, 0, iconSize, iconSize); - final RectF rectF = new RectF(mTempRect); - - mIconPaint.setAntiAlias(true); - mIconPaint.reset(); - canvas.drawARGB(0, 0, 0, 0); - mIconPaint.setColor(BITMAP_CROP_MASK_COLOR); - canvas.drawRoundRect(rectF, radius, radius, mIconPaint); - - mIconPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); - canvas.drawBitmap(bitmap, mTempRect, mTempRect, mIconPaint); - }); - return output; - } - - @Override public Object[] getTargetInfo() { return mTargetInfo; @@ -179,7 +174,8 @@ public class SearchResultPlayItem extends LinearLayout implements } } - private void handleSelection(int eventType) { + @Override + public 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=" @@ -209,8 +205,6 @@ public class SearchResultPlayItem extends LinearLayout implements SearchTarget.ItemType.PLAY_RESULTS, eventType); searchTargetEvent.bundle = new Bundle(); searchTargetEvent.bundle.putString("package_name", mPackageName); - if (mPlugin != null) { - mPlugin.notifySearchTargetEvent(searchTargetEvent); - } + SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(searchTargetEvent); } } diff --git a/src/com/android/launcher3/views/SearchSectionHeaderView.java b/src/com/android/launcher3/views/SearchSectionHeaderView.java index 0fe0a43ff5..370b92148c 100644 --- a/src/com/android/launcher3/views/SearchSectionHeaderView.java +++ b/src/com/android/launcher3/views/SearchSectionHeaderView.java @@ -21,14 +21,14 @@ import android.widget.TextView; import androidx.annotation.Nullable; -import com.android.launcher3.allapps.AllAppsGridAdapter; import com.android.launcher3.allapps.search.AllAppsSearchBarController; +import com.android.systemui.plugins.shared.SearchTarget; /** * Header text view that shows a title for a given section in All apps search */ public class SearchSectionHeaderView extends TextView implements - AllAppsSearchBarController.PayloadResultHandler { + AllAppsSearchBarController.SearchTargetHandler { public SearchSectionHeaderView(Context context) { super(context); } @@ -43,8 +43,8 @@ public class SearchSectionHeaderView extends TextView implements } @Override - public void applyAdapterInfo(AllAppsGridAdapter.AdapterItemWithPayload adapterItem) { - String title = adapterItem.getPayload(); + public void applySearchTarget(SearchTarget searchTarget) { + String title = searchTarget.type.getTitle(); if (title == null || !title.isEmpty()) { setText(title); setVisibility(VISIBLE); diff --git a/src/com/android/launcher3/views/SearchSettingsRowView.java b/src/com/android/launcher3/views/SearchSettingsRowView.java index a1a0172547..ac69548840 100644 --- a/src/com/android/launcher3/views/SearchSettingsRowView.java +++ b/src/com/android/launcher3/views/SearchSettingsRowView.java @@ -29,9 +29,8 @@ import androidx.annotation.Nullable; 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.launcher3.allapps.search.SearchEventTracker; import com.android.systemui.plugins.shared.SearchTarget; import com.android.systemui.plugins.shared.SearchTargetEvent; @@ -41,13 +40,12 @@ import java.util.ArrayList; * A row of tappable TextViews with a breadcrumb for settings search. */ public class SearchSettingsRowView extends LinearLayout implements - View.OnClickListener, AllAppsSearchBarController.PayloadResultHandler { + View.OnClickListener, AllAppsSearchBarController.SearchTargetHandler { private TextView mTitleView; private TextView mDescriptionView; private TextView mBreadcrumbsView; private Intent mIntent; - private AllAppsSearchPlugin mPlugin; private final Object[] mTargetInfo = createTargetInfo(); @@ -75,10 +73,8 @@ public class SearchSettingsRowView extends LinearLayout implements } @Override - public void applyAdapterInfo( - AllAppsGridAdapter.AdapterItemWithPayload adapterItemWithPayload) { - Bundle bundle = adapterItemWithPayload.getPayload(); - mPlugin = adapterItemWithPayload.getPlugin(); + public void applySearchTarget(SearchTarget searchTarget) { + Bundle bundle = searchTarget.bundle; mIntent = bundle.getParcelable("intent"); showIfAvailable(mTitleView, bundle.getString("title")); showIfAvailable(mDescriptionView, bundle.getString("description")); @@ -86,7 +82,7 @@ public class SearchSettingsRowView extends LinearLayout implements //TODO: implement RTL friendly breadcrumbs view showIfAvailable(mBreadcrumbsView, breadcrumbs != null ? String.join(" > ", breadcrumbs) : null); - adapterItemWithPayload.setSelectionHandler(this::handleSelection); + SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this); } @Override @@ -108,7 +104,8 @@ public class SearchSettingsRowView extends LinearLayout implements handleSelection(SearchTargetEvent.SELECT); } - private void handleSelection(int eventType) { + @Override + public void handleSelection(int eventType) { if (mIntent == null) return; // TODO: create ItemInfo object and then use it to call startActivityForResult for proper // WW logging @@ -119,8 +116,6 @@ public class SearchSettingsRowView extends LinearLayout implements SearchTarget.ItemType.SETTINGS_ROW, eventType); searchTargetEvent.bundle = new Bundle(); searchTargetEvent.bundle.putParcelable("intent", mIntent); - if (mPlugin != null) { - mPlugin.notifySearchTargetEvent(searchTargetEvent); - } + SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(searchTargetEvent); } } diff --git a/src/com/android/launcher3/views/SearchSliceWrapper.java b/src/com/android/launcher3/views/SearchSliceWrapper.java new file mode 100644 index 0000000000..b088237034 --- /dev/null +++ b/src/com/android/launcher3/views/SearchSliceWrapper.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 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 com.android.launcher3.views; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.slice.Slice; +import androidx.slice.SliceItem; +import androidx.slice.widget.EventInfo; +import androidx.slice.widget.SliceLiveData; +import androidx.slice.widget.SliceView; + +import com.android.launcher3.Launcher; +import com.android.launcher3.allapps.search.SearchEventTracker; +import com.android.systemui.plugins.shared.SearchTarget; +import com.android.systemui.plugins.shared.SearchTargetEvent; + +/** + * A Wrapper class for {@link SliceView} search results + */ +public class SearchSliceWrapper implements SliceView.OnSliceActionListener { + + private static final String TAG = "SearchSliceController"; + private static final String URI_EXTRA_KEY = "slice_uri"; + + + private final Launcher mLauncher; + private final SearchTarget mSearchTarget; + private final SliceView mSliceView; + //TODO: remove these as we move to tracking search results individually with unique ID + private final int mPosition; + private final String mSessionId; + private LiveData mSliceLiveData; + + public SearchSliceWrapper(Context context, SliceView sliceView, + SearchTarget searchTarget, String sessionId, int position) { + mLauncher = Launcher.getLauncher(context); + mPosition = position; + mSessionId = sessionId; + mSearchTarget = searchTarget; + mSliceView = sliceView; + sliceView.setOnSliceActionListener(this); + try { + mSliceLiveData = SliceLiveData.fromUri(mLauncher, getSliceUri()); + mSliceLiveData.observe((Launcher) mLauncher, sliceView); + } catch (Exception ex) { + Log.e(TAG, "unable to bind slice", ex); + } + } + + /** + * Unregisters event handlers and removes lifecycle observer + */ + public void destroy() { + mSliceView.setOnSliceActionListener(null); + mSliceLiveData.removeObservers(mLauncher); + } + + @Override + public void onSliceAction(@NonNull EventInfo info, @NonNull SliceItem item) { + SearchTargetEvent searchTargetEvent = new SearchTargetEvent( + SearchTarget.ItemType.SETTINGS_SLICE, + SearchTargetEvent.CHILD_SELECT, mPosition, + mSessionId); + searchTargetEvent.bundle = new Bundle(); + searchTargetEvent.bundle.putParcelable(URI_EXTRA_KEY, getSliceUri()); + SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(searchTargetEvent); + } + + private Uri getSliceUri() { + return mSearchTarget.bundle.getParcelable(URI_EXTRA_KEY); + } +} diff --git a/src/com/android/launcher3/views/ThumbnailSearchResultView.java b/src/com/android/launcher3/views/ThumbnailSearchResultView.java index 81bcad97ed..21212327b6 100644 --- a/src/com/android/launcher3/views/ThumbnailSearchResultView.java +++ b/src/com/android/launcher3/views/ThumbnailSearchResultView.java @@ -26,14 +26,13 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.launcher3.Launcher; -import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload; import com.android.launcher3.allapps.search.AllAppsSearchBarController; +import com.android.launcher3.allapps.search.SearchEventTracker; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.RemoteActionItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.touch.ItemClickHandler; 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; @@ -41,11 +40,9 @@ import com.android.systemui.plugins.shared.SearchTargetEvent; * A view representing a high confidence app search result that includes shortcuts */ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppCompatImageView - implements AllAppsSearchBarController.PayloadResultHandler { + implements AllAppsSearchBarController.SearchTargetHandler { private final Object[] mTargetInfo = createTargetInfo(); - AllAppsSearchPlugin mPlugin; - int mPosition; public ThumbnailSearchResultView(Context context) { super(context); @@ -59,7 +56,8 @@ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppComp super(context, attrs, defStyleAttr); } - private void handleSelection(int eventType) { + @Override + public void handleSelection(int eventType) { Launcher launcher = Launcher.getLauncher(getContext()); ItemInfo itemInfo = (ItemInfo) getTag(); if (itemInfo instanceof RemoteActionItemInfo) { @@ -68,26 +66,19 @@ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppComp } else { ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) itemInfo, launcher); } - if (mPlugin != null) { - SearchTargetEvent event = getSearchTargetEvent( - SearchTarget.ItemType.SCREENSHOT, eventType); - mPlugin.notifySearchTargetEvent(event); - } + SearchTargetEvent e = getSearchTargetEvent(SearchTarget.ItemType.SCREENSHOT, eventType); + SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(e); } @Override - public void applyAdapterInfo(AdapterItemWithPayload adapterItem) { - Launcher launcher = Launcher.getLauncher(getContext()); - mPosition = adapterItem.position; - - SearchTarget target = adapterItem.getPayload(); + public void applySearchTarget(SearchTarget target) { Bitmap bitmap; if (target.mRemoteAction != null) { RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(target.mRemoteAction, target.bundle.getString(SearchTarget.REMOTE_ACTION_TOKEN), target.bundle.getBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START)); bitmap = ((BitmapDrawable) target.mRemoteAction.getIcon() - .loadDrawable(getContext())).getBitmap(); + .loadDrawable(getContext())).getBitmap(); Bitmap crop = Bitmap.createBitmap(bitmap, 0, bitmap.getHeight() / 2 - bitmap.getWidth() / 2, bitmap.getWidth(), bitmap.getWidth()); @@ -106,8 +97,7 @@ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppComp drawable.setCornerRadius(Themes.getDialogCornerRadius(getContext())); setImageDrawable(drawable); setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT)); - mPlugin = adapterItem.getPlugin(); - adapterItem.setSelectionHandler(this::handleSelection); + SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(target, this); } @Override