1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view; 18 19 import android.annotation.IntRange; 20 import android.annotation.NonNull; 21 import android.graphics.Canvas; 22 import android.graphics.PixelFormat; 23 import android.graphics.Rect; 24 25 /** 26 * Abstract interface to someone holding a display surface. Allows you to 27 * control the surface size and format, edit the pixels in the surface, and 28 * monitor changes to the surface. This interface is typically available 29 * through the {@link SurfaceView} class. 30 * 31 * <p>When using this interface from a thread other than the one running 32 * its {@link SurfaceView}, you will want to carefully read the 33 * methods 34 * {@link #lockCanvas} and {@link Callback#surfaceCreated Callback.surfaceCreated()}. 35 */ 36 public interface SurfaceHolder { 37 38 /** @deprecated this is ignored, this value is set automatically when needed. */ 39 @Deprecated 40 public static final int SURFACE_TYPE_NORMAL = 0; 41 /** @deprecated this is ignored, this value is set automatically when needed. */ 42 @Deprecated 43 public static final int SURFACE_TYPE_HARDWARE = 1; 44 /** @deprecated this is ignored, this value is set automatically when needed. */ 45 @Deprecated 46 public static final int SURFACE_TYPE_GPU = 2; 47 /** @deprecated this is ignored, this value is set automatically when needed. */ 48 @Deprecated 49 public static final int SURFACE_TYPE_PUSH_BUFFERS = 3; 50 51 /** 52 * Exception that is thrown from {@link #lockCanvas} when called on a Surface 53 * whose type is SURFACE_TYPE_PUSH_BUFFERS. 54 */ 55 public static class BadSurfaceTypeException extends RuntimeException { BadSurfaceTypeException()56 public BadSurfaceTypeException() { 57 } 58 BadSurfaceTypeException(String name)59 public BadSurfaceTypeException(String name) { 60 super(name); 61 } 62 } 63 64 /** 65 * A client may implement this interface to receive information about 66 * changes to the surface. When used with a {@link SurfaceView}, the 67 * Surface being held is only available between calls to 68 * {@link #surfaceCreated(SurfaceHolder)} and 69 * {@link #surfaceDestroyed(SurfaceHolder)}. The Callback is set with 70 * {@link SurfaceHolder#addCallback SurfaceHolder.addCallback} method. 71 */ 72 public interface Callback { 73 /** 74 * This is called immediately after the surface is first created. 75 * Implementations of this should start up whatever rendering code 76 * they desire. Note that only one thread can ever draw into 77 * a {@link Surface}, so you should not draw into the Surface here 78 * if your normal rendering will be in another thread. 79 * 80 * @param holder The SurfaceHolder whose surface is being created. 81 */ surfaceCreated(@onNull SurfaceHolder holder)82 void surfaceCreated(@NonNull SurfaceHolder holder); 83 84 /** 85 * This is called immediately after any structural changes (format or 86 * size) have been made to the surface. You should at this point update 87 * the imagery in the surface. This method is always called at least 88 * once, after {@link #surfaceCreated}. 89 * 90 * @param holder The SurfaceHolder whose surface has changed. 91 * @param format The new {@link PixelFormat} of the surface. 92 * @param width The new width of the surface. 93 * @param height The new height of the surface. 94 */ surfaceChanged(@onNull SurfaceHolder holder, @PixelFormat.Format int format, @IntRange(from = 0) int width, @IntRange(from = 0) int height)95 void surfaceChanged(@NonNull SurfaceHolder holder, @PixelFormat.Format int format, 96 @IntRange(from = 0) int width, @IntRange(from = 0) int height); 97 98 /** 99 * This is called immediately before a surface is being destroyed. After 100 * returning from this call, you should no longer try to access this 101 * surface. If you have a rendering thread that directly accesses 102 * the surface, you must ensure that thread is no longer touching the 103 * Surface before returning from this function. 104 * 105 * @param holder The SurfaceHolder whose surface is being destroyed. 106 */ surfaceDestroyed(@onNull SurfaceHolder holder)107 void surfaceDestroyed(@NonNull SurfaceHolder holder); 108 } 109 110 /** 111 * Additional callbacks that can be received for {@link Callback}. 112 */ 113 public interface Callback2 extends Callback { 114 /** 115 * Called when the application needs to redraw the content of its 116 * surface, after it is resized or for some other reason. By not 117 * returning from here until the redraw is complete, you can ensure that 118 * the user will not see your surface in a bad state (at its new 119 * size before it has been correctly drawn that way). This will 120 * typically be preceeded by a call to {@link #surfaceChanged}. 121 * 122 * As of O, {@link #surfaceRedrawNeededAsync} may be implemented 123 * to provide a non-blocking implementation. If {@link #surfaceRedrawNeededAsync} 124 * is not implemented, then this will be called instead. 125 * 126 * @param holder The SurfaceHolder whose surface has changed. 127 */ surfaceRedrawNeeded(@onNull SurfaceHolder holder)128 void surfaceRedrawNeeded(@NonNull SurfaceHolder holder); 129 130 /** 131 * An alternative to surfaceRedrawNeeded where it is not required to block 132 * until the redraw is complete. You should initiate the redraw, and return, 133 * later invoking drawingFinished when your redraw is complete. 134 * 135 * This can be useful to avoid blocking your main application thread on rendering. 136 * 137 * As of O, if this is implemented {@link #surfaceRedrawNeeded} will not be called. 138 * However it is still recommended to implement {@link #surfaceRedrawNeeded} for 139 * compatibility with older versions of the platform. 140 * 141 * @param holder The SurfaceHolder which needs redrawing. 142 * @param drawingFinished A runnable to signal completion. This may be invoked 143 * from any thread. 144 * 145 */ surfaceRedrawNeededAsync(@onNull SurfaceHolder holder, @NonNull Runnable drawingFinished)146 default void surfaceRedrawNeededAsync(@NonNull SurfaceHolder holder, 147 @NonNull Runnable drawingFinished) { 148 surfaceRedrawNeeded(holder); 149 drawingFinished.run(); 150 } 151 } 152 153 /** 154 * Add a Callback interface for this holder. There can several Callback 155 * interfaces associated with a holder. 156 * 157 * @param callback The new Callback interface. 158 */ addCallback(Callback callback)159 public void addCallback(Callback callback); 160 161 /** 162 * Removes a previously added Callback interface from this holder. 163 * 164 * @param callback The Callback interface to remove. 165 */ removeCallback(Callback callback)166 public void removeCallback(Callback callback); 167 168 /** 169 * Use this method to find out if the surface is in the process of being 170 * created from Callback methods. This is intended to be used with 171 * {@link Callback#surfaceChanged}. 172 * 173 * @return true if the surface is in the process of being created. 174 */ isCreating()175 public boolean isCreating(); 176 177 /** 178 * Sets the surface's type. 179 * 180 * @deprecated this is ignored, this value is set automatically when needed. 181 */ 182 @Deprecated setType(int type)183 public void setType(int type); 184 185 /** 186 * Make the surface a fixed size. It will never change from this size. 187 * When working with a {@link SurfaceView}, this must be called from the 188 * same thread running the SurfaceView's window. 189 * 190 * @param width The surface's width. 191 * @param height The surface's height. 192 */ setFixedSize(int width, int height)193 public void setFixedSize(int width, int height); 194 195 /** 196 * Allow the surface to resized based on layout of its container (this is 197 * the default). When this is enabled, you should monitor 198 * {@link Callback#surfaceChanged} for changes to the size of the surface. 199 * When working with a {@link SurfaceView}, this must be called from the 200 * same thread running the SurfaceView's window. 201 */ setSizeFromLayout()202 public void setSizeFromLayout(); 203 204 /** 205 * Set the desired PixelFormat of the surface. The default is OPAQUE. 206 * When working with a {@link SurfaceView}, this must be called from the 207 * same thread running the SurfaceView's window. 208 * 209 * @param format A constant from PixelFormat. 210 * 211 * @see android.graphics.PixelFormat 212 */ setFormat(int format)213 public void setFormat(int format); 214 215 /** 216 * Enable or disable option to keep the screen turned on while this 217 * surface is displayed. The default is false, allowing it to turn off. 218 * This is safe to call from any thread. 219 * 220 * @param screenOn Set to true to force the screen to stay on, false 221 * to allow it to turn off. 222 */ setKeepScreenOn(boolean screenOn)223 public void setKeepScreenOn(boolean screenOn); 224 225 /** 226 * Start editing the pixels in the surface. The returned Canvas can be used 227 * to draw into the surface's bitmap. A null is returned if the surface has 228 * not been created or otherwise cannot be edited. You will usually need 229 * to implement {@link Callback#surfaceCreated Callback.surfaceCreated} 230 * to find out when the Surface is available for use. 231 * 232 * <p>The content of the Surface is never preserved between unlockCanvas() and 233 * lockCanvas(), for this reason, every pixel within the Surface area 234 * must be written. The only exception to this rule is when a dirty 235 * rectangle is specified, in which case, non-dirty pixels will be 236 * preserved. 237 * 238 * <p>If you call this repeatedly when the Surface is not ready (before 239 * {@link Callback#surfaceCreated Callback.surfaceCreated} or after 240 * {@link Callback#surfaceDestroyed Callback.surfaceDestroyed}), your calls 241 * will be throttled to a slow rate in order to avoid consuming CPU. 242 * 243 * <p>If null is not returned, this function internally holds a lock until 244 * the corresponding {@link #unlockCanvasAndPost} call, preventing 245 * {@link SurfaceView} from creating, destroying, or modifying the surface 246 * while it is being drawn. This can be more convenient than accessing 247 * the Surface directly, as you do not need to do special synchronization 248 * with a drawing thread in {@link Callback#surfaceDestroyed 249 * Callback.surfaceDestroyed}. 250 * 251 * @return Canvas Use to draw into the surface. 252 */ lockCanvas()253 public Canvas lockCanvas(); 254 255 256 /** 257 * Just like {@link #lockCanvas()} but allows specification of a dirty rectangle. 258 * Every 259 * pixel within that rectangle must be written; however pixels outside 260 * the dirty rectangle will be preserved by the next call to lockCanvas(). 261 * 262 * @see android.view.SurfaceHolder#lockCanvas 263 * 264 * @param dirty Area of the Surface that will be modified. 265 * @return Canvas Use to draw into the surface. 266 */ lockCanvas(Rect dirty)267 public Canvas lockCanvas(Rect dirty); 268 269 /** 270 * <p>Just like {@link #lockCanvas()} but the returned canvas is hardware-accelerated. 271 * 272 * <p>See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported"> 273 * unsupported drawing operations</a> for a list of what is and isn't 274 * supported in a hardware-accelerated canvas. 275 * 276 * @return Canvas Use to draw into the surface. 277 * @throws IllegalStateException If the canvas cannot be locked. 278 */ lockHardwareCanvas()279 default Canvas lockHardwareCanvas() { 280 throw new IllegalStateException("This SurfaceHolder doesn't support lockHardwareCanvas"); 281 } 282 283 /** 284 * Finish editing pixels in the surface. After this call, the surface's 285 * current pixels will be shown on the screen, but its content is lost, 286 * in particular there is no guarantee that the content of the Surface 287 * will remain unchanged when lockCanvas() is called again. 288 * 289 * @see #lockCanvas() 290 * 291 * @param canvas The Canvas previously returned by lockCanvas(). 292 */ unlockCanvasAndPost(Canvas canvas)293 public void unlockCanvasAndPost(Canvas canvas); 294 295 /** 296 * Retrieve the current size of the surface. Note: do not modify the 297 * returned Rect. This is only safe to call from the thread of 298 * {@link SurfaceView}'s window, or while inside of 299 * {@link #lockCanvas()}. 300 * 301 * @return Rect The surface's dimensions. The left and top are always 0. 302 */ getSurfaceFrame()303 public Rect getSurfaceFrame(); 304 305 /** 306 * Direct access to the surface object. The Surface may not always be 307 * available -- for example when using a {@link SurfaceView} the holder's 308 * Surface is not created until the view has been attached to the window 309 * manager and performed a layout in order to determine the dimensions 310 * and screen position of the Surface. You will thus usually need 311 * to implement {@link Callback#surfaceCreated Callback.surfaceCreated} 312 * to find out when the Surface is available for use. 313 * 314 * <p>Note that if you directly access the Surface from another thread, 315 * it is critical that you correctly implement 316 * {@link Callback#surfaceCreated Callback.surfaceCreated} and 317 * {@link Callback#surfaceDestroyed Callback.surfaceDestroyed} to ensure 318 * that thread only accesses the Surface while it is valid, and that the 319 * Surface does not get destroyed while the thread is using it. 320 * 321 * <p>This method is intended to be used by frameworks which often need 322 * direct access to the Surface object (usually to pass it to native code). 323 * 324 * @return Surface The surface. 325 */ getSurface()326 public Surface getSurface(); 327 } 328