Bug 898877 - Prevent pages from getting stuck without the dynamic toolbar. r=Cwiiis

The problematic scenario is when the page is exactly the height of the screen
(with dynamic toolbar not visible). In this case, the scrollable() function in
Axis.java returns false on the vertical axis, and so the JavaPanZoomController
never does any scrolling. This in turns means that the scrollBy code in
LayerMarginsAnimator never gets to run, so you can never drag the toolbar back
into being visible. The patch ensures that scrollable() returns true when some
or all of the margins are not visible, ensuring that in these scenarios the
user can still scroll the toolbar back onto the screen. This patch also adds
some comments/asserts to verify the new code is threadsafe.
This commit is contained in:
Kartikaya Gupta 2013-08-16 08:42:23 -04:00
parent a487207e1f
commit 67889faa26
5 changed files with 38 additions and 1 deletions

View File

@ -145,6 +145,7 @@ abstract class Axis {
protected abstract float getViewportLength();
protected abstract float getPageStart();
protected abstract float getPageLength();
protected abstract boolean marginsHidden();
Axis(SubdocumentScrollHelper subscroller) {
mSubscroller = subscroller;
@ -253,6 +254,13 @@ abstract class Axis {
return false;
}
// if there are margins on this axis but they are currently hidden,
// we must be able to scroll in order to make them visible, so allow
// scrolling in that case
if (marginsHidden()) {
return true;
}
// there is scrollable space, and we're not disabled, or the document fits the viewport
// but we always allow overscroll anyway
return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE ||

View File

@ -776,6 +776,12 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return mView.isFullScreen();
}
/** Implementation of PanZoomTarget */
@Override
public RectF getMaxMargins() {
return mMarginsAnimator.getMaxMargins();
}
/** Implementation of PanZoomTarget */
@Override
public void setAnimationTarget(ImmutableViewportMetrics metrics) {

View File

@ -1056,6 +1056,12 @@ class JavaPanZoomController
protected float getPageStart() { return getMetrics().pageRectLeft; }
@Override
protected float getPageLength() { return getMetrics().getPageWidthWithMargins(); }
@Override
protected boolean marginsHidden() {
ImmutableViewportMetrics metrics = getMetrics();
RectF maxMargins = mTarget.getMaxMargins();
return (metrics.marginLeft < maxMargins.left || metrics.marginRight < maxMargins.right);
}
}
private class AxisY extends Axis {
@ -1068,6 +1074,12 @@ class JavaPanZoomController
protected float getPageStart() { return getMetrics().pageRectTop; }
@Override
protected float getPageLength() { return getMetrics().getPageHeightWithMargins(); }
@Override
protected boolean marginsHidden() {
ImmutableViewportMetrics metrics = getMetrics();
RectF maxMargins = mTarget.getMaxMargins();
return (metrics.marginTop < maxMargins.top || metrics.marginBottom < maxMargins.bottom);
}
}
/*

View File

@ -10,6 +10,7 @@ import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.PrefsHelper;
import org.mozilla.gecko.TouchEventInterceptor;
import org.mozilla.gecko.util.FloatUtils;
import org.mozilla.gecko.util.ThreadUtils;
import android.graphics.PointF;
import android.graphics.RectF;
@ -33,7 +34,9 @@ public class LayerMarginsAnimator implements TouchEventInterceptor {
*/
private float SHOW_MARGINS_THRESHOLD = 0.20f;
/* This rect stores the maximum value margins can grow to when scrolling */
/* This rect stores the maximum value margins can grow to when scrolling. When writing
* to this member variable, or when reading from this member variable on a non-UI thread,
* you must synchronize on the LayerMarginsAnimator instance. */
private final RectF mMaxMargins;
/* If this boolean is true, scroll changes will not affect margins */
private boolean mMarginsPinned;
@ -86,6 +89,8 @@ public class LayerMarginsAnimator implements TouchEventInterceptor {
* Sets the maximum values for margins to grow to, in pixels.
*/
public synchronized void setMaxMargins(float left, float top, float right, float bottom) {
ThreadUtils.assertOnUiThread();
mMaxMargins.set(left, top, right, bottom);
// Update the Gecko-side global for fixed viewport margins.
@ -95,6 +100,10 @@ public class LayerMarginsAnimator implements TouchEventInterceptor {
+ ", \"bottom\" : " + bottom + ", \"left\" : " + left + " }"));
}
RectF getMaxMargins() {
return mMaxMargins;
}
private void animateMargins(final float left, final float top, final float right, final float bottom, boolean immediately) {
if (mAnimationTimer != null) {
mAnimationTimer.cancel();

View File

@ -8,11 +8,13 @@ package org.mozilla.gecko.gfx;
import org.mozilla.gecko.ZoomConstraints;
import android.graphics.PointF;
import android.graphics.RectF;
public interface PanZoomTarget {
public ImmutableViewportMetrics getViewportMetrics();
public ZoomConstraints getZoomConstraints();
public boolean isFullScreen();
public RectF getMaxMargins();
public void setAnimationTarget(ImmutableViewportMetrics viewport);
public void setViewportMetrics(ImmutableViewportMetrics viewport);