From 2986e0b4d1a08e87b3c3daf7aa404c9353e8a23c Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Thu, 25 Jan 2024 10:23:39 -0800 Subject: [PATCH] Removing the Worskapce as a dependency of CellLayout This will make it easier to test CellLayout, also we should avoid circular dependencies as much as poisble. This also allows the CellLayout to be created in other containers that are not workspace. Bug: 318417510 Test: creating HotseatReorderUnitTest in follow up cl Test: TaplReorderWidgets Test: ReorderAlgorithmUnitTest Flag: NA Change-Id: Ic45029a244cb11f8d6775c50b90af9c56f01eaa3 --- src/com/android/launcher3/CellLayout.java | 37 ++++++++-------- .../launcher3/CellLayoutContainer.java | 44 +++++++++++++++++++ src/com/android/launcher3/Hotseat.java | 1 + src/com/android/launcher3/Launcher.java | 2 +- src/com/android/launcher3/Workspace.java | 36 +++++++++------ .../celllayout/CellLayoutTestUtils.java | 2 +- .../UnitTestCellLayoutBuilderRule.kt | 14 +++++- .../workspace/TaplTwoPanelWorkspaceTest.java | 2 +- 8 files changed, 102 insertions(+), 36 deletions(-) create mode 100644 src/com/android/launcher3/CellLayoutContainer.java diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 1b4edf8f09..941a793287 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -16,7 +16,6 @@ package com.android.launcher3; -import static com.android.launcher3.LauncherState.EDIT_MODE; import static com.android.launcher3.dragndrop.DraggableView.DRAGGABLE_ICON; import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR; import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_REORDER_PREVIEW_OFFSET; @@ -214,6 +213,7 @@ public class CellLayout extends ViewGroup { // Related to accessible drag and drop DragAndDropAccessibilityDelegate mTouchHelper; + CellLayoutContainer mCellLayoutContainer; public static final FloatProperty SPRING_LOADED_PROGRESS = new FloatProperty("spring_loaded_progress") { @@ -228,8 +228,9 @@ public class CellLayout extends ViewGroup { } }; - public CellLayout(Context context) { - this(context, null); + public CellLayout(Context context, CellLayoutContainer container) { + this(context, (AttributeSet) null); + this.mCellLayoutContainer = container; } public CellLayout(Context context, AttributeSet attrs) { @@ -316,6 +317,14 @@ public class CellLayout extends ViewGroup { addView(mShortcutsAndWidgets); } + public CellLayoutContainer getCellLayoutContainer() { + return mCellLayoutContainer; + } + + public void setCellLayoutContainer(CellLayoutContainer cellLayoutContainer) { + mCellLayoutContainer = cellLayoutContainer; + } + /** * Sets or clears a delegate used for accessible drag and drop */ @@ -573,9 +582,7 @@ public class CellLayout extends ViewGroup { } protected void updateBgAlpha() { - if (!getWorkspace().mLauncher.isInState(EDIT_MODE)) { - mBackground.setAlpha((int) (mSpringLoadedProgress * 255)); - } + mBackground.setAlpha((int) (mSpringLoadedProgress * 255)); } /** @@ -1187,7 +1194,7 @@ public class CellLayout extends ViewGroup { // Apply local extracted color if the DragView is an AppWidgetHostViewDrawable. View view = dragObject.dragView.getContentView(); if (view instanceof LauncherAppWidgetHostView) { - int screenId = getWorkspace().getIdForScreen(this); + int screenId = mCellLayoutContainer.getCellLayoutId(this); cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect); ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, this, screenId); @@ -1200,25 +1207,19 @@ public class CellLayout extends ViewGroup { return getContext().getString(R.string.move_to_hotseat_position, Math.max(cellX, cellY) + 1); } else { - Workspace workspace = getWorkspace(); int row = cellY + 1; - int col = workspace.mIsRtl ? mCountX - cellX : cellX + 1; - int panelCount = workspace.getPanelCount(); - int screenId = workspace.getIdForScreen(this); - int pageIndex = workspace.getPageIndexForScreenId(screenId); + int col = Utilities.isRtl(getResources()) ? mCountX - cellX : cellX + 1; + int panelCount = mCellLayoutContainer.getPanelCount(); + int pageIndex = mCellLayoutContainer.getCellLayoutIndex(this); if (panelCount > 1) { // Increment the column if the target is on the right side of a two panel home col += (pageIndex % panelCount) * mCountX; } return getContext().getString(R.string.move_to_empty_cell_description, row, col, - workspace.getPageDescription(pageIndex)); + mCellLayoutContainer.getPageDescription(pageIndex)); } } - private Workspace getWorkspace() { - return Launcher.cast(mActivity).getWorkspace(); - } - public void clearDragOutlines() { final int oldIndex = mDragOutlineCurrent; mDragOutlineAnims[oldIndex].animateOut(); @@ -1452,7 +1453,7 @@ public class CellLayout extends ViewGroup { private void commitTempPlacement(View dragView) { mTmpOccupied.copyTo(mOccupied); - int screenId = getWorkspace().getIdForScreen(this); + int screenId = mCellLayoutContainer.getCellLayoutId(this); int container = Favorites.CONTAINER_DESKTOP; if (mContainerType == HOTSEAT) { diff --git a/src/com/android/launcher3/CellLayoutContainer.java b/src/com/android/launcher3/CellLayoutContainer.java new file mode 100644 index 0000000000..9ee0f70d4a --- /dev/null +++ b/src/com/android/launcher3/CellLayoutContainer.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 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; + +/** + * This interface should be implemented for any container/view that has a CellLayout as a children. + */ +public interface CellLayoutContainer { + + /** + * Get the CellLayoutId for the given cellLayout. + */ + int getCellLayoutId(CellLayout cellLayout); + + /** + * Get the index of the given CellLayout out of all the other CellLayouts. + */ + int getCellLayoutIndex(CellLayout cellLayout); + + /** + * The total number of CellLayouts in the container. + */ + int getPanelCount(); + + /** + * Used for accessibility, it returns the string that the assistant is going to say when + * referring to the given CellLayout. + */ + String getPageDescription(int pageIndex); +} diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 3b12b86bf7..37737d81a3 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -207,6 +207,7 @@ public class Hotseat extends CellLayout implements Insettable { public void setWorkspace(Workspace w) { mWorkspace = w; + setCellLayoutContainer(w); } @Override diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index b531780599..75714919a3 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -517,7 +517,7 @@ public class Launcher extends StatefulActivity mAppWidgetHolder.startListening(); mAppWidgetHolder.addProviderChangeListener(() -> refreshAndBindWidgetsForPackageUser(null)); mItemInflater = new ItemInflater<>(this, mAppWidgetHolder, getItemOnClickListener(), - mFocusHandler, new CellLayout(mWorkspace.getContext())); + mFocusHandler, new CellLayout(mWorkspace.getContext(), mWorkspace)); mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 2eff8aa1ad..984a9ae2bd 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -143,7 +143,7 @@ import java.util.stream.Collectors; * @param Class that extends View and PageIndicator */ public class Workspace extends PagedView - implements DropTarget, DragSource, View.OnTouchListener, + implements DropTarget, DragSource, View.OnTouchListener, CellLayoutContainer, DragController.DragListener, Insettable, StateHandler, WorkspaceLayoutManager, LauncherBindableItemsContainer, LauncherOverlayCallbacks { @@ -511,11 +511,6 @@ public class Workspace extends PagedView return !FOLDABLE_SINGLE_PAGE.get() && mLauncher.mDeviceProfile.isTwoPanels; } - @Override - public int getPanelCount() { - return isTwoPanelEnabled() ? 2 : super.getPanelCount(); - } - public void deferRemoveExtraEmptyScreen() { mDeferRemoveExtraEmptyScreen = true; } @@ -683,6 +678,7 @@ public class Workspace extends PagedView newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate( R.layout.workspace_screen, this, false /* attachToRoot */); } + newScreen.setCellLayoutContainer(this); mWorkspaceScreens.put(screenId, newScreen); mScreenOrder.add(insertIndex, screenId); @@ -949,7 +945,8 @@ public class Workspace extends PagedView return mWorkspaceScreens.get(screenId); } - public int getIdForScreen(CellLayout layout) { + @Override + public int getCellLayoutId(CellLayout layout) { int index = mWorkspaceScreens.indexOfValue(layout); if (index != -1) { return mWorkspaceScreens.keyAt(index); @@ -961,6 +958,16 @@ public class Workspace extends PagedView return indexOfChild(mWorkspaceScreens.get(screenId)); } + @Override + public int getCellLayoutIndex(CellLayout cellLayout) { + return indexOfChild(mWorkspaceScreens.get(getCellLayoutId(cellLayout))); + } + + @Override + public int getPanelCount() { + return isTwoPanelEnabled() ? 2 : super.getPanelCount(); + } + public IntSet getCurrentPageScreenIds() { return IntSet.wrap(getScreenIdForPageIndex(getCurrentPage())); } @@ -1001,7 +1008,7 @@ public class Workspace extends PagedView if (!isTwoPanelEnabled()) { return null; } - int screenId = getIdForScreen(cellLayout); + int screenId = getCellLayoutId(cellLayout); if (screenId == -1) { return null; } @@ -1826,7 +1833,7 @@ public class Workspace extends PagedView } } - int screenId = getIdForScreen(dropTargetLayout); + int screenId = getCellLayoutId(dropTargetLayout); if (Workspace.EXTRA_EMPTY_SCREEN_IDS.contains(screenId)) { commitExtraEmptyScreens(); } @@ -1909,7 +1916,7 @@ public class Workspace extends PagedView if (v == null || hasntMoved || !mCreateUserFolderOnDrop) return false; mCreateUserFolderOnDrop = false; - final int screenId = getIdForScreen(target); + final int screenId = getCellLayoutId(target); boolean aboveShortcut = (v.getTag() instanceof WorkspaceItemInfo); boolean willBecomeShortcut = (newView.getTag() instanceof WorkspaceItemInfo); @@ -2010,7 +2017,7 @@ public class Workspace extends PagedView LauncherSettings.Favorites.CONTAINER_HOTSEAT : LauncherSettings.Favorites.CONTAINER_DESKTOP; int screenId = (mTargetCell[0] < 0) ? - mDragInfo.screenId : getIdForScreen(dropTargetLayout); + mDragInfo.screenId : getCellLayoutId(dropTargetLayout); int spanX = mDragInfo != null ? mDragInfo.spanX : 1; int spanY = mDragInfo != null ? mDragInfo.spanY : 1; // First we find the cell nearest to point at which the item is @@ -2766,7 +2773,7 @@ public class Workspace extends PagedView final int container = mLauncher.isHotseatLayout(cellLayout) ? LauncherSettings.Favorites.CONTAINER_HOTSEAT : LauncherSettings.Favorites.CONTAINER_DESKTOP; - final int screenId = getIdForScreen(cellLayout); + final int screenId = getCellLayoutId(cellLayout); if (!mLauncher.isHotseatLayout(cellLayout) && screenId != getScreenIdForPageIndex(mCurrentPage) && !mLauncher.isInState(SPRING_LOADED) @@ -3480,14 +3487,15 @@ public class Workspace extends PagedView @Override protected String getCurrentPageDescription() { - int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage; - return getPageDescription(page); + int pageIndex = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage; + return getPageDescription(pageIndex); } /** * @param page page index. * @return Description of the page at the given page index. */ + @Override public String getPageDescription(int page) { int nScreens = getChildCount(); int extraScreenId = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID); diff --git a/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java b/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java index d8ae74bf3c..9fb198920b 100644 --- a/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java +++ b/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java @@ -41,7 +41,7 @@ public class CellLayoutTestUtils { CellPosMapper.CellPos pos = launcher.getCellPosMapper().mapPresenterToModel( params.getCellX(), params.getCellY(), - launcher.getWorkspace().getIdForScreen(cellLayout), CONTAINER_DESKTOP); + launcher.getWorkspace().getCellLayoutId(cellLayout), CONTAINER_DESKTOP); int screenId = pos.screenId; for (int j = boards.size(); j <= screenId; j++) { boards.add(new CellLayoutBoard(cellLayout.getCountX(), cellLayout.getCountY())); diff --git a/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt b/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt index 0f0dd657c0..b63966db74 100644 --- a/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt +++ b/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt @@ -21,6 +21,7 @@ import android.graphics.Point import android.view.View import androidx.test.core.app.ApplicationProvider import com.android.launcher3.CellLayout +import com.android.launcher3.CellLayoutContainer import com.android.launcher3.DeviceProfile import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.MultipageCellLayout @@ -40,6 +41,17 @@ class UnitTestCellLayoutBuilderRule : TestWatcher() { private val applicationContext = ActivityContextWrapper(ApplicationProvider.getApplicationContext()) + private val container = + object : CellLayoutContainer { + override fun getCellLayoutId(cellLayout: CellLayout): Int = 0 + + override fun getCellLayoutIndex(cellLayout: CellLayout): Int = 0 + + override fun getPanelCount(): Int = 1 + + override fun getPageDescription(pageIndex: Int): String = "" + } + override fun starting(description: Description?) { val dp = getDeviceProfile() prevNumColumns = dp.inv.numColumns @@ -60,7 +72,7 @@ class UnitTestCellLayoutBuilderRule : TestWatcher() { dp.cellLayoutBorderSpacePx = Point(0, 0) val cl = if (isMulti) MultipageCellLayout(getWrappedContext(applicationContext, dp)) - else CellLayout(getWrappedContext(applicationContext, dp)) + else CellLayout(getWrappedContext(applicationContext, dp), container) // I put a very large number for width and height so that all the items can fit, it doesn't // need to be exact, just bigger than the sum of cell border cl.measure( diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java index 3693163d21..43fc8ffa3f 100644 --- a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java +++ b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java @@ -349,7 +349,7 @@ public class TaplTwoPanelWorkspaceTest extends AbstractLauncherUiTest { assertEquals("Existing page count does NOT match.", pageIds.length, pageCount); for (int i = 0; i < pageCount; i++) { CellLayout page = (CellLayout) launcher.getWorkspace().getPageAt(i); - int pageId = launcher.getWorkspace().getIdForScreen(page); + int pageId = launcher.getWorkspace().getCellLayoutId(page); assertEquals("The page's id at index " + i + " does NOT match.", pageId, pageIds[i]); }