Removing UI dependency from LauncherModel in case of 2-panel layout

Bug: 175939730
Bug: 192431856
Bug: 185515153
Test: Manual
Change-Id: I8baa1cf9e5a8a04d5b8bc38c1f4b0755265cd8a9
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index ba55834..477964a 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -25,6 +25,7 @@
 import android.util.AttributeSet;
 import android.view.View;
 
+import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.logging.StatsLogManager;
@@ -128,11 +129,21 @@
     public void completeDrop(DragObject d) {
         ItemInfo item = d.dragInfo;
         if (canRemove(item)) {
-            int itemPage = mLauncher.getWorkspace().getCurrentPage();
+            ItemInfo pageItem = item;
+            if (item.container <= 0) {
+                View v = mLauncher.getWorkspace().getHomescreenIconByItemId(item.container);
+                if (v != null) {
+                    pageItem = (ItemInfo) v.getTag();
+                }
+            }
+            IntSet pageIds = pageItem.container == Favorites.CONTAINER_DESKTOP
+                    ? IntSet.wrap(pageItem.screenId)
+                    : mLauncher.getWorkspace().getCurrentPageScreenIds();
+
             onAccessibilityDrop(null, item);
             ModelWriter modelWriter = mLauncher.getModelWriter();
             Runnable onUndoClicked = () -> {
-                mLauncher.setPagesToBindSynchronously(IntSet.wrap(itemPage));
+                mLauncher.setPagesToBindSynchronously(pageIds);
                 modelWriter.abortDelete();
                 mLauncher.getStatsLogManager().logger().log(LAUNCHER_UNDO);
             };
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 78a8a97..e736022 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -36,6 +36,7 @@
 import static com.android.launcher3.LauncherState.NO_SCALE;
 import static com.android.launcher3.LauncherState.SPRING_LOADED;
 import static com.android.launcher3.Utilities.postAsyncCallback;
+import static com.android.launcher3.WorkspaceLayoutManager.LEFT_PANEL_ID;
 import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
 import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
@@ -259,6 +260,8 @@
     private static final String RUNTIME_STATE_PENDING_ACTIVITY_RESULT = "launcher.activity_result";
     // Type: SparseArray<Parcelable>
     private static final String RUNTIME_STATE_WIDGET_PANEL = "launcher.widget_panel";
+    // Type int[]
+    private static final String RUNTIME_STATE_CURRENT_SCREEN_IDS = "launcher.current_screen_ids";
 
     public static final String ON_CREATE_EVT = "Launcher.onCreate";
     public static final String ON_START_EVT = "Launcher.onStart";
@@ -287,8 +290,6 @@
     private WidgetManagerHelper mAppWidgetManager;
     private LauncherAppWidgetHost mAppWidgetHost;
 
-    private LauncherPageRestoreHelper mPageRestoreHelper;
-
     private final int[] mTmpAddItemCellCoordinates = new int[2];
 
     @Thunk
@@ -325,7 +326,7 @@
     private PopupDataProvider mPopupDataProvider;
 
     private IntSet mSynchronouslyBoundPages = new IntSet();
-    private IntSet mPagesToBindSynchronously = new IntSet();
+    @NonNull private IntSet mPagesToBindSynchronously = new IntSet();
 
     // We only want to get the SharedPreferences once since it does an FS stat each time we get
     // it from the context.
@@ -460,9 +461,11 @@
         restoreState(savedInstanceState);
         mStateManager.reapplyState();
 
-        mPageRestoreHelper = new LauncherPageRestoreHelper(mWorkspace);
         if (savedInstanceState != null) {
-            mPagesToBindSynchronously = mPageRestoreHelper.getPagesToRestore(savedInstanceState);
+            int[] pageIds = savedInstanceState.getIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS);
+            if (pageIds != null) {
+                mPagesToBindSynchronously = IntSet.wrap(pageIds);
+            }
         }
 
         if (!mModel.addCallbacksAndLoad(this)) {
@@ -1188,7 +1191,6 @@
         // Until the workspace is bound, ensure that we keep the wallpaper offset locked to the
         // default state, otherwise we will update to the wrong offsets in RTL
         mWorkspace.lockWallpaperToDefaultPage();
-        mWorkspace.bindAndInitLeftPanel();
         mWorkspace.bindAndInitFirstWorkspaceScreen(null /* recycled qsb */);
         mDragController.addDragListener(mWorkspace);
 
@@ -1586,14 +1588,19 @@
     public void onRestoreInstanceState(Bundle state) {
         super.onRestoreInstanceState(state);
         if (mSynchronouslyBoundPages != null) {
-            mSynchronouslyBoundPages.forEach(page -> mWorkspace.restoreInstanceStateForChild(page));
+            mSynchronouslyBoundPages.forEach(screenId -> {
+                int pageIndex = mWorkspace.getPageIndexForScreenId(screenId);
+                if (pageIndex != PagedView.INVALID_PAGE) {
+                    mWorkspace.restoreInstanceStateForChild(pageIndex);
+                }
+            });
         }
     }
 
     @Override
     protected void onSaveInstanceState(Bundle outState) {
-        mPageRestoreHelper.savePagesToRestore(outState);
-
+        outState.putIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS,
+                mWorkspace.getCurrentPageScreenIds().getArray().toArray());
         outState.putInt(RUNTIME_STATE, mStateManager.getState().ordinal);
 
         AbstractFloatingView widgets = AbstractFloatingView
@@ -2081,18 +2088,42 @@
         mPagesToBindSynchronously = pages;
     }
 
-    /**
-     * Implementation of the method from LauncherModel.Callbacks.
-     */
     @Override
-    public IntSet getPagesToBindSynchronously() {
-        if (mPagesToBindSynchronously != null && !mPagesToBindSynchronously.isEmpty()) {
-            return mPagesToBindSynchronously;
-        } else if (mWorkspace != null) {
-            return mWorkspace.getVisiblePageIndices();
+    public IntSet getPagesToBindSynchronously(IntArray orderedScreenIds) {
+        IntSet visibleIds = mPagesToBindSynchronously.isEmpty()
+                ? mWorkspace.getCurrentPageScreenIds() : mPagesToBindSynchronously;
+        IntArray actualIds = new IntArray();
+
+        if (mDeviceProfile.isTwoPanels) {
+            actualIds.add(LEFT_PANEL_ID);
         } else {
-            return new IntSet();
+            visibleIds.remove(LEFT_PANEL_ID);
         }
+        IntSet result = new IntSet();
+        if (visibleIds.isEmpty()) {
+            return result;
+        }
+        for (int id : orderedScreenIds.toArray()) {
+            if (id != LEFT_PANEL_ID) {
+                actualIds.add(id);
+            }
+        }
+        int firstId = visibleIds.getArray().get(0);
+        if (actualIds.contains(firstId)) {
+            result.add(firstId);
+
+            if (mDeviceProfile.isTwoPanels) {
+                int index = actualIds.indexOf(firstId);
+                int nextIndex = ((int) (index / 2)) * 2;
+                if (nextIndex == index) {
+                    nextIndex++;
+                }
+                if (nextIndex < actualIds.size()) {
+                    result.add(actualIds.get(nextIndex));
+                }
+            }
+        }
+        return result;
     }
 
     /**
@@ -2143,7 +2174,7 @@
         // Make sure the first screen is at the start if there's no widget panel,
         // or on the second place if the first is the widget panel
         boolean isLeftPanelShown =
-                mWorkspace.mWorkspaceScreens.containsKey(Workspace.LEFT_PANEL_ID);
+                mWorkspace.mWorkspaceScreens.containsKey(LEFT_PANEL_ID);
         int firstScreenPosition = isLeftPanelShown && orderedScreenIds.size() > 1 ? 1 : 0;
 
         if (FeatureFlags.QSB_ON_FIRST_SCREEN &&
@@ -2171,7 +2202,7 @@
                 continue;
             }
 
-            if (screenId == Workspace.LEFT_PANEL_ID) {
+            if (screenId == LEFT_PANEL_ID) {
                 // No need to bind the left panel, as its always bound.
                 continue;
             }
@@ -2252,7 +2283,7 @@
             }
 
             // Skip if the item is on the left widget panel but the panel is not shown
-            if (item.screenId == Workspace.LEFT_PANEL_ID && !getDeviceProfile().isTwoPanels) {
+            if (item.screenId == LEFT_PANEL_ID && !getDeviceProfile().isTwoPanels) {
                 continue;
             }
 
@@ -2555,9 +2586,6 @@
     @Override
     public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
         mSynchronouslyBoundPages = boundPages;
-        if (!boundPages.isEmpty()) {
-            mWorkspace.setCurrentPage(boundPages.getArray().get(0));
-        }
         mPagesToBindSynchronously = new IntSet();
 
         clearPendingBinds();
@@ -2598,7 +2626,8 @@
         }
 
         int currentPage = pagesBoundFirst != null && !pagesBoundFirst.isEmpty()
-                ? pagesBoundFirst.getArray().get(0) : PagedView.INVALID_PAGE;
+                ? mWorkspace.getPageIndexForScreenId(pagesBoundFirst.getArray().get(0))
+                : PagedView.INVALID_PAGE;
         // When undoing the removal of the last item on a page, return to that page.
         // Since we are just resetting the current page without user interaction,
         // override the previous page so we don't log the page switch.
diff --git a/src/com/android/launcher3/LauncherPageRestoreHelper.java b/src/com/android/launcher3/LauncherPageRestoreHelper.java
deleted file mode 100644
index e679a12..0000000
--- a/src/com/android/launcher3/LauncherPageRestoreHelper.java
+++ /dev/null
@@ -1,92 +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;
-
-import android.os.Bundle;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.launcher3.util.IntSet;
-
-import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE;
-
-/**
- * There's a logic which prioritizes the binding for the current page and defers the other pages'
- * binding. If two panel home is enabled, we want to bind both pages together.
- * LauncherPageRestoreHelper's purpose is to contain the logic for persisting, restoring and
- * calculating which pages to load immediately.
- */
-public class LauncherPageRestoreHelper {
-
-    public static final String TAG = "LauncherPageRestoreHelper";
-
-    // Type: int
-    private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
-    // Type: int
-    private static final String RUNTIME_STATE_CURRENT_SCREEN_COUNT =
-            "launcher.current_screen_count";
-
-    private Workspace mWorkspace;
-
-    public LauncherPageRestoreHelper(Workspace workspace) {
-        this.mWorkspace = workspace;
-    }
-
-    /**
-     * Some configuration changes trigger Launcher to recreate itself, and we want to give more
-     * priority to the currently active pages in the restoration process.
-     */
-    @VisibleForTesting(otherwise = PACKAGE_PRIVATE)
-    public IntSet getPagesToRestore(Bundle savedInstanceState) {
-        IntSet pagesToRestore = new IntSet();
-
-        if (savedInstanceState == null) {
-            return pagesToRestore;
-        }
-
-        int currentPage = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
-        int totalPageCount = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN_COUNT, -1);
-        int panelCount = mWorkspace.getPanelCount();
-
-        if (totalPageCount <= 0 || currentPage < 0) {
-            Log.e(TAG, "getPagesToRestore: Invalid input: " + totalPageCount + ", " + currentPage);
-            return pagesToRestore;
-        }
-
-        int newCurrentPage = mWorkspace.getLeftmostVisiblePageForIndex(currentPage);
-        for (int page = newCurrentPage; page < newCurrentPage + panelCount
-                && page < totalPageCount; page++) {
-            pagesToRestore.add(page);
-        }
-
-        return pagesToRestore;
-    }
-
-    /**
-     * This should be called from Launcher's onSaveInstanceState method to persist everything that
-     * is necessary to calculate later which pages need to be initialized first after a
-     * configuration change.
-     */
-    @VisibleForTesting(otherwise = PACKAGE_PRIVATE)
-    public void savePagesToRestore(Bundle outState) {
-        int pageCount = mWorkspace.getChildCount();
-        if (pageCount > 0) {
-            outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getCurrentPage());
-            outState.putInt(RUNTIME_STATE_CURRENT_SCREEN_COUNT, pageCount);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 440e9e3..a8ed6bc 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -61,7 +61,6 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.DbDowngradeHelper;
-import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.provider.LauncherDbUtils;
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
@@ -1090,7 +1089,7 @@
         }
 
         private int initializeMaxScreenId(SQLiteDatabase db) {
-            return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s WHERE %3$s = %4$d",
+            return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s WHERE %3$s = %4$d AND %1$s >= 0",
                     Favorites.SCREEN, Favorites.TABLE_NAME, Favorites.CONTAINER,
                     Favorites.CONTAINER_DESKTOP);
         }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6c0e893..faf2dd2 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -102,6 +102,7 @@
 import com.android.launcher3.util.EdgeEffectCompat;
 import com.android.launcher3.util.Executors;
 import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.IntSparseArrayMap;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LauncherBindableItemsContainer;
@@ -327,22 +328,6 @@
             setPageSpacing(Math.max(maxInsets, maxPadding));
         }
 
-        if (grid.isTwoPanels) {
-            // Add left widget panel if it isn't already there
-            if (!mWorkspaceScreens.containsKey(LEFT_PANEL_ID)) {
-                int newCurrentPage = mCurrentPage + 1;
-                bindAndInitLeftPanel();
-                setCurrentPage(newCurrentPage);
-            }
-        } else {
-            // Remove left widget panel if it is present
-            if (mWorkspaceScreens.containsKey(LEFT_PANEL_ID)) {
-                int newCurrentPage = mCurrentPage - 1;
-                removeLeftPanel();
-                setCurrentPage(newCurrentPage);
-            }
-        }
-
         int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx;
         int paddingBottom = grid.cellLayoutBottomPaddingPx;
         int twoPanelLandscapeSidePadding = paddingLeftRight * 2;
@@ -570,6 +555,10 @@
         if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
             return;
         }
