summaryrefslogtreecommitdiffstats
path: root/mobile/android/geckoview/src/main/java/org/mozilla/gecko/MagnifiableSurfaceView.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/geckoview/src/main/java/org/mozilla/gecko/MagnifiableSurfaceView.java')
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/gecko/MagnifiableSurfaceView.java137
1 files changed, 137 insertions, 0 deletions
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/MagnifiableSurfaceView.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/MagnifiableSurfaceView.java
new file mode 100644
index 0000000000..2003abcc6f
--- /dev/null
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/MagnifiableSurfaceView.java
@@ -0,0 +1,137 @@
+/* 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;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+/**
+ * A {@link android.view.SurfaceView} which allows a {@link android.widget.Magnifier} widget to
+ * magnify a custom {@link android.view.Surface} rather than the SurfaceView's default Surface.
+ */
+public class MagnifiableSurfaceView extends SurfaceView {
+ private static final String LOGTAG = "MagnifiableSurfaceView";
+
+ private SurfaceHolderWrapper mHolder;
+
+ public MagnifiableSurfaceView(final Context context) {
+ super(context);
+ }
+
+ @Override
+ public SurfaceHolder getHolder() {
+ if (mHolder != null) {
+ // Only return our custom holder if we are being called from the Magnifier class.
+ // Throwable.getStackTrace() is faster than Thread.getStackTrace(), but still has a cost,
+ // hence why we only check the caller if we have set an override Surface.
+ final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+ if (stackTrace.length >= 2
+ && stackTrace[1].getClassName().equals("android.widget.Magnifier")) {
+ return mHolder;
+ }
+ }
+ return super.getHolder();
+ }
+
+ /**
+ * Sets the Surface that should be magnified by a Magnifier widget.
+ *
+ * <p>This should be set immediately before calling {@link android.widget.Magnifier#show()} or
+ * {@link android.widget.Magnifier#update()}, and unset immediately afterwards.
+ *
+ * @param surface The Surface to be magnified. If null, the SurfaceView's default Surface will be
+ * used.
+ */
+ public void setMagnifierSurface(final Surface surface) {
+ if (surface != null) {
+ mHolder = new SurfaceHolderWrapper(getHolder(), surface);
+ } else {
+ mHolder = null;
+ }
+ }
+
+ /**
+ * A {@link android.view.SurfaceHolder} implementation that simply forwards all methods to a
+ * provided SurfaceHolder instance, except for getSurface() which returns a custom Surface.
+ */
+ private class SurfaceHolderWrapper implements SurfaceHolder {
+ private final SurfaceHolder mHolder;
+ private final Surface mSurface;
+
+ public SurfaceHolderWrapper(final SurfaceHolder holder, final Surface surface) {
+ mHolder = holder;
+ mSurface = surface;
+ }
+
+ @Override
+ public void addCallback(final Callback callback) {
+ mHolder.addCallback(callback);
+ }
+
+ @Override
+ public void removeCallback(final Callback callback) {
+ mHolder.removeCallback(callback);
+ }
+
+ @Override
+ public boolean isCreating() {
+ return mHolder.isCreating();
+ }
+
+ @Override
+ public void setType(final int type) {
+ mHolder.setType(type);
+ }
+
+ @Override
+ public void setFixedSize(final int width, final int height) {
+ mHolder.setFixedSize(width, height);
+ }
+
+ @Override
+ public void setSizeFromLayout() {
+ mHolder.setSizeFromLayout();
+ }
+
+ @Override
+ public void setFormat(final int format) {
+ mHolder.setFormat(format);
+ }
+
+ @Override
+ public void setKeepScreenOn(final boolean screenOn) {
+ mHolder.setKeepScreenOn(screenOn);
+ }
+
+ @Override
+ public Canvas lockCanvas() {
+ return mHolder.lockCanvas();
+ }
+
+ @Override
+ public Canvas lockCanvas(final Rect dirty) {
+ return mHolder.lockCanvas(dirty);
+ }
+
+ @Override
+ public void unlockCanvasAndPost(final Canvas canvas) {
+ mHolder.unlockCanvasAndPost(canvas);
+ }
+
+ @Override
+ public Rect getSurfaceFrame() {
+ return mHolder.getSurfaceFrame();
+ }
+
+ @Override
+ public Surface getSurface() {
+ return mSurface;
+ }
+ }
+}