Merge "Revert "Support people search results"" into sc-dev

This commit is contained in:
Darryl Johnson 2021-01-29 21:02:07 +00:00 committed by Android (Google) Code Review
commit d462965698
17 changed files with 388 additions and 144 deletions

View File

@ -57,10 +57,9 @@
style="@style/BaseIcon"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:gravity="center"
android:gravity="start|center_vertical"
launcher:iconDisplay="shortcut_popup"
android:textSize="@dimen/search_hero_inline_button_size"
android:textSize="@dimen/search_hero_subtitle_size"
launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
launcher:layoutHorizontal="false" />
@ -69,20 +68,6 @@
style="@style/BaseIcon"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:gravity="center"
launcher:iconDisplay="shortcut_popup"
android:textSize="@dimen/search_hero_inline_button_size"
launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
launcher:layoutHorizontal="false" />
<com.android.launcher3.search.SearchResultIcon
android:id="@+id/shortcut_2"
style="@style/BaseIcon"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:gravity="center"
launcher:iconDisplay="shortcut_popup"
android:textSize="@dimen/search_hero_inline_button_size"
launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?><!-- 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.
-->
<com.android.launcher3.search.SearchResultPeopleView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:gravity="center_vertical"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="horizontal">
<View
android:id="@+id/icon"
android:layout_marginRight="8dp"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="@dimen/deep_shortcut_icon_size" />
<TextView
android:layout_width="0dp"
android:textColor="?android:attr/textColorPrimary"
android:id="@+id/title"
android:textSize="@dimen/search_hero_title_size"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="@+id/provider_0"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:layout_margin="5dp"
android:background="?android:attr/selectableItemBackground"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="@dimen/deep_shortcut_icon_size" />
<ImageButton
android:id="@+id/provider_1"
android:layout_margin="5dp"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:background="?android:attr/selectableItemBackground"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="@dimen/deep_shortcut_icon_size" />
<ImageButton
android:id="@+id/provider_2"
android:layout_margin="5dp"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:background="?android:attr/selectableItemBackground"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="@dimen/deep_shortcut_icon_size" />
</com.android.launcher3.search.SearchResultPeopleView>

View File

