--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -120,17 +120,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;
@@ -179,17 +182,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,
ActionModePresenter,
LayoutInflater.Factory {
private static final String LOGTAG = "GeckoBrowserApp";
@@ -241,17 +245,16 @@ public class BrowserApp extends GeckoApp
* Container for the home screen implementation. This will be populated with any valid
* home screen implementation (currently that is just the HomePager, but that will be extended
* to permit further experimental replacement panels such as the activity-stream panel).
*/
private ViewGroup mHomeScreenContainer;
private int mCachedRecentTabsCount;
private ActionModeCompat mActionMode;
private TabHistoryController tabHistoryController;
- private ZoomedView mZoomedView;
private static final int GECKO_TOOLS_MENU = -1;
private static final int ADDON_MENU_OFFSET = 1000;
public static final String TAB_HISTORY_FRAGMENT_TAG = "tabHistoryFragment";
private static class MenuItemInfo {
public int id;
public String label;
@@ -371,19 +374,16 @@ public class BrowserApp extends GeckoApp
VisibilityTransition.IMMEDIATE : VisibilityTransition.ANIMATE;
mDynamicToolbar.setVisible(true, transition);
// The first selection has happened - reset the state.
tab.setShouldShowToolbarWithoutAnimationOnFirstSelection(false);
}
// fall through
case LOCATION_CHANGE:
- if (mZoomedView != null) {
- mZoomedView.stopZoomDisplay(false);
- }
if (Tabs.getInstance().isSelectedTab(tab)) {
updateHomePagerForTab(tab);
}
mDynamicToolbar.persistTemporaryVisibility();
break;
case START:
if (Tabs.getInstance().isSelectedTab(tab)) {
@@ -1309,34 +1309,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());
@@ -1497,20 +1487,16 @@ public class BrowserApp extends GeckoApp
mReadingListHelper = null;
}
if (mAccountsHelper != null) {
mAccountsHelper.uninit();
mAccountsHelper = null;
}
- if (mZoomedView != null) {
- mZoomedView.destroy();
- }
-
mSearchEngineManager.unregisterListeners();
EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
"Search:Keyword",
null);
EventDispatcher.getInstance().unregisterUiThreadListener(this,
"Menu:Open",
@@ -1599,16 +1585,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()) {
@@ -1618,106 +1608,70 @@ public class BrowserApp extends GeckoApp
}
@Override
public void onDoorHangerShow() {
mDynamicToolbar.setVisible(true, VisibilityTransition.ANIMATE);
super.onDoorHangerShow();
}
- 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) {
+ return null;
}
- // 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);
+ 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;
+ }
+
+ @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);
@@ -1781,21 +1735,16 @@ public class BrowserApp extends GeckoApp
break;
case "Gecko:DelayedStartup":
EventDispatcher.getInstance().unregisterUiThreadListener(this, "Gecko:DelayedStartup");
// Force tabs panel inflation once the initial pageload is finished.
ensureTabsPanelExists();
- if (AppConstants.NIGHTLY_BUILD && mZoomedView == null) {
- ViewStub stub = (ViewStub) findViewById(R.id.zoomed_view_stub);
- mZoomedView = (ZoomedView) stub.inflate();
- }
-
if (AppConstants.MOZ_MEDIA_PLAYER) {
// Check if the fragment is already added. This should never be true
// here, but this is a nice safety check. If casting is disabled,
// these classes aren't built. We use reflection to initialize them.
final Class<?> mediaManagerClass = getMediaPlayerManager();
if (mediaManagerClass != null) {
try {
@@ -3297,31 +3246,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)
@@ -4092,17 +4031,17 @@ public class BrowserApp extends GeckoApp
@Override
public void startActionMode(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();
}