Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16b74e0c authored by Samuel Fufa's avatar Samuel Fufa Committed by Android (Google) Code Review
Browse files

Merge " Migrate from Plugin SearchTarget to API search Target [3/3]"

parents 3da80bd3 bdf4f712
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.android.app.search.LayoutType;
import com.android.app.search.ResultType;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
@@ -78,10 +80,10 @@ public class DeviceSearchAdapterProvider extends SearchAdapterProvider {
        SearchTargetHandler
                payloadResultView =
                (SearchTargetHandler) holder.itemView;
        if (FeatureFlags.SEARCH_TARGET_LEGACY.get()) {
        if (!FeatureFlags.USE_SEARCH_API.get()) {
            payloadResultView.applySearchTarget(item.getSearchTargetLegacy());
        } else {
            payloadResultView.applySearchTarget(item.getSearchTarget());
            payloadResultView.applySearchTarget(item.getSearchTarget(), item.getInlineItems());
        }
    }

@@ -123,10 +125,25 @@ public class DeviceSearchAdapterProvider extends SearchAdapterProvider {
     * Returns -1 if viewType is not found
     */
    public int getViewTypeForSearchTarget(SearchTarget t) {
        //TODO: Replace with values from :SearchUi
        if (t.getResultType() == 1 && t.getLayoutType().equals("icon")) {
        if (t.getLayoutType().equals(LayoutType.TEXT_HEADER)) {
            return VIEW_TYPE_SEARCH_CORPUS_TITLE;
        }
        switch (t.getResultType()) {
            case ResultType.APPLICATION:
                if (t.getLayoutType().equals(LayoutType.ICON_SINGLE_VERTICAL_TEXT)) {
                    return VIEW_TYPE_SEARCH_ICON;
                }
                break;
            case ResultType.SETTING:
                if (t.getLayoutType().equals(LayoutType.ICON_SLICE)) {
                    return VIEW_TYPE_SEARCH_SLICE;
                }
                return VIEW_TYPE_SEARCH_ROW;
            case ResultType.SHORTCUT:
                return VIEW_TYPE_SEARCH_ICON_ROW;
            case ResultType.PLAY:
                return VIEW_TYPE_SEARCH_ROW_WITH_BUTTON;
        }
        return -1;
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -32,12 +32,16 @@ import android.app.search.SearchTarget;
import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.systemui.plugins.shared.SearchTargetLegacy;

import java.util.ArrayList;
import java.util.List;

/**
 * Extension of AdapterItem that contains an extra payload specific to item
 */
public class SearchAdapterItem extends AllAppsGridAdapter.AdapterItem {
    private SearchTargetLegacy mSearchTargetLegacy;
    private SearchTarget mSearchTarget;
    private List<SearchTarget> mInlineItems = new ArrayList<>();


    private static final int AVAILABLE_FOR_ACCESSIBILITY = VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
@@ -65,6 +69,9 @@ public class SearchAdapterItem extends AllAppsGridAdapter.AdapterItem {
        return mSearchTarget;
    }

    public List<SearchTarget> getInlineItems() {
        return mInlineItems;
    }
    @Override
    protected boolean isCountedForAccessibility() {
        return (AVAILABLE_FOR_ACCESSIBILITY & viewType) == viewType;
+26 −4
Original line number Diff line number Diff line
@@ -31,10 +31,12 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.android.app.search.ResultType;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.AppInfo;
@@ -46,6 +48,7 @@ import com.android.launcher3.util.ComponentKey;
import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
import com.android.systemui.plugins.shared.SearchTargetLegacy;

import java.util.List;
import java.util.function.Consumer;

/**
@@ -128,10 +131,27 @@ public class SearchResultIcon extends BubbleTextView implements
        }
    }

    /**
     * Applies {@link SearchTarget} to view. registers a consumer after a corresponding
     * {@link ItemInfoWithIcon} is created
     */
    public void applySearchTarget(SearchTarget searchTarget, List<SearchTarget> inlineItems,
            Consumer<ItemInfoWithIcon> cb) {
        mOnItemInfoChanged = cb;
        applySearchTarget(searchTarget, inlineItems);
    }

    @Override
    public void applySearchTarget(SearchTarget searchTarget) {
        prepareUsingApp(new ComponentName(searchTarget.getPackageName(),
                searchTarget.getExtras().getString("class")), searchTarget.getUserHandle());
    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
        switch (parentTarget.getResultType()) {
            case ResultType.APPLICATION:
                prepareUsingApp(new ComponentName(parentTarget.getPackageName(),
                        parentTarget.getExtras().getString("class")), parentTarget.getUserHandle());
                break;
            case ResultType.SHORTCUT:
                prepareUsingShortcutInfo(parentTarget.getShortcutInfo());
                break;
        }
    }

    private void prepareUsingApp(ComponentName componentName, UserHandle userHandle) {
@@ -185,8 +205,10 @@ public class SearchResultIcon extends BubbleTextView implements
    @Override
    public void handleSelection(int eventType) {
        mLauncher.getItemOnClickListener().onClick(this);
        if (!FeatureFlags.USE_SEARCH_API.get()) {
            reportEvent(eventType);
        }
    }

    private void reportEvent(int eventType) {
        SearchTargetEventLegacy.Builder b = new SearchTargetEventLegacy.Builder(mSearchTarget,
+12 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.launcher3.search;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;

import android.app.search.SearchTarget;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ShortcutInfo;
@@ -32,6 +33,7 @@ import android.widget.TextView;

import androidx.annotation.Nullable;

import com.android.app.search.ResultType;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
@@ -111,6 +113,16 @@ public class SearchResultIconRow extends LinearLayout implements
        setOnLongClickListener(this);
    }

    @Override
    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
        mResultIcon.applySearchTarget(parentTarget, children, this);
        if (parentTarget.getResultType() == ResultType.SHORTCUT) {
            ShortcutInfo shortcutInfo = parentTarget.getShortcutInfo();
            setProviderDetails(new ComponentName(shortcutInfo.getPackage(), ""),
                    shortcutInfo.getUserHandle());
        }
    }

    @Override
    public void applySearchTarget(SearchTargetLegacy searchTarget) {
        mSearchTarget = searchTarget;
+49 −77
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ package com.android.launcher3.search;

import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;

import android.app.search.SearchAction;
import android.app.search.SearchTarget;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -27,8 +29,6 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -43,12 +43,11 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.util.Themes;
import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
import com.android.systemui.plugins.shared.SearchTargetLegacy;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

/**
 * A View representing a PlayStore item.
@@ -67,9 +66,8 @@ public class SearchResultPlayItem extends LinearLayout implements
    private TextView[] mDetailViews = new TextView[3];
    private Button mPreviewButton;
    private String mPackageName;
    private boolean mIsInstantGame;

    private SearchTargetLegacy mSearchTarget;
    private Intent mIntent;
    private Intent mSecondaryIntent;


    public SearchResultPlayItem(Context context) {
@@ -93,7 +91,7 @@ public class SearchResultPlayItem extends LinearLayout implements
        mIconView = findViewById(R.id.icon);
        mTitleView = findViewById(R.id.title_view);
        mPreviewButton = findViewById(R.id.try_button);
        mPreviewButton.setOnClickListener(view -> launchInstantGame());
        mPreviewButton.setOnClickListener(view -> launchIntent(mSecondaryIntent));
        mDetailViews[0] = findViewById(R.id.detail_0);
        mDetailViews[1] = findViewById(R.id.detail_1);
        mDetailViews[2] = findViewById(R.id.detail_2);
@@ -101,53 +99,47 @@ public class SearchResultPlayItem extends LinearLayout implements
        ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams();
        iconParams.height = mDeviceProfile.allAppsIconSizePx;
        iconParams.width = mDeviceProfile.allAppsIconSizePx;
        setOnClickListener(view -> handleSelection(SearchTargetEventLegacy.SELECT));
        setOnClickListener(view -> launchIntent(mIntent));
    }


    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;
    private void showIfNecessary(TextView textView, @Nullable String string) {
        if (string == null || string.isEmpty()) {
            textView.setVisibility(GONE);
        } else {
            textView.setText(string);
            textView.setVisibility(VISIBLE);
        }
    }

    private void launchIntent(Intent intent) {
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getContext().startActivity(intent);
    }

    @Override
    public void applySearchTarget(SearchTargetLegacy searchTarget) {
        mSearchTarget = searchTarget;
        Bundle bundle = searchTarget.getExtras();
        SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
        if (bundle.getString("package", "").equals(mPackageName)) {
    public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
        if (parentTarget.getPackageName().equals(mPackageName)) {
            return;
        }
        mIsInstantGame = bundle.getBoolean("instant_game", false);
        mPackageName = bundle.getString("package");
        mPreviewButton.setVisibility(mIsInstantGame ? VISIBLE : GONE);
        mTitleView.setText(bundle.getString("title"));
//        TODO: Should use a generic type to get values b/165320033
        showIfNecessary(mDetailViews[0], bundle.getString("price"));
        showIfNecessary(mDetailViews[1], bundle.getString("rating"));
        mPackageName = parentTarget.getPackageName();
        SearchAction action = parentTarget.getSearchAction();
        mTitleView.setText(action.getTitle());
        showIfNecessary(mDetailViews[0], action.getSubtitle().toString());
        mIntent = action.getIntent();

        mIconView.setBackgroundResource(R.drawable.ic_deepshortcut_placeholder);
        loadIcon(action.getIcon().getUri().toString());

        mSecondaryIntent = children.size() == 1 ? children.get(0).getSearchAction().getIntent()
                : null;
        mPreviewButton.setVisibility(mSecondaryIntent == null ? GONE : VISIBLE);
    }

    private void loadIcon(String iconUrl) {
        UI_HELPER_EXECUTOR.execute(() -> {
            try {
                URL url = new URL(bundle.getString("icon_url"));
                URL url = new URL(iconUrl);
                URLConnection con = url.openConnection();
//                TODO: monitor memory and investigate if it's better to use glide
                con.addRequestProperty("Cache-Control", "max-age: 0");
                con.setUseCaches(true);
                Bitmap bitmap = BitmapFactory.decodeStream(con.getInputStream());
@@ -161,43 +153,23 @@ public class SearchResultPlayItem extends LinearLayout implements
        });
    }

    private void showIfNecessary(TextView textView, @Nullable String string) {
        if (string == null || string.isEmpty()) {
            textView.setVisibility(GONE);
        } else {
            textView.setText(string);
            textView.setVisibility(VISIBLE);
        }
    }
    private Bitmap getRoundedBitmap(Bitmap bitmap) {
        final int iconSize = bitmap.getWidth();
        final float radius = Themes.getDialogCornerRadius(getContext());

    @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="
                        + mPackageName));
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getContext().startActivity(i);
        logSearchEvent(eventType);
    }
        Bitmap output = BitmapRenderer.createHardwareBitmap(iconSize, iconSize, (canvas) -> {
            mTempRect.set(0, 0, iconSize, iconSize);
            final RectF rectF = new RectF(mTempRect);

    private void launchInstantGame() {
        if (!mIsInstantGame) return;
        Intent intent = new Intent(Intent.ACTION_VIEW);
        String referrer = "Pixel_Launcher";
        String id = mPackageName;
        String deepLinkUrl = "market://details?id=" + id + "&launch=true&referrer=" + referrer;
        intent.setPackage("com.android.vending");
        intent.setData(Uri.parse(deepLinkUrl));
        intent.putExtra("overlay", true);
        intent.putExtra("callerId", getContext().getPackageName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getContext().startActivity(intent);
        logSearchEvent(SearchTargetEventLegacy.CHILD_SELECT);
    }
            mIconPaint.setAntiAlias(true);
            mIconPaint.reset();
            canvas.drawARGB(0, 0, 0, 0);
            mIconPaint.setColor(BITMAP_CROP_MASK_COLOR);
            canvas.drawRoundRect(rectF, radius, radius, mIconPaint);

    private void logSearchEvent(int eventType) {
        SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
                new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
            mIconPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(bitmap, mTempRect, mTempRect, mIconPaint);
        });
        return output;
    }
}
Loading