Commit 128ef328 authored by Matt Jones's avatar Matt Jones Committed by Commit Bot

Convert the ToolbarSceneLayer to MVC

This patch converts the toolbar's composited texture and logic into
its own MVC component. The ToolbarSceneLayer has become the "view" of
the new component and is now TopToolbarSceneLayer. All classes related
to the component live in .../browser/compositor/overlays/toolbar. This
patch also adds a small suite of unit tests.

Bug: 1100332
Change-Id: If34fef9378a7b64524e6eb31e381c48b636a94aa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302853
Commit-Queue: Matthew Jones <mdjones@chromium.org>
Reviewed-by: default avatarMei Liang <meiliang@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796499}
parent a23127d5
......@@ -2954,6 +2954,7 @@ generate_jni("chrome_jni_headers") {
"java/src/org/chromium/chrome/browser/compositor/LayerTitleCache.java",
"java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java",
"java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java",
"java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/resources/ResourceFactory.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneLayer.java",
......@@ -2961,7 +2962,6 @@ generate_jni("chrome_jni_headers") {
"java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java",
"java/src/org/chromium/chrome/browser/consent_auditor/ConsentAuditorBridge.java",
"java/src/org/chromium/chrome/browser/content/ContentUtils.java",
"java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java",
......
......@@ -329,6 +329,10 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java",
"java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStacker.java",
"java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabLoadTracker.java",
"java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayCoordinator.java",
"java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediator.java",
"java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayProperties.java",
"java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/resources/ResourceFactory.java",
"java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java",
......@@ -338,7 +342,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java",
"java/src/org/chromium/chrome/browser/consent_auditor/ConsentAuditorBridge.java",
"java/src/org/chromium/chrome/browser/contacts_picker/CompressContactIconsWorkerTask.java",
"java/src/org/chromium/chrome/browser/contacts_picker/ContactDetails.java",
......
......@@ -50,6 +50,7 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutUpdateHost.java",
"junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java",
"junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java",
"junit/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediatorTest.java",
"junit/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinatorTest.java",
"junit/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuHeaderMediatorTest.java",
"junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContextTest.java",
......
......@@ -18,6 +18,7 @@ import androidx.annotation.VisibleForTesting;
import org.chromium.base.ObserverList;
import org.chromium.base.TraceEvent;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils;
import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager;
......@@ -33,9 +34,10 @@ import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler;
import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
import org.chromium.chrome.browser.compositor.overlays.SceneOverlay;
import org.chromium.chrome.browser.compositor.overlays.toolbar.TopToolbarOverlayCoordinator;
import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
import org.chromium.chrome.browser.compositor.scene_layer.ToolbarSceneLayer;
import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
import org.chromium.chrome.browser.device.DeviceClassManager;
import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
import org.chromium.chrome.browser.native_page.NativePageFactory;
import org.chromium.chrome.browser.tab.SadTab;
......@@ -81,6 +83,12 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
/** The {@link LayoutManagerHost}, who is responsible for showing the active {@link Layout}. */
protected final LayoutManagerHost mHost;
/**
* A means of notifying features that the browser controls' android view is being forced to
* hide.
*/
private final ObservableSupplierImpl<Boolean> mAndroidViewShownSupplier;
/** The last X coordinate of the last {@link MotionEvent#ACTION_DOWN} event. */
protected int mLastTapX;
......@@ -119,7 +127,7 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
private boolean mUpdateRequested;
private ContextualSearchPanel mContextualSearchPanel;
private final OverlayPanelManager mOverlayPanelManager;
private ToolbarSceneLayer mToolbarOverlay;
private TopToolbarOverlayCoordinator mToolbarOverlay;
private SceneOverlay mStatusIndicatorSceneOverlay;
/** A delegate for interacting with the Contextual Search manager. */
......@@ -149,7 +157,7 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
* TabModelObserver#didCloseTab is triggered for Toolbar overlay to have a chance
* to retrieve the right textbox color from it.
*/
private Tab mCurrentTab;
private ObservableSupplierImpl<Tab> mCurrentTabSupplier;
private final ObservableSupplierImpl<TabModelSelector> mTabModelSelectorSupplier =
new ObservableSupplierImpl<>();
......@@ -170,7 +178,7 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
} else if (tab.getId() != lastId) {
tabSelected(tab.getId(), lastId, tab.isIncognito());
}
mCurrentTab = tab;
mCurrentTabSupplier.set(tab);
}
@Override
......@@ -213,8 +221,8 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
@Override
public void didCloseTab(int tabId, boolean incognito) {
tabClosed(tabId, incognito, false);
mCurrentTab =
getTabModelSelector() != null ? getTabModelSelector().getCurrentTab() : null;
mCurrentTabSupplier.set(
getTabModelSelector() != null ? getTabModelSelector().getCurrentTab() : null);
}
@Override
......@@ -240,6 +248,9 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
public LayoutManager(LayoutManagerHost host) {
mHost = host;
mPxToDp = 1.f / mHost.getContext().getResources().getDisplayMetrics().density;
mAndroidViewShownSupplier = new ObservableSupplierImpl<>();
mAndroidViewShownSupplier.set(true);
mCurrentTabSupplier = new ObservableSupplierImpl<>();
mContext = host.getContext();
LayoutRenderHost renderHost = host.getLayoutRenderHost();
......@@ -411,11 +422,19 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
ContextualSearchManagementDelegate contextualSearchDelegate,
DynamicResourceLoader dynamicResourceLoader) {
LayoutRenderHost renderHost = mHost.getLayoutRenderHost();
mToolbarOverlay = new ToolbarSceneLayer(mContext, this, renderHost, controlContainer,
() -> mCurrentTab, getBrowserControlsManager(),
() -> getActiveLayout() != null
? getActiveLayout().getViewportMode()
: Layout.ViewportMode.USE_PREVIOUS_BROWSER_CONTROLS_STATE);
mCurrentTabSupplier.set(selector.getCurrentTab());
// If fullscreen is disabled, don't bother creating this overlay; only the android view will
// ever be shown.
if (DeviceClassManager.enableFullscreen()) {
Supplier<Integer> viewportModeSupplier = ()
-> getActiveLayout() != null ? getActiveLayout().getViewportMode()
: Layout.ViewportMode.ALWAYS_FULLSCREEN;
mToolbarOverlay = new TopToolbarOverlayCoordinator(mContext, mFrameRequestSupplier,
this, controlContainer, mCurrentTabSupplier, getBrowserControlsManager(),
viewportModeSupplier, mAndroidViewShownSupplier,
() -> renderHost.getResourceManager());
}
// Initialize Layouts
mStaticLayout.onFinishNativeInitialization();
......@@ -456,7 +475,7 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
public void setTabModelSelector(TabModelSelector selector) {
mTabModelSelector = selector;
mTabModelSelectorSupplier.set(selector);
mCurrentTab = selector.getCurrentTab();
mCurrentTabSupplier.set(selector.getCurrentTab());
mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(mTabModelSelector) {
@Override
public void onShown(Tab tab, @TabSelectionType int type) {
......@@ -504,6 +523,7 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
* Cleans up and destroys this object. It should not be used after this.
*/
public void destroy() {
if (mToolbarOverlay != null) mToolbarOverlay.destroy();
mAnimationHandler.destroy();
mSceneChangeObservers.clear();
if (mStaticLayout != null) mStaticLayout.destroy();
......@@ -516,7 +536,7 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
getTabModelSelector().getTabModelFilterProvider().removeTabModelFilterObserver(
mTabModelFilterObserver);
}
mCurrentTab = null;
mCurrentTabSupplier.set(null);
}
/**
......@@ -552,8 +572,10 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
if (mActiveLayout.forceHideBrowserControlsAndroidView()) {
mControlsHidingToken = controlsVisibilityManager.hideAndroidControlsAndClearOldToken(
mControlsHidingToken);
mAndroidViewShownSupplier.set(false);
} else {
controlsVisibilityManager.releaseAndroidControlsHidingToken(mControlsHidingToken);
mAndroidViewShownSupplier.set(true);
}
}
......
// Copyright 2020 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.compositor.overlays.toolbar;
import android.content.Context;
import android.graphics.RectF;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.compositor.LayerTitleCache;
import org.chromium.chrome.browser.compositor.layouts.CompositorModelChangeProcessor;
import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
import org.chromium.chrome.browser.compositor.overlays.SceneOverlay;
import org.chromium.chrome.browser.compositor.scene_layer.SceneOverlayLayer;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.toolbar.ControlContainer;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.resources.ResourceManager;
import java.util.List;
/** The public interface for the top toolbar texture component. */
public class TopToolbarOverlayCoordinator implements SceneOverlay {
/** The view state for this overlay. */
private final PropertyModel mModel;
/** A handle to the 'view' for this component as the layout manager requires access to it. */
private final TopToolbarSceneLayer mSceneLayer;
/** Handles processing updates to the model. */
private final CompositorModelChangeProcessor mChangeProcessor;
/** Business logic for this overlay. */
private final TopToolbarOverlayMediator mMediator;
public TopToolbarOverlayCoordinator(Context context,
CompositorModelChangeProcessor.FrameRequestSupplier frameRequestSupplier,
LayoutManager layoutManager, ControlContainer controlContainer,
ObservableSupplier<Tab> tabSupplier,
BrowserControlsStateProvider browserControlsStateProvider,
Supplier<Integer> viewportModeSupplier,
ObservableSupplier<Boolean> androidViewShownSupplier,
Supplier<ResourceManager> resourceManagerSupplier) {
mModel = new PropertyModel.Builder(TopToolbarOverlayProperties.ALL_KEYS)
.with(TopToolbarOverlayProperties.RESOURCE_ID, R.id.control_container)
.with(TopToolbarOverlayProperties.URL_BAR_RESOURCE_ID,
R.drawable.modern_location_bar)
.with(TopToolbarOverlayProperties.VISIBLE, true)
.with(TopToolbarOverlayProperties.CONTENT_OFFSET,
browserControlsStateProvider.getContentOffset())
.build();
mSceneLayer = new TopToolbarSceneLayer(resourceManagerSupplier);
mChangeProcessor = CompositorModelChangeProcessor.create(
mModel, mSceneLayer, TopToolbarSceneLayer::bind, frameRequestSupplier, true);
mMediator = new TopToolbarOverlayMediator(mModel, context, layoutManager, controlContainer,
tabSupplier, browserControlsStateProvider, viewportModeSupplier,
androidViewShownSupplier);
}
/** Clean up this component. */
public void destroy() {
mChangeProcessor.destroy();
mMediator.destroy();
mSceneLayer.destroy();
}
@Override
public SceneOverlayLayer getUpdatedSceneOverlayTree(RectF viewport, RectF visibleViewport,
LayerTitleCache layerTitleCache, ResourceManager resourceManager, float yOffset) {
return mSceneLayer;
}
@Override
public boolean isSceneOverlayTreeShowing() {
return mMediator.shouldBeAttachedToTree();
}
@Override
public EventFilter getEventFilter() {
return null;
}
@Override
public void onSizeChanged(
float width, float height, float visibleViewportOffsetY, int orientation) {}
@Override
public void getVirtualViews(List<VirtualView> views) {}
@Override
public boolean shouldHideAndroidBrowserControls() {
return false;
}
@Override
public boolean updateOverlay(long time, long dt) {
return false;
}
@Override
public boolean onBackPressed() {
return false;
}
@Override
public boolean handlesTabCreating() {
return false;
}
}
// Copyright 2020 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.compositor.overlays.toolbar;
import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar.DrawingInfo;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.ReadableIntPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableFloatPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
/** Properties associated with the top toolbar's composited layer. */
public class TopToolbarOverlayProperties {
/** The ID of the toolbar's texture resource. */
public static final ReadableIntPropertyKey RESOURCE_ID = new ReadableIntPropertyKey();
/** The texture resource used to draw the location/URL bar. */
public static final ReadableIntPropertyKey URL_BAR_RESOURCE_ID = new ReadableIntPropertyKey();
/** The background color of the toolbar. */
public static final WritableIntPropertyKey TOOLBAR_BACKGROUND_COLOR =
new WritableIntPropertyKey();
/** The color of the location/URL bar. */
public static final WritableIntPropertyKey URL_BAR_COLOR = new WritableIntPropertyKey();
/** The current offset of the web content (as pushed down by the browser controls). */
public static final WritableFloatPropertyKey CONTENT_OFFSET = new WritableFloatPropertyKey();
/** Whether the shadow under the toolbar should be visible. */
public static final WritableBooleanPropertyKey SHOW_SHADOW = new WritableBooleanPropertyKey();
/** Whether the layer should be visible. */
public static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey();
/** A "struct" for progress bar drawing info. */
public static final WritableObjectPropertyKey<DrawingInfo> PROGRESS_BAR_INFO =
new WritableObjectPropertyKey<>(true);
public static final PropertyKey[] ALL_KEYS =
new PropertyKey[] {RESOURCE_ID, URL_BAR_RESOURCE_ID, TOOLBAR_BACKGROUND_COLOR,
URL_BAR_COLOR, CONTENT_OFFSET, SHOW_SHADOW, VISIBLE, PROGRESS_BAR_INFO};
}
// Copyright 2020 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.compositor.overlays.toolbar;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
import org.chromium.chrome.browser.compositor.scene_layer.SceneOverlayLayer;
import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar.DrawingInfo;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.resources.ResourceManager;
/** A SceneLayer to render the top toolbar. This is the "view" piece of the top toolbar overlay. */
@JNINamespace("android")
class TopToolbarSceneLayer extends SceneOverlayLayer {
/** Pointer to native TopToolbarSceneLayer. */
private long mNativePtr;
/** A means of accessing a {@link ResourceManager} for textures. */
private final Supplier<ResourceManager> mResourceManagerSupplier;
/** A simple view binder that pushes the whole model to the view updater. */
public static void bind(PropertyModel model, TopToolbarSceneLayer view, PropertyKey key) {
view.pushProperties(model);
}
/**
* @param resourceManagerSupplier Access to a {@link ResourceManager} for textures.
*/
TopToolbarSceneLayer(Supplier<ResourceManager> resourceManagerSupplier) {
mResourceManagerSupplier = resourceManagerSupplier;
}
/** Push all information about the texture to native at once. */
private void pushProperties(PropertyModel model) {
if (mResourceManagerSupplier.get() == null) return;
TopToolbarSceneLayerJni.get().updateToolbarLayer(mNativePtr, TopToolbarSceneLayer.this,
mResourceManagerSupplier.get(), model.get(TopToolbarOverlayProperties.RESOURCE_ID),
model.get(TopToolbarOverlayProperties.TOOLBAR_BACKGROUND_COLOR),
model.get(TopToolbarOverlayProperties.URL_BAR_RESOURCE_ID),
model.get(TopToolbarOverlayProperties.URL_BAR_COLOR),
model.get(TopToolbarOverlayProperties.CONTENT_OFFSET),
model.get(TopToolbarOverlayProperties.SHOW_SHADOW),
model.get(TopToolbarOverlayProperties.VISIBLE));
DrawingInfo progressInfo = model.get(TopToolbarOverlayProperties.PROGRESS_BAR_INFO);
if (progressInfo == null) return;
TopToolbarSceneLayerJni.get().updateProgressBar(mNativePtr, TopToolbarSceneLayer.this,
progressInfo.progressBarRect.left, progressInfo.progressBarRect.top,
progressInfo.progressBarRect.width(), progressInfo.progressBarRect.height(),
progressInfo.progressBarColor, progressInfo.progressBarBackgroundRect.left,
progressInfo.progressBarBackgroundRect.top,
progressInfo.progressBarBackgroundRect.width(),
progressInfo.progressBarBackgroundRect.height(),
progressInfo.progressBarBackgroundColor);
}
@Override
public void setContentTree(SceneLayer contentTree) {
TopToolbarSceneLayerJni.get().setContentTree(
mNativePtr, TopToolbarSceneLayer.this, contentTree);
}
@Override
protected void initializeNative() {
if (mNativePtr == 0) {
mNativePtr = TopToolbarSceneLayerJni.get().init(TopToolbarSceneLayer.this);
}
assert mNativePtr != 0;
}
@Override
public void destroy() {
super.destroy();
mNativePtr = 0;
}
@NativeMethods
interface Natives {
long init(TopToolbarSceneLayer caller);
void setContentTree(long nativeTopToolbarSceneLayer, TopToolbarSceneLayer caller,
SceneLayer contentTree);
void updateToolbarLayer(long nativeTopToolbarSceneLayer, TopToolbarSceneLayer caller,
ResourceManager resourceManager, int resourceId, int toolbarBackgroundColor,
int urlBarResourceId, int urlBarColor, float contentOffset, boolean showShadow,
boolean visible);
void updateProgressBar(long nativeTopToolbarSceneLayer, TopToolbarSceneLayer caller,
int progressBarX, int progressBarY, int progressBarWidth, int progressBarHeight,
int progressBarColor, int progressBarBackgroundX, int progressBarBackgroundY,
int progressBarBackgroundWidth, int progressBarBackgroundHeight,
int progressBarBackgroundColor);
}
}
// Copyright 2020 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.compositor.overlays.toolbar;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.graphics.Color;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.compositor.layouts.Layout.ViewportMode;
import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tab.TabObserver;
import org.chromium.chrome.browser.toolbar.ControlContainer;
import org.chromium.ui.modelutil.PropertyModel;
/** Tests for the top toolbar overlay's mediator (composited version of the top toolbar). */
@RunWith(BaseRobolectricTestRunner.class)
public class TopToolbarOverlayMediatorTest {
private TopToolbarOverlayMediator mMediator;
private PropertyModel mModel;
@Mock
private Context mContext;
@Mock
private LayoutManager mLayoutManager;
@Mock
private ControlContainer mControlContainer;
@Mock
private BrowserControlsStateProvider mBrowserControlsProvider;
@Mock
private ObservableSupplier<Integer> mViewportModeSupplier;
@Mock
private TabImpl mTab;
@Mock
private TabImpl mTab2;
@Captor
private ArgumentCaptor<TabObserver> mTabObserverCaptor;
@Captor
private ArgumentCaptor<BrowserControlsStateProvider.Observer> mBrowserControlsObserverCaptor;
private ObservableSupplierImpl<Tab> mTabSupplier;
private ObservableSupplierImpl<Boolean> mAndroidViewShownSupplier;
@Before
public void beforeTest() {
MockitoAnnotations.initMocks(this);
mTabSupplier = new ObservableSupplierImpl<>();
mTabSupplier.set(mTab);
mAndroidViewShownSupplier = new ObservableSupplierImpl<>();
mAndroidViewShownSupplier.set(true);
when(mViewportModeSupplier.get()).thenReturn(ViewportMode.DYNAMIC_BROWSER_CONTROLS);
TopToolbarOverlayMediator.setToolbarBackgroundColorForTesting(Color.RED);
TopToolbarOverlayMediator.setUrlBarColorForTesting(Color.BLUE);
TopToolbarOverlayMediator.setIsTabletForTesting(false);
mModel = new PropertyModel.Builder(TopToolbarOverlayProperties.ALL_KEYS)
.with(TopToolbarOverlayProperties.RESOURCE_ID, 0)
.with(TopToolbarOverlayProperties.URL_BAR_RESOURCE_ID, 0)
.with(TopToolbarOverlayProperties.CONTENT_OFFSET, 0)
.with(TopToolbarOverlayProperties.SHOW_SHADOW, true)
.with(TopToolbarOverlayProperties.TOOLBAR_BACKGROUND_COLOR,
Color.TRANSPARENT)
.with(TopToolbarOverlayProperties.URL_BAR_COLOR, Color.TRANSPARENT)
.with(TopToolbarOverlayProperties.PROGRESS_BAR_INFO, null)
.build();
mMediator = new TopToolbarOverlayMediator(mModel, mContext, mLayoutManager,
mControlContainer, mTabSupplier, mBrowserControlsProvider, mViewportModeSupplier,
mAndroidViewShownSupplier);
// Ensure the observer is added to the initial tab.
verify(mTab).addObserver(mTabObserverCaptor.capture());
verify(mBrowserControlsProvider).addObserver(mBrowserControlsObserverCaptor.capture());
}
@After
public void afterTest() {
// Unset any testing state the tests may have set.
TopToolbarOverlayMediator.setIsTabletForTesting(null);
}
@Test
public void testTabObserverAfterTabSwitch() {
mTabSupplier.set(mTab2);
// Make sure the tab observer for this overlay is only observing the "current" tab.
verify(mTab).removeObserver(mTabObserverCaptor.getValue());
verify(mTab2).addObserver(mTabObserverCaptor.getValue());
}
@Test
public void testShadowVisibility_browserControlsOffsets() {
when(mBrowserControlsProvider.getBrowserControlHiddenRatio()).thenReturn(0.0f);
mBrowserControlsObserverCaptor.getValue().onControlsOffsetChanged(0, 0, 0, 0, false);
Assert.assertFalse(
"Shadow should be invisible.", mModel.get(TopToolbarOverlayProperties.SHOW_SHADOW));
when(mBrowserControlsProvider.getBrowserControlHiddenRatio()).thenReturn(0.5f);
mBrowserControlsObserverCaptor.getValue().onControlsOffsetChanged(100, 0, 0, 0, false);
Assert.assertTrue(
"Shadow should be visible.", mModel.get(TopToolbarOverlayProperties.SHOW_SHADOW));
}
@Test
public void testShadowVisibility_androidViewForceHidden() {
mAndroidViewShownSupplier.set(true);
Assert.assertFalse(
"Shadow should be invisible.", mModel.get(TopToolbarOverlayProperties.SHOW_SHADOW));
mAndroidViewShownSupplier.set(false);
Assert.assertTrue(
"Shadow should be visible.", mModel.get(TopToolbarOverlayProperties.SHOW_SHADOW));
}
@Test
public void testProgressUpdate_phone() {
mModel.set(TopToolbarOverlayProperties.PROGRESS_BAR_INFO, null);
mTabObserverCaptor.getValue().onLoadProgressChanged(mTab, 0.25f);
Assert.assertNotNull("The progress bar data should be populated.",
mModel.get(TopToolbarOverlayProperties.PROGRESS_BAR_INFO));
// Ensure the progress is correct on tab switch.
mTabObserverCaptor.getValue().onLoadProgressChanged(mTab, 0.f);
mTabSupplier.set(mTab2);
}
@Test
public void testProgressUpdate_tablet() {
TopToolbarOverlayMediator.setIsTabletForTesting(true);
mModel.set(TopToolbarOverlayProperties.PROGRESS_BAR_INFO, null);
mTabObserverCaptor.getValue().onLoadProgressChanged(mTab, 0.25f);
Assert.assertNull("The progress bar data should be still be empty.",
mModel.get(TopToolbarOverlayProperties.PROGRESS_BAR_INFO));
}
}
......@@ -2291,8 +2291,8 @@ static_library("browser") {
"android/compositor/scene_layer/tab_list_scene_layer.h",
"android/compositor/scene_layer/tab_strip_scene_layer.cc",
"android/compositor/scene_layer/tab_strip_scene_layer.h",
"android/compositor/scene_layer/toolbar_scene_layer.cc",
"android/compositor/scene_layer/toolbar_scene_layer.h",
"android/compositor/scene_layer/top_toolbar_scene_layer.cc",
"android/compositor/scene_layer/top_toolbar_scene_layer.h",
"android/compositor/tab_content_manager.cc",
"android/compositor/tab_content_manager.h",
"android/consent_auditor/consent_auditor_bridge.cc",
......
......@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/compositor/scene_layer/toolbar_scene_layer.h"
#include "chrome/browser/android/compositor/scene_layer/top_toolbar_scene_layer.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "cc/layers/solid_color_layer.h"
#include "chrome/android/chrome_jni_headers/ToolbarSceneLayer_jni.h"
#include "chrome/android/chrome_jni_headers/TopToolbarSceneLayer_jni.h"
#include "chrome/browser/android/compositor/layer/toolbar_layer.h"
#include "ui/android/resources/resource_manager_impl.h"
#include "ui/gfx/android/java_bitmap.h"
......@@ -17,7 +17,8 @@ using base::android::JavaRef;
namespace android {
ToolbarSceneLayer::ToolbarSceneLayer(JNIEnv* env, const JavaRef<jobject>& jobj)
TopToolbarSceneLayer::TopToolbarSceneLayer(JNIEnv* env,
const JavaRef<jobject>& jobj)
: SceneLayer(env, jobj),
should_show_background_(false),
background_color_(SK_ColorWHITE),
......@@ -26,10 +27,9 @@ ToolbarSceneLayer::ToolbarSceneLayer(JNIEnv* env, const JavaRef<jobject>& jobj)
layer()->SetIsDrawable(true);
}
ToolbarSceneLayer::~ToolbarSceneLayer() {
}
TopToolbarSceneLayer::~TopToolbarSceneLayer() = default;
void ToolbarSceneLayer::UpdateToolbarLayer(
void TopToolbarSceneLayer::UpdateToolbarLayer(
JNIEnv* env,
const JavaParamRef<jobject>& object,
const JavaParamRef<jobject>& jresource_manager,
......@@ -58,40 +58,38 @@ void ToolbarSceneLayer::UpdateToolbarLayer(
content_offset, false, !show_shadow);
}
void ToolbarSceneLayer::UpdateProgressBar(JNIEnv* env,
const JavaParamRef<jobject>& object,
jint progress_bar_x,
jint progress_bar_y,
jint progress_bar_width,
jint progress_bar_height,
jint progress_bar_color,
jint progress_bar_background_x,
jint progress_bar_background_y,
jint progress_bar_background_width,
jint progress_bar_background_height,
jint progress_bar_background_color) {
if (!toolbar_layer_) return;
toolbar_layer_->UpdateProgressBar(progress_bar_x,
progress_bar_y,
progress_bar_width,
progress_bar_height,
progress_bar_color,
progress_bar_background_x,
progress_bar_background_y,
progress_bar_background_width,
progress_bar_background_height,
progress_bar_background_color);
void TopToolbarSceneLayer::UpdateProgressBar(
JNIEnv* env,
const JavaParamRef<jobject>& object,
jint progress_bar_x,
jint progress_bar_y,
jint progress_bar_width,
jint progress_bar_height,
jint progress_bar_color,
jint progress_bar_background_x,
jint progress_bar_background_y,
jint progress_bar_background_width,
jint progress_bar_background_height,
jint progress_bar_background_color) {
if (!toolbar_layer_)
return;
toolbar_layer_->UpdateProgressBar(
progress_bar_x, progress_bar_y, progress_bar_width, progress_bar_height,
progress_bar_color, progress_bar_background_x, progress_bar_background_y,
progress_bar_background_width, progress_bar_background_height,
progress_bar_background_color);
}
void ToolbarSceneLayer::SetContentTree(
void TopToolbarSceneLayer::SetContentTree(
JNIEnv* env,
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jobject>& jcontent_tree) {
SceneLayer* content_tree = FromJavaObject(env, jcontent_tree);
if (!content_tree || !content_tree->layer()) return;
if (!content_tree || !content_tree->layer())
return;
if (!content_tree->layer()->parent()
|| (content_tree->layer()->parent()->id() != content_container_->id())) {
if (!content_tree->layer()->parent() ||
(content_tree->layer()->parent()->id() != content_container_->id())) {
// Clear out all the children of the container when the content changes.
// This indicates that the layout has switched.
content_container_->RemoveAllChildren();
......@@ -103,19 +101,19 @@ void ToolbarSceneLayer::SetContentTree(
background_color_ = content_tree->GetBackgroundColor();
}
SkColor ToolbarSceneLayer::GetBackgroundColor() {
SkColor TopToolbarSceneLayer::GetBackgroundColor() {
return background_color_;
}
bool ToolbarSceneLayer::ShouldShowBackground() {
bool TopToolbarSceneLayer::ShouldShowBackground() {
return should_show_background_;
}
static jlong JNI_ToolbarSceneLayer_Init(JNIEnv* env,
const JavaParamRef<jobject>& jobj) {
static jlong JNI_TopToolbarSceneLayer_Init(JNIEnv* env,
const JavaParamRef<jobject>& jobj) {
// This will automatically bind to the Java object and pass ownership there.
ToolbarSceneLayer* toolbar_scene_layer =
new ToolbarSceneLayer(env, jobj);
TopToolbarSceneLayer* toolbar_scene_layer =
new TopToolbarSceneLayer(env, jobj);
return reinterpret_cast<intptr_t>(toolbar_scene_layer);
}
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_TOOLBAR_SCENE_LAYER_H_
#define CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_TOOLBAR_SCENE_LAYER_H_
#ifndef CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_TOP_TOOLBAR_SCENE_LAYER_H_
#define CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_TOP_TOOLBAR_SCENE_LAYER_H_
#include <memory>
#include <vector>
......@@ -23,10 +23,11 @@ namespace android {
class ToolbarLayer;
class ToolbarSceneLayer : public SceneLayer {
class TopToolbarSceneLayer : public SceneLayer {
public:
ToolbarSceneLayer(JNIEnv* env, const base::android::JavaRef<jobject>& jobj);
~ToolbarSceneLayer() override;
TopToolbarSceneLayer(JNIEnv* env,
const base::android::JavaRef<jobject>& jobj);
~TopToolbarSceneLayer() override;
// Update the compositor version of the toolbar.
void UpdateToolbarLayer(
......@@ -42,19 +43,18 @@ class ToolbarSceneLayer : public SceneLayer {
bool visible);
// Update the progress bar.
void UpdateProgressBar(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& object,
jint progress_bar_x,
jint progress_bar_y,
jint progress_bar_width,
jint progress_bar_height,
jint progress_bar_color,
jint progress_bar_background_x,
jint progress_bar_background_y,
jint progress_bar_background_width,
jint progress_bar_background_height,
jint progress_bar_background_color);
void UpdateProgressBar(JNIEnv* env,
const base::android::JavaParamRef<jobject>& object,
jint progress_bar_x,
jint progress_bar_y,
jint progress_bar_width,
jint progress_bar_height,
jint progress_bar_color,
jint progress_bar_background_x,
jint progress_bar_background_y,
jint progress_bar_background_width,
jint progress_bar_background_height,
jint progress_bar_background_color);
void SetContentTree(
JNIEnv* env,
......@@ -71,9 +71,9 @@ class ToolbarSceneLayer : public SceneLayer {
scoped_refptr<cc::Layer> content_container_;
scoped_refptr<ToolbarLayer> toolbar_layer_;
DISALLOW_COPY_AND_ASSIGN(ToolbarSceneLayer);
DISALLOW_COPY_AND_ASSIGN(TopToolbarSceneLayer);
};
} // namespace android
#endif // CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_TOOLBAR_SCENE_LAYER_H_
#endif // CHROME_BROWSER_ANDROID_COMPOSITOR_SCENE_LAYER_TOP_TOOLBAR_SCENE_LAYER_H_
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