Merge "Using DiffUtil for calculating widget diff instead of a custom implementation" into tm-qpr-dev
diff --git a/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java b/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java
index 7f24905..5b1da5b 100644
--- a/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java
+++ b/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java
@@ -33,9 +33,4 @@
                 Collections.EMPTY_LIST);
         mPkgItem.title = "";
     }
-
-    @Override
-    public int getRank() {
-        return RANK_WIDGETS_TOP_SPACE;
-    }
 }
diff --git a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
index f09f4c6..0003b76 100644
--- a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
+++ b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
@@ -16,16 +16,11 @@
 
 package com.android.launcher3.widget.model;
 
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import androidx.annotation.IntDef;
-
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.widget.WidgetItemComparator;
 
-import java.lang.annotation.Retention;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -48,23 +43,4 @@
         this.mWidgets =
                 items.stream().sorted(new WidgetItemComparator()).collect(Collectors.toList());
     }
-
-    /**
-     * Returns the ranking of this entry in the
-     * {@link com.android.launcher3.widget.picker.WidgetsListAdapter}.
-     *
-     * <p>Entries with smaller value should be shown first. See
-     * {@link com.android.launcher3.widget.picker.WidgetsDiffReporter} for more details.
-     */
-    @Rank
-    public abstract int getRank();
-
-    @Retention(SOURCE)
-    @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_CONTENT = 3;
 }
diff --git a/src/com/android/launcher3/widget/model/WidgetsListContentEntry.java b/src/com/android/launcher3/widget/model/WidgetsListContentEntry.java
index 73b17f1..626e0b9 100644
--- a/src/com/android/launcher3/widget/model/WidgetsListContentEntry.java
+++ b/src/com/android/launcher3/widget/model/WidgetsListContentEntry.java
@@ -61,12 +61,6 @@
                 + mMaxSpanSizeInCells;
     }
 
