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

Commit 334e6593 authored by Alina Zaidi's avatar Alina Zaidi
Browse files

Have a recycler view to show search results.

-Have a recycler view layout for search widgets list.
-Make WidgetsFullSheet implement interface- SearchModeListener to get notified when user is using search and also when search results are ready.
-Have a WidgetsListSearchHeaderViewHolderBinder for search result headers which shows subtext in header as concatenated string of widget/shortcut labels.
-Modify WidgetsListAdapter and WidgetsDiffReporter to work well with search recycler view.

Test: Tested prototype locally. Also added robolectric test.
Bug: b/157286785
Change-Id: Ie29d9f295fddb6d727b5fc26a360f514f2f4a763
parent 24a63bac
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -51,5 +51,13 @@
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:layout_marginEnd="@dimen/fastscroll_end_margin" />

        <com.android.launcher3.widget.picker.WidgetsRecyclerView
            android:id="@+id/search_widgets_list_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:clipToPadding="false" />

    </com.android.launcher3.views.TopRoundedCornerView>
</com.android.launcher3.widget.picker.WidgetsFullSheet>
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@
            android:id="@+id/app_subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="1"
            tools:text="m widgets, n shortcuts" />

    </LinearLayout>

res/values/id.xml

0 → 100644
+21 −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.
-->
<resources>
    <item type="id" name="view_type_widgets_list" />
    <item type="id" name="view_type_widgets_header" />
    <item type="id" name="view_type_widgets_search_header" />
</resources>
+21 −0
Original line number Diff line number Diff line
@@ -221,6 +221,27 @@ public final class WidgetsDiffReporterTest {
        assertThat(currentList).containsExactlyElementsIn(newList);
    }

    @Test
    public void headersContentsMix_headerWidgetsModified_shouldInvokeCorrectCallbacks() {
        // GIVEN the current list has app headers [A, B, E content].
        ArrayList<WidgetsListBaseEntry> currentList = new ArrayList<>(
                List.of(mHeaderA, mHeaderB, mContentE));
        // GIVEN the new list has one of the headers widgets list modified.
        List<WidgetsListBaseEntry> newList = List.of(
                new WidgetsListHeaderEntry(
                        mHeaderA.mPkgItem, mHeaderA.mTitleSectionName,
                        mHeaderA.mWidgets.subList(0, 1)),
                mHeaderB, mContentE);

        // WHEN computing the list difference.
        mWidgetsDiffReporter.process(currentList, newList, COMPARATOR);

        // THEN notify "A" has been changed.
        verify(mAdapter).notifyItemChanged(/* position= */ 0);
        // THEN the current list contains all elements from the new list.
        assertThat(currentList).containsExactlyElementsIn(newList);
    }


    private WidgetsListHeaderEntry createWidgetsHeaderEntry(String packageName, String appName,
            int numOfWidgets) {
+33 −2
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Process;
import android.os.UserHandle;
import android.view.LayoutInflater;

import androidx.recyclerview.widget.RecyclerView;
@@ -37,6 +39,7 @@ import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
@@ -67,6 +70,7 @@ public final class WidgetsListAdapterTest {

    private WidgetsListAdapter mAdapter;
    private InvariantDeviceProfile mTestProfile;
    private UserHandle mUserHandle;
    private Context mContext;

    @Before
@@ -76,6 +80,7 @@ public final class WidgetsListAdapterTest {
        mTestProfile = new InvariantDeviceProfile();
        mTestProfile.numRows = 5;
        mTestProfile.numColumns = 5;
        mUserHandle = Process.myUserHandle();
        mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater, mMockWidgetCache,
                mIconCache, null, null);
        mAdapter.registerAdapterDataObserver(mListener);
@@ -126,7 +131,8 @@ public final class WidgetsListAdapterTest {
        mAdapter.setWidgets(generateSampleMap(3));

        // WHEN com.google.test.1 header is expanded.
        mAdapter.onHeaderClicked(/* isExpanded= */ true, TEST_PACKAGE_PLACEHOLDER + 1);
        mAdapter.onHeaderClicked(/* showWidgets= */ true,
                new PackageUserKey(TEST_PACKAGE_PLACEHOLDER + 1, mUserHandle));

        // THEN the visible entries list becomes:
        // [com.google.test0, com.google.test1, com.google.test1 content, com.google.test2]
@@ -143,7 +149,8 @@ public final class WidgetsListAdapterTest {
        // GIVEN test com.google.test1 is expanded.
        // Visible entries in the adapter are:
        // [com.google.test0, com.google.test1, com.google.test1 content]
        mAdapter.onHeaderClicked(/* isExpanded= */ true, TEST_PACKAGE_PLACEHOLDER + 1);
        mAdapter.onHeaderClicked(/* showWidgets= */ true,
                new PackageUserKey(TEST_PACKAGE_PLACEHOLDER + 1, mUserHandle));
        Mockito.reset(mListener);

        // WHEN the adapter is updated with the same list of apps but com.google.test1 has 2 widgets
@@ -200,6 +207,30 @@ public final class WidgetsListAdapterTest {
        verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
    }

    @Test
    public void setWidgetsOnSearch_expandedApp_shouldResetExpandedApp() {
        // GIVEN a list of widgets entries:
        // [com.google.test0, com.google.test0 content,
        //  com.google.test1, com.google.test1 content,
        //  com.google.test2, com.google.test2 content]
        // The visible widgets entries: [com.google.test0, com.google.test1, com.google.test2].
        ArrayList<WidgetsListBaseEntry> allEntries = generateSampleMap(2);
        mAdapter.setWidgetsOnSearch(allEntries);
        // GIVEN com.google.test.1 header is expanded. The visible entries list becomes:
        // [com.google.test0, com.google.test1, com.google.test1 content, com.google.test2]
        mAdapter.onHeaderClicked(/* showWidgets= */ true,
                new PackageUserKey(TEST_PACKAGE_PLACEHOLDER + 1, mUserHandle));
        Mockito.reset(mListener);

        // WHEN same widget entries are set again.
        mAdapter.setWidgetsOnSearch(allEntries);

        // THEN expanded app is reset and the visible entries list becomes:
        // [com.google.test0, com.google.test1, com.google.test2]
        verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
        verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
    }

    /**
     * Generates a list of sample widget entries.
     *
Loading