diff --git a/res/layout/launcher_preview_two_panel_layout.xml b/res/layout/launcher_preview_two_panel_layout.xml new file mode 100644 index 0000000000..7b227e0345 --- /dev/null +++ b/res/layout/launcher_preview_two_panel_layout.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java index 8e49fae1c7..d2051e03ff 100644 --- a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java +++ b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java @@ -131,7 +131,7 @@ public class GridSizeMigrationTaskV2Test { mIdp.numDatabaseHotseatIcons); GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader, destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows)); - task.migrate(); + task.migrate(mIdp); // Check hotseat items Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI, @@ -211,7 +211,7 @@ public class GridSizeMigrationTaskV2Test { mIdp.numDatabaseHotseatIcons); GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader, destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows)); - task.migrate(); + task.migrate(mIdp); // Check hotseat items Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI, @@ -259,7 +259,7 @@ public class GridSizeMigrationTaskV2Test { mIdp.numDatabaseHotseatIcons); GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader, destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows)); - task.migrate(); + task.migrate(mIdp); // Check hotseat items Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI, diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 1127ff907a..1da8028814 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -208,7 +208,7 @@ public class LauncherPreviewRenderer extends ContextWrapper private final LayoutInflater mHomeElementInflater; private final InsettableFrameLayout mRootView; private final Hotseat mHotseat; - private final CellLayout mWorkspace; + private final Map mWorkspaceScreens = new HashMap<>(); private final AppWidgetHost mAppWidgetHost; private final SparseIntArray mWallpaperColorResources; @@ -254,19 +254,31 @@ public class LauncherPreviewRenderer extends ContextWrapper new ContextThemeWrapper(this, R.style.HomeScreenElementTheme)); mHomeElementInflater.setFactory2(this); + int layoutRes = mDp.isTwoPanels ? R.layout.launcher_preview_two_panel_layout + : R.layout.launcher_preview_layout; mRootView = (InsettableFrameLayout) mHomeElementInflater.inflate( - R.layout.launcher_preview_layout, null, false); + layoutRes, null, false); mRootView.setInsets(mInsets); measureView(mRootView, mDp.widthPx, mDp.heightPx); mHotseat = mRootView.findViewById(R.id.hotseat); mHotseat.resetLayout(false); - mWorkspace = mRootView.findViewById(R.id.workspace); - mWorkspace.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx, + if (mDp.isTwoPanels) { + CellLayout leftPanel = mRootView.findViewById(R.id.workspace_left); + leftPanel.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx, + mDp.workspacePadding.top, + mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx, + mDp.workspacePadding.bottom); + mWorkspaceScreens.put(LEFT_PANEL_ID, leftPanel); + } + + CellLayout firstScreen = mRootView.findViewById(R.id.workspace); + firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx, mDp.workspacePadding.top, mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx, mDp.workspacePadding.bottom); + mWorkspaceScreens.put(FIRST_SCREEN_ID, firstScreen); if (FeatureFlags.WIDGETS_IN_LAUNCHER_PREVIEW.get()) { mAppWidgetHost = new LauncherPreviewAppWidgetHost(context); @@ -335,18 +347,20 @@ public class LauncherPreviewRenderer extends ContextWrapper @Override public CellLayout getScreenWithId(int screenId) { - return mWorkspace; + return mWorkspaceScreens.get(screenId); } private void inflateAndAddIcon(WorkspaceItemInfo info) { + CellLayout screen = mWorkspaceScreens.get(info.screenId); BubbleTextView icon = (BubbleTextView) mHomeElementInflater.inflate( - R.layout.app_icon, mWorkspace, false); + R.layout.app_icon, screen, false); icon.applyFromWorkspaceItem(info); addInScreenFromBind(icon, info); } private void inflateAndAddFolder(FolderInfo info) { - FolderIcon folderIcon = FolderIcon.inflateIcon(R.layout.folder_icon, this, mWorkspace, + CellLayout screen = mWorkspaceScreens.get(info.screenId); + FolderIcon folderIcon = FolderIcon.inflateIcon(R.layout.folder_icon, this, screen, info); addInScreenFromBind(folderIcon, info); } @@ -396,7 +410,8 @@ public class LauncherPreviewRenderer extends ContextWrapper } private void inflateAndAddPredictedIcon(WorkspaceItemInfo info) { - View view = PredictedAppIconInflater.inflate(mHomeElementInflater, mWorkspace, info); + CellLayout screen = mWorkspaceScreens.get(info.screenId); + View view = PredictedAppIconInflater.inflate(mHomeElementInflater, screen, info); if (view != null) { addInScreenFromBind(view, info); } @@ -428,8 +443,7 @@ public class LauncherPreviewRenderer extends ContextWrapper ArrayList currentAppWidgets = new ArrayList<>(); ArrayList otherAppWidgets = new ArrayList<>(); - IntSet currentScreenIds = IntSet.wrap(0); - // TODO(b/185508060): support two panel preview. + IntSet currentScreenIds = IntSet.wrap(mWorkspaceScreens.keySet()); filterCurrentWorkspaceItems(currentScreenIds, dataModel.workspaceItems, currentWorkspaceItems, otherWorkspaceItems); filterCurrentWorkspaceItems(currentScreenIds, dataModel.appWidgets, currentAppWidgets, @@ -487,12 +501,13 @@ public class LauncherPreviewRenderer extends ContextWrapper // Add first page QSB if (FeatureFlags.QSB_ON_FIRST_SCREEN) { + CellLayout firstScreen = mWorkspaceScreens.get(FIRST_SCREEN_ID); View qsb = mHomeElementInflater.inflate( - R.layout.search_container_workspace, mWorkspace, false); + R.layout.search_container_workspace, firstScreen, false); CellLayout.LayoutParams lp = - new CellLayout.LayoutParams(0, 0, mWorkspace.getCountX(), 1); + new CellLayout.LayoutParams(0, 0, firstScreen.getCountX(), 1); lp.canReorder = false; - mWorkspace.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true); + firstScreen.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true); } measureView(mRootView, mDp.widthPx, mDp.heightPx); diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java index df493599ed..13c83be123 100644 --- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java +++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java @@ -38,11 +38,13 @@ import android.view.animation.AccelerateDecelerateInterpolator; import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.Workspace; import com.android.launcher3.graphics.LauncherPreviewRenderer.PreviewContext; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.GridSizeMigrationTask; @@ -163,11 +165,17 @@ public class PreviewSurfaceRenderer { @Override public void run() { + DeviceProfile deviceProfile = mIdp.getDeviceProfile(mContext); + String query = (deviceProfile.isTwoPanels ? LauncherSettings.Favorites.SCREEN + + " = " + Workspace.LEFT_PANEL_ID + " or " : "") + + LauncherSettings.Favorites.SCREEN + " = " + Workspace.FIRST_SCREEN_ID + + " or " + LauncherSettings.Favorites.CONTAINER + " = " + + LauncherSettings.Favorites.CONTAINER_HOTSEAT; loadWorkspace(new ArrayList<>(), LauncherSettings.Favorites.PREVIEW_CONTENT_URI, - LauncherSettings.Favorites.SCREEN + " = 0 or " - + LauncherSettings.Favorites.CONTAINER + " = " - + LauncherSettings.Favorites.CONTAINER_HOTSEAT); + query); + MAIN_EXECUTOR.execute(() -> { + mBgDataModel.isLeftPanelShown = deviceProfile.isTwoPanels; renderView(previewContext, mBgDataModel, mWidgetProvidersMap); mOnDestroyCallbacks.add(previewContext::onDestroy); }); diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java index 8a1d73ed72..3935bcf7e8 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java +++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java @@ -41,6 +41,7 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.Utilities; +import com.android.launcher3.Workspace; import com.android.launcher3.graphics.LauncherPreviewRenderer; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.pm.InstallSessionHelper; @@ -183,7 +184,7 @@ public class GridSizeMigrationTaskV2 { Point targetSize = new Point(idp.numColumns, idp.numRows); GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(context, t.getDb(), srcReader, destReader, idp.numDatabaseHotseatIcons, targetSize); - task.migrate(); + task.migrate(idp); if (!migrateForPreview) { dropTable(t.getDb(), LauncherSettings.Favorites.TMP_TABLE); @@ -210,7 +211,7 @@ public class GridSizeMigrationTaskV2 { } @VisibleForTesting - protected boolean migrate() { + protected boolean migrate(InvariantDeviceProfile idp) { if (mHotseatDiff.isEmpty() && mWorkspaceDiff.isEmpty()) { return false; } @@ -224,7 +225,17 @@ public class GridSizeMigrationTaskV2 { Collections.sort(mWorkspaceDiff); // Migrate workspace. + // First we create a collection of the screens + List screens = new ArrayList<>(); + if (idp.getDeviceProfile(mContext).isTwoPanels) { + screens.add(Workspace.LEFT_PANEL_ID); + } for (int screenId = 0; screenId <= mDestReader.mLastScreenId; screenId++) { + screens.add(screenId); + } + + // Then we place the items on the screens + for (int screenId : screens) { if (DEBUG) { Log.d(TAG, "Migrating " + screenId); } @@ -236,6 +247,8 @@ public class GridSizeMigrationTaskV2 { } } + // In case the new grid is smaller, there might be some leftover items that don't fit on + // any of the screens, in this case we add them to new screens until all of them are placed. int screenId = mDestReader.mLastScreenId + 1; while (!mWorkspaceDiff.isEmpty()) { GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader, diff --git a/src/com/android/launcher3/util/IntSet.java b/src/com/android/launcher3/util/IntSet.java index 0f4df625a6..e5b4f59cf7 100644 --- a/src/com/android/launcher3/util/IntSet.java +++ b/src/com/android/launcher3/util/IntSet.java @@ -101,6 +101,15 @@ public class IntSet implements Iterable { return wrap(IntArray.wrap(array)); } + /** + * Returns an IntSet with the given values. + */ + public static IntSet wrap(Iterable iterable) { + IntSet set = new IntSet(); + iterable.forEach(set::add); + return set; + } + @Override public Iterator iterator() { return mArray.iterator();