-    @Override
-    @Rank
-    public int getRank() {
-        return RANK_WIDGETS_LIST_CONTENT;
-    }
-
     /**
      * Returns a copy of this {@link WidgetsListContentEntry} with updated
      * {@param maxSpanSizeInCells}.
diff --git a/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java b/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java
index bb0cf92..68f18ae 100644
--- a/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java
+++ b/src/com/android/launcher3/widget/model/WidgetsListHeaderEntry.java
@@ -85,12 +85,6 @@
         return "Header:" + mPkgItem.packageName + ":" + mWidgets.size();
     }
 
-    @Override
-    @Rank
-    public int getRank() {
-        return RANK_WIDGETS_LIST_HEADER;
-    }
-
     public boolean isSearchEntry() {
         return mIsSearchEntry;
     }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsDiffCallback.java b/src/com/android/launcher3/widget/picker/WidgetsDiffCallback.java
new file mode 100644
index 0000000..e610ea9
--- /dev/null
+++ b/src/com/android/launcher3/widget/picker/WidgetsDiffCallback.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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 androidx.recyclerview.widget.DiffUtil.Callback;
+
+import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+
+import java.util.List;
+
+/**
+ * DiffUtil callback to compare widgets
+ */
+public class WidgetsDiffCallback extends Callback {
+
+    private final List<WidgetsListBaseEntry> mOldEntries;
+    private final List<WidgetsListBaseEntry> mNewEntries;
+
+    public WidgetsDiffCallback(
+            List<WidgetsListBaseEntry> oldEntries,
+            List<WidgetsListBaseEntry> newEntries) {
+        mOldEntries = oldEntries;
+        mNewEntries = newEntries;
+    }
+
+    @Override
+    public int getOldListSize() {
+        return mOldEntries.size();
+    }
+
+    @Override
+    public int getNewListSize() {
+        return mNewEntries.size();
+    }
+
+    @Override
+    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
+        // Items are same if they point to the same package entry
+        WidgetsListBaseEntry oldItem = mOldEntries.get(oldItemPosition);
+        WidgetsListBaseEntry newItem = mNewEntries.get(newItemPosition);
+        return oldItem.getClass().equals(newItem.getClass())
+                && oldItem.mPkgItem.equals(newItem.mPkgItem);
+    }
+
+    @Override
+    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
+        // Always update all entries since the icon may have changed
+        return false;
+    }
+}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsDiffReporter.java b/src/com/android/launcher3/widget/picker/WidgetsDiffReporter.java
deleted file mode 100644
index d09fe84..0000000
--- a/src/com/android/launcher3/widget/picker/WidgetsDiffReporter.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2017 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.util.Log;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.launcher3.icons.IconCache;
-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.picker.WidgetsListAdapter.WidgetListBaseRowEntryComparator;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Do diff on widget's tray list items and call the {@link RecyclerView.Adapter}
- * methods accordingly.
- */
-public class WidgetsDiffReporter {
-    private static final boolean DEBUG = false;
-    private static final String TAG = "WidgetsDiffReporter";
-
-    private final IconCache mIconCache;
-    private final RecyclerView.Adapter mListener;
-
-    public WidgetsDiffReporter(IconCache iconCache, RecyclerView.Adapter listener) {
-        mIconCache = iconCache;
-        mListener = listener;
-    }
-
-    /**
-     * Notifies the difference between {@code currentEntries} & {@code newEntries} by calling the
-     * relevant {@link androidx.recyclerview.widget.RecyclerView.RecyclerViewDataObserver} methods.
-     */
-    public void process(ArrayList<WidgetsListBaseEntry> currentEntries,
-            List<WidgetsListBaseEntry> newEntries,
-            WidgetListBaseRowEntryComparator comparator) {
-        if (DEBUG) {
-            Log.d(TAG, "process oldEntries#=" + currentEntries.size()
-                    + " newEntries#=" + newEntries.size());
-        }
-        // Early exit if either of the list is empty
-        if (currentEntries.isEmpty() || newEntries.isEmpty()) {
-            // Skip if both list are empty.
-            // On rotation, we open the widget tray with empty. Then try to fetch the list again
-            // when the animation completes (which still gives empty). And we get the final result
-            // when the bind actually completes.
-            if (currentEntries.size() != newEntries.size()) {
-                currentEntries.clear();
-                currentEntries.addAll(newEntries);
-                mListener.notifyDataSetChanged();
-            }
-            return;
-        }
-        ArrayList<WidgetsListBaseEntry> orgEntries =
-                (ArrayList<WidgetsListBaseEntry>) currentEntries.clone();
-        Iterator<WidgetsListBaseEntry> orgIter = orgEntries.iterator();
-        Iterator<WidgetsListBaseEntry> newIter = newEntries.iterator();
-
-        WidgetsListBaseEntry orgRowEntry = orgIter.next();
-        WidgetsListBaseEntry newRowEntry = newIter.next();
-
-        do {
-            int diff = compareAppNameAndType(orgRowEntry, newRowEntry, comparator);
-            if (DEBUG) {
-                Log.d(TAG, String.format("diff=%d orgRowEntry (%s) newRowEntry (%s)",
-                        diff, orgRowEntry != null ? orgRowEntry.toString() : null,
-                        newRowEntry != null ? newRowEntry.toString() : null));
-            }
-            int index = -1;
-            if (diff < 0) {
-                index = currentEntries.indexOf(orgRowEntry);
-                mListener.notifyItemRemoved(index);
-                if (DEBUG) {
-                    Log.d(TAG, String.format("notifyItemRemoved called (%d)%s", index,
-                            orgRowEntry.mTitleSectionName));
-                }
-                currentEntries.remove(index);
-                orgRowEntry = orgIter.hasNext() ? orgIter.next() : null;
-            } else if (diff > 0) {
-                index = orgRowEntry != null ? currentEntries.indexOf(orgRowEntry)
-                        : currentEntries.size();
-                currentEntries.add(index, newRowEntry);
-                if (DEBUG) {
-                    Log.d(TAG, String.format("notifyItemInserted called (%d)%s", index,
-                            newRowEntry.mTitleSectionName));
-                }
-                newRowEntry = newIter.hasNext() ? newIter.next() : null;
-                mListener.notifyItemInserted(index);
-
-            } else {
-                // same app name & type but,
-                // did the icon, title, etc, change?
-                // or did the header view changed due to user interactions?
-                // or did the widget size and desc, span, etc change?
-                if (!isSamePackageItemInfo(orgRowEntry.mPkgItem, newRowEntry.mPkgItem)
-                        || hasHeaderUpdated(orgRowEntry, newRowEntry)
-                        || hasWidgetsListContentChanged(orgRowEntry, newRowEntry)) {
-                    index = currentEntries.indexOf(orgRowEntry);
-                    currentEntries.set(index, newRowEntry);
-                    mListener.notifyItemChanged(index);
-                    if (DEBUG) {
-                        Log.d(TAG, String.format("notifyItemChanged called (%d)%s", index,
-                                newRowEntry.mTitleSectionName));
-                    }
-                }
-                orgRowEntry = orgIter.hasNext() ? orgIter.next() : null;
-                newRowEntry = newIter.hasNext() ? newIter.next() : null;
-            }
-        } while(orgRowEntry != null || newRowEntry != null);
-    }
-
-    /**
-     * Compares the app name and then entry type for the given {@link WidgetsListBaseEntry}s.
-     *
-     * @Return 0 if both entries' order is the same. Negative integer if {@code newRowEntry} should
-     *         order before {@code orgRowEntry}. Positive integer if {@code orgRowEntry} should
-     *         order before {@code newRowEntry}.
-     */
-    private int compareAppNameAndType(WidgetsListBaseEntry curRow, WidgetsListBaseEntry newRow,
-            WidgetListBaseRowEntryComparator comparator) {
-        if (curRow == null && newRow == null) {
-            throw new IllegalStateException(
-                    "Cannot compare PackageItemInfo if both rows are null.");
-        }
-
-        if (curRow == null && newRow != null) {
-            return 1; // new row needs to be inserted
-        } else if (curRow != null && newRow == null) {
-            return -1; // old row needs to be deleted
-        }
-        int diff = comparator.compare(curRow, newRow);
-        if (diff == 0) {
-            return newRow.getRank() - curRow.getRank();
-        }
-        return diff;
-    }
-
-    /**
-     * Returns {@code true} if both {@code curRow} & {@code newRow} are
-     * {@link WidgetsListContentEntry}s with a different list or arrangement of widgets.
-     */
-    private boolean hasWidgetsListContentChanged(WidgetsListBaseEntry curRow,
-            WidgetsListBaseEntry newRow) {
-        if (!(curRow instanceof WidgetsListContentEntry)
-                || !(newRow instanceof WidgetsListContentEntry)) {
-            return false;
-        }
-        return !curRow.equals(newRow);
-    }
-
-    /**
-     * Returns {@code true} if {@code newRow} is {@link WidgetsListHeaderEntry} and its content has
-     * been changed due to user interactions.
-     */
-    private boolean hasHeaderUpdated(WidgetsListBaseEntry curRow, WidgetsListBaseEntry newRow) {
-        if (newRow instanceof WidgetsListHeaderEntry && curRow instanceof WidgetsListHeaderEntry) {
-            // Always refresh search header entries to reset rounded corners in their view holder.
-            return !curRow.equals(newRow) || ((WidgetsListHeaderEntry) curRow).isSearchEntry();
-        }
-        return false;
-    }
-
-    private boolean isSamePackageItemInfo(PackageItemInfo curInfo, PackageItemInfo newInfo) {
-        return curInfo.bitmap.icon.equals(newInfo.bitmap.icon)
-                && !mIconCache.isDefaultIcon(curInfo.bitmap, curInfo.user);
-    }
-}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 66e3a43..545e661 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -59,7 +59,6 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
@@ -961,8 +960,6 @@
         AdapterHolder(int adapterType) {
             mAdapterType = adapterType;
             Context context = getContext();
-            LauncherAppState apps = LauncherAppState.getInstance(context);
-
             HeaderChangeListener headerChangeListener = new HeaderChangeListener() {
                 @Override
                 public void onHeaderChanged(@NonNull PackageUserKey selectedHeader) {
@@ -993,7 +990,6 @@
             mWidgetsListAdapter = new WidgetsListAdapter(
                     context,
                     LayoutInflater.from(context),
-                    apps.getIconCache(),
                     this::getEmptySpaceHeight,
                     /* iconClickListener= */ WidgetsFullSheet.this,
                     /* iconLongClickListener= */ WidgetsFullSheet.this,
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index b5ff719..20b1d9b 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -32,13 +32,14 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.DiffUtil.DiffResult;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerView.Adapter;
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
 import com.android.launcher3.R;
-import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.recyclerview.ViewHolderBinder;
 import com.android.launcher3.util.LabelComparator;
@@ -82,7 +83,6 @@
     public static final int VIEW_TYPE_WIDGETS_HEADER = R.id.view_type_widgets_header;
 
     private final Context mContext;
-    private final WidgetsDiffReporter mDiffReporter;
     private final SparseArray<ViewHolderBinder> mViewHolderBinders = new SparseArray<>();
     private final WidgetListBaseRowEntryComparator mRowComparator =
             new WidgetListBaseRowEntryComparator();
@@ -102,12 +102,11 @@
     private int mMaxSpanSize = 4;
 
     public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
-            IconCache iconCache, IntSupplier emptySpaceHeightProvider,
-            OnClickListener iconClickListener, OnLongClickListener iconLongClickListener,
+            IntSupplier emptySpaceHeightProvider, OnClickListener iconClickListener,
+            OnLongClickListener iconLongClickListener,
             WidgetsFullSheet.HeaderChangeListener headerChangeListener) {
         mHeaderChangeListener = headerChangeListener;
         mContext = context;
-        mDiffReporter = new WidgetsDiffReporter(iconCache, this);
 
         mViewHolderBinders.put(
                 VIEW_TYPE_WIDGETS_LIST,
@@ -205,7 +204,11 @@
                 })
                 .collect(Collectors.toList());
 
-        mDiffReporter.process(mVisibleEntries, newVisibleEntries, mRowComparator);
+        DiffResult diffResult = DiffUtil.calculateDiff(
+                new WidgetsDiffCallback(mVisibleEntries, newVisibleEntries), false);
+        mVisibleEntries.clear();
+        mVisibleEntries.addAll(newVisibleEntries);
+        diffResult.dispatchUpdatesTo(this);
 
         if (mPendingClickHeader != null) {
             // Get the position for the clicked header after adjusting the visible entries. The
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index f490333..1b743e8 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -40,7 +40,6 @@
 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.picker.WidgetsDiffReporter;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -73,8 +72,7 @@
     /**
      * Returns a list of {@link WidgetsListBaseEntry}. All {@link WidgetItem} in a single row
      * are sorted (based on label and user), but the overall list of
-     * {@link WidgetsListBaseEntry}s is not sorted. This list is sorted at the UI when using
-     * {@link WidgetsDiffReporter}
+     * {@link WidgetsListBaseEntry}s is not sorted.
      *
      * @see com.android.launcher3.widget.picker.WidgetsListAdapter#setWidgets(List)
      */
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
deleted file mode 100644
index 8c87957..0000000
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
+++ /dev/null
@@ -1,310 +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.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.os.UserHandle;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.launcher3.InvariantDeviceProfile;
-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.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.picker.WidgetsListAdapter.WidgetListBaseRowEntryComparator;
-
-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 WidgetsDiffReporterTest {
-    private static final String TEST_PACKAGE_PREFIX = "com.android.test";
-    private static final WidgetListBaseRowEntryComparator COMPARATOR =
-            new WidgetListBaseRowEntryComparator();
-
-    @Mock private IconCache mIconCache;
-    @Mock private RecyclerView.Adapter mAdapter;
-
-    private InvariantDeviceProfile mTestProfile;
-    private WidgetsDiffReporter mWidgetsDiffReporter;
-    private Context mContext;
-    private WidgetsListHeaderEntry mHeaderA;
-    private WidgetsListHeaderEntry mHeaderB;
-    private WidgetsListHeaderEntry mHeaderC;
-    private WidgetsListHeaderEntry mHeaderD;
-    private WidgetsListHeaderEntry mHeaderE;
-    private WidgetsListContentEntry mContentC;
-    private WidgetsListContentEntry mContentE;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mTestProfile = new InvariantDeviceProfile();
-        mTestProfile.numRows = 5;
-        mTestProfile.numColumns = 5;
-
-        doAnswer(invocation -> ((ComponentWithLabel) invocation.getArgument(0))
-                .getComponent().getPackageName())
-                .when(mIconCache).getTitleNoCache(any());
-
-        mContext = getApplicationContext();
-        mWidgetsDiffReporter = new WidgetsDiffReporter(mIconCache, mAdapter);
-        mHeaderA = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "A",
-                /* appName= */ "A", /* numOfWidgets= */ 3);
-        mHeaderB = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "B",
-                /* appName= */ "B", /* numOfWidgets= */ 3);
-        mHeaderC = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "C",
-                /* appName= */ "C", /* numOfWidgets= */ 3);
-        mContentC = createWidgetsContentEntry(TEST_PACKAGE_PREFIX + "C",
-                /* appName= */ "C", /* numOfWidgets= */ 3);
-        mHeaderD = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "D",
-                /* appName= */ "D", /* numOfWidgets= */ 3);
-        mHeaderE = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "E",
-                /* appName= */ "E", /* numOfWidgets= */ 3);
-        mContentE = createWidgetsContentEntry(TEST_PACKAGE_PREFIX + "E",
-                /* appName= */ "E", /* numOfWidgets= */ 3);
-    }
-
-    @Test
-    public void listNotChanged_shouldNotInvokeAnyCallbacks() {
-        // GIVEN the current list has app headers [A, B, C].
-        ArrayList<WidgetsListBaseEntry> currentList = new ArrayList<>(
-                List.of(mHeaderA, mHeaderB, mHeaderC));
-
-        // WHEN computing the list difference.
-        mWidgetsDiffReporter.process(currentList, currentList, COMPARATOR);
-
-        // THEN there is no adaptor callback.
-        verifyZeroInteractions(mAdapter);
-        // THEN the current list contains the same entries.
-        assertThat(currentList).containsExactly(mHeaderA, mHeaderB, mHeaderC);
-    }
-
-    @Test
-    public void headersOnly_emptyListToNonEmpty_shouldInvokeNotifyDataSetChanged() {
-        // GIVEN the current list has app headers [A, B, C].
-        ArrayList<WidgetsListBaseEntry> currentList = new ArrayList<>();
-
-        List<WidgetsListBaseEntry> newList = List.of(
-                createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "A", "A", 3),
-                createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "B", "B", 3),
-                createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "C", "C", 3));
-
-        // WHEN computing the list difference.
-        mWidgetsDiffReporter.process(currentList, newList, COMPARATOR);
-
-        // THEN notifyDataSetChanged is called
-        verify(mAdapter).notifyDataSetChanged();
-        // THEN the current list contains all elements from the new list.
-        assertThat(currentList).containsExactlyElementsIn(newList);
-    }
-
-    @Test
-    public void headersOnly_nonEmptyToEmptyList_shouldInvokeNotifyDataSetChanged() {
-        // GIVEN the current list has app headers [A, B, C].
-        ArrayList<WidgetsListBaseEntry> currentList = new ArrayList<>(
-                List.of(mHeaderA, mHeaderB, mHeaderC));
-        // GIVEN the new list is empty.
-        List<WidgetsListBaseEntry> newList = List.of();
-
-        // WHEN computing the list difference.
-        mWidgetsDiffReporter.process(currentList, newList, COMPARATOR);
-
-        // THEN notifyDataSetChanged is called.
-        verify(mAdapter).notifyDataSetChanged();
-        // THEN the current list isEmpty.
-        assertThat(currentList).isEmpty();
-    }
-
-    @Test
-    public void headersOnly_itemAddedAndRemovedInTheNewList_shouldInvokeCorrectCallbacks() {
-        // GIVEN the current list has app headers [A, B, D].
-        ArrayList<WidgetsListBaseEntry> currentList = new ArrayList<>(
-                List.of(mHeaderA, mHeaderB, mHeaderD));
-        // GIVEN the new list has app headers [A, C, E].
-        List<WidgetsListBaseEntry> newList = List.of(mHeaderA, mHeaderC, mHeaderE);
-
-        // WHEN computing the list difference.
-        mWidgetsDiffReporter.process(currentList, newList, COMPARATOR);
-
-        // THEN "B" is removed from position 1.
-        verify(mAdapter).notifyItemRemoved(/* position= */ 1);
-        // THEN "D" is removed from position 2.
-        verify(mAdapter).notifyItemRemoved(/* position= */ 2);
-        // THEN "C" is inserted at position 1.
-        verify(mAdapter).notifyItemInserted(/* position= */ 1);
-        // THEN "E" is inserted at position 2.
-        verify(mAdapter).notifyItemInserted(/* position= */ 2);
-        // THEN the current list contains all elements from the new list.
-        assertThat(currentList).containsExactlyElementsIn(newList);
-    }
-
-    @Test
-    public void headersContentsMix_itemAddedAndRemovedInTheNewList_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 app headers [A, C content, D].
-        List<WidgetsListBaseEntry> newList = List.of(mHeaderA, mContentC, mHeaderD);
-
-        // WHEN computing the list difference.
-        mWidgetsDiffReporter.process(currentList, newList, COMPARATOR);
-
-        // THEN "B" is removed from position 1.
-        verify(mAdapter).notifyItemRemoved(/* position= */ 1);
-        // THEN "C content" is inserted at position 1.
-        verify(mAdapter).notifyItemInserted(/* position= */ 1);
-        // THEN "D" is inserted at position 2.
-        verify(mAdapter).notifyItemInserted(/* position= */ 2);
-        // THEN "E content" is removed from position 3.
-        verify(mAdapter).notifyItemRemoved(/* position= */ 3);
-        // THEN the current list contains all elements from the new list.
-        assertThat(currentList).containsExactlyElementsIn(newList);
-    }
-
-    @Test
-    public void headersContentsMix_userInteractWithHeader_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 app headers [A, B, E content] and the user has interacted with B.
-        List<WidgetsListBaseEntry> newList =
-                List.of(mHeaderA, mHeaderB.withWidgetListShown(), mContentE);
-
-        // WHEN computing the list difference.
-        mWidgetsDiffReporter.process(currentList, newList, COMPARATOR);
-
-        // THEN notify "B" has been changed.
-        verify(mAdapter).notifyItemChanged(/* position= */ 1);
-        // THEN the current list contains all elements from the new list.
-        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(
-                WidgetsListHeaderEntry.create(
-                        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);
-    }
-
-    @Test
-    public void headersContentsMix_contentMaxSpanSizeModified_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 max span size in "E content" modified.
-        List<WidgetsListBaseEntry> newList = List.of(
-                mHeaderA,
-                mHeaderB,
-                new WidgetsListContentEntry(
-                        mContentE.mPkgItem,
-                        mContentE.mTitleSectionName,
-                        mContentE.mWidgets,
-                        mContentE.getMaxSpanSizeInCells() + 1));
-
-        // WHEN computing the list difference.
-        mWidgetsDiffReporter.process(currentList, newList, COMPARATOR);
-
-        // THEN notify "E content" has been changed.
-        verify(mAdapter).notifyItemChanged(/* position= */ 2);
-        // THEN the current list contains all elements from the new list.
-        assertThat(currentList).containsExactlyElementsIn(newList);
-    }
-
-
-    private WidgetsListHeaderEntry createWidgetsHeaderEntry(String packageName, String appName,
-            int numOfWidgets) {
-        List<WidgetItem> widgetItems = generateWidgetItems(packageName, numOfWidgets);
-        PackageItemInfo pInfo = createPackageItemInfo(packageName, appName,
-                widgetItems.get(0).user);
-
-        return WidgetsListHeaderEntry.create(pInfo, /* titleSectionName= */ "", widgetItems);
-    }
-
-    private WidgetsListContentEntry createWidgetsContentEntry(String packageName, String appName,
-            int numOfWidgets) {
-        List<WidgetItem> widgetItems = generateWidgetItems(packageName, numOfWidgets);
-        PackageItemInfo pInfo = createPackageItemInfo(packageName, appName,
-                widgetItems.get(0).user);
-
-        return new WidgetsListContentEntry(pInfo, /* titleSectionName= */ "", widgetItems);
-    }
-
-    private PackageItemInfo createPackageItemInfo(String packageName, String appName,
-            UserHandle userHandle) {
-        PackageItemInfo pInfo = new PackageItemInfo(packageName, userHandle);
-        pInfo.title = appName;
-        pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
-        return pInfo;
-    }
-
-    private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ArrayList<WidgetItem> widgetItems = new ArrayList<>();
-        for (int i = 0; i < numOfWidgets; i++) {
-            ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
-            AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(cn);
-
-            WidgetItem widgetItem = new WidgetItem(
-                    LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
-                    mTestProfile, mIconCache);
-            widgetItems.add(widgetItem);
-        }
-        return widgetItems;
-    }
-}
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
deleted file mode 100644
index 0044d04..0000000
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2017 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 org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.verify;
-
-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;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.launcher3.InvariantDeviceProfile;
-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.WidgetsListBaseEntry;
-import com.android.launcher3.widget.model.WidgetsListContentEntry;
-import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for WidgetsListAdapter
- * Note that all indices matching are shifted by 1 to account for the empty space at the start.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class WidgetsListAdapterTest {
-    private static final String TEST_PACKAGE_PLACEHOLDER = "com.google.test";
-
-    @Mock private LayoutInflater mMockLayoutInflater;
-    @Mock private RecyclerView.AdapterDataObserver mListener;
-    @Mock private IconCache mIconCache;
-
-    private WidgetsListAdapter mAdapter;
-    private InvariantDeviceProfile mTestProfile;
-    private UserHandle mUserHandle;
-    private Context mContext;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = new ActivityContextWrapper(getApplicationContext());
-        mTestProfile = new InvariantDeviceProfile();
-        mTestProfile.numRows = 5;
-        mTestProfile.numColumns = 5;
-        mUserHandle = Process.myUserHandle();
-        mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater,
-                mIconCache, () -> 0, null, null, null);
-        mAdapter.registerAdapterDataObserver(mListener);
-
-        doAnswer(invocation -> ((ComponentWithLabel) invocation.getArgument(0))
-                        .getComponent().getPackageName())
-                .when(mIconCache).getTitleNoCache(any());
-    }
-
-    @Test
-    public void setWidgets_shouldNotifyDataSetChanged() {
-        mAdapter.setWidgets(generateSampleMap(1));
-
-        verify(mListener).onChanged();
-    }
-
-    @Test
-    public void setWidgets_withItemInserted_shouldNotifyItemInserted() {
-        mAdapter.setWidgets(generateSampleMap(1));
-        mAdapter.setWidgets(generateSampleMap(2));
-
-        verify(mListener).onItemRangeInserted(eq(2), eq(1));
-    }
-
-    @Test
-    public void setWidgets_withItemRemoved_shouldNotifyItemRemoved() {
-        mAdapter.setWidgets(generateSampleMap(2));
-        mAdapter.setWidgets(generateSampleMap(1));
-
-        verify(mListener).onItemRangeRemoved(eq(2), eq(1));
-    }
-
-    @Test
-    public void setWidgets_appIconChanged_shouldNotifyItemChanged() {
-        mAdapter.setWidgets(generateSampleMap(1));
-        mAdapter.setWidgets(generateSampleMap(1));
-
-        verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
-    }
-
-    @Test
-    public void headerClick_expanded_shouldNotifyItemChange() {
-        // 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].
-        mAdapter.setWidgets(generateSampleMap(3));
-
-        // WHEN com.google.test.1 header is expanded.
-        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]
-        // com.google.test.1 content is inserted into position 2.
-        verify(mListener).onItemRangeInserted(eq(3), eq(1));
-    }
-
-    @Test
-    public void setWidgets_expandedApp_moreWidgets_shouldNotifyItemChangedWithWidgetItemInfoDiff() {
-        // GIVEN the adapter was first populated with com.google.test0 & com.google.test1. Each app
-        // has one widget.
-        ArrayList<WidgetsListBaseEntry> allEntries = generateSampleMap(2);
-        mAdapter.setWidgets(allEntries);
-        // 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(/* 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
-        // now.
-        WidgetsListContentEntry testPackage1ContentEntry =
-                (WidgetsListContentEntry) allEntries.get(3);
-        WidgetItem widgetItem = testPackage1ContentEntry.mWidgets.get(0);
-        WidgetsListContentEntry newTestPackage1ContentEntry = new WidgetsListContentEntry(
-                testPackage1ContentEntry.mPkgItem,
-                testPackage1ContentEntry.mTitleSectionName, List.of(widgetItem, widgetItem));
-        allEntries.set(3, newTestPackage1ContentEntry);
-        mAdapter.setWidgets(allEntries);
-
-        // THEN the onItemRangeChanged is invoked for "com.google.test1 content" at index 2.
-        verify(mListener).onItemRangeChanged(eq(3), eq(1), isNull());
-    }
-
-    @Test
-    public void setWidgets_hodgepodge_shouldInvokeExpectedDataObserverCallbacks() {
-        // GIVEN a widgets entry list:
-        // Index:  0|   1      | 2|      3   | 4|     5    | 6|     7    | 8|     9    |
-        //        [A, A content, B, B content, C, C content, D, D content, E, E content]
-        List<WidgetsListBaseEntry> allAppsWithWidgets = generateSampleMap(5);
-        // GIVEN the current widgets list consist of [A, A content, B, B content, E, E content].
-        // GIVEN the visible widgets list consist of [A, B, E]
-        List<WidgetsListBaseEntry> currentList = List.of(
-                // A & A content
-                allAppsWithWidgets.get(0), allAppsWithWidgets.get(1),
-                // B & B content
-                allAppsWithWidgets.get(2), allAppsWithWidgets.get(3),
-                // E & E content
-                allAppsWithWidgets.get(8), allAppsWithWidgets.get(9));
-        mAdapter.setWidgets(currentList);
-
-        // WHEN the widgets list is updated to [A, A content, C, C content, D, D content].
-        // WHEN the visible widgets list is updated to [A, C, D].
-        List<WidgetsListBaseEntry> newList = List.of(
-                // A & A content
-                allAppsWithWidgets.get(0), allAppsWithWidgets.get(1),
-                // C & C content
-                allAppsWithWidgets.get(4), allAppsWithWidgets.get(5),
-                // D & D content
-                allAppsWithWidgets.get(6), allAppsWithWidgets.get(7));
-        mAdapter.setWidgets(newList);
-
-        // Account for 1st items as empty space
-        // Computation logic                           | [Intermediate list during computation]
-        // THEN B <> C < 0, removed B from index 1     | [A, E]
-        verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
-        // THEN E <> C > 0, C inserted to index 1      | [A, C, E]
-        verify(mListener).onItemRangeInserted(/* positionStart= */ 2, /* itemCount= */ 1);
-        // THEN E <> D > 0, D inserted to index 2      | [A, C, D, E]
-        verify(mListener).onItemRangeInserted(/* positionStart= */ 3, /* itemCount= */ 1);
-        // THEN E <> null = -1, E deleted from index 3 | [A, C, D]
-        verify(mListener).onItemRangeRemoved(/* positionStart= */ 4, /* itemCount= */ 1);
-    }
-
-    @Test
-    public void setWidgetsOnSearch_expandedApp_shouldResetExpandedApp() {
-        // GIVEN a list of widgets entries:
-        // [Empty item
-        //  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:
-        // [Empty item,
-        // com.google.test0,
-        // com.google.test1,
-        // com.google.test2].
-        ArrayList<WidgetsListBaseEntry> allEntries = generateSampleMap(3);
-        mAdapter.setWidgetsOnSearch(allEntries);
-        // GIVEN com.google.test.1 header is expanded. The visible entries list becomes:
-        // [Empty item, 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:
-        // [Empty item, com.google.test0, com.google.test1, com.google.test2]
-        verify(mListener).onItemRangeChanged(eq(2), eq(1), isNull());
-        verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
-    }
-
-    /**
-     * Generates a list of sample widget entries.
-     *
-     * <p>Each sample app has 1 widget only. An app is represented by 2 entries,
-     * {@link WidgetsListHeaderEntry} & {@link WidgetsListContentEntry}. Only
-     * {@link WidgetsListHeaderEntry} is always visible in the {@link WidgetsListAdapter}.
-     * {@link WidgetsListContentEntry} is only shown upon clicking the corresponding app's
-     * {@link WidgetsListHeaderEntry}. Only at most one {@link WidgetsListContentEntry} is shown at
-     * a time.
-     *
-     * @param num the number of apps that have widgets.
-     */
-    private ArrayList<WidgetsListBaseEntry> generateSampleMap(int num) {
-        ArrayList<WidgetsListBaseEntry> result = new ArrayList<>();
-        if (num <= 0) return result;
-
-        for (int i = 0; i < num; i++) {
-            String packageName = TEST_PACKAGE_PLACEHOLDER + i;
-
-            List<WidgetItem> widgetItems = generateWidgetItems(packageName, /* numOfWidgets= */ 1);
-
-            PackageItemInfo pInfo = new PackageItemInfo(packageName, widgetItems.get(0).user);
-            pInfo.title = pInfo.packageName;
-            pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
-
-            result.add(WidgetsListHeaderEntry.create(
-                    pInfo, /* titleSectionName= */ "", widgetItems));
-            result.add(new WidgetsListContentEntry(pInfo, /* titleSectionName= */ "", widgetItems));
-        }
-
-        return result;
-    }
-
-    private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ArrayList<WidgetItem> 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;
-    }
-}