Commit e9925c47 authored by Mei Liang's avatar Mei Liang Committed by Commit Bot

Add TabSelectionEditorAction.close handler

This CL adds a close action to TabSelectionEditorActionProvider. In
addition, this CL provides an constructor for customized process
selected tabs action.

Change-Id: Ia5ae7902641055f3bd30e7351f5e2df2a0822ab1
Bug: 1004570
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1907307Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Mei Liang <meiliang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714598}
parent 82bd3ae4
...@@ -326,9 +326,9 @@ public class TabGridDialogMediator { ...@@ -326,9 +326,9 @@ public class TabGridDialogMediator {
private void setupDialogSelectionEditor() { private void setupDialogSelectionEditor() {
assert mTabSelectionEditorController != null; assert mTabSelectionEditorController != null;
TabSelectionEditorActionProvider actionProvider = new TabSelectionEditorActionProvider( TabSelectionEditorActionProvider actionProvider =
mTabModelSelector, mTabSelectionEditorController, new TabSelectionEditorActionProvider(mTabSelectionEditorController,
TabSelectionEditorActionProvider.TabSelectionEditorAction.UNGROUP); TabSelectionEditorActionProvider.TabSelectionEditorAction.UNGROUP);
String actionButtonText = String actionButtonText =
mContext.getString(R.string.tab_grid_dialog_selection_mode_remove); mContext.getString(R.string.tab_grid_dialog_selection_mode_remove);
......
...@@ -21,42 +21,65 @@ import java.util.List; ...@@ -21,42 +21,65 @@ import java.util.List;
* Provider of actions for a list of selected tabs in {@link TabSelectionEditorMediator}. * Provider of actions for a list of selected tabs in {@link TabSelectionEditorMediator}.
*/ */
class TabSelectionEditorActionProvider { class TabSelectionEditorActionProvider {
@IntDef({TabSelectionEditorAction.UNGROUP, TabSelectionEditorAction.GROUP}) @IntDef({TabSelectionEditorAction.UNDEFINED_ACTION, TabSelectionEditorAction.GROUP,
TabSelectionEditorAction.UNGROUP, TabSelectionEditorAction.CLOSE})
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@interface TabSelectionEditorAction { @interface TabSelectionEditorAction {
int GROUP = 0; int UNDEFINED_ACTION = 0;
int UNGROUP = 1; int GROUP = 1;
int NUM_ENTRIES = 2; int UNGROUP = 2;
int CLOSE = 3;
int NUM_ENTRIES = 4;
} }
private final TabModelSelector mTabModelSelector;
private final TabSelectionEditorCoordinator private final TabSelectionEditorCoordinator
.TabSelectionEditorController mTabSelectionEditorController; .TabSelectionEditorController mTabSelectionEditorController;
private final int mAction; private final @TabSelectionEditorAction int mAction;
/**
* Construct {@link TabSelectionEditorActionProvider} with customized process selected tabs
* action.
* @see TabSelectionEditorActionProvider#processSelectedTabs(List, TabModelSelector).
*/
TabSelectionEditorActionProvider() {
mTabSelectionEditorController = null;
mAction = TabSelectionEditorAction.UNDEFINED_ACTION;
}
TabSelectionEditorActionProvider(TabModelSelector tabModelSelector, /**
* Construct {@link TabSelectionEditorActionProvider} with defined
* {@link TabSelectionEditorAction}.
*
* @param tabSelectionEditorController Controller that associated with the TabSelectionEditor.
* @param action {@link TabSelectionEditorAction} to provide.
*/
TabSelectionEditorActionProvider(
TabSelectionEditorCoordinator.TabSelectionEditorController tabSelectionEditorController, TabSelectionEditorCoordinator.TabSelectionEditorController tabSelectionEditorController,
@TabSelectionEditorAction int action) { @TabSelectionEditorAction int action) {
mTabModelSelector = tabModelSelector;
mTabSelectionEditorController = tabSelectionEditorController; mTabSelectionEditorController = tabSelectionEditorController;
mAction = action; mAction = action;
} }
/** /**
* Defines how to process {@code selectedTabs} based on the {@link TabSelectionEditorAction} * Defines how to process {@code selectedTabs} based on the {@link TabSelectionEditorAction}
* specified in the constructor. * specified in the constructor. If {@link TabSelectionEditorAction} is not specified, the
* caller must override this method.
* *
* @param selectedTabs The list of selected tabs to process. * @param selectedTabs The list of selected tabs to process.
* @param tabModelSelector {@link TabModelSelector} to use.
*/ */
void processSelectedTabs(List<Tab> selectedTabs) { void processSelectedTabs(List<Tab> selectedTabs, TabModelSelector tabModelSelector) {
assert mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter() assert !(mAction == TabSelectionEditorAction.GROUP)
instanceof TabGroupModelFilter; && !(mAction == TabSelectionEditorAction.UNGROUP)
|| tabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter()
instanceof TabGroupModelFilter;
switch (mAction) { switch (mAction) {
case TabSelectionEditorAction.GROUP: case TabSelectionEditorAction.GROUP:
Tab destinationTab = getDestinationTab(selectedTabs); Tab destinationTab = getDestinationTab(selectedTabs, tabModelSelector);
TabGroupModelFilter tabGroupModelFilter = TabGroupModelFilter tabGroupModelFilter =
(TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() (TabGroupModelFilter) tabModelSelector.getTabModelFilterProvider()
.getCurrentTabModelFilter(); .getCurrentTabModelFilter();
tabGroupModelFilter.mergeListOfTabsToGroup( tabGroupModelFilter.mergeListOfTabsToGroup(
selectedTabs, destinationTab, false, true); selectedTabs, destinationTab, false, true);
...@@ -67,28 +90,35 @@ class TabSelectionEditorActionProvider { ...@@ -67,28 +90,35 @@ class TabSelectionEditorActionProvider {
break; break;
case TabSelectionEditorAction.UNGROUP: case TabSelectionEditorAction.UNGROUP:
TabGroupModelFilter filter = TabGroupModelFilter filter =
(TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider() (TabGroupModelFilter) tabModelSelector.getTabModelFilterProvider()
.getCurrentTabModelFilter(); .getCurrentTabModelFilter();
for (Tab tab : selectedTabs) { for (Tab tab : selectedTabs) {
filter.moveTabOutOfGroup(tab.getId()); filter.moveTabOutOfGroup(tab.getId());
} }
mTabSelectionEditorController.hide(); mTabSelectionEditorController.hide();
break; break;
case TabSelectionEditorAction.CLOSE:
tabModelSelector.getCurrentModel().closeMultipleTabs(selectedTabs, true);
mTabSelectionEditorController.hide();
break;
case TabSelectionEditorAction.UNDEFINED_ACTION:
default: default:
assert false; assert false : "TabSelectionEditorActionProvider must override"
+ "processSelectedTab() if mAction is not pre-defined with"
+ "TabSelectionEditorAction.";
} }
} }
/** /**
* @return The {@link Tab} that has the greatest index in TabModel among the given list of tabs. * @return The {@link Tab} that has the greatest index in TabModel among the given list of tabs.
*/ */
private Tab getDestinationTab(List<Tab> tabs) { private Tab getDestinationTab(List<Tab> tabs, TabModelSelector tabModelSelector) {
int greatestIndex = TabModel.INVALID_TAB_INDEX; int greatestIndex = TabModel.INVALID_TAB_INDEX;
for (int i = 0; i < tabs.size(); i++) { for (int i = 0; i < tabs.size(); i++) {
int index = TabModelUtils.getTabIndexById( int index = TabModelUtils.getTabIndexById(
mTabModelSelector.getCurrentModel(), tabs.get(i).getId()); tabModelSelector.getCurrentModel(), tabs.get(i).getId());
greatestIndex = Math.max(index, greatestIndex); greatestIndex = Math.max(index, greatestIndex);
} }
return mTabModelSelector.getCurrentModel().getTabAt(greatestIndex); return tabModelSelector.getCurrentModel().getTabAt(greatestIndex);
} }
} }
...@@ -94,7 +94,7 @@ class TabSelectionEditorMediator ...@@ -94,7 +94,7 @@ class TabSelectionEditorMediator
} }
if (mActionProvider == null) return; if (mActionProvider == null) return;
mActionProvider.processSelectedTabs(selectedTabs); mActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector);
} }
}; };
...@@ -163,8 +163,8 @@ class TabSelectionEditorMediator ...@@ -163,8 +163,8 @@ class TabSelectionEditorMediator
mTabModelSelector.addObserver(mTabModelSelectorObserver); mTabModelSelector.addObserver(mTabModelSelectorObserver);
// Default action for action button is to group selected tabs. // Default action for action button is to group selected tabs.
mActionProvider = new TabSelectionEditorActionProvider(mTabModelSelector, this, mActionProvider = new TabSelectionEditorActionProvider(
TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP); this, TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP);
if (mPositionProvider != null) { if (mPositionProvider != null) {
mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER, mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.tasks.tab_management; package org.chromium.chrome.browser.tasks.tab_management;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
...@@ -28,6 +29,7 @@ import org.chromium.base.metrics.RecordUserAction; ...@@ -28,6 +29,7 @@ import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider; import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
...@@ -36,6 +38,7 @@ import org.chromium.testing.local.LocalRobolectricTestRunner; ...@@ -36,6 +38,7 @@ import org.chromium.testing.local.LocalRobolectricTestRunner;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* Tests for {@link TabSelectionEditorActionProvider}. * Tests for {@link TabSelectionEditorActionProvider}.
...@@ -97,11 +100,10 @@ public class TabSelectionEditorActionProviderUnitTest { ...@@ -97,11 +100,10 @@ public class TabSelectionEditorActionProviderUnitTest {
@Test @Test
public void testGroupAction() { public void testGroupAction() {
TabSelectionEditorActionProvider tabSelectionEditorActionProvider = TabSelectionEditorActionProvider tabSelectionEditorActionProvider =
new TabSelectionEditorActionProvider(mTabModelSelector, new TabSelectionEditorActionProvider(mTabSelectionEditorController,
mTabSelectionEditorController,
TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP); TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP);
List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2));
tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs); tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector);
verify(mTabGroupModelFilter) verify(mTabGroupModelFilter)
.mergeListOfTabsToGroup(eq(selectedTabs), eq(mTab2), eq(false), eq(true)); .mergeListOfTabsToGroup(eq(selectedTabs), eq(mTab2), eq(false), eq(true));
...@@ -111,17 +113,46 @@ public class TabSelectionEditorActionProviderUnitTest { ...@@ -111,17 +113,46 @@ public class TabSelectionEditorActionProviderUnitTest {
@Test @Test
public void testUngroupAction() { public void testUngroupAction() {
TabSelectionEditorActionProvider tabSelectionEditorActionProvider = TabSelectionEditorActionProvider tabSelectionEditorActionProvider =
new TabSelectionEditorActionProvider(mTabModelSelector, new TabSelectionEditorActionProvider(mTabSelectionEditorController,
mTabSelectionEditorController,
TabSelectionEditorActionProvider.TabSelectionEditorAction.UNGROUP); TabSelectionEditorActionProvider.TabSelectionEditorAction.UNGROUP);
List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2)); List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2));
tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs); tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector);
verify(mTabGroupModelFilter).moveTabOutOfGroup(TAB1_ID); verify(mTabGroupModelFilter).moveTabOutOfGroup(TAB1_ID);
verify(mTabGroupModelFilter).moveTabOutOfGroup(TAB2_ID); verify(mTabGroupModelFilter).moveTabOutOfGroup(TAB2_ID);
verify(mTabSelectionEditorController).hide(); verify(mTabSelectionEditorController).hide();
} }
@Test
public void testCloseAction() {
TabSelectionEditorActionProvider tabSelectionEditorActionProvider =
new TabSelectionEditorActionProvider(mTabSelectionEditorController,
TabSelectionEditorActionProvider.TabSelectionEditorAction.CLOSE);
List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2));
tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector);
verify(mTabModel).closeMultipleTabs(selectedTabs, true);
verify(mTabSelectionEditorController).hide();
}
@Test
public void testCustomizeAction() {
AtomicBoolean isProcessed = new AtomicBoolean();
TabSelectionEditorActionProvider tabSelectionEditorActionProvider =
new TabSelectionEditorActionProvider() {
@Override
void processSelectedTabs(
List<Tab> selectedTabs, TabModelSelector tabModelSelector) {
isProcessed.set(true);
}
};
List<Tab> selectedTabs = new ArrayList<>(Arrays.asList(mTab1, mTab2));
tabSelectionEditorActionProvider.processSelectedTabs(selectedTabs, mTabModelSelector);
assertTrue(isProcessed.get());
}
private Tab prepareTab(int id, String title) { private Tab prepareTab(int id, String title) {
Tab tab = mock(Tab.class); Tab tab = mock(Tab.class);
when(tab.getView()).thenReturn(mock(View.class)); when(tab.getView()).thenReturn(mock(View.class));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment