--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -123,17 +123,20 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
@@ -182,17 +185,18 @@ import java.util.List;
import java.util.Locale;
import java.util.Vector;
import java.util.regex.Pattern;
public class BrowserApp extends GeckoApp
implements TabsPanel.TabsLayoutChangeListener,
PropertyAnimator.PropertyAnimationListener,
View.OnKeyListener,
- LayerView.DynamicToolbarListener,
+ DynamicToolbarAnimator.MetricsListener,
+ DynamicToolbarAnimator.ToolbarChromeProxy,
BrowserSearch.OnSearchListener,
BrowserSearch.OnEditSuggestionListener,
OnUrlOpenListener,
OnUrlOpenInBackgroundListener,
AnchoredPopup.OnVisibilityChangeListener,
ActionModeCompat.Presenter,
LayoutInflater.Factory {
private static final String LOGTAG = "GeckoBrowserApp";
@@ -1312,34 +1316,24 @@ public class BrowserApp extends GeckoApp
// Intercept key events for gamepad shortcuts
mBrowserToolbar.setOnKeyListener(this);
}
private void setDynamicToolbarEnabled(boolean enabled) {
ThreadUtils.assertOnUiThread();
- if (enabled) {
- if (mLayerView != null) {
- mLayerView.getDynamicToolbarAnimator().addTranslationListener(this);
- }
- setToolbarMargin(0);
- mHomeScreenContainer.setPadding(0, mBrowserChrome.getHeight(), 0, 0);
- } else {
- // Immediately show the toolbar when disabling the dynamic
- // toolbar.
- if (mLayerView != null) {
- mLayerView.getDynamicToolbarAnimator().removeTranslationListener(this);
- }
- mHomeScreenContainer.setPadding(0, 0, 0, 0);
- if (mBrowserChrome != null) {
- ViewHelper.setTranslationY(mBrowserChrome, 0);
- }
- if (mLayerView != null) {
- mLayerView.setSurfaceTranslation(0);
+ if (mLayerView != null) {
+ if (enabled) {
+ mDynamicToolbar.setPinned(false, PinReason.DISABLED);
+ } else {
+ // Immediately show the toolbar when disabling the dynamic
+ // toolbar.
+ mDynamicToolbar.setPinned(true, PinReason.DISABLED);
+ mDynamicToolbar.setVisible(true, VisibilityTransition.IMMEDIATE);
}
}
refreshToolbarHeight();
}
private static boolean isAboutHome(final Tab tab) {
return AboutPages.isAboutHome(tab.getURL());
@@ -1602,16 +1596,20 @@ public class BrowserApp extends GeckoApp
@Override
protected void initializeChrome() {
super.initializeChrome();
mDoorHangerPopup.setAnchor(mBrowserToolbar.getDoorHangerAnchor());
mDoorHangerPopup.setOnVisibilityChangeListener(this);
+ if (mLayerView != null) {
+ mLayerView.getDynamicToolbarAnimator().addMetricsListener(this);
+ mLayerView.getDynamicToolbarAnimator().setToolbarChromeProxy(this);
+ }
mDynamicToolbar.setLayerView(mLayerView);
setDynamicToolbarEnabled(mDynamicToolbar.isEnabled());
// Intercept key events for gamepad shortcuts
mLayerView.setOnKeyListener(this);
// Initialize the actionbar menu items on startup for both large and small tablets
if (HardwareUtils.isTablet()) {
@@ -1633,106 +1631,70 @@ public class BrowserApp extends GeckoApp
@Override
public void onDoorHangerHide() {
final Animator alphaAnimator = ObjectAnimator.ofFloat(mDoorhangerOverlay, "alpha", 0);
alphaAnimator.setDuration(200);
alphaAnimator.start();
}
- private void setToolbarMargin(int margin) {
- ((RelativeLayout.LayoutParams) mGeckoLayout.getLayoutParams()).topMargin = margin;
- mGeckoLayout.requestLayout();
- }
-
- @Override
- public void onTranslationChanged(float aToolbarTranslation, float aLayerViewTranslation) {
- if (mBrowserChrome == null) {
- return;
- }
-
- final View browserChrome = mBrowserChrome;
- final ToolbarProgressView progressView = mProgressView;
-
- ViewHelper.setTranslationY(browserChrome, -aToolbarTranslation);
- mLayerView.setSurfaceTranslation(mToolbarHeight - aLayerViewTranslation);
-
- // Stop the progressView from moving all the way up so that we can still see a good chunk of it
- // when the chrome is offscreen.
- final float offset = getResources().getDimensionPixelOffset(R.dimen.progress_bar_scroll_offset);
- final float progressTranslationY = Math.min(aToolbarTranslation, mToolbarHeight - offset);
- ViewHelper.setTranslationY(progressView, -progressTranslationY);
-
- if (mFormAssistPopup != null) {
- mFormAssistPopup.onTranslationChanged();
- }
- }
-
@Override
public void onMetricsChanged(ImmutableViewportMetrics aMetrics) {
if (isHomePagerVisible() || mBrowserChrome == null) {
return;
}
if (mFormAssistPopup != null) {
mFormAssistPopup.onMetricsChanged(aMetrics);
}
}
+ // ToolbarChromeProxy inteface
@Override
- public void onPanZoomStopped() {
- if (!mDynamicToolbar.isEnabled() || isHomePagerVisible() ||
- mBrowserChrome.getVisibility() != View.VISIBLE) {
- return;
+ public Bitmap getBitmapOfToolbarChrome() {
+ if (mBrowserChrome != null) {
+ Bitmap bm = Bitmap.createBitmap(mBrowserChrome.getWidth(), mBrowserChrome.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bm);
+ Drawable bgDrawable = mBrowserChrome.getBackground();
+ if (bgDrawable != null) {
+ bgDrawable.draw(canvas);
+ } else {
+ canvas.drawColor(Color.WHITE);
+ }
+
+ mBrowserChrome.draw(canvas);
+ return bm;
}
- // Make sure the toolbar is fully hidden or fully shown when the user
- // lifts their finger, depending on various conditions.
- ImmutableViewportMetrics metrics = mLayerView.getViewportMetrics();
- float toolbarTranslation = mLayerView.getDynamicToolbarAnimator().getToolbarTranslation();
-
- boolean shortPage = metrics.getPageHeight() < metrics.getHeight();
- boolean atBottomOfLongPage =
- FloatUtils.fuzzyEquals(metrics.pageRectBottom, metrics.viewportRectBottom())
- && (metrics.pageRectBottom > 2 * metrics.getHeight());
- Log.v(LOGTAG, "On pan/zoom stopped, short page: " + shortPage
- + "; atBottomOfLongPage: " + atBottomOfLongPage);
- if (shortPage || atBottomOfLongPage) {
- mDynamicToolbar.setVisible(true, VisibilityTransition.ANIMATE);
- }
+ return null;
+ }
+
+ @Override
+ public boolean isToolbarChromeVisible() {
+ return mBrowserChrome.getVisibility() == View.VISIBLE;
+ }
+
+ @Override
+ public void toggleToolbarChrome(final boolean aShow) {
+ toggleChrome(aShow);
}
public void refreshToolbarHeight() {
ThreadUtils.assertOnUiThread();
int height = 0;
if (mBrowserChrome != null) {
height = mBrowserChrome.getHeight();
}
- if (!mDynamicToolbar.isEnabled() || isHomePagerVisible()) {
- // Use aVisibleHeight here so that when the dynamic toolbar is
- // enabled, the padding will animate with the toolbar becoming
- // visible.
- if (mDynamicToolbar.isEnabled()) {
- // When the dynamic toolbar is enabled, set the padding on the
- // about:home widget directly - this is to avoid resizing the
- // LayerView, which can cause visible artifacts.
- mHomeScreenContainer.setPadding(0, height, 0, 0);
- } else {
- setToolbarMargin(height);
- height = 0;
- }
- } else {
- setToolbarMargin(0);
- }
+ mHomeScreenContainer.setPadding(0, height, 0, 0);
if (mLayerView != null && height != mToolbarHeight) {
mToolbarHeight = height;
- mLayerView.setMaxTranslation(height);
+ mLayerView.setMaxToolbarHeight(height);
mDynamicToolbar.setVisible(true, VisibilityTransition.IMMEDIATE);
}
}
@Override
void toggleChrome(final boolean aShow) {
if (aShow) {
mBrowserChrome.setVisibility(View.VISIBLE);
@@ -3348,31 +3310,21 @@ public class BrowserApp extends GeckoApp
@Override
public void setFullScreen(final boolean fullscreen) {
super.setFullScreen(fullscreen);
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (fullscreen) {
- if (mDynamicToolbar.isEnabled()) {
- mDynamicToolbar.setVisible(false, VisibilityTransition.IMMEDIATE);
- mDynamicToolbar.setPinned(true, PinReason.FULL_SCREEN);
- } else {
- setToolbarMargin(0);
- }
- mBrowserChrome.setVisibility(View.GONE);
+ mDynamicToolbar.setVisible(false, VisibilityTransition.IMMEDIATE);
+ mDynamicToolbar.setPinned(true, PinReason.FULL_SCREEN);
} else {
- mBrowserChrome.setVisibility(View.VISIBLE);
- if (mDynamicToolbar.isEnabled()) {
- mDynamicToolbar.setPinned(false, PinReason.FULL_SCREEN);
- mDynamicToolbar.setVisible(true, VisibilityTransition.IMMEDIATE);
- } else {
- setToolbarMargin(mBrowserChrome.getHeight());
- }
+ mDynamicToolbar.setPinned(false, PinReason.FULL_SCREEN);
+ mDynamicToolbar.setVisible(true, VisibilityTransition.IMMEDIATE);
}
}
});
}
@Override
public boolean onPrepareOptionsMenu(Menu aMenu) {
if (aMenu == null)
@@ -4133,17 +4085,17 @@ public class BrowserApp extends GeckoApp
@Override
public void startActionModeCompat(final ActionModeCompat.Callback callback) {
// If actionMode is null, we're not currently showing one. Flip to the action mode view
if (mActionMode == null) {
mActionBarFlipper.showNext();
DynamicToolbarAnimator toolbar = mLayerView.getDynamicToolbarAnimator();
// If the toolbar is dynamic and not currently showing, just slide it in
- if (mDynamicToolbar.isEnabled() && toolbar.getToolbarTranslation() != 0) {
+ if (mDynamicToolbar.isEnabled() && toolbar.getCurrentToolbarHeight() == 0) {
mDynamicToolbar.setTemporarilyVisible(true, VisibilityTransition.ANIMATE);
}
mDynamicToolbar.setPinned(true, PinReason.ACTION_MODE);
} else {
// Otherwise, we're already showing an action mode. Just finish it and show the new one
mActionMode.finish();
}