diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index a1059673619e..3bd5b5c7556c 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -145,6 +145,7 @@ FENNEC_JAVA_FILES = \ gfx/VirtualLayer.java \ ui/Axis.java \ ui/PanZoomController.java \ + ui/PanZoomTarget.java \ ui/SimpleScaleGestureDetector.java \ ui/SubdocumentScrollHelper.java \ GeckoNetworkManager.java \ diff --git a/mobile/android/base/gfx/LayerController.java b/mobile/android/base/gfx/LayerController.java index 025807f23248..3b2301c9681d 100644 --- a/mobile/android/base/gfx/LayerController.java +++ b/mobile/android/base/gfx/LayerController.java @@ -7,6 +7,7 @@ package org.mozilla.gecko.gfx; import org.mozilla.gecko.ZoomConstraints; import org.mozilla.gecko.ui.PanZoomController; +import org.mozilla.gecko.ui.PanZoomTarget; import org.mozilla.gecko.ui.SimpleScaleGestureDetector; import android.content.Context; import android.content.res.Resources; @@ -24,7 +25,7 @@ import android.view.GestureDetector; * * Many methods require that the monitor be held, with a synchronized (controller) { ... } block. */ -public class LayerController { +public class LayerController implements PanZoomTarget { private static final String LOGTAG = "GeckoLayerController"; private Layer mRootLayer; /* The root layer. */ @@ -94,6 +95,7 @@ public class LayerController { public LayerView getView() { return mView; } public Context getContext() { return mContext; } public ImmutableViewportMetrics getViewportMetrics() { return mViewportMetrics; } + public Object getLock() { return this; } public FloatSize getViewportSize() { return mViewportMetrics.getSize(); diff --git a/mobile/android/base/ui/PanZoomController.java b/mobile/android/base/ui/PanZoomController.java index 4445bb2a1a8f..d5b94a0769dc 100644 --- a/mobile/android/base/ui/PanZoomController.java +++ b/mobile/android/base/ui/PanZoomController.java @@ -10,7 +10,6 @@ import org.json.JSONException; import org.json.JSONObject; import org.mozilla.gecko.gfx.ImmutableViewportMetrics; -import org.mozilla.gecko.gfx.LayerController; import org.mozilla.gecko.gfx.PointUtils; import org.mozilla.gecko.gfx.ViewportMetrics; import org.mozilla.gecko.FloatUtils; @@ -105,7 +104,7 @@ public class PanZoomController prevented the default actions yet. we still need to abort animations. */ } - private final LayerController mController; + private final PanZoomTarget mTarget; private final SubdocumentScrollHelper mSubscroller; private final Axis mX; private final Axis mY; @@ -123,8 +122,8 @@ public class PanZoomController /* Current state the pan/zoom UI is in. */ private PanZoomState mState; - public PanZoomController(LayerController controller) { - mController = controller; + public PanZoomController(PanZoomTarget target) { + mTarget = target; mSubscroller = new SubdocumentScrollHelper(this); mX = new AxisX(mSubscroller); mY = new AxisY(mSubscroller); @@ -156,7 +155,7 @@ public class PanZoomController } private ImmutableViewportMetrics getMetrics() { - return mController.getViewportMetrics(); + return mTarget.getViewportMetrics(); } // for debugging bug 713011; it can be taken out once that is resolved. @@ -175,7 +174,7 @@ public class PanZoomController final RectF zoomRect = new RectF(x, y, x + (float)message.getDouble("w"), y + (float)message.getDouble("h")); - mController.post(new Runnable() { + mTarget.post(new Runnable() { public void run() { animatedZoomTo(zoomRect); } @@ -193,7 +192,7 @@ public class PanZoomController y + dh/2, cssPageRect.width(), y + dh/2 + newHeight); - mController.post(new Runnable() { + mTarget.post(new Runnable() { public void run() { animatedZoomTo(r); } @@ -278,9 +277,9 @@ public class PanZoomController case NOTHING: // Don't do animations here; they're distracting and can cause flashes on page // transitions. - synchronized (mController) { - mController.setViewportMetrics(getValidViewportMetrics()); - mController.notifyLayerClientOfGeometryChange(); + synchronized (mTarget.getLock()) { + mTarget.setViewportMetrics(getValidViewportMetrics()); + mTarget.notifyLayerClientOfGeometryChange(); } break; } @@ -312,13 +311,13 @@ public class PanZoomController /** This must be called on the UI thread. */ public void pageRectUpdated() { if (mState == PanZoomState.NOTHING) { - synchronized (mController) { + synchronized (mTarget.getLock()) { ViewportMetrics validated = getValidViewportMetrics(); if (! (new ViewportMetrics(getMetrics())).fuzzyEquals(validated)) { // page size changed such that we are now in overscroll. snap to the // the nearest valid viewport - mController.setViewportMetrics(validated); - mController.notifyLayerClientOfGeometryChange(); + mTarget.setViewportMetrics(validated); + mTarget.notifyLayerClientOfGeometryChange(); } } } @@ -338,8 +337,8 @@ public class PanZoomController // We just interrupted a double-tap animation, so force a redraw in // case this touchstart is just a tap that doesn't end up triggering // a redraw - mController.setForceRedraw(); - mController.notifyLayerClientOfGeometryChange(); + mTarget.setForceRedraw(); + mTarget.notifyLayerClientOfGeometryChange(); // fall through case FLING: case BOUNCE: @@ -564,7 +563,7 @@ public class PanZoomController // getRedrawHint() is returning false. This means we can safely call // setAnimationTarget to set the new final display port and not have it get // clobbered by display ports from intermediate animation frames. - mController.setAnimationTarget(metrics); + mTarget.setAnimationTarget(metrics); startAnimationTimer(new BounceRunnable(bounceStartMetrics, metrics)); } @@ -585,7 +584,7 @@ public class PanZoomController mAnimationRunnable = runnable; mAnimationTimer.scheduleAtFixedRate(new TimerTask() { @Override - public void run() { mController.post(runnable); } + public void run() { mTarget.post(runnable); } }, 0, 1000L/60L); } @@ -627,8 +626,8 @@ public class PanZoomController return; } if (! mSubscroller.scrollBy(displacement)) { - synchronized (mController) { - mController.scrollBy(displacement); + synchronized (mTarget.getLock()) { + mTarget.scrollBy(displacement); } } } @@ -699,20 +698,20 @@ public class PanZoomController /* Performs one frame of a bounce animation. */ private void advanceBounce() { - synchronized (mController) { + synchronized (mTarget.getLock()) { float t = ZOOM_ANIMATION_FRAMES[mBounceFrame]; ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t); - mController.setViewportMetrics(newMetrics); - mController.notifyLayerClientOfGeometryChange(); + mTarget.setViewportMetrics(newMetrics); + mTarget.notifyLayerClientOfGeometryChange(); mBounceFrame++; } } /* Concludes a bounce animation and snaps the viewport into place. */ private void finishBounce() { - synchronized (mController) { - mController.setViewportMetrics(mBounceEndMetrics); - mController.notifyLayerClientOfGeometryChange(); + synchronized (mTarget.getLock()) { + mTarget.setViewportMetrics(mBounceEndMetrics); + mTarget.notifyLayerClientOfGeometryChange(); mBounceFrame = -1; } } @@ -773,8 +772,8 @@ public class PanZoomController stopAnimationTimer(); // Force a viewport synchronisation - mController.setForceRedraw(); - mController.notifyLayerClientOfGeometryChange(); + mTarget.setForceRedraw(); + mTarget.notifyLayerClientOfGeometryChange(); } /* Returns the nearest viewport metrics with no overscroll visible. */ @@ -794,7 +793,7 @@ public class PanZoomController float minZoomFactor = 0.0f; float maxZoomFactor = MAX_ZOOM; - ZoomConstraints constraints = mController.getZoomConstraints(); + ZoomConstraints constraints = mTarget.getZoomConstraints(); if (constraints.getMinZoom() > 0) minZoomFactor = constraints.getMinZoom(); @@ -873,7 +872,7 @@ public class PanZoomController if (mState == PanZoomState.ANIMATED_ZOOM) return false; - if (!mController.getZoomConstraints().getAllowZoom()) + if (!mTarget.getZoomConstraints().getAllowZoom()) return false; setState(PanZoomState.PINCHING); @@ -909,12 +908,12 @@ public class PanZoomController else spanRatio = 1.0f - (1.0f - spanRatio) * resistance; - synchronized (mController) { + synchronized (mTarget.getLock()) { float newZoomFactor = getMetrics().zoomFactor * spanRatio; float minZoomFactor = 0.0f; float maxZoomFactor = MAX_ZOOM; - ZoomConstraints constraints = mController.getZoomConstraints(); + ZoomConstraints constraints = mTarget.getZoomConstraints(); if (constraints.getMinZoom() > 0) minZoomFactor = constraints.getMinZoom(); @@ -940,10 +939,10 @@ public class PanZoomController newZoomFactor = maxZoomFactor + excessZoom; } - mController.scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(), - mLastZoomFocus.y - detector.getFocusY())); + mTarget.scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(), + mLastZoomFocus.y - detector.getFocusY())); PointF focus = new PointF(detector.getFocusX(), detector.getFocusY()); - mController.scaleWithFocus(newZoomFactor, focus); + mTarget.scaleWithFocus(newZoomFactor, focus); } mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY()); @@ -960,8 +959,8 @@ public class PanZoomController startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime()); // Force a viewport synchronisation - mController.setForceRedraw(); - mController.notifyLayerClientOfGeometryChange(); + mTarget.setForceRedraw(); + mTarget.notifyLayerClientOfGeometryChange(); } public boolean getRedrawHint() { @@ -983,7 +982,7 @@ public class PanZoomController String json; try { PointF point = new PointF(motionEvent.getX(), motionEvent.getY()); - point = mController.convertViewPointToLayerPoint(point); + point = mTarget.convertViewPointToLayerPoint(point); if (point == null) { return; } @@ -1004,7 +1003,7 @@ public class PanZoomController @Override public boolean onSingleTapUp(MotionEvent motionEvent) { // When zooming is enabled, wait to see if there's a double-tap. - if (!mController.getZoomConstraints().getAllowZoom()) { + if (!mTarget.getZoomConstraints().getAllowZoom()) { sendPointToGecko("Gesture:SingleTap", motionEvent); } // return false because we still want to get the ACTION_UP event that triggers this @@ -1014,7 +1013,7 @@ public class PanZoomController @Override public boolean onSingleTapConfirmed(MotionEvent motionEvent) { // When zooming is disabled, we handle this in onSingleTapUp. - if (mController.getZoomConstraints().getAllowZoom()) { + if (mTarget.getZoomConstraints().getAllowZoom()) { sendPointToGecko("Gesture:SingleTap", motionEvent); } return true; @@ -1022,7 +1021,7 @@ public class PanZoomController @Override public boolean onDoubleTap(MotionEvent motionEvent) { - if (mController.getZoomConstraints().getAllowZoom()) { + if (mTarget.getZoomConstraints().getAllowZoom()) { sendPointToGecko("Gesture:DoubleTap", motionEvent); } return true; diff --git a/mobile/android/base/ui/PanZoomTarget.java b/mobile/android/base/ui/PanZoomTarget.java new file mode 100644 index 000000000000..a64084dac829 --- /dev/null +++ b/mobile/android/base/ui/PanZoomTarget.java @@ -0,0 +1,29 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.ui; + +import org.mozilla.gecko.ZoomConstraints; +import org.mozilla.gecko.gfx.ImmutableViewportMetrics; +import org.mozilla.gecko.gfx.ViewportMetrics; + +import android.graphics.PointF; + +public interface PanZoomTarget { + public ImmutableViewportMetrics getViewportMetrics(); + public ZoomConstraints getZoomConstraints(); + + public void setAnimationTarget(ViewportMetrics viewport); + public void setViewportMetrics(ViewportMetrics viewport); + public void scrollBy(PointF point); + public void scaleWithFocus(float zoomFactor, PointF focus); + + public void notifyLayerClientOfGeometryChange(); + public void setForceRedraw(); + + public boolean post(Runnable action); + public Object getLock(); + public PointF convertViewPointToLayerPoint(PointF viewPoint); +}