Bug 1425262 - 1. Implement GeckoDisplay as a class managed by GeckoSession; r?rbarker
Implement GeckoDisplay as a class managed by GeckoSession and used by
GeckoSession clients. Also add `acquireDisplay` and `releaseDisplay`
methods to manage the GeckoDisplay instance.
MozReview-Commit-ID: 6yTdXmx4yIO
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoDisplay.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoDisplay.java
@@ -4,68 +4,55 @@
* 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.gfx;
import android.view.Surface;
/**
- * Displays implement this interface to provide GeckoSession
- * with a Surface for displaying content.
+ * Applications use a GeckoDisplay instance to provide GeckoSession with a Surface for
+ * displaying content. To ensure drawing only happens on a valid Surface, GeckoSession
+ * will only use the provided Surface after {@link #surfaceChanged(Surface, int, int)} is
+ * called and before {@link #surfaceDestroyed()} returns.
*/
-public interface GeckoDisplay {
- /**
- * Displays notify GeckoSession of changes to its Surface through this interface that
- * GeckoSession implements. To ensure drawing only happens on a valid Surface,
- * GeckoSession will only use the provided Surface after {@link
- * #surfaceChanged(Surface, int, int)} is called and before {@link
- * #surfaceDestroyed()} returns.
- */
- interface Listener {
- /**
- * Required callback. The display's Surface has been created or changed. Must be
- * called on the application main thread. GeckoSession may block this call to
- * ensure the Surface is valid while resuming drawing.
- *
- * @param surface The new Surface.
- * @param width New width of the Surface.
- * @param height New height of the Surface.
- */
- void surfaceChanged(Surface surface, int width, int height);
+public class GeckoDisplay {
+ private final LayerSession mSession;
- /**
- * Required callback. The display's Surface has been destroyed. Must be called on
- * the application main thread. GeckoSession may block this call to ensure the
- * Surface is valid while pausing drawing.
- */
- void surfaceDestroyed();
-
- /**
- * Optional callback. The display's coordinates on the screen has changed. Must be
- * called on the application main thread.
- *
- * @param left The X coordinate of the display on the screen, in screen pixels.
- * @param top The Y coordinate of the display on the screen, in screen pixels.
- */
- void screenOriginChanged(int left, int top);
+ /* package */ GeckoDisplay(final LayerSession session) {
+ mSession = session;
}
/**
- * Get the current listener attached to this display. Must be called on the
- * application main thread.
+ * Required callback. The display's Surface has been created or changed. Must be
+ * called on the application main thread. GeckoSession may block this call to ensure
+ * the Surface is valid while resuming drawing.
*
- * @return Current listener or null if there is no listener.
+ * @param surface The new Surface.
+ * @param width New width of the Surface.
+ * @param height New height of the Surface.
*/
- Listener getListener();
+ public void surfaceChanged(Surface surface, int width, int height) {
+ mSession.onSurfaceChanged(surface, width, height);
+ }
/**
- * Set a new listener attached to this display. Must be called on the application main
- * thread. When attaching a new listener, and there is an existing valid Surface, the
- * display must call {@link Listener#surfaceChanged(Surface, int, int)} (and other
- * optional callbacks, if implemented) on the new listener. Similarly, when detaching
- * a previous listener, and there is an existing valid Surface, the display must call
- * {@link Listener#surfaceDestroyed()} on the previous listener.
+ * Required callback. The display's Surface has been destroyed. Must be called on the
+ * application main thread. GeckoSession may block this call to ensure the Surface is
+ * valid while pausing drawing.
+ */
+ public void surfaceDestroyed() {
+ mSession.onSurfaceDestroyed();
+ }
+
+ /**
+ * Optional callback. The display's coordinates on the screen has changed. Must be
+ * called on the application main thread. Together with the transformation matrix, the
+ * screen origin determines how a point on the display maps to a point on the screen.
*
- * @param listener New listener or null if detaching previous listener.
+ * @param left The X coordinate of the display on the screen, in screen pixels.
+ * @param top The Y coordinate of the display on the screen, in screen pixels.
+ * @see #transformationMatrixChanged(Matrix)
*/
- void setListener(Listener listener);
+ public void screenOriginChanged(final int left, final int top) {
+ mSession.onScreenOriginChanged(left, top);
+ }
}
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerSession.java
@@ -153,17 +153,17 @@ public class LayerSession {
// avoid unwanted scroll interactions.
LayerSession.this.onSelectionCaretDrag(dragging);
}
}
protected final Compositor mCompositor = new Compositor();
// All fields are accessed on UI thread only.
- private GeckoDisplay mDisplay;
+ private final GeckoDisplay mDisplay = new GeckoDisplay(this);
private NativePanZoomController mNPZC;
private OverscrollEdgeEffect mOverscroll;
private DynamicToolbarAnimator mToolbar;
private CompositorController mController;
private boolean mAttachedCompositor;
private boolean mCalledCreateCompositor;
private boolean mCompositorReady;
@@ -588,48 +588,38 @@ public class LayerSession {
return;
}
mLeft = left;
mTop = top;
onWindowBoundsChanged();
}
- public void addDisplay(final GeckoDisplay display) {
+ /**
+ * Acquire the GeckoDisplay instance for providing the session with a drawing Surface.
+ * Be sure to call {@link GeckoDisplay#surfaceChanged(Surface, int, int)} on the
+ * acquired display if there is already a valid Surface.
+ *
+ * @return GeckoDisplay instance.
+ * @see #releaseDisplay(GeckoDisplay)
+ */
+ public @NonNull GeckoDisplay acquireDisplay() {
ThreadUtils.assertOnUiThread();
- if (display.getListener() != null) {
- throw new IllegalArgumentException("Display already attached");
- } else if (mDisplay != null) {
- throw new IllegalArgumentException("Only one display supported");
- }
-
- mDisplay = display;
- display.setListener(new GeckoDisplay.Listener() {
- @Override
- public void surfaceChanged(final Surface surface, final int width,
- final int height) {
- onSurfaceChanged(surface, width, height);
- }
-
- @Override
- public void surfaceDestroyed() {
- onSurfaceDestroyed();
- }
-
- @Override
- public void screenOriginChanged(final int left, final int top) {
- onScreenOriginChanged(left, top);
- }
- });
+ return mDisplay;
}
- public void removeDisplay(final GeckoDisplay display) {
+ /**
+ * Release an acquired GeckoDisplay instance. Be sure to call {@link
+ * GeckoDisplay#surfaceDestroyed()} before releasing the display if it still has a
+ * valid Surface.
+ *
+ * @param display Acquired GeckoDisplay instance.
+ * @see #acquireDisplay()
+ */
+ public void releaseDisplay(final @NonNull GeckoDisplay display) {
ThreadUtils.assertOnUiThread();
- if (mDisplay != display) {
+ if (display != mDisplay) {
throw new IllegalArgumentException("Display not attached");
}
-
- display.setListener(null);
- mDisplay = null;
}
}