diff --git a/res/values/id.xml b/res/values/id.xml index 52a7e98f89..375750f0d6 100644 --- a/res/values/id.xml +++ b/res/values/id.xml @@ -19,7 +19,6 @@ - diff --git a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java index 1d1c9dce1a..f09f4c6b5d 100644 --- a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java +++ b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java @@ -59,27 +59,12 @@ public abstract class WidgetsListBaseEntry { @Rank public abstract int getRank(); - /** - * Marker interface for subclasses that are headers for widget list items. - * - * @param The type of this class. - */ - public interface Header> { - /** Returns whether the widget list is currently expanded. */ - boolean isWidgetListShown(); - - /** Returns a copy of the item with the widget list shown. */ - T withWidgetListShown(); - } - @Retention(SOURCE) - @IntDef({RANK_WIDGETS_TOP_SPACE, RANK_WIDGETS_LIST_HEADER, RANK_WIDGETS_LIST_SEARCH_HEADER, - RANK_WIDGETS_LIST_CONTENT}) + @IntDef({RANK_WIDGETS_TOP_SPACE, RANK_WIDGETS_LIST_HEADER, RANK_WIDGETS_LIST_CONTENT}) public @interface Rank { } public static final int RANK_WIDGETS_TOP_SPACE = 1; public static final int RANK_WIDGETS_LIST_HEADER = 2; - public static final int RANK_WIDGETS_LIST_SEARCH_HEADER = 3; - public static final int RANK_WIDGETS_LIST_CONTENT = 4; + public static final int RANK_WIDGETS_LIST_CONTENT = 3; } diff --git a/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java b/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java index 5b3ea94a2d..bb0cf9284e 100644 --- a/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java +++ b/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java @@ -15,35 +15,67 @@ */ package com.android.launcher3.widget.model; +import android.content.Context; +import android.content.res.Resources; + +import androidx.annotation.Nullable; + +import com.android.launcher3.R; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.model.data.PackageItemInfo; +import com.android.launcher3.util.PluralMessageFormat; import java.util.List; +import java.util.function.BiFunction; +import java.util.stream.Collectors; /** An information holder for an app which has widgets or/and shortcuts. */ -public final class WidgetsListHeaderEntry extends WidgetsListBaseEntry - implements WidgetsListBaseEntry.Header { +public final class WidgetsListHeaderEntry extends WidgetsListBaseEntry { - public final int widgetsCount; - public final int shortcutsCount; + private static final BiFunction SUBTITLE_SEARCH = + (context, entry) -> entry.mWidgets.stream() + .map(item -> item.label).sorted().collect(Collectors.joining(", ")); + + private static final BiFunction SUBTITLE_DEFAULT = + (context, entry) -> { + List items = entry.mWidgets; + int wc = (int) items.stream().filter(item -> item.widgetInfo != null).count(); + int sc = Math.max(0, items.size() - wc); + + Resources resources = context.getResources(); + if (wc == 0 && sc == 0) { + return null; + } + + String subtitle; + if (wc > 0 && sc > 0) { + String widgetsCount = PluralMessageFormat.getIcuPluralString(context, + R.string.widgets_count, wc); + String shortcutsCount = PluralMessageFormat.getIcuPluralString(context, + R.string.shortcuts_count, sc); + subtitle = resources.getString(R.string.widgets_and_shortcuts_count, + widgetsCount, shortcutsCount); + } else if (wc > 0) { + subtitle = PluralMessageFormat.getIcuPluralString(context, + R.string.widgets_count, wc); + } else { + subtitle = PluralMessageFormat.getIcuPluralString(context, + R.string.shortcuts_count, sc); + } + return subtitle; + }; private final boolean mIsWidgetListShown; - - public WidgetsListHeaderEntry(PackageItemInfo pkgItem, String titleSectionName, - List items) { - this(pkgItem, titleSectionName, items, /* isWidgetListShown= */ false); - } + private final boolean mIsSearchEntry; private WidgetsListHeaderEntry(PackageItemInfo pkgItem, String titleSectionName, - List items, boolean isWidgetListShown) { + List items, boolean isSearchEntry, boolean isWidgetListShown) { super(pkgItem, titleSectionName, items); - widgetsCount = (int) items.stream().filter(item -> item.widgetInfo != null).count(); - shortcutsCount = Math.max(0, items.size() - widgetsCount); + mIsSearchEntry = isSearchEntry; mIsWidgetListShown = isWidgetListShown; } /** Returns {@code true} if the widgets list associated with this header is shown. */ - @Override public boolean isWidgetListShown() { return mIsWidgetListShown; } @@ -59,23 +91,54 @@ public final class WidgetsListHeaderEntry extends WidgetsListBaseEntry return RANK_WIDGETS_LIST_HEADER; } + public boolean isSearchEntry() { + return mIsSearchEntry; + } + + @Nullable + public String getSubtitle(Context context) { + return mIsSearchEntry + ? SUBTITLE_SEARCH.apply(context, this) : SUBTITLE_DEFAULT.apply(context, this); + } + @Override public boolean equals(Object obj) { if (!(obj instanceof WidgetsListHeaderEntry)) return false; WidgetsListHeaderEntry otherEntry = (WidgetsListHeaderEntry) obj; return mWidgets.equals(otherEntry.mWidgets) && mPkgItem.equals(otherEntry.mPkgItem) && mTitleSectionName.equals(otherEntry.mTitleSectionName) - && mIsWidgetListShown == otherEntry.mIsWidgetListShown; + && mIsWidgetListShown == otherEntry.mIsWidgetListShown + && mIsSearchEntry == otherEntry.mIsSearchEntry; } /** Returns a copy of this {@link WidgetsListHeaderEntry} with the widget list shown. */ - @Override public WidgetsListHeaderEntry withWidgetListShown() { if (mIsWidgetListShown) return this; return new WidgetsListHeaderEntry( mPkgItem, mTitleSectionName, mWidgets, + mIsSearchEntry, /* isWidgetListShown= */ true); } + + public static WidgetsListHeaderEntry create(PackageItemInfo pkgItem, String titleSectionName, + List items) { + return new WidgetsListHeaderEntry( + pkgItem, + titleSectionName, + items, + /* forSearch */ false, + /* isWidgetListShown= */ false); + } + + public static WidgetsListHeaderEntry createForSearch(PackageItemInfo pkgItem, + String titleSectionName, List items) { + return new WidgetsListHeaderEntry( + pkgItem, + titleSectionName, + items, + /* forSearch */ true, + /* isWidgetListShown= */ false); + } } diff --git a/src/com/android/launcher3/widget/model/WidgetsListSearchHeaderEntry.java b/src/com/android/launcher3/widget/model/WidgetsListSearchHeaderEntry.java deleted file mode 100644 index 055e4ecbe6..0000000000 --- a/src/com/android/launcher3/widget/model/WidgetsListSearchHeaderEntry.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2021 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.widget.model; - -import com.android.launcher3.model.WidgetItem; -import com.android.launcher3.model.data.PackageItemInfo; - -import java.util.List; - -/** An information holder for an app which has widgets or/and shortcuts, to be shown in search. */ -public final class WidgetsListSearchHeaderEntry extends WidgetsListBaseEntry - implements WidgetsListBaseEntry.Header { - - private final boolean mIsWidgetListShown; - - public WidgetsListSearchHeaderEntry(PackageItemInfo pkgItem, String titleSectionName, - List items) { - this(pkgItem, titleSectionName, items, /* isWidgetListShown= */ false); - } - - private WidgetsListSearchHeaderEntry(PackageItemInfo pkgItem, String titleSectionName, - List items, boolean isWidgetListShown) { - super(pkgItem, titleSectionName, items); - mIsWidgetListShown = isWidgetListShown; - } - - /** Returns {@code true} if the widgets list associated with this header is shown. */ - @Override - public boolean isWidgetListShown() { - return mIsWidgetListShown; - } - - @Override - public String toString() { - return "SearchHeader:" + mPkgItem.packageName + ":" + mWidgets.size(); - } - - @Override - @Rank - public int getRank() { - return RANK_WIDGETS_LIST_SEARCH_HEADER; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof WidgetsListSearchHeaderEntry)) return false; - WidgetsListSearchHeaderEntry otherEntry = (WidgetsListSearchHeaderEntry) obj; - return mWidgets.equals(otherEntry.mWidgets) && mPkgItem.equals(otherEntry.mPkgItem) - && mTitleSectionName.equals(otherEntry.mTitleSectionName) - && mIsWidgetListShown == otherEntry.mIsWidgetListShown; - } - - /** Returns a copy of this {@link WidgetsListSearchHeaderEntry} with the widget list shown. */ - @Override - public WidgetsListSearchHeaderEntry withWidgetListShown() { - if (mIsWidgetListShown) return this; - return new WidgetsListSearchHeaderEntry( - mPkgItem, - mTitleSectionName, - mWidgets, - /* isWidgetListShown= */ true); - } -} diff --git a/src/com/android/launcher3/widget/picker/WidgetsDiffReporter.java b/src/com/android/launcher3/widget/picker/WidgetsDiffReporter.java index 99374f5eef..d09fe84e7b 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsDiffReporter.java +++ b/src/com/android/launcher3/widget/picker/WidgetsDiffReporter.java @@ -25,7 +25,6 @@ import com.android.launcher3.model.data.PackageItemInfo; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.model.WidgetsListContentEntry; import com.android.launcher3.widget.model.WidgetsListHeaderEntry; -import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry; import com.android.launcher3.widget.picker.WidgetsListAdapter.WidgetListBaseRowEntryComparator; import java.util.ArrayList; @@ -175,12 +174,8 @@ public class WidgetsDiffReporter { */ private boolean hasHeaderUpdated(WidgetsListBaseEntry curRow, WidgetsListBaseEntry newRow) { if (newRow instanceof WidgetsListHeaderEntry && curRow instanceof WidgetsListHeaderEntry) { - return !curRow.equals(newRow); - } - if (newRow instanceof WidgetsListSearchHeaderEntry - && curRow instanceof WidgetsListSearchHeaderEntry) { // Always refresh search header entries to reset rounded corners in their view holder. - return true; + return !curRow.equals(newRow) || ((WidgetsListHeaderEntry) curRow).isSearchEntry(); } return false; } diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java index bb80e9b80b..7c7cdf4c16 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java @@ -286,7 +286,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet } }; packageItemInfo.title = getContext().getString(R.string.suggested_widgets_header_title); - WidgetsListHeaderEntry widgetsListHeaderEntry = new WidgetsListHeaderEntry( + WidgetsListHeaderEntry widgetsListHeaderEntry = WidgetsListHeaderEntry.create( packageItemInfo, getContext().getString(R.string.suggested_widgets_header_title), mActivityContext.getPopupDataProvider().getRecommendedWidgets()) diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java index dc1d2dc343..549ac42e80 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java @@ -48,7 +48,6 @@ import com.android.launcher3.widget.model.WidgetListSpaceEntry; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.model.WidgetsListContentEntry; import com.android.launcher3.widget.model.WidgetsListHeaderEntry; -import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry; import java.util.ArrayList; import java.util.Arrays; @@ -81,7 +80,6 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC public static final int VIEW_TYPE_WIDGETS_SPACE = R.id.view_type_widgets_space; public static final int VIEW_TYPE_WIDGETS_LIST = R.id.view_type_widgets_list; public static final int VIEW_TYPE_WIDGETS_HEADER = R.id.view_type_widgets_header; - public static final int VIEW_TYPE_WIDGETS_SEARCH_HEADER = R.id.view_type_widgets_search_header; private final Context mContext; private final WidgetsDiffReporter mDiffReporter; @@ -96,7 +94,6 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC private Predicate mHeaderAndSelectedContentFilter = entry -> entry instanceof WidgetsListHeaderEntry - || entry instanceof WidgetsListSearchHeaderEntry || PackageUserKey.fromPackageItemInfo(entry.mPkgItem) .equals(mWidgetsContentVisiblePackageUserKey); @Nullable private Predicate mFilter = null; @@ -124,12 +121,6 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC layoutInflater, /* onHeaderClickListener= */ this, listDrawableFactory)); - mViewHolderBinders.put( - VIEW_TYPE_WIDGETS_SEARCH_HEADER, - new WidgetsListSearchHeaderViewHolderBinder( - layoutInflater, - /* onHeaderClickListener= */ this, - listDrawableFactory)); mViewHolderBinders.put( VIEW_TYPE_WIDGETS_SPACE, new WidgetsSpaceViewHolderBinder(emptySpaceHeightProvider)); @@ -205,10 +196,10 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC && (mHeaderChangeListener == null || !(entry instanceof WidgetsListContentEntry))) .map(entry -> { - if (entry instanceof WidgetsListBaseEntry.Header + if (entry instanceof WidgetsListHeaderEntry && matchesKey(entry, mWidgetsContentVisiblePackageUserKey)) { // Adjust the original entries to expand headers for the selected content. - return ((WidgetsListBaseEntry.Header) entry).withWidgetListShown(); + return ((WidgetsListHeaderEntry) entry).withWidgetListShown(); } else if (entry instanceof WidgetsListContentEntry) { // Adjust the original content entries to accommodate for the current // maxSpanSize. @@ -233,7 +224,7 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC /** Returns whether {@code entry} matches {@code key}. */ private static boolean isHeaderForPackageUserKey( @NonNull WidgetsListBaseEntry entry, @Nullable PackageUserKey key) { - return entry instanceof WidgetsListBaseEntry.Header && matchesKey(entry, key); + return entry instanceof WidgetsListHeaderEntry && matchesKey(entry, key); } private static boolean matchesKey(@NonNull WidgetsListBaseEntry entry, @@ -276,16 +267,11 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC * first header in the new list that gets generated as we search. */ void selectFirstHeaderEntry() { - WidgetsListSearchHeaderEntry firstEntry = null; - for (WidgetsListBaseEntry entry: mVisibleEntries) { - if (entry instanceof WidgetsListSearchHeaderEntry) { - firstEntry = (WidgetsListSearchHeaderEntry) entry; - break; - } - } - if (firstEntry != null) { - onHeaderClicked(true, PackageUserKey.fromPackageItemInfo(firstEntry.mPkgItem)); - } + mVisibleEntries.stream() + .filter(entry -> entry instanceof WidgetsListHeaderEntry) + .findFirst() + .ifPresent(entry -> + onHeaderClicked(true, PackageUserKey.fromPackageItemInfo(entry.mPkgItem))); } @Override @@ -325,8 +311,6 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC return VIEW_TYPE_WIDGETS_LIST; } else if (entry instanceof WidgetsListHeaderEntry) { return VIEW_TYPE_WIDGETS_HEADER; - } else if (entry instanceof WidgetsListSearchHeaderEntry) { - return VIEW_TYPE_WIDGETS_SEARCH_HEADER; } else if (entry instanceof WidgetListSpaceEntry) { return VIEW_TYPE_WIDGETS_SPACE; } diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java index 8c91d4331d..a6ef89ff3b 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java @@ -18,12 +18,12 @@ package com.android.launcher3.widget.picker; import static com.android.launcher3.config.FeatureFlags.LARGE_SCREEN_WIDGET_PICKER; import android.content.Context; -import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.os.Bundle; +import android.text.TextUtils; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; @@ -45,13 +45,9 @@ import com.android.launcher3.icons.PlaceHolderIconDrawable; import com.android.launcher3.icons.cache.HandlerRunnable; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.PackageItemInfo; -import com.android.launcher3.util.PluralMessageFormat; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.widget.model.WidgetsListHeaderEntry; -import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry; - -import java.util.stream.Collectors; /** * A UI represents a header of an app shown in the full widgets tray. @@ -201,11 +197,6 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd /** Apply app icon, labels and tag using a generic {@link WidgetsListHeaderEntry}. */ @UiThread public void applyFromItemInfoWithIcon(WidgetsListHeaderEntry entry) { - applyIconAndLabel(entry); - } - - @UiThread - private void applyIconAndLabel(WidgetsListHeaderEntry entry) { PackageItemInfo info = entry.mPkgItem; setIcon(info.newIcon(getContext())); setTitles(entry); @@ -247,55 +238,13 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd private void setTitles(WidgetsListHeaderEntry entry) { mTitle.setText(entry.mPkgItem.title); - Resources resources = getContext().getResources(); - if (entry.widgetsCount == 0 && entry.shortcutsCount == 0) { + String subtitle = entry.getSubtitle(getContext()); + if (TextUtils.isEmpty(subtitle)) { mSubtitle.setVisibility(GONE); - return; - } - - String subtitle; - if (entry.widgetsCount > 0 && entry.shortcutsCount > 0) { - String widgetsCount = PluralMessageFormat.getIcuPluralString(getContext(), - R.string.widgets_count, entry.widgetsCount); - String shortcutsCount = PluralMessageFormat.getIcuPluralString(getContext(), - R.string.shortcuts_count, entry.shortcutsCount); - subtitle = resources.getString(R.string.widgets_and_shortcuts_count, widgetsCount, - shortcutsCount); - } else if (entry.widgetsCount > 0) { - subtitle = PluralMessageFormat.getIcuPluralString(getContext(), - R.string.widgets_count, entry.widgetsCount); } else { - subtitle = PluralMessageFormat.getIcuPluralString(getContext(), - R.string.shortcuts_count, entry.shortcutsCount); + mSubtitle.setText(subtitle); + mSubtitle.setVisibility(VISIBLE); } - mSubtitle.setText(subtitle); - mSubtitle.setVisibility(VISIBLE); - } - - /** Apply app icon, labels and tag using a generic {@link WidgetsListSearchHeaderEntry}. */ - @UiThread - public void applyFromItemInfoWithIcon(WidgetsListSearchHeaderEntry entry) { - applyIconAndLabel(entry); - } - - @UiThread - private void applyIconAndLabel(WidgetsListSearchHeaderEntry entry) { - PackageItemInfo info = entry.mPkgItem; - setIcon(info.newIcon(getContext())); - setTitles(entry); - setExpanded(entry.isWidgetListShown()); - - super.setTag(info); - - verifyHighRes(); - } - - private void setTitles(WidgetsListSearchHeaderEntry entry) { - mTitle.setText(entry.mPkgItem.title); - - mSubtitle.setText(entry.mWidgets.stream() - .map(item -> item.label).sorted().collect(Collectors.joining(", "))); - mSubtitle.setVisibility(VISIBLE); } @Override diff --git a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java deleted file mode 100644 index 9e659fe2da..0000000000 --- a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2021 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.widget.picker; - -import android.view.LayoutInflater; -import android.view.ViewGroup; - -import com.android.launcher3.R; -import com.android.launcher3.recyclerview.ViewHolderBinder; -import com.android.launcher3.util.PackageUserKey; -import com.android.launcher3.widget.model.WidgetsListHeaderEntry; -import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry; - -import java.util.List; - -/** - * Binds data from {@link WidgetsListHeaderEntry} to UI elements in {@link WidgetsListHeaderHolder}. - */ -public final class WidgetsListSearchHeaderViewHolderBinder implements - ViewHolderBinder { - private final LayoutInflater mLayoutInflater; - private final OnHeaderClickListener mOnHeaderClickListener; - private final WidgetsListDrawableFactory mListDrawableFactory; - - public WidgetsListSearchHeaderViewHolderBinder(LayoutInflater layoutInflater, - OnHeaderClickListener onHeaderClickListener, - WidgetsListDrawableFactory listDrawableFactory) { - mLayoutInflater = layoutInflater; - mOnHeaderClickListener = onHeaderClickListener; - mListDrawableFactory = listDrawableFactory; - } - - @Override - public WidgetsListSearchHeaderHolder newViewHolder(ViewGroup parent) { - WidgetsListHeader header = (WidgetsListHeader) mLayoutInflater.inflate( - R.layout.widgets_list_row_header, parent, false); - header.setBackground(mListDrawableFactory.createHeaderBackgroundDrawable()); - return new WidgetsListSearchHeaderHolder(header); - } - - @Override - public void bindViewHolder(WidgetsListSearchHeaderHolder viewHolder, - WidgetsListSearchHeaderEntry data, @ListPosition int position, List payloads) { - WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader; - widgetsListHeader.applyFromItemInfoWithIcon(data); - widgetsListHeader.setSelected(data.isWidgetListShown()); - widgetsListHeader.setExpanded(data.isWidgetListShown()); - widgetsListHeader.setListDrawableState( - WidgetsListDrawableState.obtain( - (position & POSITION_FIRST) != 0, - (position & POSITION_LAST) != 0, - /* isExpanded= */ data.isWidgetListShown())); - widgetsListHeader.setOnExpandChangeListener(isExpanded -> - mOnHeaderClickListener.onHeaderClicked(isExpanded, - PackageUserKey.fromPackageItemInfo(data.mPkgItem))); - } -} diff --git a/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java b/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java index 9be3b5f1e4..613066a048 100644 --- a/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java +++ b/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java @@ -28,7 +28,6 @@ import com.android.launcher3.search.StringMatcherUtility.StringMatcher; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.model.WidgetsListContentEntry; import com.android.launcher3.widget.model.WidgetsListHeaderEntry; -import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry; import java.util.ArrayList; import java.util.List; @@ -72,7 +71,7 @@ public final class SimpleWidgetsSearchAlgorithm implements SearchAlgorithm matchedWidgetItems = filterWidgetItems( input, headerEntry.mPkgItem.title.toString(), headerEntry.mWidgets); if (matchedWidgetItems.size() > 0) { - results.add(new WidgetsListSearchHeaderEntry(headerEntry.mPkgItem, + results.add(WidgetsListHeaderEntry.createForSearch(headerEntry.mPkgItem, headerEntry.mTitleSectionName, matchedWidgetItems)); results.add(new WidgetsListContentEntry(headerEntry.mPkgItem, headerEntry.mTitleSectionName, matchedWidgetItems)); diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java index 702f3430aa..f4903338d1 100644 --- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java +++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java @@ -87,7 +87,7 @@ public class WidgetsModel { List widgetItems = entry.getValue(); String sectionName = (pkgItem.title == null) ? "" : indexer.computeSectionName(pkgItem.title); - result.add(new WidgetsListHeaderEntry(pkgItem, sectionName, widgetItems)); + result.add(WidgetsListHeaderEntry.create(pkgItem, sectionName, widgetItems)); result.add(new WidgetsListContentEntry(pkgItem, sectionName, widgetItems)); } return result; diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java index b480a4c002..8c87957530 100644 --- a/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java +++ b/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java @@ -229,7 +229,7 @@ public final class WidgetsDiffReporterTest { List.of(mHeaderA, mHeaderB, mContentE)); // GIVEN the new list has one of the headers widgets list modified. List newList = List.of( - new WidgetsListHeaderEntry( + WidgetsListHeaderEntry.create( mHeaderA.mPkgItem, mHeaderA.mTitleSectionName, mHeaderA.mWidgets.subList(0, 1)), mHeaderB, mContentE); @@ -274,7 +274,7 @@ public final class WidgetsDiffReporterTest { PackageItemInfo pInfo = createPackageItemInfo(packageName, appName, widgetItems.get(0).user); - return new WidgetsListHeaderEntry(pInfo, /* titleSectionName= */ "", widgetItems); + return WidgetsListHeaderEntry.create(pInfo, /* titleSectionName= */ "", widgetItems); } private WidgetsListContentEntry createWidgetsContentEntry(String packageName, String appName, diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java index 230b27f799..0044d046b1 100644 --- a/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java +++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java @@ -270,7 +270,8 @@ public final class WidgetsListAdapterTest { pInfo.title = pInfo.packageName; pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0); - result.add(new WidgetsListHeaderEntry(pInfo, /* titleSectionName= */ "", widgetItems)); + result.add(WidgetsListHeaderEntry.create( + pInfo, /* titleSectionName= */ "", widgetItems)); result.add(new WidgetsListContentEntry(pInfo, /* titleSectionName= */ "", widgetItems)); } diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java index 211318cf12..f53d15b141 100644 --- a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java +++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java @@ -134,7 +134,7 @@ public final class WidgetsListHeaderViewHolderBinderTest { appInfo.title = appName; appInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0); - return new WidgetsListHeaderEntry(appInfo, + return WidgetsListHeaderEntry.create(appInfo, /* titleSectionName= */ "", generateWidgetItems(packageName, numOfWidgets)); } diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java deleted file mode 100644 index 66c2f3638a..0000000000 --- a/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2021 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.widget.picker; - -import static androidx.test.core.app.ApplicationProvider.getApplicationContext; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.verify; - -import static java.util.Collections.EMPTY_LIST; - -import android.appwidget.AppWidgetProviderInfo; -import android.content.ComponentName; -import android.content.Context; -import android.graphics.Bitmap; -import android.os.UserHandle; -import android.view.LayoutInflater; -import android.widget.FrameLayout; -import android.widget.TextView; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.R; -import com.android.launcher3.icons.BitmapInfo; -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.ActivityContextWrapper; -import com.android.launcher3.util.PackageUserKey; -import com.android.launcher3.util.WidgetUtils; -import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; -import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.ArrayList; -import java.util.List; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public final class WidgetsListSearchHeaderViewHolderBinderTest { - private static final String TEST_PACKAGE = "com.google.test"; - private static final String APP_NAME = "Test app"; - - private Context mContext; - private WidgetsListSearchHeaderViewHolderBinder mViewHolderBinder; - private InvariantDeviceProfile mTestProfile; - - @Mock - private IconCache mIconCache; - @Mock - private OnHeaderClickListener mOnHeaderClickListener; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = new ActivityContextWrapper(getApplicationContext()); - mTestProfile = new InvariantDeviceProfile(); - mTestProfile.numRows = 5; - mTestProfile.numColumns = 5; - - doAnswer(invocation -> { - ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0); - return componentWithLabel.getComponent().getShortClassName(); - }).when(mIconCache).getTitleNoCache(any()); - mViewHolderBinder = new WidgetsListSearchHeaderViewHolderBinder( - LayoutInflater.from(mContext), - mOnHeaderClickListener, - new WidgetsListDrawableFactory(mContext)); - } - - @Test - public void bindViewHolder_appWith3Widgets_shouldShowTheCorrectAppNameAndSubtitle() { - WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder( - new FrameLayout(mContext)); - WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader; - WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader( - APP_NAME, - TEST_PACKAGE, - /* numOfWidgets= */ 3); - mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST); - - TextView appTitle = widgetsListHeader.findViewById(R.id.app_title); - TextView appSubtitle = widgetsListHeader.findViewById(R.id.app_subtitle); - assertThat(appTitle.getText()).isEqualTo(APP_NAME); - assertThat(appSubtitle.getText()) - .isEqualTo(".SampleWidget0, .SampleWidget1, .SampleWidget2"); - } - - @Test - public void bindViewHolder_shouldAttachOnHeaderClickListener() { - WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder( - new FrameLayout(mContext)); - WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader; - WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader( - APP_NAME, - TEST_PACKAGE, - /* numOfWidgets= */ 3); - - mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST); - widgetsListHeader.callOnClick(); - - verify(mOnHeaderClickListener).onHeaderClicked(eq(true), - eq(PackageUserKey.fromPackageItemInfo(entry.mPkgItem))); - } - - private WidgetsListSearchHeaderEntry generateSampleSearchHeader(String appName, - String packageName, int numOfWidgets) { - PackageItemInfo appInfo = new PackageItemInfo(packageName, UserHandle.CURRENT); - appInfo.title = appName; - appInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0); - - return new WidgetsListSearchHeaderEntry(appInfo, - /* titleSectionName= */ "", - generateWidgetItems(packageName, numOfWidgets)); - } - - private List generateWidgetItems(String packageName, int numOfWidgets) { - ArrayList widgetItems = new ArrayList<>(); - for (int i = 0; i < numOfWidgets; i++) { - ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i); - AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn); - - widgetItems.add(new WidgetItem( - LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo), - mTestProfile, mIconCache)); - } - return widgetItems; - } -} diff --git a/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java index d812ab012e..0124f73f2c 100644 --- a/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java +++ b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java @@ -50,7 +50,6 @@ import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.model.WidgetsListContentEntry; import com.android.launcher3.widget.model.WidgetsListHeaderEntry; -import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry; import org.junit.Before; import org.junit.Test; @@ -117,12 +116,12 @@ public class SimpleWidgetsSearchAlgorithmTest { .getAllWidgets(); assertEquals(List.of( - new WidgetsListSearchHeaderEntry( + WidgetsListHeaderEntry.createForSearch( mCalendarHeaderEntry.mPkgItem, mCalendarHeaderEntry.mTitleSectionName, mCalendarHeaderEntry.mWidgets), mCalendarContentEntry, - new WidgetsListSearchHeaderEntry( + WidgetsListHeaderEntry.createForSearch( mCameraHeaderEntry.mPkgItem, mCameraHeaderEntry.mTitleSectionName, mCameraHeaderEntry.mWidgets), @@ -138,7 +137,7 @@ public class SimpleWidgetsSearchAlgorithmTest { .getAllWidgets(); assertEquals(List.of( - new WidgetsListSearchHeaderEntry( + WidgetsListHeaderEntry.createForSearch( mCalendarHeaderEntry.mPkgItem, mCalendarHeaderEntry.mTitleSectionName, mCalendarHeaderEntry.mWidgets.subList(1, 2)), @@ -146,7 +145,7 @@ public class SimpleWidgetsSearchAlgorithmTest { mCalendarHeaderEntry.mPkgItem, mCalendarHeaderEntry.mTitleSectionName, mCalendarHeaderEntry.mWidgets.subList(1, 2)), - new WidgetsListSearchHeaderEntry( + WidgetsListHeaderEntry.createForSearch( mCameraHeaderEntry.mPkgItem, mCameraHeaderEntry.mTitleSectionName, mCameraHeaderEntry.mWidgets.subList(1, 3)), @@ -175,7 +174,7 @@ public class SimpleWidgetsSearchAlgorithmTest { PackageItemInfo pInfo = createPackageItemInfo(packageName, appName, widgetItems.get(0).user); - return new WidgetsListHeaderEntry(pInfo, /* titleSectionName= */ "", widgetItems); + return WidgetsListHeaderEntry.create(pInfo, /* titleSectionName= */ "", widgetItems); } private WidgetsListContentEntry createWidgetsContentEntry(String packageName, String appName,