MagnifiableSurfaceView.java (3904B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 package org.mozilla.gecko; 6 7 import android.content.Context; 8 import android.graphics.Canvas; 9 import android.graphics.Rect; 10 import android.view.Surface; 11 import android.view.SurfaceHolder; 12 import android.view.SurfaceView; 13 14 /** 15 * A {@link android.view.SurfaceView} which allows a {@link android.widget.Magnifier} widget to 16 * magnify a custom {@link android.view.Surface} rather than the SurfaceView's default Surface. 17 */ 18 public class MagnifiableSurfaceView extends SurfaceView { 19 private static final String LOGTAG = "MagnifiableSurfaceView"; 20 21 private SurfaceHolderWrapper mHolder; 22 23 public MagnifiableSurfaceView(final Context context) { 24 super(context); 25 } 26 27 @Override 28 public SurfaceHolder getHolder() { 29 if (mHolder != null) { 30 // Only return our custom holder if we are being called from the Magnifier class. 31 // Throwable.getStackTrace() is faster than Thread.getStackTrace(), but still has a cost, 32 // hence why we only check the caller if we have set an override Surface. 33 final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 34 if (stackTrace.length >= 2 35 && stackTrace[1].getClassName().equals("android.widget.Magnifier")) { 36 return mHolder; 37 } 38 } 39 return super.getHolder(); 40 } 41 42 /** 43 * Sets the Surface that should be magnified by a Magnifier widget. 44 * 45 * <p>This should be set immediately before calling {@link android.widget.Magnifier#show()} or 46 * {@link android.widget.Magnifier#update()}, and unset immediately afterwards. 47 * 48 * @param surface The Surface to be magnified. If null, the SurfaceView's default Surface will be 49 * used. 50 */ 51 public void setMagnifierSurface(final Surface surface) { 52 if (surface != null) { 53 mHolder = new SurfaceHolderWrapper(getHolder(), surface); 54 } else { 55 mHolder = null; 56 } 57 } 58 59 /** 60 * A {@link android.view.SurfaceHolder} implementation that simply forwards all methods to a 61 * provided SurfaceHolder instance, except for getSurface() which returns a custom Surface. 62 */ 63 private class SurfaceHolderWrapper implements SurfaceHolder { 64 private final SurfaceHolder mHolder; 65 private final Surface mSurface; 66 67 public SurfaceHolderWrapper(final SurfaceHolder holder, final Surface surface) { 68 mHolder = holder; 69 mSurface = surface; 70 } 71 72 @Override 73 public void addCallback(final Callback callback) { 74 mHolder.addCallback(callback); 75 } 76 77 @Override 78 public void removeCallback(final Callback callback) { 79 mHolder.removeCallback(callback); 80 } 81 82 @Override 83 public boolean isCreating() { 84 return mHolder.isCreating(); 85 } 86 87 @Override 88 public void setType(final int type) { 89 mHolder.setType(type); 90 } 91 92 @Override 93 public void setFixedSize(final int width, final int height) { 94 mHolder.setFixedSize(width, height); 95 } 96 97 @Override 98 public void setSizeFromLayout() { 99 mHolder.setSizeFromLayout(); 100 } 101 102 @Override 103 public void setFormat(final int format) { 104 mHolder.setFormat(format); 105 } 106 107 @Override 108 public void setKeepScreenOn(final boolean screenOn) { 109 mHolder.setKeepScreenOn(screenOn); 110 } 111 112 @Override 113 public Canvas lockCanvas() { 114 return mHolder.lockCanvas(); 115 } 116 117 @Override 118 public Canvas lockCanvas(final Rect dirty) { 119 return mHolder.lockCanvas(dirty); 120 } 121 122 @Override 123 public void unlockCanvasAndPost(final Canvas canvas) { 124 mHolder.unlockCanvasAndPost(canvas); 125 } 126 127 @Override 128 public Rect getSurfaceFrame() { 129 return mHolder.getSurfaceFrame(); 130 } 131 132 @Override 133 public Surface getSurface() { 134 return mSurface; 135 } 136 } 137 }