Track search results with position and search Identifier
Bug: 169087008 Test: Manual Change-Id: I54c74093b90e5aea03a7810f55fcc32f0ddf8dda
This commit is contained in:
parent
2508239d1e
commit
f01064953b
|
@ -200,6 +200,7 @@ public class AllAppsGridAdapter extends
|
|||
*/
|
||||
public static class AdapterItemWithPayload<T> extends AdapterItem {
|
||||
private T mPayload;
|
||||
private String mSearchSessionId;
|
||||
private AllAppsSearchPlugin mPlugin;
|
||||
private IntConsumer mSelectionHandler;
|
||||
|
||||
|
@ -221,6 +222,14 @@ public class AllAppsGridAdapter extends
|
|||
mSelectionHandler = runnable;
|
||||
}
|
||||
|
||||
public void setSearchSessionId(String searchSessionId) {
|
||||
mSearchSessionId = searchSessionId;
|
||||
}
|
||||
|
||||
public String getSearchSessionId() {
|
||||
return mSearchSessionId;
|
||||
}
|
||||
|
||||
public IntConsumer getSelectionHandler() {
|
||||
return mSelectionHandler;
|
||||
}
|
||||
|
@ -228,6 +237,8 @@ public class AllAppsGridAdapter extends
|
|||
public T getPayload() {
|
||||
return mPayload;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -476,24 +487,23 @@ public class AllAppsGridAdapter extends
|
|||
//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 @@ public class AllAppsGridAdapter extends
|
|||
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 @@ public class AllAppsGridAdapter extends
|
|||
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
|
||||
|
|
|
@ -35,6 +35,8 @@ import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
|
|||
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 @@ public class AllAppsSearchBarController
|
|||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -61,6 +61,7 @@ public class HeroSearchResultView extends LinearLayout implements DragSource,
|
|||
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 @@ public class HeroSearchResultView extends LinearLayout implements DragSource,
|
|||
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);
|
||||
|
@ -149,6 +150,11 @@ public class HeroSearchResultView extends LinearLayout implements DragSource,
|
|||
adapterItem.setSelectionHandler(this::handleSelection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getTargetInfo() {
|
||||
return mTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDropCompleted(View target, DropTarget.DragObject d, boolean success) {
|
||||
mBubbleTextView.setVisibility(VISIBLE);
|
||||
|
@ -184,7 +190,7 @@ public class HeroSearchResultView extends LinearLayout implements DragSource,
|
|||
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 @@ public class HeroSearchResultView extends LinearLayout implements DragSource,
|
|||
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) {
|
||||
|
|
|
@ -67,7 +67,7 @@ public class SearchResultPeopleView extends LinearLayout implements
|
|||
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 @@ 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);
|
||||
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 @@ public class SearchResultPeopleView extends LinearLayout implements
|
|||
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 @@ public class SearchResultPeopleView extends LinearLayout implements
|
|||
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) {
|
||||
|
|
|
@ -58,6 +58,8 @@ public class SearchResultPlayItem extends LinearLayout implements
|
|||
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 @@ public class SearchResultPlayItem extends LinearLayout implements
|
|||
});
|
||||
}
|
||||
|
||||
@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 @@ public class SearchResultPlayItem extends LinearLayout implements
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -50,6 +50,8 @@ public class SearchResultShortcut extends FrameLayout implements
|
|||
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 @@ public class SearchResultShortcut extends FrameLayout implements
|
|||
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);
|
||||
|
|
|
@ -52,4 +52,9 @@ public class SearchSectionHeaderView extends TextView implements
|
|||
setVisibility(INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getTargetInfo() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ public class SearchSettingsRowView extends LinearLayout implements
|
|||
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 @@ public class SearchSettingsRowView extends LinearLayout implements
|
|||
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 @@ public class SearchSettingsRowView extends LinearLayout implements
|
|||
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);
|
||||
|
|
|
@ -39,8 +39,10 @@ import com.android.systemui.plugins.shared.SearchTargetEvent;
|
|||
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 @@ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppComp
|
|||
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 @@ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppComp
|
|||
|
||||
@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 @@ public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppComp
|
|||
mPlugin = adapterItem.getPlugin();
|
||||
adapterItem.setSelectionHandler(this::handleSelection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getTargetInfo() {
|
||||
return mTargetInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import java.util.function.Consumer;
|
|||
@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);
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ public class SearchTarget implements Comparable<SearchTarget> {
|
|||
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 class SearchTarget implements Comparable<SearchTarget> {
|
|||
*
|
||||
*/
|
||||
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
|
||||
|
|
|
@ -31,10 +31,14 @@ public class SearchTargetEvent {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue