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

Commit ffd2b6d2 authored by Samuel Fufa's avatar Samuel Fufa
Browse files

Search support for widgets with config activity

Shows widget preview in search if widget requires config.

preview: https://drive.google.com/file/d/1q1ROu7-OUGfskDMRxXPNQMdr3T-WMMkv/view?usp=sharing
Bug: 168321831
Test: Manual
Change-Id: I6c1c168ebac4ce33a4234e8a417eba789f664f43
parent bbaf9ff6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.views.SearchResultWidgetPreview xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:padding="@dimen/dynamic_grid_cell_padding_x"
    android:layout_height="wrap_content">
    <include layout="@layout/widget_cell" android:id="@+id/widget_cell"/>
<!--    <include layout="@layout/widget_cell_content" />-->
</com.android.launcher3.views.SearchResultWidgetPreview>
 No newline at end of file
+8 −1
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ public class AllAppsGridAdapter extends

    public static final int VIEW_TYPE_SEARCH_WIDGET_LIVE = 1 << 15;

    public static final int VIEW_TYPE_SEARCH_WIDGET_PREVIEW = 1 << 16;

    // Common view type masks
    public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
    public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON | VIEW_TYPE_SEARCH_ICON;
@@ -287,7 +289,8 @@ public class AllAppsGridAdapter extends
            int viewType = mApps.getAdapterItems().get(position).viewType;
            if (isIconViewType(viewType)) {
                return 1 * SPAN_MULTIPLIER;
            } else if (viewType == VIEW_TYPE_SEARCH_THUMBNAIL) {
            } else if (viewType == VIEW_TYPE_SEARCH_THUMBNAIL
                    || viewType == VIEW_TYPE_SEARCH_WIDGET_PREVIEW) {
                return mAppsPerRow;
            } else {
                // Section breaks span the full width
@@ -433,6 +436,9 @@ public class AllAppsGridAdapter extends
            case VIEW_TYPE_SEARCH_WIDGET_LIVE:
                return new ViewHolder(mLayoutInflater.inflate(
                        R.layout.search_result_widget_live, parent, false));
            case VIEW_TYPE_SEARCH_WIDGET_PREVIEW:
                return new ViewHolder(mLayoutInflater.inflate(
                        R.layout.search_result_widget_preview, parent, false));
            default:
                throw new RuntimeException("Unexpected view type");
        }
@@ -476,6 +482,7 @@ public class AllAppsGridAdapter extends
            case VIEW_TYPE_SEARCH_THUMBNAIL:
            case VIEW_TYPE_SEARCH_SUGGEST:
            case VIEW_TYPE_SEARCH_WIDGET_LIVE:
            case VIEW_TYPE_SEARCH_WIDGET_PREVIEW:
                SearchAdapterItem item =
                        (SearchAdapterItem) mApps.getAdapterItems().get(position);
                SearchTargetHandler payloadResultView = (SearchTargetHandler) holder.itemView;
+141 −0
Original line number Diff line number Diff line
/*
 * 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 static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;

import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.R;
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
import com.android.launcher3.allapps.search.SearchEventTracker;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.widget.BaseWidgetSheet;
import com.android.launcher3.widget.PendingItemDragHelper;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.WidgetImageView;
import com.android.systemui.plugins.shared.SearchTarget;
import com.android.systemui.plugins.shared.SearchTargetEvent;

/**
 * displays preview of a widget upon receiving {@link AppWidgetProviderInfo} from Search provider
 */
