mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-27 23:36:47 +00:00
Support people search results
+ Introduce temporary workaround icon loading with URLConnection for play results Manual: go/search-action-icon Bug: 177223401 Test: Manual Change-Id: I3b597faaad38e8cd1419065b80b359720baf52b0
This commit is contained in:
@@ -15,12 +15,9 @@
|
||||
*/
|
||||
package com.android.launcher3.search;
|
||||
|
||||
import static com.android.launcher3.model.data.SearchActionItemInfo.FLAG_BADGE_FROM_ICON;
|
||||
import static com.android.launcher3.model.data.SearchActionItemInfo.FLAG_BADGE_WITH_PACKAGE;
|
||||
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;
|
||||
|
||||
@@ -30,9 +27,14 @@ import android.app.search.SearchTargetEvent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
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.Icon;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.AttributeSet;
|
||||
@@ -45,6 +47,7 @@ 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;
|
||||
@@ -54,14 +57,25 @@ 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 {
|
||||
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;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
|
||||
@@ -99,7 +113,7 @@ public class SearchResultIcon extends BubbleTextView implements SearchTargetHand
|
||||
* Applies {@link SearchTarget} to view. registers a consumer after a corresponding
|
||||
* {@link ItemInfoWithIcon} is created
|
||||
*/
|
||||
public void applySearchTarget(SearchTarget searchTarget, List<SearchTarget> inlineItems,
|
||||
public void apply(SearchTarget searchTarget, List<SearchTarget> inlineItems,
|
||||
Consumer<ItemInfoWithIcon> cb) {
|
||||
mOnItemInfoChanged = cb;
|
||||
apply(searchTarget, inlineItems);
|
||||
@@ -115,8 +129,8 @@ public class SearchResultIcon extends BubbleTextView implements SearchTargetHand
|
||||
prepareUsingSearchAction(parentTarget);
|
||||
mLongPressSupported = false;
|
||||
} else {
|
||||
prepareUsingApp(new ComponentName(parentTarget.getPackageName(),
|
||||
parentTarget.getExtras().getString(SearchTargetUtil.EXTRA_CLASS)),
|
||||
String className = parentTarget.getExtras().getString(SearchTargetUtil.EXTRA_CLASS);
|
||||
prepareUsingApp(new ComponentName(parentTarget.getPackageName(), className),
|
||||
parentTarget.getUserHandle());
|
||||
mLongPressSupported = true;
|
||||
}
|
||||
@@ -136,14 +150,17 @@ public class SearchResultIcon extends BubbleTextView implements SearchTargetHand
|
||||
//TODO: remove this after flags are introduced in SearchAction. Settings results require
|
||||
// startActivityForResult
|
||||
boolean isSettingsResult = searchTarget.getResultType() == ResultType.SETTING;
|
||||
if ((extras != null && extras.getBoolean(BUNDLE_EXTRA_SHOULD_START_FOR_RESULT))
|
||||
if ((extras != null && extras.getBoolean(
|
||||
SearchTargetUtil.BUNDLE_EXTRA_SHOULD_START_FOR_RESULT))
|
||||
|| isSettingsResult) {
|
||||
itemInfo.setFlags(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT);
|
||||
} else if (extras != null && extras.getBoolean(BUNDLE_EXTRA_SHOULD_START)) {
|
||||
} else if (extras != null && extras.getBoolean(
|
||||
SearchTargetUtil.BUNDLE_EXTRA_SHOULD_START)) {
|
||||
itemInfo.setFlags(SearchActionItemInfo.FLAG_SHOULD_START);
|
||||
}
|
||||
if (extras != null && extras.getBoolean(BUNDLE_EXTRA_BADGE_FROM_ICON)) {
|
||||
itemInfo.setFlags(FLAG_BADGE_FROM_ICON);
|
||||
if (extras != null && extras.getBoolean(
|
||||
SearchTargetUtil.BUNDLE_EXTRA_BADGE_WITH_PACKAGE)) {
|
||||
itemInfo.setFlags(FLAG_BADGE_WITH_PACKAGE);
|
||||
}
|
||||
if (extras != null && extras.getBoolean(BUNDLE_EXTRA_PRIMARY_ICON_FROM_TITLE)) {
|
||||
itemInfo.setFlags(FLAG_PRIMARY_ICON_FROM_TITLE);
|
||||
@@ -154,39 +171,76 @@ public class SearchResultIcon extends BubbleTextView implements SearchTargetHand
|
||||
MODEL_EXECUTOR.post(() -> {
|
||||
try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
|
||||
Icon icon = searchTarget.getSearchAction().getIcon();
|
||||
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 {
|
||||
d = itemInfo.getIcon().loadDrawable(getContext());
|
||||
bitmapInfo = li.createBadgedIconBitmap(d, itemInfo.user,
|
||||
Build.VERSION.SDK_INT);
|
||||
}
|
||||
|
||||
BitmapInfo bitmapMainIcon;
|
||||
BitmapInfo pkgBitmap = getPackageBitmap(appState, searchTarget);
|
||||
if (itemInfo.hasFlags(FLAG_PRIMARY_ICON_FROM_TITLE)) {
|
||||
bitmapMainIcon = li.createIconBitmap(
|
||||
String.valueOf(itemInfo.title.charAt(0)),
|
||||
bitmapInfo.color);
|
||||
// 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;
|
||||
} else {
|
||||
bitmapMainIcon = bitmapInfo;
|
||||
}
|
||||
if (itemInfo.hasFlags(FLAG_BADGE_FROM_ICON)) {
|
||||
itemInfo.bitmap = li.badgeBitmap(bitmapMainIcon.icon, bitmapInfo);
|
||||
} else {
|
||||
itemInfo.bitmap = bitmapInfo;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// badge with package name
|
||||
if (itemInfo.hasFlags(FLAG_BADGE_WITH_PACKAGE) && itemInfo.bitmap != pkgBitmap) {
|
||||
itemInfo.bitmap = li.badgeBitmap(itemInfo.bitmap.icon, pkgBitmap);
|
||||
}
|
||||
}
|
||||
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));
|
||||
@@ -233,7 +287,6 @@ public class SearchResultIcon extends BubbleTextView implements SearchTargetHand
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void notifyItemInfoChanged(ItemInfoWithIcon itemInfoWithIcon) {
|
||||
if (mOnItemInfoChanged != null) {
|
||||
mOnItemInfoChanged.accept(itemInfoWithIcon);
|
||||
|
||||
Reference in New Issue
Block a user