Commit 21d1516e authored by Jinsuk Kim's avatar Jinsuk Kim Committed by Commit Bot

Android: CompositorViewHolder manages viewport sizing

This CL moves the logic in ChromeFullscreenManager that controls
viewport to CompositorViewHolder so that it will be the source of
viewport information.

ContentView sizing/offset update is still initiated by
ChromeFullscreenManager but they are decoupled(i.e. no more
ViewSizeDelegate), and now the flow is handled through CVH
listening to BrowserControlsStateProvider.onControlOffsetChanged.

Bug: 966272
Change-Id: I111b47d4fd93f4d1866dc0cab7012c9339278788
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2278742
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#786580}
parent 0055de9a
...@@ -43,6 +43,7 @@ chrome_junit_test_java_sources = [ ...@@ -43,6 +43,7 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/browserservices/ui/view/trustedwebactivity/DisclosureNotificationTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/view/trustedwebactivity/DisclosureNotificationTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ui/view/trustedwebactivity/DisclosureSnackbarTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/view/trustedwebactivity/DisclosureSnackbarTest.java",
"junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerImplTest.java", "junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerImplTest.java",
"junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java",
"junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimationHandlerTest.java", "junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimationHandlerTest.java",
"junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimatorTest.java", "junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimatorTest.java",
"junit/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessorUnitTest.java", "junit/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessorUnitTest.java",
......
...@@ -18,6 +18,7 @@ import android.os.Handler; ...@@ -18,6 +18,7 @@ import android.os.Handler;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Pair; import android.util.Pair;
import android.view.DragEvent; import android.view.DragEvent;
import android.view.Gravity;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.PointerIcon; import android.view.PointerIcon;
import android.view.View; import android.view.View;
...@@ -26,6 +27,7 @@ import android.view.accessibility.AccessibilityEvent; ...@@ -26,6 +27,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.accessibility.AccessibilityEventCompat; import androidx.core.view.accessibility.AccessibilityEventCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
...@@ -66,6 +68,7 @@ import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; ...@@ -66,6 +68,7 @@ import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
import org.chromium.components.browser_ui.widget.InsetObserverView; import org.chromium.components.browser_ui.widget.InsetObserverView;
import org.chromium.components.content_capture.ContentCaptureConsumer; import org.chromium.components.content_capture.ContentCaptureConsumer;
import org.chromium.components.content_capture.ContentCaptureConsumerImpl; import org.chromium.components.content_capture.ContentCaptureConsumerImpl;
import org.chromium.components.embedder_support.view.ContentView;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.KeyboardVisibilityDelegate;
import org.chromium.ui.UiUtils; import org.chromium.ui.UiUtils;
...@@ -91,7 +94,8 @@ import java.util.Set; ...@@ -91,7 +94,8 @@ import java.util.Set;
public class CompositorViewHolder extends FrameLayout public class CompositorViewHolder extends FrameLayout
implements ContentOffsetProvider, LayoutManagerHost, LayoutRenderHost, Invalidator.Host, implements ContentOffsetProvider, LayoutManagerHost, LayoutRenderHost, Invalidator.Host,
BrowserControlsStateProvider.Observer, InsetObserverView.WindowInsetObserver, BrowserControlsStateProvider.Observer, InsetObserverView.WindowInsetObserver,
ChromeAccessibilityUtil.Observer, TabObscuringHandler.Observer { ChromeAccessibilityUtil.Observer, TabObscuringHandler.Observer,
ViewGroup.OnHierarchyChangeListener {
private static final long SYSTEM_UI_VIEWPORT_UPDATE_DELAY_MS = 500; private static final long SYSTEM_UI_VIEWPORT_UPDATE_DELAY_MS = 500;
/** /**
...@@ -155,6 +159,12 @@ public class CompositorViewHolder extends FrameLayout ...@@ -155,6 +159,12 @@ public class CompositorViewHolder extends FrameLayout
/** The currently attached View. */ /** The currently attached View. */
private View mView; private View mView;
/**
* Current ContentView. Updates when active tab is switched or WebContents is swapped
* in the current Tab.
*/
private ContentView mContentView;
private TabObserver mTabObserver; private TabObserver mTabObserver;
// Cache objects that should not be created frequently. // Cache objects that should not be created frequently.
...@@ -290,6 +300,7 @@ public class CompositorViewHolder extends FrameLayout ...@@ -290,6 +300,7 @@ public class CompositorViewHolder extends FrameLayout
@Override @Override
public void onContentViewScrollingStateChanged(boolean scrolling) { public void onContentViewScrollingStateChanged(boolean scrolling) {
mContentViewScrolling = scrolling; mContentViewScrolling = scrolling;
if (!scrolling) updateContentViewChildrenDimension();
} }
@Override @Override
...@@ -521,6 +532,9 @@ public class CompositorViewHolder extends FrameLayout ...@@ -521,6 +532,9 @@ public class CompositorViewHolder extends FrameLayout
mContentCaptureConsumer.onWebContentsChanged(null); mContentCaptureConsumer.onWebContentsChanged(null);
mContentCaptureConsumer = null; mContentCaptureConsumer = null;
} }
if (mContentView != null) {
mContentView.removeOnHierarchyChangeListener(this);
}
} }
/** /**
...@@ -708,7 +722,8 @@ public class CompositorViewHolder extends FrameLayout ...@@ -708,7 +722,8 @@ public class CompositorViewHolder extends FrameLayout
return currentTab; return currentTab;
} }
private View getContentView() { @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
ViewGroup getContentView() {
Tab tab = getCurrentTab(); Tab tab = getCurrentTab();
return tab != null ? tab.getContentView() : null; return tab != null ? tab.getContentView() : null;
} }
...@@ -788,10 +803,7 @@ public class CompositorViewHolder extends FrameLayout ...@@ -788,10 +803,7 @@ public class CompositorViewHolder extends FrameLayout
* Called whenever the host activity is started. * Called whenever the host activity is started.
*/ */
public void onStart() { public void onStart() {
if (mFullscreenManager != null) { if (mFullscreenManager != null) mFullscreenManager.addObserver(this);
mFullscreenManager.addObserver(this);
mFullscreenManager.setViewportSizeDelegate(this::updateViewportSize);
}
requestRender(); requestRender();
} }
...@@ -799,10 +811,7 @@ public class CompositorViewHolder extends FrameLayout ...@@ -799,10 +811,7 @@ public class CompositorViewHolder extends FrameLayout
* Called whenever the host activity is stopped. * Called whenever the host activity is stopped.
*/ */
public void onStop() { public void onStop() {
if (mFullscreenManager != null) { if (mFullscreenManager != null) mFullscreenManager.removeObserver(this);
mFullscreenManager.removeObserver(this);
mFullscreenManager.setViewportSizeDelegate(null);
}
} }
@Override @Override
...@@ -810,6 +819,7 @@ public class CompositorViewHolder extends FrameLayout ...@@ -810,6 +819,7 @@ public class CompositorViewHolder extends FrameLayout
int bottomOffset, int bottomControlsMinHeightOffset, boolean needsAnimate) { int bottomOffset, int bottomControlsMinHeightOffset, boolean needsAnimate) {
onViewportChanged(); onViewportChanged();
if (needsAnimate) requestRender(); if (needsAnimate) requestRender();
updateContentViewChildrenDimension();
} }
@Override @Override
...@@ -861,6 +871,65 @@ public class CompositorViewHolder extends FrameLayout ...@@ -861,6 +871,65 @@ public class CompositorViewHolder extends FrameLayout
setSize(getWebContents(), getContentView(), viewportSize.x, viewportSize.y); setSize(getWebContents(), getContentView(), viewportSize.x, viewportSize.y);
} }
// View.OnHierarchyChangeListener implementation
@Override
public void onChildViewRemoved(View parent, View child) {
updateContentViewChildrenDimension();
}
@Override
public void onChildViewAdded(View parent, View child) {
updateContentViewChildrenDimension();
}
private void updateContentViewChildrenDimension() {
TraceEvent.begin("CompositorViewHolder:updateContentViewChildrenDimension");
ViewGroup view = getContentView();
if (view != null) {
assert mFullscreenManager != null;
float topViewsTranslation = getOverlayTranslateY();
float bottomMargin = BrowserControlsUtils.getBottomContentOffset(mFullscreenManager);
applyTranslationToTopChildViews(view, topViewsTranslation);
applyMarginToFullscreenChildViews(view, topViewsTranslation, bottomMargin);
updateViewportSize();
}
TraceEvent.end("CompositorViewHolder:updateContentViewChildrenDimension");
}
private static void applyMarginToFullscreenChildViews(
ViewGroup contentView, float topMargin, float bottomMargin) {
for (int i = 0; i < contentView.getChildCount(); i++) {
View child = contentView.getChildAt(i);
if (!(child.getLayoutParams() instanceof FrameLayout.LayoutParams)) continue;
FrameLayout.LayoutParams layoutParams =
(FrameLayout.LayoutParams) child.getLayoutParams();
if (layoutParams.height == LayoutParams.MATCH_PARENT
&& (layoutParams.topMargin != (int) topMargin
|| layoutParams.bottomMargin != (int) bottomMargin)) {
layoutParams.topMargin = (int) topMargin;
layoutParams.bottomMargin = (int) bottomMargin;
child.requestLayout();
TraceEvent.instant("FullscreenManager:child.requestLayout()");
}
}
}
private static void applyTranslationToTopChildViews(ViewGroup contentView, float translation) {
for (int i = 0; i < contentView.getChildCount(); i++) {
View child = contentView.getChildAt(i);
if (!(child.getLayoutParams() instanceof FrameLayout.LayoutParams)) continue;
FrameLayout.LayoutParams layoutParams =
(FrameLayout.LayoutParams) child.getLayoutParams();
if (Gravity.TOP == (layoutParams.gravity & Gravity.FILL_VERTICAL)) {
child.setTranslationY(translation);
TraceEvent.instant("FullscreenManager:child.setTranslationY()");
}
}
}
/** /**
* Sets the overlay mode. * Sets the overlay mode.
*/ */
...@@ -1041,7 +1110,6 @@ public class CompositorViewHolder extends FrameLayout ...@@ -1041,7 +1110,6 @@ public class CompositorViewHolder extends FrameLayout
public void setFullscreenHandler(ChromeFullscreenManager fullscreen) { public void setFullscreenHandler(ChromeFullscreenManager fullscreen) {
mFullscreenManager = fullscreen; mFullscreenManager = fullscreen;
mFullscreenManager.addObserver(this); mFullscreenManager.addObserver(this);
mFullscreenManager.setViewportSizeDelegate(this::updateViewportSize);
onViewportChanged(); onViewportChanged();
} }
...@@ -1224,6 +1292,7 @@ public class CompositorViewHolder extends FrameLayout ...@@ -1224,6 +1292,7 @@ public class CompositorViewHolder extends FrameLayout
tab.addObserver(mTabObserver); tab.addObserver(mTabObserver);
mCompositorView.onTabChanged(); mCompositorView.onTabChanged();
} }
updateViewStateListener(tab != null ? tab.getContentView() : null);
} }
mTabVisible = tab; mTabVisible = tab;
...@@ -1245,6 +1314,16 @@ public class CompositorViewHolder extends FrameLayout ...@@ -1245,6 +1314,16 @@ public class CompositorViewHolder extends FrameLayout
} }
} }
private void updateViewStateListener(ContentView newContentView) {
if (mContentView != null) {
mContentView.removeOnHierarchyChangeListener(this);
}
if (newContentView != null) {
newContentView.addOnHierarchyChangeListener(this);
}
mContentView = newContentView;
}
/** /**
* Sets the correct size for {@link View} on {@code tab} and sets the correct rendering * Sets the correct size for {@link View} on {@code tab} and sets the correct rendering
* parameters on {@link WebContents} on {@code tab}. * parameters on {@link WebContents} on {@code tab}.
......
...@@ -11,7 +11,6 @@ import android.app.Activity; ...@@ -11,7 +11,6 @@ import android.app.Activity;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
...@@ -22,7 +21,6 @@ import org.chromium.base.ActivityState; ...@@ -22,7 +21,6 @@ import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus;
import org.chromium.base.ApplicationStatus.ActivityStateListener; import org.chromium.base.ApplicationStatus.ActivityStateListener;
import org.chromium.base.ObserverList; import org.chromium.base.ObserverList;
import org.chromium.base.TraceEvent;
import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.task.PostTask; import org.chromium.base.task.PostTask;
import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.ActivityTabProvider;
...@@ -42,7 +40,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; ...@@ -42,7 +40,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
import org.chromium.chrome.browser.toolbar.ControlContainer; import org.chromium.chrome.browser.toolbar.ControlContainer;
import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.browser.vr.VrModuleProvider;
import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate; import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate;
import org.chromium.components.embedder_support.view.ContentView;
import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.content_public.common.BrowserControlsState; import org.chromium.content_public.common.BrowserControlsState;
import org.chromium.ui.util.TokenHolder; import org.chromium.ui.util.TokenHolder;
...@@ -54,9 +51,8 @@ import java.lang.annotation.RetentionPolicy; ...@@ -54,9 +51,8 @@ import java.lang.annotation.RetentionPolicy;
/** /**
* A class that manages control and content views to create the fullscreen mode. * A class that manages control and content views to create the fullscreen mode.
*/ */
public class ChromeFullscreenManager implements ActivityStateListener, public class ChromeFullscreenManager
ViewGroup.OnHierarchyChangeListener, VrModeObserver, implements ActivityStateListener, VrModeObserver, BrowserControlsSizer, FullscreenManager {
BrowserControlsSizer, FullscreenManager {
// The amount of time to delay the control show request after returning to a once visible // The amount of time to delay the control show request after returning to a once visible
// activity. This delay is meant to allow Android to run its Activity focusing animation and // activity. This delay is meant to allow Android to run its Activity focusing animation and
// have the controls scroll back in smoothly once that has finished. // have the controls scroll back in smoothly once that has finished.
...@@ -98,13 +94,8 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -98,13 +94,8 @@ public class ChromeFullscreenManager implements ActivityStateListener,
private boolean mOffsetsChanged; private boolean mOffsetsChanged;
private ActivityTabTabObserver mActiveTabObserver; private ActivityTabTabObserver mActiveTabObserver;
// Current ContentView. Updates when active tab is switched or WebContents is swapped
// in the current Tab.
private ContentView mContentView;
private final ObserverList<BrowserControlsStateProvider.Observer> mControlsObservers = private final ObserverList<BrowserControlsStateProvider.Observer> mControlsObservers =
new ObserverList<>(); new ObserverList<>();
private Runnable mViewportSizeDelegate;
private FullscreenHtmlApiHandler mHtmlApiHandler; private FullscreenHtmlApiHandler mHtmlApiHandler;
@Nullable @Nullable
private Tab mTab; private Tab mTab;
...@@ -194,19 +185,9 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -194,19 +185,9 @@ public class ChromeFullscreenManager implements ActivityStateListener,
protected void onObservingDifferentTab(Tab tab) { protected void onObservingDifferentTab(Tab tab) {
setTab(tab); setTab(tab);
} }
@Override
public void onContentViewScrollingStateChanged(boolean scrolling) {
if (!scrolling) updateContentViewChildrenState();
}
}; };
mTabControlsObserver = new TabModelSelectorTabObserver(modelSelector) { mTabControlsObserver = new TabModelSelectorTabObserver(modelSelector) {
@Override
public void onContentChanged(Tab tab) {
if (tab == getTab()) updateViewStateListener();
}
@Override @Override
public void onInteractabilityChanged(Tab tab, boolean interactable) { public void onInteractabilityChanged(Tab tab, boolean interactable) {
if (!interactable || tab != getTab()) return; if (!interactable || tab != getTab()) return;
...@@ -267,8 +248,8 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -267,8 +248,8 @@ public class ChromeFullscreenManager implements ActivityStateListener,
* @return The currently selected tab for fullscreen. * @return The currently selected tab for fullscreen.
*/ */
@Nullable @Nullable
@VisibleForTesting @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
Tab getTab() { public Tab getTab() {
return mTab; return mTab;
} }
...@@ -276,7 +257,6 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -276,7 +257,6 @@ public class ChromeFullscreenManager implements ActivityStateListener,
Tab previousTab = getTab(); Tab previousTab = getTab();
mTab = tab; mTab = tab;
if (previousTab != tab) { if (previousTab != tab) {
updateViewStateListener();
if (tab != null) { if (tab != null) {
mBrowserVisibilityDelegate.showControlsTransient(); mBrowserVisibilityDelegate.showControlsTransient();
if (tab.isUserInteractable()) restoreControlsPositions(); if (tab.isUserInteractable()) restoreControlsPositions();
...@@ -310,16 +290,6 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -310,16 +290,6 @@ public class ChromeFullscreenManager implements ActivityStateListener,
return mHtmlApiHandler.getPersistentFullscreenMode(); return mHtmlApiHandler.getPersistentFullscreenMode();
} }
private void updateViewStateListener() {
if (mContentView != null) {
mContentView.removeOnHierarchyChangeListener(this);
}
mContentView = getContentView();
if (mContentView != null) {
mContentView.addOnHierarchyChangeListener(this);
}
}
// ActivityStateListener // ActivityStateListener
@Override @Override
...@@ -344,8 +314,8 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -344,8 +314,8 @@ public class ChromeFullscreenManager implements ActivityStateListener,
* {@link BrowserControlsUtils#areBrowserControlsOffScreen(BrowserControlsStateProvider)} when * {@link BrowserControlsUtils#areBrowserControlsOffScreen(BrowserControlsStateProvider)} when
* both min-heights are 0. * both min-heights are 0.
*/ */
@VisibleForTesting @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
boolean areBrowserControlsAtMinHeight() { public boolean areBrowserControlsAtMinHeight() {
return mControlsAtMinHeight.get(); return mControlsAtMinHeight.get();
} }
...@@ -488,43 +458,6 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -488,43 +458,6 @@ public class ChromeFullscreenManager implements ActivityStateListener,
mHtmlApiHandler.removeObserver(observer); mHtmlApiHandler.removeObserver(observer);
} }
/**
* @param delegate A Runnable to be executed when the WebContents viewport should be updated.
*/
public void setViewportSizeDelegate(Runnable delegate) {
mViewportSizeDelegate = delegate;
}
// View.OnHierarchyChangeListener implementation
@Override
public void onChildViewRemoved(View parent, View child) {
updateContentViewChildrenState();
}
@Override
public void onChildViewAdded(View parent, View child) {
updateContentViewChildrenState();
}
/**
* Updates the current ContentView's children and any popups with the correct offsets based on
* the current fullscreen state.
*/
private void updateContentViewChildrenState() {
TraceEvent.begin("FullscreenManager:updateContentViewChildrenState");
ViewGroup view = getContentView();
if (view != null) {
float topViewsTranslation = getTopVisibleContentOffset();
float bottomMargin = getBottomContentOffset();
applyTranslationToTopChildViews(view, topViewsTranslation);
applyMarginToFullChildViews(view, topViewsTranslation, bottomMargin);
if (mViewportSizeDelegate != null) mViewportSizeDelegate.run();
}
TraceEvent.end("FullscreenManager:updateContentViewChildrenState");
}
/** /**
* Utility routine for ensuring visibility updates are synchronized with * Utility routine for ensuring visibility updates are synchronized with
* animation, preventing message loop stalls due to untimely invalidation. * animation, preventing message loop stalls due to untimely invalidation.
...@@ -570,7 +503,7 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -570,7 +503,7 @@ public class ChromeFullscreenManager implements ActivityStateListener,
if (offsetOverridden()) return true; if (offsetOverridden()) return true;
boolean showControls = !BrowserControlsUtils.drawControlsAsTexture(this); boolean showControls = !BrowserControlsUtils.drawControlsAsTexture(this);
ViewGroup contentView = getContentView(); ViewGroup contentView = mTab != null ? mTab.getContentView() : null;
if (contentView == null) return showControls; if (contentView == null) return showControls;
for (int i = 0; i < contentView.getChildCount(); i++) { for (int i = 0; i < contentView.getChildCount(); i++) {
...@@ -588,44 +521,6 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -588,44 +521,6 @@ public class ChromeFullscreenManager implements ActivityStateListener,
return showControls; return showControls;
} }
private void applyMarginToFullChildViews(
ViewGroup contentView, float topMargin, float bottomMargin) {
for (int i = 0; i < contentView.getChildCount(); i++) {
View child = contentView.getChildAt(i);
if (!(child.getLayoutParams() instanceof FrameLayout.LayoutParams)) continue;
FrameLayout.LayoutParams layoutParams =
(FrameLayout.LayoutParams) child.getLayoutParams();
if (layoutParams.height == LayoutParams.MATCH_PARENT
&& (layoutParams.topMargin != (int) topMargin
|| layoutParams.bottomMargin != (int) bottomMargin)) {
layoutParams.topMargin = (int) topMargin;
layoutParams.bottomMargin = (int) bottomMargin;
child.requestLayout();
TraceEvent.instant("FullscreenManager:child.requestLayout()");
}
}
}
private void applyTranslationToTopChildViews(ViewGroup contentView, float translation) {
for (int i = 0; i < contentView.getChildCount(); i++) {
View child = contentView.getChildAt(i);
if (!(child.getLayoutParams() instanceof FrameLayout.LayoutParams)) continue;
FrameLayout.LayoutParams layoutParams =
(FrameLayout.LayoutParams) child.getLayoutParams();
if (Gravity.TOP == (layoutParams.gravity & Gravity.FILL_VERTICAL)) {
child.setTranslationY(translation);
TraceEvent.instant("FullscreenManager:child.setTranslationY()");
}
}
}
private ContentView getContentView() {
Tab tab = getTab();
return tab != null ? (ContentView) tab.getContentView() : null;
}
/** /**
* Updates the positions of the browser controls and content to the default non fullscreen * Updates the positions of the browser controls and content to the default non fullscreen
* values. * values.
...@@ -686,7 +581,6 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -686,7 +581,6 @@ public class ChromeFullscreenManager implements ActivityStateListener,
&& getBottomContentOffset() == getBottomControlsMinHeight()); && getBottomContentOffset() == getBottomControlsMinHeight());
updateControlOffset(); updateControlOffset();
notifyControlOffsetChanged(); notifyControlOffsetChanged();
updateContentViewChildrenState();
} }
private void notifyControlOffsetChanged() { private void notifyControlOffsetChanged() {
...@@ -934,14 +828,11 @@ public class ChromeFullscreenManager implements ActivityStateListener, ...@@ -934,14 +828,11 @@ public class ChromeFullscreenManager implements ActivityStateListener,
if (mActiveTabObserver != null) mActiveTabObserver.destroy(); if (mActiveTabObserver != null) mActiveTabObserver.destroy();
mBrowserVisibilityDelegate.destroy(); mBrowserVisibilityDelegate.destroy();
if (mTabControlsObserver != null) mTabControlsObserver.destroy(); if (mTabControlsObserver != null) mTabControlsObserver.destroy();
if (mContentView != null) {
mContentView.removeOnHierarchyChangeListener(this);
}
VrModuleProvider.unregisterVrModeObserver(this); VrModuleProvider.unregisterVrModeObserver(this);
} }
@VisibleForTesting @VisibleForTesting
TabModelSelectorTabObserver getTabControlsObserverForTesting() { public TabModelSelectorTabObserver getTabControlsObserverForTesting() {
return mTabControlsObserver; return mTabControlsObserver;
} }
......
...@@ -278,10 +278,6 @@ public class FullscreenManagerTest { ...@@ -278,10 +278,6 @@ public class FullscreenManagerTest {
final CallbackHelper viewportCallback = new CallbackHelper(); final CallbackHelper viewportCallback = new CallbackHelper();
ChromeFullscreenManager fullscreenManager =
mActivityTestRule.getActivity().getFullscreenManager();
fullscreenManager.setViewportSizeDelegate(viewportCallback::notifyCalled);
Assert.assertEquals(0, scrollStartCallback.getCallCount()); Assert.assertEquals(0, scrollStartCallback.getCallCount());
Assert.assertEquals(0, viewportCallback.getCallCount()); Assert.assertEquals(0, viewportCallback.getCallCount());
......
...@@ -6,6 +6,7 @@ include_rules = [ ...@@ -6,6 +6,7 @@ include_rules = [
"+chrome/browser/performance_hints/android/java", "+chrome/browser/performance_hints/android/java",
"+chrome/browser/profiles/android", "+chrome/browser/profiles/android",
"+chrome/browser/tab", "+chrome/browser/tab",
"+chrome/browser/tabmodel",
"+chrome/browser/thumbnail/generator/android/java", "+chrome/browser/thumbnail/generator/android/java",
"+chrome/browser/ui/messages/android/java", "+chrome/browser/ui/messages/android/java",
"+components/autofill/android/java/src/org/chromium/components/autofill", "+components/autofill/android/java/src/org/chromium/components/autofill",
......
// 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;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import androidx.test.core.app.ApplicationProvider;
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.Mock;
import org.mockito.MockitoAnnotations;
import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.supplier.Supplier;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
import org.chromium.chrome.browser.toolbar.ControlContainer;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.embedder_support.view.ContentView;
/**
* Unit tests for {@link CompositorViewHolder}.
*/
@RunWith(BaseRobolectricTestRunner.class)
public class CompositorViewHolderUnitTest {
@Rule
public TestRule mProcessor = new Features.JUnitProcessor();
// Since these tests don't depend on the heights being pixels, we can use these as dpi directly.
private static final int TOOLBAR_HEIGHT = 56;
@Mock
private Activity mActivity;
@Mock
private ControlContainer mControlContainer;
@Mock
private View mContainerView;
@Mock
private TabModelSelector mTabModelSelector;
@Mock
private ActivityTabProvider mActivityTabProvider;
@Mock
private android.content.res.Resources mResources;
@Mock
private Tab mTab;
@Mock
private ContentView mContentView;
private Context mContext;
private CompositorViewHolder mCompositorViewHolder;
private ChromeFullscreenManager mFullscreenManager;
private Supplier<Boolean> mControlsResizeView;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.CREATED);
// Setup for ChromeFullscreenManager which initiates content/control offset changes
// for CompositorViewHolder.
when(mActivity.getResources()).thenReturn(mResources);
when(mResources.getDimensionPixelSize(R.dimen.control_container_height))
.thenReturn(TOOLBAR_HEIGHT);
when(mControlContainer.getView()).thenReturn(mContainerView);
when(mTab.isUserInteractable()).thenReturn(true);
ChromeFullscreenManager fullscreenManager = new ChromeFullscreenManager(
mActivity, ChromeFullscreenManager.ControlsPosition.TOP);
mFullscreenManager = spy(fullscreenManager);
mFullscreenManager.initialize(mControlContainer, mActivityTabProvider, mTabModelSelector,
R.dimen.control_container_height);
when(mFullscreenManager.getTab()).thenReturn(mTab);
mContext = ApplicationProvider.getApplicationContext();
mCompositorViewHolder = spy(new CompositorViewHolder(mContext));
mCompositorViewHolder.setFullscreenHandler(mFullscreenManager);
when(mCompositorViewHolder.getContentView()).thenReturn(mContentView);
mControlsResizeView = mCompositorViewHolder::controlsResizeView;
}
// controlsResizeView tests ---
// For these tests, we will simulate the scrolls assuming we either completely show or hide (or
// scroll until the min-height) the controls and don't leave at in-between positions. The reason
// is that CompositorViewHolder only flips the mControlsResizeView bit if the controls are
// idle, meaning they're at the min-height or fully shown. Making sure the controls snap to
// these two positions is not CVH's responsibility as it's handled in native code by compositor
// or blink.
@Test
public void testControlsResizeViewChanges() {
// Let's use simpler numbers for this test.
final int topHeight = 100;
final int topMinHeight = 0;
TabModelSelectorTabObserver tabControlsObserver =
mFullscreenManager.getTabControlsObserverForTesting();
mFullscreenManager.setTopControlsHeight(topHeight, topMinHeight);
// Send initial offsets.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 0, /*bottomControlsMinHeightOffsetY*/ 0);
// Initially, the controls should be fully visible.
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView.get());
// Scroll to fully hidden.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -100,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 0,
/*topControlsMinHeightOffsetY*/ 0, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue("Browser controls aren't at min-height.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertFalse("ControlsResizeView is true,"
+ " but it should be false when the controls are hidden.",
mControlsResizeView.get());
// Now, scroll back to fully visible.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 0, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse("Browser controls are hidden when they should be fully visible.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
// #controlsResizeView should be flipped back to true.
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView.get());
}
@Test
public void testControlsResizeViewChangesWithMinHeight() {
// Let's use simpler numbers for this test. We'll simulate the scrolling logic in the
// compositor. Which means the top and bottom controls will have the same normalized ratio.
// E.g. if the top content offset is 25 (at min-height so the normalized ratio is 0), the
// bottom content offset will be 0 (min-height-0 + normalized-ratio-0 * rest-of-height-60).
final int topHeight = 100;
final int topMinHeight = 25;
final int bottomHeight = 60;
final int bottomMinHeight = 0;
TabModelSelectorTabObserver tabControlsObserver =
mFullscreenManager.getTabControlsObserverForTesting();
mFullscreenManager.setTopControlsHeight(topHeight, topMinHeight);
mFullscreenManager.setBottomControlsHeight(bottomHeight, bottomMinHeight);
// Send initial offsets.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
// Initially, the controls should be fully visible.
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView.get());
// Scroll all the way to the min-height.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -75,
/*bottomControlsOffsetY*/ 60, /*contentOffsetY*/ 25,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue("Browser controls aren't at min-height.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertFalse("ControlsResizeView is true,"
+ " but it should be false when the controls are at min-height.",
mControlsResizeView.get());
// Now, scroll back to fully visible.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse("Browser controls are at min-height when they should be fully visible.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
// #controlsResizeView should be flipped back to true.
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView.get());
}
@Test
public void testControlsResizeViewWhenControlsAreNotIdle() {
// Let's use simpler numbers for this test. We'll simulate the scrolling logic in the
// compositor. Which means the top and bottom controls will have the same normalized ratio.
// E.g. if the top content offset is 25 (at min-height so the normalized ratio is 0), the
// bottom content offset will be 0 (min-height-0 + normalized-ratio-0 * rest-of-height-60).
final int topHeight = 100;
final int topMinHeight = 25;
final int bottomHeight = 60;
final int bottomMinHeight = 0;
TabModelSelectorTabObserver tabControlsObserver =
mFullscreenManager.getTabControlsObserverForTesting();
mFullscreenManager.setTopControlsHeight(topHeight, topMinHeight);
mFullscreenManager.setBottomControlsHeight(bottomHeight, bottomMinHeight);
// Send initial offsets.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView.get());
// Scroll a little hide the controls partially.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -25,
/*bottomControlsOffsetY*/ 20, /*contentOffsetY*/ 75,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue("ControlsResizeView is false, but it should still be true.",
mControlsResizeView.get());
// Scroll controls all the way to the min-height.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -75,
/*bottomControlsOffsetY*/ 60, /*contentOffsetY*/ 25,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse("ControlsResizeView is true,"
+ " but it should've flipped to false since the controls are idle now.",
mControlsResizeView.get());
// Scroll controls to show a little more.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -50,
/*bottomControlsOffsetY*/ 40, /*contentOffsetY*/ 50,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse("ControlsResizeView is true, but it should still be false.",
mControlsResizeView.get());
}
// --- controlsResizeView tests
}
...@@ -7,12 +7,10 @@ package org.chromium.chrome.browser.fullscreen; ...@@ -7,12 +7,10 @@ package org.chromium.chrome.browser.fullscreen;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doNothing;
...@@ -40,10 +38,8 @@ import org.chromium.base.test.BaseRobolectricTestRunner; ...@@ -40,10 +38,8 @@ import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
import org.chromium.chrome.browser.toolbar.ControlContainer; import org.chromium.chrome.browser.toolbar.ControlContainer;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.embedder_support.view.ContentView; import org.chromium.components.embedder_support.view.ContentView;
...@@ -81,7 +77,6 @@ public class FullscreenManagerUnitTest { ...@@ -81,7 +77,6 @@ public class FullscreenManagerUnitTest {
private UserDataHost mUserDataHost = new UserDataHost(); private UserDataHost mUserDataHost = new UserDataHost();
private ChromeFullscreenManager mFullscreenManager; private ChromeFullscreenManager mFullscreenManager;
private boolean mControlsResizeView;
@Before @Before
public void setUp() { public void setUp() {
...@@ -108,10 +103,6 @@ public class FullscreenManagerUnitTest { ...@@ -108,10 +103,6 @@ public class FullscreenManagerUnitTest {
mFullscreenManager.initialize(mControlContainer, mActivityTabProvider, mTabModelSelector, mFullscreenManager.initialize(mControlContainer, mActivityTabProvider, mTabModelSelector,
R.dimen.control_container_height); R.dimen.control_container_height);
mFullscreenManager.addObserver(mBrowserControlsStateProviderObserver); mFullscreenManager.addObserver(mBrowserControlsStateProviderObserver);
mFullscreenManager.setViewportSizeDelegate(() -> {
if (!BrowserControlsUtils.areBrowserControlsIdle(mFullscreenManager)) return;
mControlsResizeView = BrowserControlsUtils.controlsResizeView(mFullscreenManager);
});
when(mFullscreenManager.getTab()).thenReturn(mTab); when(mFullscreenManager.getTab()).thenReturn(mTab);
} }
...@@ -274,160 +265,4 @@ public class FullscreenManagerUnitTest { ...@@ -274,160 +265,4 @@ public class FullscreenManagerUnitTest {
verify(mBrowserControlsStateProviderObserver).onTopControlsHeightChanged(TOOLBAR_HEIGHT, 0); verify(mBrowserControlsStateProviderObserver).onTopControlsHeightChanged(TOOLBAR_HEIGHT, 0);
} }
// controlsResizeView tests ---
// For these tests, we will simulate the scrolls assuming we either completely show or hide (or
// scroll until the min-height) the controls and don't leave at in-between positions. The reason
// is that ChromeFullscreenManager only flips the mControlsResizeView bit if the controls are
// idle, meaning they're at the min-height or fully shown. Making sure the controls snap to
// these two positions is not CFM's responsibility as it's handled in native code by compositor
// or blink.
@Test
public void testControlsResizeViewChanges() {
// Let's use simpler numbers for this test.
final int topHeight = 100;
final int topMinHeight = 0;
TabModelSelectorTabObserver tabControlsObserver =
mFullscreenManager.getTabControlsObserverForTesting();
mFullscreenManager.setTopControlsHeight(topHeight, topMinHeight);
// Send initial offsets.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 0, /*bottomControlsMinHeightOffsetY*/ 0);
// Initially, the controls should be fully visible.
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView);
// Scroll to fully hidden.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -100,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 0,
/*topControlsMinHeightOffsetY*/ 0, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue("Browser controls aren't at min-height.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertFalse("ControlsResizeView is true,"
+ " but it should be false when the controls are hidden.",
mControlsResizeView);
// Now, scroll back to fully visible.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 0, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse("Browser controls are hidden when they should be fully visible.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
// #controlsResizeView should be flipped back to true.
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView);
}
@Test
public void testControlsResizeViewChangesWithMinHeight() {
// Let's use simpler numbers for this test. We'll simulate the scrolling logic in the
// compositor. Which means the top and bottom controls will have the same normalized ratio.
// E.g. if the top content offset is 25 (at min-height so the normalized ratio is 0), the
// bottom content offset will be 0 (min-height-0 + normalized-ratio-0 * rest-of-height-60).
final int topHeight = 100;
final int topMinHeight = 25;
final int bottomHeight = 60;
final int bottomMinHeight = 0;
TabModelSelectorTabObserver tabControlsObserver =
mFullscreenManager.getTabControlsObserverForTesting();
mFullscreenManager.setTopControlsHeight(topHeight, topMinHeight);
mFullscreenManager.setBottomControlsHeight(bottomHeight, bottomMinHeight);
// Send initial offsets.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
// Initially, the controls should be fully visible.
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView);
// Scroll all the way to the min-height.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -75,
/*bottomControlsOffsetY*/ 60, /*contentOffsetY*/ 25,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue("Browser controls aren't at min-height.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertFalse("ControlsResizeView is true,"
+ " but it should be false when the controls are at min-height.",
mControlsResizeView);
// Now, scroll back to fully visible.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse("Browser controls are at min-height when they should be fully visible.",
mFullscreenManager.areBrowserControlsAtMinHeight());
assertTrue("Browser controls aren't fully visible.",
BrowserControlsUtils.areBrowserControlsFullyVisible(mFullscreenManager));
// #controlsResizeView should be flipped back to true.
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView);
}
@Test
public void testControlsResizeViewWhenControlsAreNotIdle() {
// Let's use simpler numbers for this test. We'll simulate the scrolling logic in the
// compositor. Which means the top and bottom controls will have the same normalized ratio.
// E.g. if the top content offset is 25 (at min-height so the normalized ratio is 0), the
// bottom content offset will be 0 (min-height-0 + normalized-ratio-0 * rest-of-height-60).
final int topHeight = 100;
final int topMinHeight = 25;
final int bottomHeight = 60;
final int bottomMinHeight = 0;
TabModelSelectorTabObserver tabControlsObserver =
mFullscreenManager.getTabControlsObserverForTesting();
mFullscreenManager.setTopControlsHeight(topHeight, topMinHeight);
mFullscreenManager.setBottomControlsHeight(bottomHeight, bottomMinHeight);
// Send initial offsets.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ 0,
/*bottomControlsOffsetY*/ 0, /*contentOffsetY*/ 100,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue("ControlsResizeView is false,"
+ " but it should be true when the controls are fully visible.",
mControlsResizeView);
// Scroll a little hide the controls partially.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -25,
/*bottomControlsOffsetY*/ 20, /*contentOffsetY*/ 75,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertTrue(
"ControlsResizeView is false, but it should still be true.", mControlsResizeView);
// Scroll controls all the way to the min-height.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -75,
/*bottomControlsOffsetY*/ 60, /*contentOffsetY*/ 25,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse("ControlsResizeView is true,"
+ " but it should've flipped to false since the controls are idle now.",
mControlsResizeView);
// Scroll controls to show a little more.
tabControlsObserver.onBrowserControlsOffsetChanged(mTab, /*topControlsOffsetY*/ -50,
/*bottomControlsOffsetY*/ 40, /*contentOffsetY*/ 50,
/*topControlsMinHeightOffsetY*/ 25, /*bottomControlsMinHeightOffsetY*/ 0);
assertFalse(
"ControlsResizeView is true, but it should still be false.", mControlsResizeView);
}
// --- controlsResizeView tests
} }
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