@ -41,6 +41,7 @@ public class DeviceSearchAdapterProvider extends SearchAdapterProvider {
public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 7;
public static final int VIEW_TYPE_SEARCH_ICON = (1 << 8) | VIEW_TYPE_ICON;
public static final int VIEW_TYPE_SEARCH_ICON_ROW = (1 << 9);
public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11;
public static final int VIEW_TYPE_SEARCH_THUMBNAIL = 1 << 12;
public static final int VIEW_TYPE_SEARCH_WIDGET_LIVE = 1 << 15;
public static final int VIEW_TYPE_SEARCH_WIDGET_PREVIEW = 1 << 16;
@ -58,6 +59,7 @@ public class DeviceSearchAdapterProvider extends SearchAdapterProvider {
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ICON, R.layout.search_result_icon);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ICON_ROW, R.layout.search_result_icon_row);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_SLICE, R.layout.search_result_slice);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_PEOPLE, R.layout.search_result_people_item);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_THUMBNAIL, R.layout.search_result_thumbnail);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_WIDGET_LIVE, R.layout.search_result_widget_live);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_WIDGET_PREVIEW,
@ -123,7 +125,6 @@ public class DeviceSearchAdapterProvider extends SearchAdapterProvider {
break;
case LayoutType.ICON_DOUBLE_HORIZONTAL_TEXT:
case LayoutType.ICON_SINGLE_HORIZONTAL_TEXT:
case LayoutType.ICON_DOUBLE_HORIZONTAL_TEXT_BUTTON:
return VIEW_TYPE_SEARCH_ICON_ROW;
case LayoutType.THUMBNAIL:
if (t.getSearchAction() != null) {

View File

@ -18,6 +18,7 @@ package com.android.launcher3.search;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ICON;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ICON_ROW;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_PEOPLE;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_SLICE;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_THUMBNAIL;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_WIDGET_LIVE;
@ -41,10 +42,9 @@ public class SearchAdapterItem extends AllAppsGridAdapter.AdapterItem {
private static final int AVAILABLE_FOR_ACCESSIBILITY =
VIEW_TYPE_SEARCH_SLICE | VIEW_TYPE_SEARCH_THUMBNAIL | VIEW_TYPE_SEARCH_ICON_ROW
| VIEW_TYPE_SEARCH_ICON | VIEW_TYPE_SEARCH_WIDGET_PREVIEW
| VIEW_TYPE_SEARCH_WIDGET_LIVE;
VIEW_TYPE_SEARCH_SLICE | VIEW_TYPE_SEARCH_PEOPLE | VIEW_TYPE_SEARCH_THUMBNAIL
| VIEW_TYPE_SEARCH_ICON_ROW | VIEW_TYPE_SEARCH_ICON
| VIEW_TYPE_SEARCH_WIDGET_PREVIEW | VIEW_TYPE_SEARCH_WIDGET_LIVE;
public SearchAdapterItem(SearchTargetLegacy searchTargetLegacy, int type) {
mSearchTargetLegacy = searchTargetLegacy;

View File

@ -15,9 +15,12 @@
*/
package com.android.launcher3.search;
import static com.android.launcher3.model.data.SearchActionItemInfo.FLAG_BADGE_WITH_PACKAGE;
import static com.android.launcher3.model.data.SearchActionItemInfo.FLAG_BADGE_FROM_ICON;
import static com.android.launcher3.model.data.SearchActionItemInfo.FLAG_PRIMARY_ICON_FROM_TITLE;
import static com.android.launcher3.search.SearchTargetUtil.BUNDLE_EXTRA_BADGE_FROM_ICON;
import static com.android.launcher3.search.SearchTargetUtil.BUNDLE_EXTRA_PRIMARY_ICON_FROM_TITLE;
import static com.android.launcher3.search.SearchTargetUtil.BUNDLE_EXTRA_SHOULD_START;
import static com.android.launcher3.search.SearchTargetUtil.BUNDLE_EXTRA_SHOULD_START_FOR_RESULT;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@ -27,14 +30,9 @@ import android.app.search.SearchTargetEvent;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.AttributeSet;
@ -47,7 +45,6 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
@ -57,25 +54,14 @@ import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.Themes;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.function.Consumer;
/**
* A {@link BubbleTextView} representing a single cell result in AllApps
*/
public class SearchResultIcon extends BubbleTextView implements
SearchTargetHandler, View.OnClickListener,
View.OnLongClickListener {
//Play store thumbnail process workaround
private final Rect mTempRect = new Rect();
private final Paint mIconPaint = new Paint();
private static final int BITMAP_CROP_MASK_COLOR = 0xff424242;
public class SearchResultIcon extends BubbleTextView implements SearchTargetHandler {
private final Launcher mLauncher;
@ -113,7 +99,7 @@ public class SearchResultIcon extends BubbleTextView implements
* Applies {@link SearchTarget} to view. registers a consumer after a corresponding
* {@link ItemInfoWithIcon} is created
*/
public void apply(SearchTarget searchTarget, List<SearchTarget> inlineItems,
public void applySearchTarget(SearchTarget searchTarget, List<SearchTarget> inlineItems,
Consumer<ItemInfoWithIcon> cb) {
mOnItemInfoChanged = cb;
apply(searchTarget, inlineItems);
@ -129,8 +115,8 @@ public class SearchResultIcon extends BubbleTextView implements
prepareUsingSearchAction(parentTarget);
mLongPressSupported = false;
} else {
String className = parentTarget.getExtras().getString(SearchTargetUtil.EXTRA_CLASS);
prepareUsingApp(new ComponentName(parentTarget.getPackageName(), className),
prepareUsingApp(new ComponentName(parentTarget.getPackageName(),
parentTarget.getExtras().getString(SearchTargetUtil.EXTRA_CLASS)),
parentTarget.getUserHandle());
mLongPressSupported = true;
}
@ -150,17 +136,14 @@ public class SearchResultIcon extends BubbleTextView implements
//TODO: remove this after flags are introduced in SearchAction. Settings results require
// startActivityForResult
boolean isSettingsResult = searchTarget.getResultType() == ResultType.SETTING;
if ((extras != null && extras.getBoolean(
SearchTargetUtil.BUNDLE_EXTRA_SHOULD_START_FOR_RESULT))
if ((extras != null && extras.getBoolean(BUNDLE_EXTRA_SHOULD_START_FOR_RESULT))
|| isSettingsResult) {
itemInfo.setFlags(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT);
} else if (extras != null && extras.getBoolean(
SearchTargetUtil.BUNDLE_EXTRA_SHOULD_START)) {
} else if (extras != null && extras.getBoolean(BUNDLE_EXTRA_SHOULD_START)) {
itemInfo.setFlags(SearchActionItemInfo.FLAG_SHOULD_START);
}
if (extras != null && extras.getBoolean(
SearchTargetUtil.BUNDLE_EXTRA_BADGE_WITH_PACKAGE)) {
itemInfo.setFlags(FLAG_BADGE_WITH_PACKAGE);
if (extras != null && extras.getBoolean(BUNDLE_EXTRA_BADGE_FROM_ICON)) {
itemInfo.setFlags(FLAG_BADGE_FROM_ICON);
}
if (extras != null && extras.getBoolean(BUNDLE_EXTRA_PRIMARY_ICON_FROM_TITLE)) {
itemInfo.setFlags(FLAG_PRIMARY_ICON_FROM_TITLE);
@ -171,76 +154,39 @@ public class SearchResultIcon extends BubbleTextView implements
MODEL_EXECUTOR.post(() -> {
try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
Icon icon = searchTarget.getSearchAction().getIcon();
BitmapInfo pkgBitmap = getPackageBitmap(appState, searchTarget);
if (itemInfo.hasFlags(FLAG_PRIMARY_ICON_FROM_TITLE)) {
// create a bitmap with first char if FLAG_PRIMARY_ICON_FROM_TITLE is set
itemInfo.bitmap = li.createIconBitmap(String.valueOf(itemInfo.title.charAt(0)),
pkgBitmap.color);
} else if (icon == null) {
// Use default icon from package name
itemInfo.bitmap = pkgBitmap;
Drawable d;
// This bitmapInfo can be used as main icon or as a badge
BitmapInfo bitmapInfo;
if (icon == null) {
PackageItemInfo pkgInfo = new PackageItemInfo(searchTarget.getPackageName());
pkgInfo.user = searchTarget.getUserHandle();
appState.getIconCache().getTitleAndIconForApp(pkgInfo, false);
bitmapInfo = pkgInfo.bitmap;
} else {
boolean isPlayResult = searchTarget.getResultType() == ResultType.PLAY;
if (isPlayResult) {
Bitmap b = getPlayResultBitmap(searchAction.getIcon());
itemInfo.bitmap = b == null
? BitmapInfo.LOW_RES_INFO : BitmapInfo.fromBitmap(b);
} else {
itemInfo.bitmap = li.createBadgedIconBitmap(icon.loadDrawable(getContext()),
itemInfo.user, false);
}
d = itemInfo.getIcon().loadDrawable(getContext());
bitmapInfo = li.createBadgedIconBitmap(d, itemInfo.user,
Build.VERSION.SDK_INT);
}
// badge with package name
if (itemInfo.hasFlags(FLAG_BADGE_WITH_PACKAGE) && itemInfo.bitmap != pkgBitmap) {
itemInfo.bitmap = li.badgeBitmap(itemInfo.bitmap.icon, pkgBitmap);
BitmapInfo bitmapMainIcon;
if (itemInfo.hasFlags(FLAG_PRIMARY_ICON_FROM_TITLE)) {
bitmapMainIcon = li.createIconBitmap(
String.valueOf(itemInfo.title.charAt(0)),
bitmapInfo.color);
} else {
bitmapMainIcon = bitmapInfo;
}
if (itemInfo.hasFlags(FLAG_BADGE_FROM_ICON)) {
itemInfo.bitmap = li.badgeBitmap(bitmapMainIcon.icon, bitmapInfo);
} else {
itemInfo.bitmap = bitmapInfo;
}
}
MAIN_EXECUTOR.post(() -> applyFromSearchActionItemInfo(itemInfo));
});
}
private static BitmapInfo getPackageBitmap(LauncherAppState appState, SearchTarget target) {
PackageItemInfo pkgInfo = new PackageItemInfo(target.getPackageName());
pkgInfo.user = target.getUserHandle();
appState.getIconCache().getTitleAndIconForApp(pkgInfo, false);
return pkgInfo.bitmap;
}
private Bitmap getPlayResultBitmap(Icon icon) {
try {
int iconSize = getIconSize();
URL url = new URL(icon.getUri().toString());
URLConnection con = url.openConnection();
con.addRequestProperty("Cache-Control", "max-age: 0");
con.setUseCaches(true);
Bitmap bitmap = BitmapFactory.decodeStream(con.getInputStream());
return getRoundedBitmap(Bitmap.createScaledBitmap(bitmap, iconSize, iconSize, false));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private Bitmap getRoundedBitmap(Bitmap bitmap) {
final int iconSize = bitmap.getWidth();
final float radius = Themes.getDialogCornerRadius(getContext());
return 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);
});
}
private void prepareUsingApp(ComponentName componentName, UserHandle userHandle) {
AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
AppInfo appInfo = appsStore.getApp(new ComponentKey(componentName, userHandle));
@ -287,6 +233,7 @@ public class SearchResultIcon extends BubbleTextView implements
}
private void notifyItemInfoChanged(ItemInfoWithIcon itemInfoWithIcon) {
if (mOnItemInfoChanged != null) {
mOnItemInfoChanged.accept(itemInfoWithIcon);

View File

@ -23,6 +23,7 @@ import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -43,15 +44,15 @@ import java.util.List;
*/
public class SearchResultIconRow extends LinearLayout implements SearchTargetHandler {
public static final int MAX_INLINE_ITEMS = 3;
public static final int MAX_INLINE_ITEMS = 2;
protected final Launcher mLauncher;
private final LauncherAppState mLauncherAppState;
protected SearchResultIcon mResultIcon;
private SearchResultIcon mResultIcon;
private TextView mTitleView;
private TextView mSubTitleView;
protected final SearchResultIcon[] mInlineIcons = new SearchResultIcon[MAX_INLINE_ITEMS];
private final SearchResultIcon[] mInlineIcons = new SearchResultIcon[MAX_INLINE_ITEMS];
private PackageItemInfo mProviderInfo;
@ -90,9 +91,9 @@ public class SearchResultIconRow extends LinearLayout implements SearchTargetHan
mInlineIcons[0] = findViewById(R.id.shortcut_0);
mInlineIcons[1] = findViewById(R.id.shortcut_1);
mInlineIcons[2] = findViewById(R.id.shortcut_2);
for (SearchResultIcon inlineIcon : mInlineIcons) {
inlineIcon.getLayoutParams().width = getIconSize();
// TODO: inlineIcon.setOnClickListener();
}
setOnClickListener(mResultIcon);
@ -102,7 +103,7 @@ public class SearchResultIconRow extends LinearLayout implements SearchTargetHan
@Override
public void apply(SearchTarget parentTarget, List<SearchTarget> children) {
showSubtitleIfNeeded(null);
mResultIcon.apply(parentTarget, children, this::onItemInfoCreated);
mResultIcon.applySearchTarget(parentTarget, children, this::onItemInfoCreated);
if (parentTarget.getShortcutInfo() != null) {
updateWithShortcutInfo(parentTarget.getShortcutInfo());
} else if (parentTarget.getSearchAction() != null) {
@ -141,7 +142,7 @@ public class SearchResultIconRow extends LinearLayout implements SearchTargetHan
protected void showInlineItems(List<SearchTarget> children) {
for (int i = 0; i < MAX_INLINE_ITEMS; i++) {
if (i < children.size()) {
mInlineIcons[i].apply(children.get(i), new ArrayList<>());
mInlineIcons[i].apply(children.get(0), new ArrayList<>());
mInlineIcons[i].setVisibility(VISIBLE);
} else {
mInlineIcons[i].setVisibility(GONE);
@ -153,4 +154,15 @@ public class SearchResultIconRow extends LinearLayout implements SearchTargetHan
setTag(info);
mTitleView.setText(info.title);
}
@Override
public void onClick(View view) {
// do nothing.
}
@Override
public boolean onLongClick(View view) {
// do nothing.
return false;
}
}

View File

@ -22,6 +22,7 @@ import android.app.search.SearchTargetEvent;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
@ -132,4 +133,15 @@ public class SearchResultIconSlice extends LinearLayout implements SearchTargetH
public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) {
notifyEvent(mLauncher, mTargetId, SearchTargetEvent.ACTION_TAP);
}
@Override
public void onClick(View view) {
notifyEvent(mLauncher, mTargetId, SearchTargetEvent.ACTION_LONGPRESS);
}
@Override
public boolean onLongClick(View view) {
// do nothing
return false;
}
}

View File

@ -0,0 +1,199 @@
/*
* 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.search;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.app.search.SearchTargetEvent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
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.icons.BitmapInfo;
import com.android.launcher3.icons.LauncherIcons;
import com.android.systemui.plugins.shared.SearchTargetLegacy;
import java.util.ArrayList;
/**
* A view representing a single people search result in all apps
*/
public class SearchResultPeopleView extends LinearLayout implements SearchTargetHandler {
public static final String TARGET_TYPE_PEOPLE = "people";
private final int mIconSize;
private final int mButtonSize;
private final PackageManager mPackageManager;
private View mIconView;
private TextView mTitleView;
private ImageButton[] mProviderButtons = new ImageButton[3];
private Intent mIntent;
private SearchTargetLegacy mSearchTarget;
public SearchResultPeopleView(Context context) {
this(context, null, 0);
}
public SearchResultPeopleView(Context context,
@Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SearchResultPeopleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
DeviceProfile deviceProfile = Launcher.getLauncher(getContext()).getDeviceProfile();
mPackageManager = getContext().getPackageManager();
mIconSize = deviceProfile.iconSizePx;
mButtonSize = (int) (deviceProfile.iconSizePx / 1.5f);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mIconView = findViewById(R.id.icon);
mIconView.getLayoutParams().height = mIconSize;
mIconView.getLayoutParams().width = mIconSize;
mTitleView = findViewById(R.id.title);
mProviderButtons[0] = findViewById(R.id.provider_0);
mProviderButtons[1] = findViewById(R.id.provider_1);
mProviderButtons[2] = findViewById(R.id.provider_2);
for (ImageButton button : mProviderButtons) {
button.getLayoutParams().width = mButtonSize;
button.getLayoutParams().height = mButtonSize;
}
}
/*
@Override
public void applySearchTarget(SearchTargetLegacy searchTarget) {
mSearchTarget = searchTarget;
Bundle payload = searchTarget.getExtras();
mTitleView.setText(payload.getString("title"));
mIntent = payload.getParcelable("intent");
Bitmap contactIcon = payload.getParcelable("icon");
try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
BitmapInfo badgeInfo = li.createBadgedIconBitmap(
getAppIcon(mIntent.getPackage()), Process.myUserHandle(),
Build.VERSION.SDK_INT);
setIcon(li.badgeBitmap(roundBitmap(contactIcon), badgeInfo).icon, false);
} catch (Exception e) {
setIcon(contactIcon, true);
}
ArrayList<Bundle> providers = payload.getParcelableArrayList("providers");
for (int i = 0; i < mProviderButtons.length; i++) {
ImageButton button = mProviderButtons[i];
if (providers != null && i < providers.size()) {
Bundle provider = providers.get(i);
Intent intent = provider.getParcelable("intent");
setupProviderButton(button, provider, intent);
UI_HELPER_EXECUTOR.post(() -> {
String pkg = provider.getString("package_name");
Drawable appIcon = getAppIcon(pkg);
if (appIcon != null) {
MAIN_EXECUTOR.post(() -> button.setImageDrawable(appIcon));
}
});
button.setVisibility(VISIBLE);
} else {
button.setVisibility(GONE);
}
}
}
*/
/**
* 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);
d.setCornerRadius(R.attr.folderIconRadius);
d.setBounds(0, 0, mIconSize, mIconSize);
final Bitmap bitmap = Bitmap.createBitmap(d.getBounds().width(), d.getBounds().height(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
d.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
d.draw(canvas);
return bitmap;
}
private void setIcon(Bitmap icon, Boolean round) {
if (round) {
RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(getResources(), icon);
d.setCornerRadius(R.attr.folderIconRadius);
d.setBounds(0, 0, mIconSize, mIconSize);
mIconView.setBackground(d);
} else {
mIconView.setBackground(new BitmapDrawable(getResources(), icon));
}
}
private Drawable getAppIcon(String pkg) {
try {
ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(
pkg, 0);
return applicationInfo.loadIcon(mPackageManager);
} catch (PackageManager.NameNotFoundException ignored) {
return null;
}
}
private void setupProviderButton(ImageButton button, Bundle provider, Intent intent) {
Launcher launcher = Launcher.getLauncher(getContext());
button.setOnClickListener(b -> {
launcher.startActivitySafely(b, intent, null);
Bundle bundle = new Bundle();
bundle.putBundle("provider", provider);
});
}
@Override
public void onClick(View view) {
// do nothing.
}
@Override
public boolean onLongClick(View view) {
// do nothing.
return false;
}
}

View File

@ -39,9 +39,10 @@ import java.util.List;
* A view representing a high confidence app search result that includes shortcuts
*/
public class SearchResultThumbnailView extends androidx.appcompat.widget.AppCompatImageView
implements SearchTargetHandler, View.OnClickListener {
implements SearchTargetHandler {
private SearchTarget mSearchTarget;
private SearchResultIcon mResultIcon;
public SearchResultThumbnailView(Context context) {
super(context);
@ -101,4 +102,10 @@ public class SearchResultThumbnailView extends androidx.appcompat.widget.AppComp
(SearchActionItemInfo) view.getTag());
notifyEvent(getContext(), mSearchTarget.getId(), SearchTargetEvent.ACTION_LAUNCH_TOUCH);
}
@Override
public boolean onLongClick(View view) {
// do nothing.
return false;
}
}

View File

@ -186,6 +186,10 @@ public class SearchResultWidget extends LinearLayout implements SearchTargetHand
return false;
}
@Override
public void onClick(View view) {
// do nothing.
}
static class ClickListener extends GestureDetector.SimpleOnGestureListener {
private final Runnable mCb;

View File

@ -47,8 +47,7 @@ import java.util.List;
/**
* displays preview of a widget upon receiving {@link AppWidgetProviderInfo} from Search provider
*/
public class SearchResultWidgetPreview extends LinearLayout implements SearchTargetHandler,
View.OnClickListener, View.OnLongClickListener {
public class SearchResultWidgetPreview extends LinearLayout implements SearchTargetHandler {
private final Launcher mLauncher;
private final LauncherAppState mAppState;

View File

@ -18,6 +18,7 @@ package com.android.launcher3.search;
import android.app.search.SearchTarget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.Nullable;
@ -47,4 +48,15 @@ public class SearchSectionHeaderView extends TextView implements SearchTargetHan
setText(parentTarget.getSearchAction().getTitle());
setVisibility(VISIBLE);
}
@Override
public void onClick(View view) {
// do nothing.
}
@Override
public boolean onLongClick(View view) {
// do nothing.
return false;
}
}

View File

@ -15,8 +15,6 @@
*/
package com.android.launcher3.search;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.app.search.Query;
import android.app.search.SearchContext;
import android.app.search.SearchSession;
@ -41,6 +39,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.function.Consumer;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
/**
* Search pipeline utilizing {@link android.app.search.SearchUiManager}
*/

View File

@ -19,13 +19,15 @@ package com.android.launcher3.search;
import android.app.search.SearchTarget;
import android.app.search.SearchTargetEvent;
import android.content.Context;
import android.view.View;
import java.util.List;
import java.util.function.Consumer;
/**
* An interface for supporting dynamic search results
*/
public interface SearchTargetHandler {
public interface SearchTargetHandler extends View.OnClickListener, View.OnLongClickListener {
/**
* Update view using values from {@link SearchTarget}

View File

@ -15,13 +15,6 @@
*/
package com.android.launcher3.search;
import static com.android.app.search.LayoutType.ICON_DOUBLE_HORIZONTAL_TEXT;
import static com.android.app.search.LayoutType.ICON_SINGLE_HORIZONTAL_TEXT;
import static com.android.app.search.LayoutType.THUMBNAIL;
import static com.android.app.search.ResultType.ACTION;
import static com.android.app.search.ResultType.SCREENSHOT;
import static com.android.app.search.ResultType.SUGGEST;
import android.app.PendingIntent;
import android.app.search.SearchAction;
import android.app.search.SearchTarget;
@ -38,11 +31,18 @@ import android.os.UserHandle;
import com.android.app.search.ResultType;
import static com.android.app.search.LayoutType.ICON_DOUBLE_HORIZONTAL_TEXT;
import static com.android.app.search.LayoutType.ICON_SINGLE_HORIZONTAL_TEXT;
import static com.android.app.search.LayoutType.THUMBNAIL;
import static com.android.app.search.ResultType.ACTION;
import static com.android.app.search.ResultType.SCREENSHOT;
import static com.android.app.search.ResultType.SUGGEST;
public class SearchTargetUtil {
public static final String BUNDLE_EXTRA_SHOULD_START = "should_start";
public static final String BUNDLE_EXTRA_SHOULD_START_FOR_RESULT = "should_start_for_result";
public static final String BUNDLE_EXTRA_BADGE_WITH_PACKAGE = "badge_with_package";
public static final String BUNDLE_EXTRA_BADGE_FROM_ICON = "badge_from_icon";
public static final String BUNDLE_EXTRA_PRIMARY_ICON_FROM_TITLE = "primary_icon_from_title";
public static final String EXTRA_CLASS = "class";
@ -56,10 +56,10 @@ public class SearchTargetUtil {
/**
* Generate SearchTargetUtil for ICON_DOUBLE_HORIZONTAL_TEXT layout type.
*
* targets.add(SearchTargetUtil.generateIconDoubleHorizontalText_SearchAction(
* mContext, "red", Color.RED));
* targets.add(SearchTargetUtil.generateIconDoubleHorizontalText_SearchAction(
* mContext, "yellow", Color.YELLOW));
targets.add(SearchTargetUtil.generateIconDoubleHorizontalText_SearchAction(
mContext, "red", Color.RED));
targets.add(SearchTargetUtil.generateIconDoubleHorizontalText_SearchAction(
mContext, "yellow", Color.YELLOW));
*/
public static SearchTarget generateIconDoubleHorizontalText_SearchAction(
Context context, String id, int color) {
@ -83,7 +83,7 @@ public class SearchTargetUtil {
Bundle b = new Bundle();
b.putBoolean(BUNDLE_EXTRA_SHOULD_START_FOR_RESULT, true);
b.putBoolean(BUNDLE_EXTRA_BADGE_WITH_PACKAGE, true);
b.putBoolean(BUNDLE_EXTRA_BADGE_FROM_ICON, true);
b.putBoolean(BUNDLE_EXTRA_PRIMARY_ICON_FROM_TITLE, true);
builder.setSearchAction(new SearchAction.Builder(id, id + TITLE)
@ -96,7 +96,7 @@ public class SearchTargetUtil {
}
/**
* Inside SearchServicePipeline, add following samples to test the search target.
* Inside SearchServicePipeline, add following samples to test the search target.
*
* targets.add(SearchTargetUtil.generateThumbnail_SearchAction("blue", Color.BLUE));
* targets.add(SearchTargetUtil.generateThumbnail_SearchAction("red", Color.RED));
@ -130,10 +130,11 @@ public class SearchTargetUtil {
}
/**
*
* targets.add(SearchTargetUtil.generateIconHorizontalText_SearchAction(
* mContext, "red", Color.RED));
* mContext, "red", Color.RED));
* targets.add(SearchTargetUtil.generateIconHorizontalText_SearchAction(
* mContext, "yellow", Color.YELLOW));
* mContext, "yellow", Color.YELLOW));
*/
public static SearchTarget generateIconHorizontalText_SearchAction(
Context context, String id, int color) {

View File

@ -30,7 +30,7 @@ public class SearchActionItemInfo extends ItemInfoWithIcon {
public static final int FLAG_SHOULD_START = 1 << 1;
public static final int FLAG_SHOULD_START_FOR_RESULT = FLAG_SHOULD_START | 1 << 2;
public static final int FLAG_BADGE_WITH_PACKAGE = 1 << 3;
public static final int FLAG_BADGE_FROM_ICON = 1 << 3;
public static final int FLAG_PRIMARY_ICON_FROM_TITLE = 1 << 4;
private final String mFallbackPackageName;

View File

@ -20,7 +20,7 @@ import android.os.Bundle;
/**
* Event used for the feedback loop to the plugin. (and future aiai)
*
* @deprecated Use {@link android.app.search.SearchTargetEvent}
* @deprecated Use SearchTargetEvent
*/
@Deprecated
public class SearchTargetEventLegacy {