Commit 4ee2b042 authored by dfalcantara's avatar dfalcantara Committed by Commit bot

Make infobars hide on scroll

* Makes it so that infobars hide when scrolling the page and
  return at the top of the page.

* SwipableOverlayView is now the base class of InfoBarContainer
  and now extends from ScrollLayout.

* Adds way to disable the SwipableOverlayView from being swiped
  away.

* AppBannerView (which is going away soon) is adjusted to account
  for the new ScrollLayout requirement of having only one child.

BUG=453170

Review URL: https://codereview.chromium.org/893483002

Cr-Commit-Position: refs/heads/master@{#313987}
parent f85f099e
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<FrameLayout
android:id="@+id/banner_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- View showing the icon. --> <!-- View showing the icon. -->
<ImageView <ImageView
android:id="@+id/app_icon" android:id="@+id/app_icon"
...@@ -84,4 +88,5 @@ ...@@ -84,4 +88,5 @@
android:visibility="gone" android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</FrameLayout>
</org.chromium.chrome.browser.banners.AppBannerView> </org.chromium.chrome.browser.banners.AppBannerView>
...@@ -1259,7 +1259,6 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener, ...@@ -1259,7 +1259,6 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
updateTitle(); updateTitle();
removeSadTabIfPresent(); removeSadTabIfPresent();
mInfoBarContainer.onPageStarted();
if (getContentViewCore() != null) { if (getContentViewCore() != null) {
getContentViewCore().stopCurrentAccessibilityNotifications(); getContentViewCore().stopCurrentAccessibilityNotifications();
...@@ -1365,10 +1364,11 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener, ...@@ -1365,10 +1364,11 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
// initialized. // initialized.
WebContents webContents = mContentViewCore.getWebContents(); WebContents webContents = mContentViewCore.getWebContents();
mInfoBarContainer = new InfoBarContainer( mInfoBarContainer = new InfoBarContainer(
mContext, getId(), mContentViewParent, webContents); mContext, getId(), mContentViewParent, webContents, this);
} else { } else {
mInfoBarContainer.onParentViewChanged(getId(), mContentViewParent); mInfoBarContainer.onParentViewChanged(getId(), mContentViewParent);
} }
mInfoBarContainer.setContentViewCore(mContentViewCore);
if (AppBannerManager.isEnabled() && mAppBannerManager == null) { if (AppBannerManager.isEnabled() && mAppBannerManager == null) {
mAppBannerManager = new AppBannerManager(this); mAppBannerManager = new AppBannerManager(this);
...@@ -1773,6 +1773,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener, ...@@ -1773,6 +1773,7 @@ public class Tab implements ViewGroup.OnHierarchyChangeListener,
if (mInfoBarContainer != null && mInfoBarContainer.getParent() != null) { if (mInfoBarContainer != null && mInfoBarContainer.getParent() != null) {
mInfoBarContainer.removeFromParentView(); mInfoBarContainer.removeFromParentView();
mInfoBarContainer.setContentViewCore(null);
} }
mContentViewParent = null; mContentViewParent = null;
mContentViewCore.destroy(); mContentViewCore.destroy();
......
...@@ -122,6 +122,7 @@ public class AppBannerView extends SwipableOverlayView ...@@ -122,6 +122,7 @@ public class AppBannerView extends SwipableOverlayView
private AppData mAppData; private AppData mAppData;
// Views comprising the app banner. // Views comprising the app banner.
private ViewGroup mContainerView;
private ImageView mIconView; private ImageView mIconView;
private TextView mTitleView; private TextView mTitleView;
private Button mInstallButtonView; private Button mInstallButtonView;
...@@ -164,7 +165,8 @@ public class AppBannerView extends SwipableOverlayView ...@@ -164,7 +165,8 @@ public class AppBannerView extends SwipableOverlayView
AppBannerView banner = AppBannerView banner =
(AppBannerView) LayoutInflater.from(context).inflate(BANNER_LAYOUT, null); (AppBannerView) LayoutInflater.from(context).inflate(BANNER_LAYOUT, null);
banner.initialize(observer, data); banner.initialize(observer, data);
banner.addToView(contentViewCore); banner.setContentViewCore(contentViewCore);
banner.addToParentView(contentViewCore.getContainerView());
return banner; return banner;
} }
...@@ -219,6 +221,7 @@ public class AppBannerView extends SwipableOverlayView ...@@ -219,6 +221,7 @@ public class AppBannerView extends SwipableOverlayView
} }
// Pull out all of the controls we are expecting. // Pull out all of the controls we are expecting.
mContainerView = (ViewGroup) findViewById(R.id.banner_container);
mIconView = (ImageView) findViewById(R.id.app_icon); mIconView = (ImageView) findViewById(R.id.app_icon);
mTitleView = (TextView) findViewById(R.id.app_title); mTitleView = (TextView) findViewById(R.id.app_title);
mInstallButtonView = (Button) findViewById(R.id.app_install_button); mInstallButtonView = (Button) findViewById(R.id.app_install_button);
...@@ -380,7 +383,7 @@ public class AppBannerView extends SwipableOverlayView ...@@ -380,7 +383,7 @@ public class AppBannerView extends SwipableOverlayView
} }
@Override @Override
protected ViewGroup.MarginLayoutParams createLayoutParams() { public ViewGroup.MarginLayoutParams createLayoutParams() {
// Define the margin around the entire banner that accounts for the drop shadow. // Define the margin around the entire banner that accounts for the drop shadow.
ViewGroup.MarginLayoutParams params = super.createLayoutParams(); ViewGroup.MarginLayoutParams params = super.createLayoutParams();
params.setMargins(mMarginLeft, 0, mMarginRight, mMarginBottom); params.setMargins(mMarginLeft, 0, mMarginRight, mMarginBottom);
...@@ -392,8 +395,8 @@ public class AppBannerView extends SwipableOverlayView ...@@ -392,8 +395,8 @@ public class AppBannerView extends SwipableOverlayView
* @return Whether or not the View was successfully dismissed. * @return Whether or not the View was successfully dismissed.
*/ */
@Override @Override
boolean removeFromParent() { public boolean removeFromParentView() {
if (super.removeFromParent()) { if (super.removeFromParentView()) {
mObserver.onBannerRemoved(this); mObserver.onBannerRemoved(this);
destroy(); destroy();
return true; return true;
...@@ -634,9 +637,10 @@ public class AppBannerView extends SwipableOverlayView ...@@ -634,9 +637,10 @@ public class AppBannerView extends SwipableOverlayView
// Determine how big each component wants to be. The icon is measured separately because // Determine how big each component wants to be. The icon is measured separately because
// it is not stacked with the other controls. // it is not stacked with the other controls.
measureChildForSpace(mIconView, maxControlWidth, maxControlHeight); measureChildForSpace(mIconView, maxControlWidth, maxControlHeight);
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < mContainerView.getChildCount(); i++) {
if (getChildAt(i) != mIconView) { View child = mContainerView.getChildAt(i);
measureChildForSpace(getChildAt(i), maxControlWidth, maxStackedControlHeight); if (child != mIconView) {
measureChildForSpace(child, maxControlWidth, maxStackedControlHeight);
} }
} }
...@@ -699,6 +703,7 @@ public class AppBannerView extends SwipableOverlayView ...@@ -699,6 +703,7 @@ public class AppBannerView extends SwipableOverlayView
+ (mPaddingCard * 2); + (mPaddingCard * 2);
int bannerHeight = biggestStackHeight + bannerPadding; int bannerHeight = biggestStackHeight + bannerPadding;
setMeasuredDimension(bannerWidth, bannerHeight); setMeasuredDimension(bannerWidth, bannerHeight);
measureChildForSpaceExactly(mContainerView, bannerWidth, bannerHeight);
// Make the banner highlight view be the exact same size as the banner's card background. // Make the banner highlight view be the exact same size as the banner's card background.
final int cardWidth = bannerWidth - bgPaddingWidth; final int cardWidth = bannerWidth - bgPaddingWidth;
...@@ -713,6 +718,8 @@ public class AppBannerView extends SwipableOverlayView ...@@ -713,6 +718,8 @@ public class AppBannerView extends SwipableOverlayView
@Override @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b); super.onLayout(changed, l, t, r, b);
mContainerView.layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
int top = mBackgroundDrawablePadding.top; int top = mBackgroundDrawablePadding.top;
int bottom = getMeasuredHeight() - mBackgroundDrawablePadding.bottom; int bottom = getMeasuredHeight() - mBackgroundDrawablePadding.bottom;
int start = mBackgroundDrawablePadding.left; int start = mBackgroundDrawablePadding.left;
......
...@@ -20,7 +20,11 @@ import android.view.ViewGroup; ...@@ -20,7 +20,11 @@ import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ScrollView;
import org.chromium.chrome.browser.EmptyTabObserver;
import org.chromium.chrome.browser.Tab;
import org.chromium.chrome.browser.TabObserver;
import org.chromium.content.browser.ContentViewCore; import org.chromium.content.browser.ContentViewCore;
import org.chromium.content_public.browser.GestureStateListener; import org.chromium.content_public.browser.GestureStateListener;
import org.chromium.ui.UiUtils; import org.chromium.ui.UiUtils;
...@@ -67,12 +71,13 @@ import org.chromium.ui.UiUtils; ...@@ -67,12 +71,13 @@ import org.chromium.ui.UiUtils;
* fling is completed, the more forgiving FLING_THRESHOLD is used to determine how far a user must * fling is completed, the more forgiving FLING_THRESHOLD is used to determine how far a user must
* swipe to dismiss the View rather than try to use the fling velocity. * swipe to dismiss the View rather than try to use the fling velocity.
*/ */
public abstract class SwipableOverlayView extends FrameLayout { public abstract class SwipableOverlayView extends ScrollView {
private static final float ALPHA_THRESHOLD = 0.25f; private static final float ALPHA_THRESHOLD = 0.25f;
private static final float DISMISS_SWIPE_THRESHOLD = 0.75f; private static final float DISMISS_SWIPE_THRESHOLD = 0.75f;
private static final float FULL_THRESHOLD = 0.5f; private static final float FULL_THRESHOLD = 0.5f;
private static final float VERTICAL_FLING_SHOW_THRESHOLD = 0.2f; private static final float VERTICAL_FLING_SHOW_THRESHOLD = 0.2f;
private static final float VERTICAL_FLING_HIDE_THRESHOLD = 0.9f; private static final float VERTICAL_FLING_HIDE_THRESHOLD = 0.9f;
private static final long REATTACH_FADE_IN_MS = 250;
protected static final float ZERO_THRESHOLD = 0.001f; protected static final float ZERO_THRESHOLD = 0.001f;
private static final int GESTURE_NONE = 0; private static final int GESTURE_NONE = 0;
...@@ -87,18 +92,34 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -87,18 +92,34 @@ public abstract class SwipableOverlayView extends FrameLayout {
private static final long MS_DISMISS_FLING_THRESHOLD = MS_ANIMATION_DURATION * 2; private static final long MS_DISMISS_FLING_THRESHOLD = MS_ANIMATION_DURATION * 2;
private static final long MS_SLOW_DISMISS = MS_ANIMATION_DURATION * 3; private static final long MS_SLOW_DISMISS = MS_ANIMATION_DURATION * 3;
/** Resets the state of the SwipableOverlayView, as needed. */
protected class SwipableOverlayViewTabObserver extends EmptyTabObserver {
@Override
public void onDidNavigateMainFrame(Tab tab, String url, String baseUrl,
boolean isNavigationToDifferentPage, boolean isFragmentNavigation,
int statusCode) {
setDoStayInvisible(false);
}
}
// Detects when the user is dragging the View. // Detects when the user is dragging the View.
private final GestureDetector mGestureDetector; private final GestureDetector mGestureDetector;
// Detects when the user is dragging the ContentViewCore. // Detects when the user is dragging the ContentViewCore.
private final GestureStateListener mGestureStateListener; private final GestureStateListener mGestureStateListener;
// Listens for changes in the layout.
private final View.OnLayoutChangeListener mLayoutChangeListener;
// Monitors for animation completions and resets the state. // Monitors for animation completions and resets the state.
private final AnimatorListenerAdapter mAnimatorListenerAdapter; private final AnimatorListenerAdapter mAnimatorListenerAdapter;
// Interpolator used for the animation. // Interpolator used for the animation.
private final Interpolator mInterpolator; private final Interpolator mInterpolator;
// Observes the Tab.
private final TabObserver mTabObserver;
// Tracks whether the user is scrolling or flinging. // Tracks whether the user is scrolling or flinging.
private int mGestureState; private int mGestureState;
...@@ -135,6 +156,12 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -135,6 +156,12 @@ public abstract class SwipableOverlayView extends FrameLayout {
// The ContentViewCore to which the overlay is added. // The ContentViewCore to which the overlay is added.
private ContentViewCore mContentViewCore; private ContentViewCore mContentViewCore;
// Keeps the View from becoming visible when it normally would.
private boolean mDoStayInvisible;
// Whether the View should be allowed to be swiped away.
private boolean mIsSwipable = true;
/** /**
* Creates a SwipableOverlayView. * Creates a SwipableOverlayView.
* @param context Context for acquiring resources. * @param context Context for acquiring resources.
...@@ -146,22 +173,53 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -146,22 +173,53 @@ public abstract class SwipableOverlayView extends FrameLayout {
mGestureDetector = new GestureDetector(context, gestureListener); mGestureDetector = new GestureDetector(context, gestureListener);
mGestureStateListener = createGestureStateListener(); mGestureStateListener = createGestureStateListener();
mGestureState = GESTURE_NONE; mGestureState = GESTURE_NONE;
mLayoutChangeListener = createLayoutChangeListener();
mAnimatorListenerAdapter = createAnimatorListenerAdapter(); mAnimatorListenerAdapter = createAnimatorListenerAdapter();
mInterpolator = new DecelerateInterpolator(1.0f); mInterpolator = new DecelerateInterpolator(1.0f);
mTabObserver = createTabObserver();
}
/**
* Indicates whether the View should be allowed to be swiped away.
* @param swipable Whether the View is reacts to horizontal gestures.
*/
protected void setIsSwipable(boolean swipable) {
mIsSwipable = swipable;
} }
/** /**
* Adds this View to the given ContentViewCore's view. * Watches the given ContentViewCore for scrolling changes.
* @param layout Layout to add this View to.
*/ */
protected void addToView(ContentViewCore contentViewCore) { public void setContentViewCore(ContentViewCore contentViewCore) {
assert mContentViewCore == null; if (mContentViewCore != null) {
mContentViewCore.removeGestureStateListener(mGestureStateListener);
}
mContentViewCore = contentViewCore; mContentViewCore = contentViewCore;
contentViewCore.getContainerView().addView(this, 0, createLayoutParams()); if (mContentViewCore != null) {
contentViewCore.addGestureStateListener(mGestureStateListener); mContentViewCore.addGestureStateListener(mGestureStateListener);
}
}
public void addToParentView(ViewGroup parentView) {
if (parentView != null && parentView.indexOfChild(this) == -1) {
parentView.addView(this, createLayoutParams());
// Listen for the layout to know when to animate the View coming onto the screen. // Listen for the layout to know when to animate the View coming onto the screen.
addOnLayoutChangeListener(createLayoutChangeListener()); addOnLayoutChangeListener(mLayoutChangeListener);
}
}
/**
* Removes the SwipableOverlayView from its parent and stops monitoring the ContentViewCore.
* @return Whether the View was removed from its parent.
*/
public boolean removeFromParentView() {
if (getParent() == null) return false;
((ViewGroup) getParent()).removeView(this);
removeOnLayoutChangeListener(mLayoutChangeListener);
return true;
} }
/** /**
...@@ -169,21 +227,43 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -169,21 +227,43 @@ public abstract class SwipableOverlayView extends FrameLayout {
* for other types of behavior. * for other types of behavior.
* @return LayoutParams for use when adding the View to its parent. * @return LayoutParams for use when adding the View to its parent.
*/ */
protected ViewGroup.MarginLayoutParams createLayoutParams() { public ViewGroup.MarginLayoutParams createLayoutParams() {
return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
} }
/** /**
* Removes the View from its parent. * Call with {@code true} when a higher priority bottom element is visible to keep the View
* from ever becoming visible. Call with {@code false} to restore normal visibility behavior.
* @param doStayInvisible Whether the View should stay invisible even when they would
* normally become visible.
*/ */
boolean removeFromParent() { public void setDoStayInvisible(boolean doStayInvisible) {
if (mContentViewCore != null) { mDoStayInvisible = doStayInvisible;
mContentViewCore.getContainerView().removeView(this);
mContentViewCore = null;
return true;
} }
return false;
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!mDoStayInvisible) {
ObjectAnimator.ofFloat(this, "alpha", 0.f, 1.f).setDuration(REATTACH_FADE_IN_MS)
.start();
setVisibility(VISIBLE);
}
}
/**
* @return TabObserver that can be used to monitor a Tab.
*/
protected TabObserver createTabObserver() {
return new SwipableOverlayViewTabObserver();
}
/**
* @return TabObserver that is used to monitor a Tab.
*/
public TabObserver getTabObserver() {
return mTabObserver;
} }
/** /**
...@@ -192,8 +272,16 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -192,8 +272,16 @@ public abstract class SwipableOverlayView extends FrameLayout {
@Override @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Hide the View when the keyboard is showing. // Hide the View when the keyboard is showing.
boolean keyboardIsShowing = UiUtils.isKeyboardShowing(getContext(), this); boolean isShowing = (getVisibility() == View.VISIBLE);
setVisibility(keyboardIsShowing ? INVISIBLE : VISIBLE); if (UiUtils.isKeyboardShowing(getContext(), this)) {
if (isShowing) {
setVisibility(View.INVISIBLE);
}
} else {
if (!isShowing && !mDoStayInvisible) {
setVisibility(View.VISIBLE);
}
}
// Update the viewport height when the parent View's height changes (e.g. after rotation). // Update the viewport height when the parent View's height changes (e.g. after rotation).
int currentParentHeight = getParent() == null ? 0 : ((View) getParent()).getHeight(); int currentParentHeight = getParent() == null ? 0 : ((View) getParent()).getHeight();
...@@ -218,6 +306,8 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -218,6 +306,8 @@ public abstract class SwipableOverlayView extends FrameLayout {
*/ */
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if (!mIsSwipable) return false;
if (mGestureDetector.onTouchEvent(event)) return true; if (mGestureDetector.onTouchEvent(event)) return true;
if (mCurrentAnimation != null) return true; if (mCurrentAnimation != null) return true;
...@@ -391,7 +481,7 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -391,7 +481,7 @@ public abstract class SwipableOverlayView extends FrameLayout {
@Override @Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) { int oldLeft, int oldTop, int oldRight, int oldBottom) {
removeOnLayoutChangeListener(this); removeOnLayoutChangeListener(mLayoutChangeListener);
// Animate the View coming in from the bottom of the screen. // Animate the View coming in from the bottom of the screen.
setTranslationY(mTotalHeight); setTranslationY(mTotalHeight);
...@@ -560,7 +650,7 @@ public abstract class SwipableOverlayView extends FrameLayout { ...@@ -560,7 +650,7 @@ public abstract class SwipableOverlayView extends FrameLayout {
return new AnimatorListenerAdapter() { return new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (mIsDismissed) removeFromParent(); if (mIsDismissed) removeFromParentView();
mGestureState = GESTURE_NONE; mGestureState = GESTURE_NONE;
mCurrentAnimation = null; mCurrentAnimation = null;
......
...@@ -46,8 +46,8 @@ public final class DomDistillerFeedbackReporter implements ...@@ -46,8 +46,8 @@ public final class DomDistillerFeedbackReporter implements
* @return whether the DOM Distiller feature is enabled. * @return whether the DOM Distiller feature is enabled.
*/ */
public static boolean isEnabled() { public static boolean isEnabled() {
return (ChromeVersionInfo.isLocalBuild() || ChromeVersionInfo.isDevBuild()) && return (ChromeVersionInfo.isLocalBuild() || ChromeVersionInfo.isDevBuild())
nativeIsEnabled(); && nativeIsEnabled();
} }
/** /**
......
...@@ -63,7 +63,8 @@ public class DomDistillerFeedbackReportingView extends SwipableOverlayView { ...@@ -63,7 +63,8 @@ public class DomDistillerFeedbackReportingView extends SwipableOverlayView {
(DomDistillerFeedbackReportingView) LayoutInflater.from(context) (DomDistillerFeedbackReportingView) LayoutInflater.from(context)
.inflate(VIEW_LAYOUT, null); .inflate(VIEW_LAYOUT, null);
view.initialize(feedbackObserver); view.initialize(feedbackObserver);
view.addToView(contentViewCore); view.setContentViewCore(contentViewCore);
view.addToParentView(contentViewCore.getContainerView());
return view; return view;
} }
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.infobar; package org.chromium.chrome.browser.infobar;
import android.animation.ObjectAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
...@@ -14,16 +13,14 @@ import android.view.View; ...@@ -14,16 +13,14 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ScrollView;
import org.chromium.base.CalledByNative; import org.chromium.base.CalledByNative;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.EmptyTabObserver;
import org.chromium.chrome.browser.Tab; import org.chromium.chrome.browser.Tab;
import org.chromium.chrome.browser.TabObserver; import org.chromium.chrome.browser.TabObserver;
import org.chromium.chrome.browser.banners.SwipableOverlayView;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.UiUtils;
import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.DeviceFormFactor;
import java.util.ArrayDeque; import java.util.ArrayDeque;
...@@ -38,9 +35,8 @@ import java.util.LinkedList; ...@@ -38,9 +35,8 @@ import java.util.LinkedList;
* When initiated from native code, special code is needed to keep the Java and native infobar in * When initiated from native code, special code is needed to keep the Java and native infobar in
* sync, see NativeInfoBar. * sync, see NativeInfoBar.
*/ */
public class InfoBarContainer extends ScrollView { public class InfoBarContainer extends SwipableOverlayView {
private static final String TAG = "InfoBarContainer"; private static final String TAG = "InfoBarContainer";
private static final long REATTACH_FADE_IN_MS = 250;
private static final int TAB_STRIP_AND_TOOLBAR_HEIGHT_PHONE_DP = 56; private static final int TAB_STRIP_AND_TOOLBAR_HEIGHT_PHONE_DP = 56;
private static final int TAB_STRIP_AND_TOOLBAR_HEIGHT_TABLET_DP = 96; private static final int TAB_STRIP_AND_TOOLBAR_HEIGHT_TABLET_DP = 96;
...@@ -111,13 +107,11 @@ public class InfoBarContainer extends ScrollView { ...@@ -111,13 +107,11 @@ public class InfoBarContainer extends ScrollView {
private Paint mTopBorderPaint; private Paint mTopBorderPaint;
// Keeps the infobars from becoming visible when they normally would. public InfoBarContainer(
private boolean mDoStayInvisible; Context context, int tabId, ViewGroup parentView, WebContents webContents, Tab tab) {
private TabObserver mTabObserver; super(context, null);
tab.addObserver(getTabObserver());
public InfoBarContainer(Context context, int tabId, ViewGroup parentView, setIsSwipable(false);
WebContents webContents) {
super(context);
// Workaround for http://crbug.com/407149. See explanation in onMeasure() below. // Workaround for http://crbug.com/407149. See explanation in onMeasure() below.
setVerticalScrollBarEnabled(false); setVerticalScrollBarEnabled(false);
...@@ -202,16 +196,8 @@ public class InfoBarContainer extends ScrollView { ...@@ -202,16 +196,8 @@ public class InfoBarContainer extends ScrollView {
return true; return true;
} }
private void addToParentView() { protected void addToParentView() {
if (mParentView != null && mParentView.indexOfChild(this) == -1) { super.addToParentView(mParentView);
mParentView.addView(this);
}
}
public void removeFromParentView() {
if (getParent() != null) {
((ViewGroup) getParent()).removeView(this);
}
} }
/** /**
...@@ -226,47 +212,14 @@ public class InfoBarContainer extends ScrollView { ...@@ -226,47 +212,14 @@ public class InfoBarContainer extends ScrollView {
addToParentView(); addToParentView();
} }
/**
* Call with {@code true} when a higher priority bottom element is visible to keep the infobars
* from ever becoming visible. Call with {@code false} to restore normal visibility behavior.
* @param doStayInvisible Whether the infobars should stay invisible even when they would
* normally become visible.
* @param tab The current Tab.
*/
public void setDoStayInvisible(boolean doStayInvisible, Tab tab) {
mDoStayInvisible = doStayInvisible;
if (mTabObserver == null) mTabObserver = createTabObserver();
if (doStayInvisible) {
tab.addObserver(mTabObserver);
} else {
tab.removeObserver(mTabObserver);
}
}
/**
* Creates a TabObserver for monitoring a Tab, used to reset internal settings when a
* navigation is done.
* @return TabObserver that can be used to monitor a Tab.
*/
private TabObserver createTabObserver() {
return new EmptyTabObserver() {
@Override @Override
public void onDidNavigateMainFrame(Tab tab, String url, String baseUrl, protected TabObserver createTabObserver() {
boolean isNavigationToDifferentPage, boolean isFragmentNavigation, return new SwipableOverlayViewTabObserver() {
int statusCode) {
setDoStayInvisible(false, tab);
}
};
}
@Override @Override
protected void onAttachedToWindow() { public void onPageLoadStarted(Tab tab) {
super.onAttachedToWindow(); onPageStarted();
if (!mDoStayInvisible) {
ObjectAnimator.ofFloat(this, "alpha", 0.f, 1.f).setDuration(REATTACH_FADE_IN_MS)
.start();
setVisibility(VISIBLE);
} }
};
} }
@Override @Override
...@@ -383,17 +336,6 @@ public class InfoBarContainer extends ScrollView { ...@@ -383,17 +336,6 @@ public class InfoBarContainer extends ScrollView {
@Override @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Hide the infobars when the keyboard is showing.
boolean isShowing = (getVisibility() == View.VISIBLE);
if (UiUtils.isKeyboardShowing(mContext, this)) {
if (isShowing) {
setVisibility(View.INVISIBLE);
}
} else {
if (!isShowing && !mDoStayInvisible) {
setVisibility(View.VISIBLE);
}
}
super.onLayout(changed, l, t, r, b); super.onLayout(changed, l, t, r, b);
// Keep the infobars fixed to the bottom of the screen when infobars are added or removed. // Keep the infobars fixed to the bottom of the screen when infobars are added or removed.
...@@ -578,6 +520,21 @@ public class InfoBarContainer extends ScrollView { ...@@ -578,6 +520,21 @@ public class InfoBarContainer extends ScrollView {
return mNativeInfoBarContainer; return mNativeInfoBarContainer;
} }
@Override
protected void onViewSwipedAway() {
assert false;
}
@Override
protected void onViewClicked() {
assert false;
}
@Override
protected void onViewPressed(MotionEvent event) {
assert false;
}
private native long nativeInit(WebContents webContents); private native long nativeInit(WebContents webContents);
private native void nativeDestroy(long nativeInfoBarContainerAndroid); private native void nativeDestroy(long nativeInfoBarContainerAndroid);
} }
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