Commit af57f317 authored by Jinsuk Kim's avatar Jinsuk Kim Committed by Commit Bot

Duet: Delete TabGroupPopupUi code

TabGroupPopupUi-related classes are introduced for TabGroup and Duet.
This CL deletes them as Duet was sunset.

Bug: 1081343
Change-Id: I24cabbce1feb4b8aa87a8eed6f05b6e2812558c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2404285Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Reviewed-by: default avatarYue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806341}
parent 468c9f69
......@@ -74,7 +74,7 @@ specific_include_rules = {
],
# Tests and test-oriented classes are allowed to rely on ChromeActivity for DEPS. When committing
# a file that doesn't conform to these patterns, add an allow rule to the DEPS file to the
# a file that doesn't conform to these patterns, add an allow rule to the DEPS file to the
# testing directory.
".*Test\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
......@@ -131,12 +131,6 @@ specific_include_rules = {
"TasksSurfaceCoordinator\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
],
"TabGroupPopupUi\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
],
"TabGroupPopupUiCoordinator\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
],
"TabGroupUi\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
],
......
......@@ -130,11 +130,6 @@ android_library("java") {
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelProperties.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinder.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiCoordinator.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiParent.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiProperties.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiViewBinder.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditor.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import android.view.View;
import org.chromium.chrome.browser.app.ChromeActivity;
/**
* Interface for the popup TabGroup UI.
*/
public interface TabGroupPopupUi {
void initializeWithNative(ChromeActivity activity);
View.OnLongClickListener getLongClickListenerForTriggering();
void destroy();
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import android.view.View;
import org.chromium.base.Callback;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.chrome.browser.ThemeColorProvider;
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.lifecycle.Destroyable;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
/**
* A coordinator for TabStrip component as a popup window in bottom toolbar.
*/
public class TabGroupPopupUiCoordinator
implements TabGroupPopupUi, Destroyable, TabGroupPopupUiMediator.TabGroupPopUiUpdater {
private final ThemeColorProvider mThemeColorProvider;
private final ObservableSupplier<View> mAnchorViewSupplier;
private final Callback<View> mAnchorViewSupplierCallback;
private PropertyModelChangeProcessor mModelChangeProcessor;
private View mAnchorView;
private TabGroupUiCoordinator mTabGroupUiCoordinator;
private TabGroupPopupUiMediator mMediator;
private TabGroupPopupUiParent mTabGroupPopupUiParent;
TabGroupPopupUiCoordinator(
ThemeColorProvider themeColorProvider, ObservableSupplier<View> parentViewSupplier) {
mThemeColorProvider = themeColorProvider;
mAnchorViewSupplier = parentViewSupplier;
mAnchorViewSupplierCallback = this::onAnchorViewChanged;
mAnchorViewSupplier.addObserver(mAnchorViewSupplierCallback);
}
// TabGroupPopUi implementation.
@Override
// TODO(crbug.com/1022827): Narrow down the dependencies required here and in
// TabGroupUiCoordinator instead of passing in ChromeActivity.
public void initializeWithNative(ChromeActivity activity) {
PropertyModel model = new PropertyModel(TabGroupPopupUiProperties.ALL_KEYS);
mTabGroupPopupUiParent = new TabGroupPopupUiParent(activity, mAnchorView);
mTabGroupUiCoordinator = new TabGroupUiCoordinator(
mTabGroupPopupUiParent.getCurrentContainerView(), mThemeColorProvider, null);
mTabGroupUiCoordinator.initializeWithNative(activity, null);
mModelChangeProcessor = PropertyModelChangeProcessor.create(
model, mTabGroupPopupUiParent, TabGroupPopupUiViewBinder::bind);
mMediator = new TabGroupPopupUiMediator(model, activity.getTabModelSelector(),
activity.getOverviewModeBehaviorSupplier(), activity.getBrowserControlsManager(),
this, mTabGroupUiCoordinator,
BottomSheetControllerProvider.from(activity.getWindowAndroid()));
mMediator.onAnchorViewChanged(mAnchorView, mAnchorView.getId());
}
@Override
public View.OnLongClickListener getLongClickListenerForTriggering() {
return v -> {
mMediator.maybeShowTabStrip();
return true;
};
}
/**
* Destroy any members that needs clean up.
*/
@Override
public void destroy() {
if (mMediator != null) {
mMediator.destroy();
}
if (mModelChangeProcessor != null) {
mModelChangeProcessor.destroy();
}
if (mTabGroupUiCoordinator != null) {
mTabGroupUiCoordinator.destroy();
}
mAnchorViewSupplier.removeObserver(mAnchorViewSupplierCallback);
}
// TabGroupPopUiUpdater implementation.
@Override
public void updateTabGroupPopUi() {
mTabGroupPopupUiParent.updateStripWindow();
}
private void onAnchorViewChanged(View anchorView) {
if (mAnchorView == anchorView) return;
mAnchorView = anchorView;
if (mMediator == null) return;
mMediator.onAnchorViewChanged(anchorView, anchorView.getId());
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.Callback;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabCreationState;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
import org.chromium.chrome.tab_ui.R;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver;
import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver;
import org.chromium.ui.KeyboardVisibilityDelegate;
import org.chromium.ui.modelutil.PropertyModel;
import java.util.List;
/**
* A mediator for the TabGroupPopUi. Responsible for managing the
* internal state of the component.
*/
public class TabGroupPopupUiMediator {
/**
* An interface to update the size of the TabGroupPopupUi.
*/
public interface TabGroupPopUiUpdater {
/**
* Update the TabGroupPopUi.
*/
void updateTabGroupPopUi();
}
private final PropertyModel mModel;
private final TabModelObserver mTabModelObserver;
private final TabModelSelector mTabModelSelector;
private final BrowserControlsStateProvider mBrowserControlsStateProvider;
private final BrowserControlsStateProvider.Observer mBrowserControlsObserver;
private final KeyboardVisibilityDelegate.KeyboardVisibilityListener mKeyboardVisibilityListener;
private final TabGroupPopUiUpdater mUiUpdater;
private final TabGroupUiMediator.TabGroupUiController mTabGroupUiController;
private final BottomSheetController mBottomSheetController;
private final BottomSheetObserver mBottomSheetObserver;
private ObservableSupplier<OverviewModeBehavior> mOverviewModeBehaviorSupplier;
private final Callback<OverviewModeBehavior> mOverviewModeBehaviorSupplierObserver;
private final OverviewModeBehavior.OverviewModeObserver mOverviewModeObserver;
private OverviewModeBehavior mOverviewModeBehavior;
private boolean mIsOverviewModeVisible;
TabGroupPopupUiMediator(PropertyModel model, TabModelSelector tabModelSelector,
ObservableSupplier<OverviewModeBehavior> overviewModeBehaviorSupplier,
BrowserControlsStateProvider browserControlsStateProvider, TabGroupPopUiUpdater updater,
TabGroupUiMediator.TabGroupUiController controller,
BottomSheetController bottomSheetController) {
mModel = model;
mTabModelSelector = tabModelSelector;
mOverviewModeBehaviorSupplier = overviewModeBehaviorSupplier;
mBrowserControlsStateProvider = browserControlsStateProvider;
mUiUpdater = updater;
mTabGroupUiController = controller;
mBottomSheetController = bottomSheetController;
mBrowserControlsObserver = new BrowserControlsStateProvider.Observer() {
@Override
public void onControlsOffsetChanged(int topOffset, int topControlsMinHeightOffset,
int bottomOffset, int bottomControlsMinHeightOffset, boolean needsAnimate) {
// Modify the alpha the strip container view base on bottomOffset. The range of
// bottomOffset is within 0 to mIconSize.
mModel.set(TabGroupPopupUiProperties.CONTENT_VIEW_ALPHA,
1 - mBrowserControlsStateProvider.getBrowserControlHiddenRatio());
}
};
mBrowserControlsStateProvider.addObserver(mBrowserControlsObserver);
mTabModelObserver = new TabModelObserver() {
@Override
public void didSelectTab(Tab tab, int type, int lastId) {
List<Tab> tabList = mTabModelSelector.getTabModelFilterProvider()
.getCurrentTabModelFilter()
.getRelatedTabList(lastId);
if (tabList.contains(tab)) return;
if (isCurrentTabInGroup()) {
if (isTabStripShowing()) {
mUiUpdater.updateTabGroupPopUi();
} else {
maybeShowTabStrip();
}
} else {
hideTabStrip();
}
}
@Override
public void willCloseTab(Tab tab, boolean animate) {
if (!isCurrentTabInGroup()) {
hideTabStrip();
}
if (isTabStripShowing()) {
mUiUpdater.updateTabGroupPopUi();
}
}
@Override
public void didAddTab(Tab tab, int type, @TabCreationState int creationState) {
if (isTabStripShowing()) {
mUiUpdater.updateTabGroupPopUi();
return;
}
if (type != TabLaunchType.FROM_RESTORE) {
maybeShowTabStrip();
}
}
@Override
public void tabClosureUndone(Tab tab) {
if (isTabStripShowing()) {
mUiUpdater.updateTabGroupPopUi();
return;
}
maybeShowTabStrip();
}
@Override
public void restoreCompleted() {
maybeShowTabStrip();
}
};
mTabModelSelector.getTabModelFilterProvider().addTabModelFilterObserver(mTabModelObserver);
mOverviewModeObserver = new EmptyOverviewModeObserver() {
@Override
public void onOverviewModeStartedShowing(boolean showToolbar) {
mIsOverviewModeVisible = true;
hideTabStrip();
}
@Override
public void onOverviewModeFinishedHiding() {
mIsOverviewModeVisible = false;
maybeShowTabStrip();
}
};
mOverviewModeBehaviorSupplierObserver = new Callback<OverviewModeBehavior>() {
@Override
public void onResult(OverviewModeBehavior overviewModeBehavior) {
assert overviewModeBehavior != null;
mOverviewModeBehavior = overviewModeBehavior;
mOverviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver);
// TODO(crbug.com/1084528): Replace with OneShotSupplier when it is available.
mOverviewModeBehaviorSupplier.removeObserver(this);
mOverviewModeBehaviorSupplier = null;
}
};
mOverviewModeBehaviorSupplier.addObserver(mOverviewModeBehaviorSupplierObserver);
mKeyboardVisibilityListener = new KeyboardVisibilityDelegate.KeyboardVisibilityListener() {
private boolean mWasShowingStrip;
@Override
public void keyboardVisibilityChanged(boolean isShowing) {
if (isShowing) {
mWasShowingStrip = isTabStripShowing();
hideTabStrip();
} else {
if (mWasShowingStrip) {
maybeShowTabStrip();
}
}
}
};
KeyboardVisibilityDelegate.getInstance().addKeyboardVisibilityListener(
mKeyboardVisibilityListener);
mBottomSheetObserver = new EmptyBottomSheetObserver() {
private Boolean mWasShowingStrip;
@Override
public void onSheetStateChanged(int newState) {
if (newState == BottomSheetController.SheetState.HIDDEN) {
if (mWasShowingStrip != null && mWasShowingStrip) {
maybeShowTabStrip();
}
mWasShowingStrip = null;
} else {
if (mWasShowingStrip == null) {
mWasShowingStrip = isTabStripShowing();
}
hideTabStrip();
}
}
};
mBottomSheetController.addObserver(mBottomSheetObserver);
// TODO(yuezhanggg): Reset the strip with empty tab list as well.
mTabGroupUiController.setupLeftButtonOnClickListener(view -> hideTabStrip());
}
void onAnchorViewChanged(View anchorView, int anchorViewId) {
boolean isShowing = isTabStripShowing();
if (isShowing) {
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
}
// When showing bottom toolbar, the arrow on dismiss button should point down; when showing
// adaptive toolbar, the arrow on dismiss button should point up.
mTabGroupUiController.setupLeftButtonDrawable(anchorViewId == R.id.toolbar
? R.drawable.ic_expand_less_black_24dp
: R.drawable.ic_expand_more_black_24dp);
mModel.set(TabGroupPopupUiProperties.ANCHOR_VIEW, anchorView);
if (isShowing) {
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
}
}
void maybeShowTabStrip() {
if (mIsOverviewModeVisible || !isCurrentTabInGroup()) return;
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
}
private void hideTabStrip() {
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
}
private boolean isCurrentTabInGroup() {
assert mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter()
instanceof TabGroupModelFilter;
TabGroupModelFilter filter =
(TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider()
.getCurrentTabModelFilter();
Tab currentTab = mTabModelSelector.getCurrentTab();
if (currentTab == null) return false;
List<Tab> tabgroup = filter.getRelatedTabList(currentTab.getId());
return tabgroup.size() > 1;
}
private boolean isTabStripShowing() {
return mModel.get(TabGroupPopupUiProperties.IS_VISIBLE);
}
/**
* Destroy any members that needs clean up.
*/
public void destroy() {
KeyboardVisibilityDelegate.getInstance().removeKeyboardVisibilityListener(
mKeyboardVisibilityListener);
if (mOverviewModeBehavior != null) {
mOverviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver);
}
if (mOverviewModeBehaviorSupplier != null) {
mOverviewModeBehaviorSupplier.removeObserver(mOverviewModeBehaviorSupplierObserver);
}
mTabModelSelector.getTabModelFilterProvider().removeTabModelFilterObserver(
mTabModelObserver);
mBrowserControlsStateProvider.removeObserver(mBrowserControlsObserver);
mBottomSheetController.removeObserver(mBottomSheetObserver);
}
@VisibleForTesting
boolean getIsOverviewModeVisibleForTesting() {
return mIsOverviewModeVisible;
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.tab_ui.R;
import org.chromium.ui.widget.AnchoredPopupWindow;
import org.chromium.ui.widget.ViewRectProvider;
/**
* Parent for TabGroupPopUi component.
*/
public class TabGroupPopupUiParent {
private final Context mContext;
private final float mIconSize;
private AnchoredPopupWindow mTopPopupWindow;
private ViewGroup mTopStripContainerView;
private AnchoredPopupWindow mBottomPopupWindow;
private ViewGroup mBottomStripContainerView;
private AnchoredPopupWindow mCurrentPopupWindow;
private ViewGroup mCurrentStripContainerView;
private boolean mIsShowingTopToolbar;
TabGroupPopupUiParent(Context context, View anchorView) {
mContext = context;
mIconSize = context.getResources().getDimension(R.dimen.infobar_big_icon_size);
onAnchorViewChanged(anchorView, anchorView.getId());
}
void onAnchorViewChanged(View anchorView, int anchorViewId) {
ViewGroup previousContainerView = mCurrentStripContainerView;
mIsShowingTopToolbar = anchorViewId == R.id.toolbar;
if (mIsShowingTopToolbar) {
if (mTopPopupWindow == null) {
mTopStripContainerView = new FrameLayout(mContext);
mTopPopupWindow = createTabGroupPopUi(anchorView, true);
}
mCurrentPopupWindow = mTopPopupWindow;
mCurrentStripContainerView = mTopStripContainerView;
} else {
if (mBottomPopupWindow == null) {
mBottomStripContainerView = new FrameLayout(mContext);
mBottomPopupWindow = createTabGroupPopUi(anchorView, false);
}
mCurrentPopupWindow = mBottomPopupWindow;
mCurrentStripContainerView = mBottomStripContainerView;
}
if (previousContainerView == null) return;
// Transfer the ownership of the tab strip view.
View contentView = previousContainerView.getChildAt(0);
assert contentView != null;
previousContainerView.removeViewAt(0);
mCurrentStripContainerView.addView(contentView);
}
private AnchoredPopupWindow createTabGroupPopUi(View anchorView, boolean isTop) {
ViewGroup stripContainerView = isTop ? mTopStripContainerView : mBottomStripContainerView;
assert stripContainerView != null;
ViewRectProvider rectProvider = new ViewRectProvider(anchorView);
AnchoredPopupWindow popupWindow = new AnchoredPopupWindow(mContext, anchorView,
ApiCompatibilityUtils.getDrawable(
mContext.getResources(), R.drawable.popup_bg_tinted),
stripContainerView, rectProvider) {
@Override
public void onRectHidden() {}
};
popupWindow.setHorizontalOverlapAnchor(true);
popupWindow.setOutsideTouchable(true);
popupWindow.setDismissOnTouchInteraction(false);
popupWindow.setFocusable(false);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupWindow.setPreferredVerticalOrientation(isTop
? AnchoredPopupWindow.VerticalOrientation.BELOW
: AnchoredPopupWindow.VerticalOrientation.ABOVE);
stripContainerView.setBackground(ApiCompatibilityUtils.getDrawable(
mContext.getResources(), R.drawable.popup_bg_tinted));
if (isTop) {
rectProvider.setInsetPx(0, (int) mIconSize, 0, (int) mIconSize);
} else {
rectProvider.setInsetPx(0, (int) mIconSize / 2, 0, (int) mIconSize / 2);
}
return popupWindow;
}
void updateStripWindow() {
if (mCurrentPopupWindow == null) return;
Handler handler = new Handler();
handler.post(() -> mCurrentPopupWindow.onRectChanged());
}
void setVisibility(boolean isVisible) {
if (isVisible) {
mCurrentPopupWindow.show();
} else {
mCurrentPopupWindow.dismiss();
}
}
ViewGroup getCurrentContainerView() {
assert mCurrentStripContainerView != null;
return mCurrentStripContainerView;
}
void setContentViewAlpha(float alpha) {
if (mCurrentStripContainerView == null) return;
mCurrentStripContainerView.setAlpha(alpha);
}
@VisibleForTesting
AnchoredPopupWindow getCurrentPopupWindowForTesting() {
return mCurrentPopupWindow;
}
@VisibleForTesting
ViewGroup getCurrentStripContainerViewForTesting() {
return getCurrentContainerView();
}
@VisibleForTesting
ViewGroup getTopStripContainerViewForTesting() {
return mTopStripContainerView;
}
@VisibleForTesting
ViewGroup getBottomStripContainerViewForTesting() {
return mBottomStripContainerView;
}
}
\ No newline at end of file
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import android.view.View;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
/**
* {@link PropertyKey} list for the TabGroupPopupUi.
*/
class TabGroupPopupUiProperties {
public static final PropertyModel.WritableBooleanPropertyKey IS_VISIBLE =
new PropertyModel.WritableBooleanPropertyKey();
public static final PropertyModel.WritableObjectPropertyKey<View> ANCHOR_VIEW =
new PropertyModel.WritableObjectPropertyKey<>();
public static final PropertyModel.WritableFloatPropertyKey CONTENT_VIEW_ALPHA =
new PropertyModel.WritableFloatPropertyKey();
public static final PropertyKey[] ALL_KEYS =
new PropertyKey[] {IS_VISIBLE, ANCHOR_VIEW, CONTENT_VIEW_ALPHA};
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupPopupUiProperties.ANCHOR_VIEW;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupPopupUiProperties.CONTENT_VIEW_ALPHA;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupPopupUiProperties.IS_VISIBLE;
import android.view.View;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
/**
* ViewBinder for TabGroupPopupUi.
*/
class TabGroupPopupUiViewBinder {
/**
* Binds the given model to the given view, updating the payload in propertyKey.
*
* @param model The model to use.
* @param view The view to use.
* @param propertyKey The key for the property to update for.
*/
public static void bind(
PropertyModel model, TabGroupPopupUiParent view, PropertyKey propertyKey) {
if (IS_VISIBLE == propertyKey) {
view.setVisibility(model.get(IS_VISIBLE));
} else if (CONTENT_VIEW_ALPHA == propertyKey) {
view.setContentViewAlpha(model.get(CONTENT_VIEW_ALPHA));
} else if (ANCHOR_VIEW == propertyKey) {
View anchorView = model.get(ANCHOR_VIEW);
view.onAnchorViewChanged(anchorView, anchorView.getId());
}
}
}
......@@ -5,7 +5,6 @@
package org.chromium.chrome.browser.tasks.tab_management;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.IntDef;
......@@ -128,14 +127,4 @@ public interface TabManagementDelegate {
* @return the {@link TabSuggestions} for the activity
*/
TabSuggestions createTabSuggestions(ChromeActivity activity);
/**
* Create the {@link TabGroupPopupUi}.
* @param themeColorProvider The {@link ThemeColorProvider} for this UI.
* @param parentViewSupplier The {@link ObservableSupplier} that provides parent view of this
* component.
* @return The {@link TabGroupPopupUi}.
*/
TabGroupPopupUi createTabGroupPopUi(
ThemeColorProvider themeColorProvider, ObservableSupplier<View> parentViewSupplier);
}
......@@ -7,7 +7,6 @@ package org.chromium.chrome.browser.tasks.tab_management;
import static org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider.SYNTHETIC_TRIAL_POSTFIX;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.base.SysUtils;
......@@ -108,10 +107,4 @@ public class TabManagementDelegateImpl implements TabManagementDelegate {
return new TabSuggestionsOrchestrator(
activity.getTabModelSelector(), activity.getLifecycleDispatcher());
}
@Override
public TabGroupPopupUi createTabGroupPopUi(
ThemeColorProvider themeColorProvider, ObservableSupplier<View> parentViewSupplier) {
return new TabGroupPopupUiCoordinator(themeColorProvider, parentViewSupplier);
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.UiThreadTest;
import org.chromium.chrome.browser.toolbar.top.ToolbarPhone;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import org.chromium.ui.test.util.DummyUiActivityTestCase;
import org.chromium.ui.widget.AnchoredPopupWindow;
/**
* Tests for {@link TabGroupPopupUiViewBinder}.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
public class TabGroupPopupUiViewBinderTest extends DummyUiActivityTestCase {
private ToolbarPhone mTopAnchorView;
private FrameLayout mBottomAnchorView;
private TabGroupPopupUiParent mParent;
private PropertyModel mModel;
private PropertyModelChangeProcessor mMCP;
@Override
public void setUpTest() throws Exception {
super.setUpTest();
TestThreadUtils.runOnUiThreadBlocking(() -> {
mTopAnchorView = new ToolbarPhone(getActivity(), null);
mTopAnchorView.setId(R.id.toolbar);
mBottomAnchorView = new FrameLayout(getActivity());
mParent = new TabGroupPopupUiParent(getActivity(), mTopAnchorView);
mModel = new PropertyModel(TabGroupPopupUiProperties.ALL_KEYS);
mMCP = PropertyModelChangeProcessor.create(
mModel, mParent, TabGroupPopupUiViewBinder::bind);
});
}
@Override
public void tearDownTest() throws Exception {
TestThreadUtils.runOnUiThreadBlocking(mMCP::destroy);
super.tearDownTest();
}
@Test
@UiThreadTest
@SmallTest
public void testSetVisibility() {
AnchoredPopupWindow popupWindow = mParent.getCurrentPopupWindowForTesting();
assertNotNull(popupWindow);
assertFalse(popupWindow.isShowing());
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
assertTrue(popupWindow.isShowing());
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
assertFalse(popupWindow.isShowing());
}
@Test
@UiThreadTest
@SmallTest
public void testSetContentViewAlpha() {
ViewGroup containerView = mParent.getCurrentStripContainerViewForTesting();
assertNotNull(containerView);
assertEquals(1f, containerView.getAlpha(), 0);
mModel.set(TabGroupPopupUiProperties.CONTENT_VIEW_ALPHA, 0.5f);
assertEquals(0.5f, containerView.getAlpha(), 0);
mModel.set(TabGroupPopupUiProperties.CONTENT_VIEW_ALPHA, 0.25f);
assertEquals(0.25f, containerView.getAlpha(), 0);
}
@Test
@UiThreadTest
@SmallTest
public void testSetAnchorView() {
ViewGroup topContainerView;
ViewGroup bottomContainerView;
// Assume initial anchor view is top toolbar, and components for bottom toolbar is not
// initialized.
topContainerView = mParent.getTopStripContainerViewForTesting();
bottomContainerView = mParent.getBottomStripContainerViewForTesting();
assertEquals(topContainerView, mParent.getCurrentStripContainerViewForTesting());
assertNull(bottomContainerView);
// Create a dummy view representing the strip component and add it to the current container
// view.
FrameLayout contentView = new FrameLayout(getActivity());
mParent.getCurrentStripContainerViewForTesting().addView(contentView);
// Change anchor view from the top toolbar to the bottom toolbar.
mModel.set(TabGroupPopupUiProperties.ANCHOR_VIEW, mBottomAnchorView);
// Check that components related to bottom anchor view are initialized. Also, the ownership
// of the content view should be given to the bottom strip container.
topContainerView = mParent.getTopStripContainerViewForTesting();
bottomContainerView = mParent.getBottomStripContainerViewForTesting();
assertNotNull(bottomContainerView);
assertEquals(bottomContainerView, mParent.getCurrentStripContainerViewForTesting());
assertEquals(0, topContainerView.getChildCount());
assertEquals(1, bottomContainerView.getChildCount());
assertEquals(contentView, bottomContainerView.getChildAt(0));
// Change anchor view from the bottom toolbar to the top toolbar.
mModel.set(TabGroupPopupUiProperties.ANCHOR_VIEW, mTopAnchorView);
// Check the ownership of the content view should be given back to top strip container.
topContainerView = mParent.getTopStripContainerViewForTesting();
bottomContainerView = mParent.getBottomStripContainerViewForTesting();
assertNotNull(topContainerView);
assertNotNull(bottomContainerView);
assertEquals(topContainerView, mParent.getCurrentStripContainerViewForTesting());
assertEquals(1, topContainerView.getChildCount());
assertEquals(0, bottomContainerView.getChildCount());
assertEquals(contentView, topContainerView.getChildAt(0));
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tasks.tab_management;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.widget.FrameLayout;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabCreationState;
import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData;
import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider;
import org.chromium.chrome.browser.tabmodel.TabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
import org.chromium.chrome.browser.toolbar.top.ToolbarPhone;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver;
import org.chromium.testing.local.LocalRobolectricTestRunner;
import org.chromium.ui.KeyboardVisibilityDelegate;
import org.chromium.ui.modelutil.PropertyModel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Tests for {@link TabGroupPopupUiMediator}.
*/
@SuppressWarnings({"ResultOfMethodCallIgnored", "ArraysAsListWithZeroOrOneArgument"})
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class TabGroupPopupUiMediatorUnitTest {
@Rule
public TestRule mProcessor = new Features.JUnitProcessor();
private static final String TAB1_TITLE = "Tab1";
private static final String TAB2_TITLE = "Tab2";
private static final String TAB3_TITLE = "Tab3";
private static final String TAB4_TITLE = "Tab4";
private static final int TAB1_ID = 456;
private static final int TAB2_ID = 789;
private static final int TAB3_ID = 123;
private static final int TAB4_ID = 357;
@Mock
TabModelSelectorImpl mTabModelSelector;
@Mock
OverviewModeBehavior mOverviewModeBehavior;
@Mock
BrowserControlsStateProvider mBrowserControlsStateProvider;
@Mock
TabGroupPopupUiMediator.TabGroupPopUiUpdater mUpdater;
@Mock
TabGroupUiMediator.TabGroupUiController mTabGroupUiController;
@Mock
TabModelFilterProvider mTabModelFilterProvider;
@Mock
TabGroupModelFilter mTabGroupModelFilter;
@Mock
KeyboardVisibilityDelegate mKeyboardVisibilityDelegate;
@Mock
ToolbarPhone mTopAnchorView;
@Mock
FrameLayout mBottomAnchorView;
@Mock
BottomSheetController mBottomSheetController;
@Captor
ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor;
@Captor
private ArgumentCaptor<BrowserControlsStateProvider.Observer>
mBrowserControlsStateProviderObserverCaptor;
@Captor
ArgumentCaptor<OverviewModeBehavior.OverviewModeObserver> mOverviewModeObserverCaptor;
@Captor
ArgumentCaptor<KeyboardVisibilityDelegate.KeyboardVisibilityListener>
mKeyboardVisibilityListenerCaptor;
@Captor
ArgumentCaptor<BottomSheetObserver> mBottomSheetObserver;
private TabImpl mTab1;
private TabImpl mTab2;
private TabImpl mTab3;
private PropertyModel mModel;
private TabGroupPopupUiMediator mMediator;
private ObservableSupplierImpl<OverviewModeBehavior> mOverviewModeBehaviorSupplier =
new ObservableSupplierImpl<>();
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTab1 = prepareTab(TAB1_ID, TAB1_TITLE);
mTab2 = prepareTab(TAB2_ID, TAB2_TITLE);
mTab3 = prepareTab(TAB3_ID, TAB3_TITLE);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
doReturn(mTabModelFilterProvider).when(mTabModelSelector).getTabModelFilterProvider();
doReturn(mTabGroupModelFilter).when(mTabModelFilterProvider).getCurrentTabModelFilter();
doNothing()
.when(mTabModelFilterProvider)
.addTabModelFilterObserver(mTabModelObserverCaptor.capture());
doNothing()
.when(mBrowserControlsStateProvider)
.addObserver(mBrowserControlsStateProviderObserverCaptor.capture());
doNothing()
.when(mOverviewModeBehavior)
.addOverviewModeObserver(mOverviewModeObserverCaptor.capture());
doNothing()
.when(mKeyboardVisibilityDelegate)
.addKeyboardVisibilityListener(mKeyboardVisibilityListenerCaptor.capture());
doNothing().when(mBottomSheetController).addObserver(mBottomSheetObserver.capture());
mOverviewModeBehaviorSupplier.set(mOverviewModeBehavior);
KeyboardVisibilityDelegate.setInstance(mKeyboardVisibilityDelegate);
mModel = new PropertyModel(TabGroupPopupUiProperties.ALL_KEYS);
mMediator = new TabGroupPopupUiMediator(mModel, mTabModelSelector,
mOverviewModeBehaviorSupplier, mBrowserControlsStateProvider, mUpdater,
mTabGroupUiController, mBottomSheetController);
}
@Test
public void testOnControlOffsetChanged() {
mModel.set(TabGroupPopupUiProperties.CONTENT_VIEW_ALPHA, 0f);
// Mock that the hidden ratio of browser control is 0.8765.
float hiddenRatio = 0.8765f;
doReturn(hiddenRatio).when(mBrowserControlsStateProvider).getBrowserControlHiddenRatio();
mBrowserControlsStateProviderObserverCaptor.getValue().onControlsOffsetChanged(
0, 0, 0, 0, false);
assertThat(
mModel.get(TabGroupPopupUiProperties.CONTENT_VIEW_ALPHA), equalTo(1 - hiddenRatio));
// Mock that the hidden ratio of browser control is 0.12345.
hiddenRatio = 0.1234f;
doReturn(hiddenRatio).when(mBrowserControlsStateProvider).getBrowserControlHiddenRatio();
mBrowserControlsStateProviderObserverCaptor.getValue().onControlsOffsetChanged(
0, 0, 0, 0, false);
assertThat(
mModel.get(TabGroupPopupUiProperties.CONTENT_VIEW_ALPHA), equalTo(1 - hiddenRatio));
}
@Test
public void tabSelection_Show() {
// Mock that the strip is hidden.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 and tab2 are in the same group, and tab 3 is a single tab.
createTabGroup(new ArrayList<>(Arrays.asList(mTab1, mTab2)), TAB1_ID);
createTabGroup(new ArrayList<>(Arrays.asList(mTab3)), TAB3_ID);
doReturn(mTab2).when(mTabModelSelector).getCurrentTab();
mTabModelObserverCaptor.getValue().didSelectTab(
mTab2, TabLaunchType.FROM_CHROME_UI, TAB3_ID);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabSelection_Hide() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1 and tab2 are in the same group, and tab 3 is a single tab.
createTabGroup(new ArrayList<>(Arrays.asList(mTab1, mTab2)), TAB1_ID);
createTabGroup(new ArrayList<>(Arrays.asList(mTab3)), TAB3_ID);
doReturn(mTab3).when(mTabModelSelector).getCurrentTab();
mTabModelObserverCaptor.getValue().didSelectTab(
mTab3, TabLaunchType.FROM_CHROME_UI, TAB1_ID);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabSelection_Update() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1 and tab2 are in the same group, tab3 and new tab are in the same group.
createTabGroup(new ArrayList<>(Arrays.asList(mTab1, mTab2)), TAB1_ID);
createTabGroup(
new ArrayList<>(Arrays.asList(mTab3, prepareTab(TAB4_ID, TAB4_TITLE))), TAB3_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mTabModelObserverCaptor.getValue().didSelectTab(
mTab1, TabLaunchType.FROM_CHROME_UI, TAB3_ID);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater).updateTabGroupPopUi();
}
@Test
public void tabSelection_SameGroup() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1 and tab2 are in the same group.
createTabGroup(new ArrayList<>(Arrays.asList(mTab1, mTab2)), TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mTabModelObserverCaptor.getValue().didSelectTab(
mTab1, TabLaunchType.FROM_CHROME_UI, TAB2_ID);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabClosure_Hide() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1 and tab2 are in the same group, and tab1 is closing.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab2));
doReturn(tabGroup).when(mTabGroupModelFilter).getRelatedTabList(TAB1_ID);
doReturn(tabGroup).when(mTabGroupModelFilter).getRelatedTabList(TAB2_ID);
mTabModelObserverCaptor.getValue().willCloseTab(mTab1, false);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabClosure_Update() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1, tab2 and tab3 are in the same group, and tab1 is closing.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab2, mTab3));
doReturn(tabGroup).when(mTabGroupModelFilter).getRelatedTabList(TAB1_ID);
doReturn(tabGroup).when(mTabGroupModelFilter).getRelatedTabList(TAB2_ID);
doReturn(tabGroup).when(mTabGroupModelFilter).getRelatedTabList(TAB3_ID);
mTabModelObserverCaptor.getValue().willCloseTab(mTab1, false);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater).updateTabGroupPopUi();
}
@Test
public void tabAddition_Show() {
// Mock that the strip is hidden.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 and tab2 are in the same group, and tab2 has just been created.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
mTabModelObserverCaptor.getValue().didAddTab(
mTab2, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabAddition_Update() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1, tab2 and tab3 are in the same group, and tab3 has just been created.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3));
createTabGroup(tabGroup, TAB1_ID);
mTabModelObserverCaptor.getValue().didAddTab(
mTab3, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater).updateTabGroupPopUi();
}
@Test
public void tabAddition_NotShow_Restore() {
// Mock that the strip is hidden.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 and tab2 are in the same group, and they are being restored.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
mTabModelObserverCaptor.getValue().didAddTab(
mTab2, TabLaunchType.FROM_RESTORE, TabCreationState.FROZEN_ON_RESTORE);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabClosureUndone_Show() {
// Mock that the strip is hiding.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 and tab2 are in the same group, and we have just undone the closure of
// tab2.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
mTabModelObserverCaptor.getValue().tabClosureUndone(mTab2);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabClosureUndone_Update() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1, tab2 and tab3 are in the same group, and we have just undone the closure
// of tab3.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3));
createTabGroup(tabGroup, TAB1_ID);
mTabModelObserverCaptor.getValue().tabClosureUndone(mTab3);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
verify(mUpdater).updateTabGroupPopUi();
}
@Test
public void tabClosureUndone_NotShow() {
// Mock that the strip is hiding.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 is a single tab.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1));
createTabGroup(tabGroup, TAB1_ID);
mTabModelObserverCaptor.getValue().tabClosureUndone(mTab1);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
verify(mUpdater, never()).updateTabGroupPopUi();
}
@Test
public void tabRestoreCompletion_NotShow() {
// Mock that the strip is hiding.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 is the current tab and it is a single tab.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mTabModelObserverCaptor.getValue().restoreCompleted();
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void tabRestoreCompletion_Show() {
// Mock that the strip is hiding.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 is the current tab and it is in a group of {tab1, tab2}.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mTabModelObserverCaptor.getValue().restoreCompleted();
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void testOverviewModeHiding() {
// Mock that the strip is hiding.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 and tab2 are in the same group, and tab1 is the current tab.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mOverviewModeObserverCaptor.getValue().onOverviewModeFinishedHiding();
assertThat(mMediator.getIsOverviewModeVisibleForTesting(), equalTo(false));
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void testOverviewModeShowing() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Mock that tab1 and tab2 are in the same group, and tab1 is the current tab.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
mOverviewModeObserverCaptor.getValue().onOverviewModeStartedShowing(true);
assertThat(mMediator.getIsOverviewModeVisibleForTesting(), equalTo(true));
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testNeverShowStripWhenOverviewVisible() {
// Mock that the strip is hiding and overview is visible.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
mOverviewModeObserverCaptor.getValue().onOverviewModeStartedShowing(true);
assertThat(mMediator.getIsOverviewModeVisibleForTesting(), equalTo(true));
// Calling maybeShowTabStrip should never show strip in this case.
mMediator.maybeShowTabStrip();
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testNeverShowStripWhenSingleTab() {
// Mock that the strip is hiding and overview is visible.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
// Mock that tab1 is the current tab and it is a single tab.
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
// Calling maybeShowTabStrip should never show strip in this case.
mMediator.maybeShowTabStrip();
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testShowKeyboard_HideStrip() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
mKeyboardVisibilityListenerCaptor.getValue().keyboardVisibilityChanged(true);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testHideKeyboard_ShowStrip() {
// Mock that the strip is showing before showing the keyboard. tab1 and tab2 are in the same
// group, and tab1 is the current tab.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
// Hide the keyboard after showing it.
mKeyboardVisibilityListenerCaptor.getValue().keyboardVisibilityChanged(true);
mKeyboardVisibilityListenerCaptor.getValue().keyboardVisibilityChanged(false);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void testHideKeyboard_NotReshowStrip() {
// Mock that the strip is hidden before showing the keyboard. tab1 and tab2 are in the same
// group, and tab1 is the current tab.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
// Hide the keyboard after showing it.
mKeyboardVisibilityListenerCaptor.getValue().keyboardVisibilityChanged(true);
mKeyboardVisibilityListenerCaptor.getValue().keyboardVisibilityChanged(false);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testShowBottomSheet_HideStrip() {
// Mock that the strip is showing.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
// Show bottom sheet.
mBottomSheetObserver.getValue().onSheetStateChanged(BottomSheetController.SheetState.PEEK);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testHideBottomSheet_ShowStrip() {
// Mock that the strip is showing before showing the bottom sheet. tab1 and tab2 are in the
// same group, and tab1 is the current tab.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
// Hide the bottom sheet after showing it.
mBottomSheetObserver.getValue().onSheetStateChanged(BottomSheetController.SheetState.PEEK);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
mBottomSheetObserver.getValue().onSheetStateChanged(
BottomSheetController.SheetState.HIDDEN);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true));
}
@Test
public void testHideBottomSheet_NotReshowStrip() {
// Mock that the strip is hidden before showing the bottom sheet. tab1 and tab2 are in the
// same group, and tab1 is the current tab.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, false);
List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2));
createTabGroup(tabGroup, TAB1_ID);
doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
// Hide the bottom sheet after showing it.
mBottomSheetObserver.getValue().onSheetStateChanged(BottomSheetController.SheetState.PEEK);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
mBottomSheetObserver.getValue().onSheetStateChanged(
BottomSheetController.SheetState.HIDDEN);
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testAnchorViewChange_TopToolbar() {
mMediator.onAnchorViewChanged(mTopAnchorView, R.id.toolbar);
assertThat(mModel.get(TabGroupPopupUiProperties.ANCHOR_VIEW), equalTo(mTopAnchorView));
verify(mTabGroupUiController)
.setupLeftButtonDrawable(eq(R.drawable.ic_expand_less_black_24dp));
}
@Test
public void testAnchorViewChange_BottomToolbar() {
mMediator.onAnchorViewChanged(mBottomAnchorView, R.id.bottom_controls);
assertThat(mModel.get(TabGroupPopupUiProperties.ANCHOR_VIEW), equalTo(mBottomAnchorView));
verify(mTabGroupUiController)
.setupLeftButtonDrawable(eq(R.drawable.ic_expand_more_black_24dp));
}
@Test
public void testAnchorViewChange_WithStripShowing() {
// Mock that strip is showing when anchor view changes.
mModel.set(TabGroupPopupUiProperties.IS_VISIBLE, true);
mMediator.onAnchorViewChanged(mBottomAnchorView, R.id.bottom_controls);
assertTrue(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE));
assertThat(mModel.get(TabGroupPopupUiProperties.ANCHOR_VIEW), equalTo(mBottomAnchorView));
verify(mTabGroupUiController)
.setupLeftButtonDrawable(eq(R.drawable.ic_expand_more_black_24dp));
}
@Test
public void testNoCurrentTab_NotShow() {
// Mock overview mode is hiding, and current tab is null.
doReturn(null).when(mTabModelSelector).getCurrentTab();
mOverviewModeObserverCaptor.getValue().onOverviewModeFinishedHiding();
assertThat(mMediator.getIsOverviewModeVisibleForTesting(), equalTo(false));
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
mMediator.maybeShowTabStrip();
assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false));
}
@Test
public void testDestroy() {
mMediator.destroy();
verify(mKeyboardVisibilityDelegate)
.removeKeyboardVisibilityListener(mKeyboardVisibilityListenerCaptor.capture());
verify(mOverviewModeBehavior)
.removeOverviewModeObserver(mOverviewModeObserverCaptor.capture());
verify(mTabModelFilterProvider)
.removeTabModelFilterObserver(mTabModelObserverCaptor.capture());
verify(mBrowserControlsStateProvider)
.removeObserver(mBrowserControlsStateProviderObserverCaptor.capture());
}
// TODO(yuezhanggg): Pull methods below to a utility class.
private TabImpl prepareTab(int id, String title) {
TabImpl tab = TabUiUnitTestUtils.prepareTab(id, title, "");
doReturn(true).when(tab).isIncognito();
return tab;
}
private void createTabGroup(List<Tab> tabs, int rootId) {
for (Tab tab : tabs) {
when(mTabGroupModelFilter.getRelatedTabList(tab.getId())).thenReturn(tabs);
CriticalPersistedTabData criticalPersistedTabData = CriticalPersistedTabData.from(tab);
doReturn(rootId).when(criticalPersistedTabData).getRootId();
}
}
}
......@@ -13,7 +13,6 @@ public_tab_management_java_sources = [
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_groups/EmptyTabGroupModelFilterObserver.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUi.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java",
......@@ -43,7 +42,6 @@ tab_management_test_java_sources = [
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiViewBinderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiViewBinderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerViewBinderTest.java",
......@@ -70,7 +68,6 @@ tab_management_junit_java_sources = [
"//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediatorUnitTest.java",
"//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java",
"//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java",
"//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java",
"//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupTitleEditorUnitTest.java",
"//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java",
"//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java",
......
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