+        if (isTwoPanelEnabled()) {
+            insertNewWorkspaceScreen(Workspace.LEFT_PANEL_ID, getChildCount());
+        }
+
         // Add the first page
         CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount());
         // Always add a QSB on the first screen.
@@ -590,19 +579,6 @@
         }
     }
 
-    /**
-     * Initializes and binds the left panel
-     */
-    public void bindAndInitLeftPanel() {
-        if (!FeatureFlags.QSB_ON_FIRST_SCREEN || !isTwoPanelEnabled()
-                || mWorkspaceScreens.containsKey(Workspace.LEFT_PANEL_ID)) {
-            return;
-        }
-
-        insertNewWorkspaceScreen(Workspace.LEFT_PANEL_ID, getChildCount());
-        mLauncher.getModelWriter().setLeftPanelShown(true);
-    }
-
     public void removeAllWorkspaceScreens() {
         // Disable all layout transitions before removing all pages to ensure that we don't get the
         // transition animations competing with us changing the scroll when we add pages
@@ -624,7 +600,6 @@
         mLauncher.mHandler.removeCallbacksAndMessages(DeferredWidgetRefresh.class);
 
         // Ensure that the first page is always present
-        bindAndInitLeftPanel();
         bindAndInitFirstWorkspaceScreen(qsb);
 
         // Re-enable the layout transitions
@@ -645,18 +620,6 @@
         insertNewWorkspaceScreen(screenId, getChildCount());
     }
 
-    private void removeLeftPanel() {
-        if (!mWorkspaceScreens.containsKey(LEFT_PANEL_ID)) {
-            return;
-        }
-        mLauncher.getModelWriter().setLeftPanelShown(false);
-        CellLayout leftPanel = mWorkspaceScreens.get(LEFT_PANEL_ID);
-        mWorkspaceScreens.remove(LEFT_PANEL_ID);
-        removeView(leftPanel);
-        mScreenOrder.removeValue(LEFT_PANEL_ID);
-        updatePageScrollValues();
-    }
-
     public CellLayout insertNewWorkspaceScreen(int screenId, int insertIndex) {
         if (mWorkspaceScreens.containsKey(screenId)) {
             throw new RuntimeException("Screen id " + screenId + " already exists!");
@@ -829,6 +792,10 @@
         return indexOfChild(mWorkspaceScreens.get(screenId));
     }
 
+    public IntSet getCurrentPageScreenIds() {
+        return IntSet.wrap(getScreenIdForPageIndex(getCurrentPage()));
+    }
+
     public int getScreenIdForPageIndex(int index) {
         if (0 <= index && index < mScreenOrder.size()) {
             return mScreenOrder.get(index);
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index 13c83be..f3087c0 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -175,7 +175,6 @@
                             query);
 
                     MAIN_EXECUTOR.execute(() -> {
-                        mBgDataModel.isLeftPanelShown = deviceProfile.isTwoPanels;
                         renderView(previewContext, mBgDataModel, mWidgetProvidersMap);
                         mOnDestroyCallbacks.add(previewContext::onDestroy);
                     });
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index b2b0010..4f12d0b 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -15,6 +15,9 @@
  */
 package com.android.launcher3.model;
 
+import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
+import static com.android.launcher3.WorkspaceLayoutManager.LEFT_PANEL_ID;
+
 import android.content.Intent;
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.LauncherApps;
@@ -27,6 +30,7 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel.CallbackTask;
 import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.BgDataModel.Callbacks;
 import com.android.launcher3.model.data.AppInfo;
@@ -38,6 +42,7 @@
 import com.android.launcher3.pm.PackageInstallInfo;
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.PackageManagerHelper;
 
 import java.util.ArrayList;
@@ -291,11 +296,15 @@
         boolean found = false;
 
         int screenCount = workspaceScreens.size();
-        int firstScreenToCheck = dataModel.isLeftPanelShown ? 2 : 1;
-        // Search on the screens for empty space
-        for (int screen = firstScreenToCheck; screen < screenCount; screen++) {
+        // First check the preferred screen.
+        IntSet screensToExclude = IntSet.wrap(LEFT_PANEL_ID);
+        if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
+            screensToExclude.add(FIRST_SCREEN_ID);
+        }
+
+        for (int screen = 0; screen < screenCount; screen++) {
             screenId = workspaceScreens.get(screen);
-            if (findNextAvailableIconSpaceInScreen(
+            if (!screensToExclude.contains(screenId) && findNextAvailableIconSpaceInScreen(
                     app, screenItems.get(screenId), coordinates, spanX, spanY)) {
                 // We found a space for it
                 found = true;
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index c202d8d..0e132c2 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -165,25 +165,7 @@
         }
 
         private void bind() {
-            IntSet currentScreenIndices;
-            {
-                // Create an anonymous scope to calculate currentScreen as it has to be a
-                // final variable.
-                IntSet screenIndices = mCallbacks.getPagesToBindSynchronously();
-                if (screenIndices == null || screenIndices.isEmpty()
-                        || screenIndices.getArray().get(screenIndices.size() - 1)
-                        >= mOrderedScreenIds.size()) {
-                    // There maybe no workspace screens (just hotseat items and an empty page).
-                    // Also we want to prevent IndexOutOfBoundsExceptions.
-                    screenIndices = new IntSet();
-                }
-                currentScreenIndices = screenIndices;
-            }
-
-
-            IntSet currentScreenIds  = new IntSet();
-            currentScreenIndices.forEach(
-                    index -> currentScreenIds.add(mOrderedScreenIds.get(index)));
+            IntSet currentScreenIds = mCallbacks.getPagesToBindSynchronously(mOrderedScreenIds);
 
             // Separate the items that are on the current screen, and all the other remaining items
             ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
@@ -218,7 +200,7 @@
             Executor pendingExecutor = pendingTasks::add;
             bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
             bindAppWidgets(otherAppWidgets, pendingExecutor);
-            executeCallbacksTask(c -> c.finishBindingItems(currentScreenIndices), pendingExecutor);
+            executeCallbacksTask(c -> c.finishBindingItems(currentScreenIds), pendingExecutor);
             pendingExecutor.execute(
                     () -> {
                         MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
@@ -229,7 +211,7 @@
             executeCallbacksTask(
                     c -> {
                         MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-                        c.onInitialBindComplete(currentScreenIndices, pendingTasks);
+                        c.onInitialBindComplete(currentScreenIds, pendingTasks);
                     }, mUiExecutor);
         }
 
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index dd4c3c3..13ad90e 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -117,11 +117,6 @@
     public int lastBindId = 0;
 
     /**
-     * Value that indicates if left widget panel is shown or not.
-     */
-    public boolean isLeftPanelShown = false;
-
-    /**
      * Clears all the data
      */
     public synchronized void clear() {
@@ -146,14 +141,6 @@
         if (FeatureFlags.QSB_ON_FIRST_SCREEN || screenSet.isEmpty()) {
             screenSet.add(Workspace.FIRST_SCREEN_ID);
         }
-
-        if (isLeftPanelShown) {
-            // We should add it even though there are no items on it.
-            screenSet.add(Workspace.LEFT_PANEL_ID);
-        } else {
-            // We should NOT add it even though there are items on it.
-            screenSet.remove(Workspace.LEFT_PANEL_ID);
-        }
         return screenSet.getArray();
     }
 
@@ -459,10 +446,11 @@
         int FLAG_QUIET_MODE_CHANGE_PERMISSION = 1 << 2;
 
         /**
-         * Returns an IntSet of page numbers to bind first, synchronously if possible
+         * Returns an IntSet of page ids to bind first, synchronously if possible
          * or an empty IntSet
+         * @param orderedScreenIds All the page ids to be bound
          */
-        default IntSet getPagesToBindSynchronously() {
+        default IntSet getPagesToBindSynchronously(IntArray orderedScreenIds) {
             return new IntSet();
         }
 
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 31ca6e7..43f9be5 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.model;
 
+import static com.android.launcher3.WorkspaceLayoutManager.LEFT_PANEL_ID;
 import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
@@ -86,6 +87,7 @@
 import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IOUtils;
+import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.LooperIdleLock;
 import com.android.launcher3.util.PackageManagerHelper;
@@ -175,11 +177,17 @@
     private void sendFirstScreenActiveInstallsBroadcast() {
         ArrayList<ItemInfo> firstScreenItems = new ArrayList<>();
         ArrayList<ItemInfo> allItems = mBgDataModel.getAllWorkspaceItems();
-        // Screen set is never empty
-        final int firstScreen = mBgDataModel.collectWorkspaceScreens().get(0);
-        // TODO(b/185515153): support two panel home.
 
-        filterCurrentWorkspaceItems(IntSet.wrap(firstScreen), allItems, firstScreenItems,
+        // Screen set is never empty
+        IntArray allScreens = mBgDataModel.collectWorkspaceScreens();
+        final int firstScreen = allScreens.get(0);
+
+        IntSet firstScreens = IntSet.wrap(firstScreen);
+        if (firstScreen == LEFT_PANEL_ID && allScreens.size() >= 2) {
+            firstScreens.add(allScreens.get(1));
+        }
+
+        filterCurrentWorkspaceItems(firstScreens, allItems, firstScreenItems,
                 new ArrayList<>() /* otherScreenItems are ignored */);
         mFirstScreenBroadcast.sendBroadcasts(mApp.getContext(), firstScreenItems);
     }
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 55edfd4..0439e75 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -121,13 +121,6 @@
         }
     }
 
-    /**
-     * Sets the value that indicates if left widget panel is shown or not.
-     */
-    public void setLeftPanelShown(boolean value) {
-        mBgDataModel.isLeftPanelShown = value;
-    }
-
     private void checkItemInfoLocked(int itemId, ItemInfo item, StackTraceElement[] stackTrace) {
         ItemInfo modelItem = mBgDataModel.itemsIdMap.get(itemId);
         if (modelItem != null && item != modelItem) {