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

Commit 114de69c authored by Samuel Fufa's avatar Samuel Fufa
Browse files

Introduce support for play results in launcher

Introduces PluginSearchPipeline class, a plugin listener for AllAppsSearchPlugin. Coverts from List<Bundle> results from callback to AdapterItems to be rendered in SearchController.
- Moves AdapterItem to AllAppsGridAdapter

Bug: 164699827
Test: Manual
Change-Id: I20ec147e6b3f4707cf69d62b4b4ac70a90196345
parent 4fb5f74b
Loading
Loading
Loading
Loading
+75 −0
Original line number Diff line number Diff line
<?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.views.SearchResultPlayItem xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp"
    android:orientation="horizontal">
    <View
        android:id="@+id/icon"
        android:layout_width="@dimen/deep_shortcut_icon_size"
        android:layout_height="@dimen/deep_shortcut_icon_size"
        android:layout_gravity="start|center_vertical"
        android:background="@drawable/ic_deepshortcut_placeholder" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="start|center_vertical"
        android:layout_weight="1"
        android:orientation="vertical"
        android:padding="8dp">

        <TextView
            android:id="@+id/title_view"
            style="@style/TextHeadline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAlignment="viewStart"
            android:textColor="?android:attr/textColorPrimary"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/detail_0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="?android:attr/textColorPrimary" />

        <TextView
            android:id="@+id/detail_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="?android:attr/textColorPrimary"
            android:visibility="gone" />

        <TextView
            android:id="@+id/detail_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="?android:attr/textColorPrimary"
            android:visibility="gone" />
    </LinearLayout>
    <Button
        android:id="@+id/try_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="start|center_vertical"
        android:background="?android:attr/selectableItemBackground"
        android:text="@string/search_action_try_now">
    </Button>