public class SearchResultWidgetPreview extends LinearLayout implements
        AllAppsSearchBarController.SearchTargetHandler, View.OnLongClickListener,
        View.OnClickListener {

    public static final String TARGET_TYPE_WIDGET_PREVIEW = "widget_preview";
    private final Launcher mLauncher;
    private final LauncherAppState mAppState;
    private WidgetCell mWidgetCell;
    private Toast mWidgetToast;

    private SearchTarget mSearchTarget;


    public SearchResultWidgetPreview(Context context) {
        this(context, null, 0);
    }

    public SearchResultWidgetPreview(Context context,
            @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SearchResultWidgetPreview(Context context, @Nullable AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mLauncher = Launcher.getLauncher(context);
        mAppState = LauncherAppState.getInstance(context);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mWidgetCell = findViewById(R.id.widget_cell);
        mWidgetCell.setOnLongClickListener(this);
        mWidgetCell.setOnClickListener(this);
    }

    @Override
    public void applySearchTarget(SearchTarget searchTarget) {
        if (searchTarget.getExtras() == null
                || searchTarget.getExtras().getParcelable("provider") == null) {
            setVisibility(GONE);
            return;
        }
        mSearchTarget = searchTarget;
        AppWidgetProviderInfo providerInfo = searchTarget.getExtras().getParcelable("provider");
        LauncherAppWidgetProviderInfo pInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(
                getContext(), providerInfo);
        MODEL_EXECUTOR.post(() -> {
            WidgetItem widgetItem = new WidgetItem(pInfo, mLauncher.getDeviceProfile().inv,
                    mAppState.getIconCache());
            MAIN_EXECUTOR.post(() -> {
                mWidgetCell.applyFromCellItem(widgetItem, mAppState.getWidgetCache());
                mWidgetCell.ensurePreview();
            });
        });

    }

    @Override
    public boolean onLongClick(View view) {
        view.cancelLongPress();
        if (!ItemLongClickListener.canStartDrag(mLauncher)) return false;
        if (mWidgetCell.getTag() == null) return false;

        WidgetImageView imageView = mWidgetCell.getWidgetView();
        if (imageView.getBitmap() == null) {
            return false;
        }

        int[] loc = new int[2];
        mLauncher.getDragLayer().getLocationInDragLayer(imageView, loc);

        new PendingItemDragHelper(mWidgetCell).startDrag(
                imageView.getBitmapBounds(), imageView.getBitmap().getWidth(), imageView.getWidth(),
                new Point(loc[0], loc[1]), mLauncher.getAppsView(), new DragOptions());
        handleSelection(SearchTargetEvent.LONG_PRESS);
        return true;
    }

    @Override
    public void onClick(View view) {
        mWidgetToast = BaseWidgetSheet.showWidgetToast(getContext(), mWidgetToast);
        handleSelection(SearchTargetEvent.SELECT);
    }

    @Override
    public void handleSelection(int eventType) {
        SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
                new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
    }
}
+19 −11
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ import com.android.launcher3.views.AbstractSlideInView;
/**
 * Base class for various widgets popup
 */
abstract class BaseWidgetSheet extends AbstractSlideInView
public abstract class BaseWidgetSheet extends AbstractSlideInView
        implements OnClickListener, OnLongClickListener, DragSource,
        PopupDataProvider.PopupDataChangeListener {

@@ -74,16 +74,7 @@ abstract class BaseWidgetSheet extends AbstractSlideInView

    @Override
    public final void onClick(View v) {
        // Let the user know that they have to long press to add a widget
        if (mWidgetInstructionToast != null) {
            mWidgetInstructionToast.cancel();
        }

        CharSequence msg = Utilities.wrapForTts(
                getContext().getText(R.string.long_press_widget_to_add),
                getContext().getString(R.string.long_accessible_way_to_add));
        mWidgetInstructionToast = Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT);
        mWidgetInstructionToast.show();
        mWidgetInstructionToast = showWidgetToast(getContext(), mWidgetInstructionToast);
    }

    @Override
@@ -146,4 +137,21 @@ abstract class BaseWidgetSheet extends AbstractSlideInView
    protected SystemUiController getSystemUiController() {
        return mLauncher.getSystemUiController();
    }

    /**
     * Show Widget tap toast prompting user to drag instead
     */
    public static Toast showWidgetToast(Context context, Toast toast) {
        // Let the user know that they have to long press to add a widget
        if (toast != null) {
            toast.cancel();
        }

        CharSequence msg = Utilities.wrapForTts(
                context.getText(R.string.long_press_widget_to_add),
                context.getString(R.string.long_accessible_way_to_add));
        toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        toast.show();
        return toast;
    }
}