</com.android.launcher3.views.SearchResultPlayItem>
+8 −8
Original line number Diff line number Diff line
@@ -13,11 +13,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
<com.android.launcher3.views.SearchSectionHeaderView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/section_title"
          android:textSize="14sp"
          android:fontFamily="@style/TextHeadline"
    android:layout_width="wrap_content"
          android:textColor="?android:attr/textColorPrimary"
    android:layout_height="wrap_content"
    android:fontFamily="@style/TextHeadline"
    android:padding="4dp"
          android:layout_height="wrap_content"/>
 No newline at end of file
    android:textColor="?android:attr/textColorPrimary"
    android:textSize="14sp" />
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@
    <!--All apps Search-->
    <!-- Section title for apps [CHAR_LIMIT=50] -->
    <string name="search_corpus_apps">Apps</string>
    <!-- try instant app action for play search result [CHAR_LIMIT=50 -->
    <string name="search_action_try_now">Try Now</string>

    <!-- Popup items -->
    <!-- Text to display as the header above notifications. [CHAR_LIMIT=30] -->
+21 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.launcher3.allapps;

import static com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import static com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
@@ -527,6 +529,25 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
        return mViewPager == null ? getActiveRecyclerView() : mViewPager;
    }

    /**
     * Handles selection on focused view and returns success
     */
    public boolean selectFocusedView(View v) {
        ItemInfo itemInfo = getHighlightedItemInfo();
        if (itemInfo != null) {
            return mLauncher.startActivitySafely(v, itemInfo.getIntent(), itemInfo);
        }
        AdapterItem focusedItem = getActiveRecyclerView().getApps().getFocusedChild();
        if (focusedItem instanceof AdapterItemWithPayload) {
            Runnable onSelection = ((AdapterItemWithPayload) focusedItem).getSelectionHandler();
            if (onSelection != null) {
                onSelection.run();
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the ItemInfo of a view that is in focus, ready to be launched by an IME.
     */
+114 −11
Original line number Diff line number Diff line
@@ -40,10 +40,10 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
import com.android.launcher3.allapps.search.AllAppsSearchBarController.PayloadResultHandler;
import com.android.launcher3.allapps.search.SearchSectionInfo;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.views.HeroSearchResultView;

import java.util.List;

@@ -71,6 +71,8 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.

    public static final int VIEW_TYPE_SEARCH_HERO_APP = 1 << 6;

    public static final int DETAIL_ROW_WITH_BUTTON = 1 << 7;

    // 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;
@@ -85,6 +87,108 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
        }
    }

    /**
     * Info about a particular adapter item (can be either section or app)
     */
    public static class AdapterItem {
        /** Common properties */
        // The index of this adapter item in the list
        public int position;
        // The type of this item
        public int viewType;

        /** App-only properties */
        // The section name of this app.  Note that there can be multiple items with different
        // sectionNames in the same section
        public String sectionName = null;
        // The row that this item shows up on
        public int rowIndex;
        // The index of this app in the row
        public int rowAppIndex;
        // The associated AppInfo for the app
        public AppInfo appInfo = null;
        // The index of this app not including sections
        public int appIndex = -1;
        // Search section associated to result
        public SearchSectionInfo searchSectionInfo = null;

        /**
         * Factory method for AppIcon AdapterItem
         */
        public static AdapterItem asApp(int pos, String sectionName, AppInfo appInfo,
                int appIndex) {
            AdapterItem item = new AdapterItem();
            item.viewType = VIEW_TYPE_ICON;
            item.position = pos;
            item.sectionName = sectionName;
            item.appInfo = appInfo;
            item.appIndex = appIndex;
            return item;
        }

        /**
         * Factory method for empty search results view
         */
        public static AdapterItem asEmptySearch(int pos) {
            AdapterItem item = new AdapterItem();
            item.viewType = VIEW_TYPE_EMPTY_SEARCH;
            item.position = pos;
            return item;
        }

        /**
         * Factory method for a dividerView in AllAppsSearch
         */
        public static AdapterItem asAllAppsDivider(int pos) {
            AdapterItem item = new AdapterItem();
            item.viewType = VIEW_TYPE_ALL_APPS_DIVIDER;
            item.position = pos;
            return item;
        }

        /**
         * Factory method for a market search button
         */
        public static AdapterItem asMarketSearch(int pos) {
            AdapterItem item = new AdapterItem();
            item.viewType = VIEW_TYPE_SEARCH_MARKET;
            item.position = pos;
            return item;
        }

        boolean isCountedForAccessibility() {
            return viewType == VIEW_TYPE_ICON
                    || viewType == VIEW_TYPE_SEARCH_HERO_APP
                    || viewType == DETAIL_ROW_WITH_BUTTON;
        }
    }

    /**
     * Extension of AdapterItem that contains an extra payload specific to item
     * @param <T> Play load Type
     */
    public static class AdapterItemWithPayload<T> extends AdapterItem {
        private T mPayload;
        private Runnable mSelectionHandler;

        public AdapterItemWithPayload(T payload, int type) {
            mPayload = payload;
            viewType = type;
        }

        public void setSelectionHandler(Runnable runnable) {
            mSelectionHandler = runnable;
        }

        public Runnable getSelectionHandler() {
            return mSelectionHandler;
        }

        public T getPayload() {
            return mPayload;
        }
    }

    /**
     * A subclass of GridLayoutManager that overrides accessibility values during app search.
     */
@@ -286,6 +390,9 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
            case VIEW_TYPE_SEARCH_HERO_APP:
                return new ViewHolder(mLayoutInflater.inflate(
                        R.layout.search_result_hero_app, parent, false));
            case DETAIL_ROW_WITH_BUTTON:
                return new ViewHolder(mLayoutInflater.inflate(
                        R.layout.search_result_play_item, parent, false));
            default:
                throw new RuntimeException("Unexpected view type");
        }
@@ -315,15 +422,11 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
                }
                break;
            case VIEW_TYPE_SEARCH_CORPUS_TITLE:
                TextView titleView = (TextView) holder.itemView;
                titleView.setText(mApps.getAdapterItems().get(position).searchSectionInfo.getTitle(
                        titleView.getContext()));
                break;
            case DETAIL_ROW_WITH_BUTTON:
            case VIEW_TYPE_SEARCH_HERO_APP:
                HeroSearchResultView heroView = (HeroSearchResultView) holder.itemView;
                heroView.prepareUsingAdapterItem(
                        (AlphabeticalAppsList.HeroAppAdapterItem) mApps.getAdapterItems().get(
                                position));
                PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView;
                payloadResultView.applyAdapterInfo(
                        (AdapterItemWithPayload) mApps.getAdapterItems().get(position));
                break;
            case VIEW_TYPE_ALL_APPS_DIVIDER:
                // nothing to do
@@ -344,7 +447,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.

    @Override
    public int getItemViewType(int position) {
        AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(position);
        AdapterItem item = mApps.getAdapterItems().get(position);
        return item.viewType;
    }

Loading