1 /* 2 * Copyright (C) 2007 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 dalvik.system.CloseGuard; 20 21 import android.content.res.CompatibilityInfo.Translator; 22 import android.graphics.Bitmap; 23 import android.graphics.Canvas; 24 import android.graphics.Matrix; 25 import android.graphics.Rect; 26 import android.graphics.Region; 27 import android.graphics.SurfaceTexture; 28 import android.os.IBinder; 29 import android.os.Parcelable; 30 import android.os.Parcel; 31 import android.os.SystemProperties; 32 import android.util.Log; 33 34 /** 35 * Handle onto a raw buffer that is being managed by the screen compositor. 36 */ 37 public class Surface implements Parcelable { 38 private static final String TAG = "Surface"; 39 40 private static final boolean HEADLESS = "1".equals( 41 SystemProperties.get("ro.config.headless", "0")); 42 43 public static final Parcelable.Creator<Surface> CREATOR = 44 new Parcelable.Creator<Surface>() { 45 public Surface createFromParcel(Parcel source) { 46 try { 47 Surface s = new Surface(); 48 s.readFromParcel(source); 49 return s; 50 } catch (Exception e) { 51 Log.e(TAG, "Exception creating surface from parcel", e); 52 return null; 53 } 54 } 55 56 public Surface[] newArray(int size) { 57 return new Surface[size]; 58 } 59 }; 60 61 /** 62 * Rotation constant: 0 degree rotation (natural orientation) 63 */ 64 public static final int ROTATION_0 = 0; 65 66 /** 67 * Rotation constant: 90 degree rotation. 68 */ 69 public static final int ROTATION_90 = 1; 70 71 /** 72 * Rotation constant: 180 degree rotation. 73 */ 74 public static final int ROTATION_180 = 2; 75 76 /** 77 * Rotation constant: 270 degree rotation. 78 */ 79 public static final int ROTATION_270 = 3; 80 81 /* built-in physical display ids (keep in sync with ISurfaceComposer.h) 82 * these are different from the logical display ids used elsewhere in the framework */ 83 84 /** 85 * Built-in physical display id: Main display. 86 * Use only with {@link #getBuiltInDisplay()}. 87 * @hide 88 */ 89 public static final int BUILT_IN_DISPLAY_ID_MAIN = 0; 90 91 /** 92 * Built-in physical display id: Attached HDMI display. 93 * Use only with {@link #getBuiltInDisplay()}. 94 * @hide 95 */ 96 public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; 97 98 /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ 99 100 /** 101 * Surface creation flag: Surface is created hidden 102 * @hide */ 103 public static final int HIDDEN = 0x00000004; 104 105 /** 106 * Surface creation flag: The surface contains secure content, special 107 * measures will be taken to disallow the surface's content to be copied 108 * from another process. In particular, screenshots and VNC servers will 109 * be disabled, but other measures can take place, for instance the 110 * surface might not be hardware accelerated. 111 * @hide 112 */ 113 public static final int SECURE = 0x00000080; 114 115 /** 116 * Surface creation flag: Creates a surface where color components are interpreted 117 * as "non pre-multiplied" by their alpha channel. Of course this flag is 118 * meaningless for surfaces without an alpha channel. By default 119 * surfaces are pre-multiplied, which means that each color component is 120 * already multiplied by its alpha value. In this case the blending 121 * equation used is: 122 * 123 * DEST = SRC + DEST * (1-SRC_ALPHA) 124 * 125 * By contrast, non pre-multiplied surfaces use the following equation: 126 * 127 * DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA) 128 * 129 * pre-multiplied surfaces must always be used if transparent pixels are 130 * composited on top of each-other into the surface. A pre-multiplied 131 * surface can never lower the value of the alpha component of a given 132 * pixel. 133 * 134 * In some rare situations, a non pre-multiplied surface is preferable. 135 * @hide 136 */ 137 public static final int NON_PREMULTIPLIED = 0x00000100; 138 139 /** 140 * Surface creation flag: Indicates that the surface must be considered opaque, 141 * even if its pixel format is set to translucent. This can be useful if an 142 * application needs full RGBA 8888 support for instance but will 143 * still draw every pixel opaque. 144 * @hide 145 */ 146 public static final int OPAQUE = 0x00000400; 147 148 /** 149 * Surface creation flag: Application requires a hardware-protected path to an 150 * external display sink. If a hardware-protected path is not available, 151 * then this surface will not be displayed on the external sink. 152 * @hide 153 */ 154 public static final int PROTECTED_APP = 0x00000800; 155 156 // 0x1000 is reserved for an independent DRM protected flag in framework 157 158 /** 159 * Surface creation flag: Creates a normal surface. 160 * This is the default. 161 * @hide 162 */ 163 public static final int FX_SURFACE_NORMAL = 0x00000000; 164 165 /** 166 * Surface creation flag: Creates a Blur surface. 167 * Everything behind this surface is blurred by some amount. 168 * The quality and refresh speed of the blur effect is not settable or guaranteed. 169 * It is an error to lock a Blur surface, since it doesn't have a backing store. 170 * @hide 171 * @deprecated 172 */ 173 @Deprecated 174 public static final int FX_SURFACE_BLUR = 0x00010000; 175 176 /** 177 * Surface creation flag: Creates a Dim surface. 178 * Everything behind this surface is dimmed by the amount specified 179 * in {@link #setAlpha}. It is an error to lock a Dim surface, since it 180 * doesn't have a backing store. 181 * @hide 182 */ 183 public static final int FX_SURFACE_DIM = 0x00020000; 184 185 /** 186 * @hide 187 */ 188 public static final int FX_SURFACE_SCREENSHOT = 0x00030000; 189 190 /** 191 * Mask used for FX values above. 192 * @hide 193 */ 194 public static final int FX_SURFACE_MASK = 0x000F0000; 195 196 /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ 197 198 /** 199 * Surface flag: Hide the surface. 200 * Equivalent to calling hide(). 201 * @hide 202 */ 203 public static final int SURFACE_HIDDEN = 0x01; 204 205 206 private final CloseGuard mCloseGuard = CloseGuard.get(); 207 private String mName; 208 209 // Note: These fields are accessed by native code. 210 // The mSurfaceControl will only be present for Surfaces used by the window 211 // server or system processes. When this class is parceled we defer to the 212 // mSurfaceControl to do the parceling. Otherwise we parcel the 213 // mNativeSurface. 214 private int mNativeSurface; // Surface* 215 private int mNativeSurfaceControl; // SurfaceControl* 216 private int mGenerationId; // incremented each time mNativeSurface changes 217 private final Canvas mCanvas = new CompatibleCanvas(); 218 private int mCanvasSaveCount; // Canvas save count at time of lockCanvas() 219 220 // The Translator for density compatibility mode. This is used for scaling 221 // the canvas to perform the appropriate density transformation. 222 private Translator mCompatibilityTranslator; 223 224 // A matrix to scale the matrix set by application. This is set to null for 225 // non compatibility mode. 226 private Matrix mCompatibleMatrix; 227 228 private int mWidth; 229 private int mHeight; 230 nativeCreate(SurfaceSession session, String name, int w, int h, int format, int flags)231 private native void nativeCreate(SurfaceSession session, String name, 232 int w, int h, int format, int flags) 233 throws OutOfResourcesException; nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)234 private native void nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture) 235 throws OutOfResourcesException; nativeRelease()236 private native void nativeRelease(); nativeDestroy()237 private native void nativeDestroy(); 238 nativeIsValid()239 private native boolean nativeIsValid(); nativeGetIdentity()240 private native int nativeGetIdentity(); nativeIsConsumerRunningBehind()241 private native boolean nativeIsConsumerRunningBehind(); 242 nativeLockCanvas(Rect dirty)243 private native Canvas nativeLockCanvas(Rect dirty); nativeUnlockCanvasAndPost(Canvas canvas)244 private native void nativeUnlockCanvasAndPost(Canvas canvas); 245 nativeScreenshot(IBinder displayToken, int width, int height, int minLayer, int maxLayer, boolean allLayers)246 private static native Bitmap nativeScreenshot(IBinder displayToken, 247 int width, int height, int minLayer, int maxLayer, boolean allLayers); 248 nativeOpenTransaction()249 private static native void nativeOpenTransaction(); nativeCloseTransaction()250 private static native void nativeCloseTransaction(); nativeSetAnimationTransaction()251 private static native void nativeSetAnimationTransaction(); 252 nativeSetLayer(int zorder)253 private native void nativeSetLayer(int zorder); nativeSetPosition(float x, float y)254 private native void nativeSetPosition(float x, float y); nativeSetSize(int w, int h)255 private native void nativeSetSize(int w, int h); nativeSetTransparentRegionHint(Region region)256 private native void nativeSetTransparentRegionHint(Region region); nativeSetAlpha(float alpha)257 private native void nativeSetAlpha(float alpha); nativeSetMatrix(float dsdx, float dtdx, float dsdy, float dtdy)258 private native void nativeSetMatrix(float dsdx, float dtdx, float dsdy, float dtdy); nativeSetFlags(int flags, int mask)259 private native void nativeSetFlags(int flags, int mask); nativeSetWindowCrop(Rect crop)260 private native void nativeSetWindowCrop(Rect crop); nativeSetLayerStack(int layerStack)261 private native void nativeSetLayerStack(int layerStack); 262 nativeGetBuiltInDisplay(int physicalDisplayId)263 private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId); nativeCreateDisplay(String name, boolean secure)264 private static native IBinder nativeCreateDisplay(String name, boolean secure); nativeSetDisplaySurface( IBinder displayToken, Surface surface)265 private static native void nativeSetDisplaySurface( 266 IBinder displayToken, Surface surface); nativeSetDisplayLayerStack( IBinder displayToken, int layerStack)267 private static native void nativeSetDisplayLayerStack( 268 IBinder displayToken, int layerStack); nativeSetDisplayProjection( IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)269 private static native void nativeSetDisplayProjection( 270 IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect); nativeGetDisplayInfo( IBinder displayToken, PhysicalDisplayInfo outInfo)271 private static native boolean nativeGetDisplayInfo( 272 IBinder displayToken, PhysicalDisplayInfo outInfo); nativeBlankDisplay(IBinder displayToken)273 private static native void nativeBlankDisplay(IBinder displayToken); nativeUnblankDisplay(IBinder displayToken)274 private static native void nativeUnblankDisplay(IBinder displayToken); 275 nativeCopyFrom(Surface other)276 private native void nativeCopyFrom(Surface other); nativeTransferFrom(Surface other)277 private native void nativeTransferFrom(Surface other); nativeReadFromParcel(Parcel source)278 private native void nativeReadFromParcel(Parcel source); nativeWriteToParcel(Parcel dest)279 private native void nativeWriteToParcel(Parcel dest); 280 281 282 /** 283 * Create an empty surface, which will later be filled in by readFromParcel(). 284 * @hide 285 */ Surface()286 public Surface() { 287 checkHeadless(); 288 289 mCloseGuard.open("release"); 290 } 291 292 /** 293 * Create a surface with a name. 294 * 295 * The surface creation flags specify what kind of surface to create and 296 * certain options such as whether the surface can be assumed to be opaque 297 * and whether it should be initially hidden. Surfaces should always be 298 * created with the {@link #HIDDEN} flag set to ensure that they are not 299 * made visible prematurely before all of the surface's properties have been 300 * configured. 301 * 302 * Good practice is to first create the surface with the {@link #HIDDEN} flag 303 * specified, open a transaction, set the surface layer, layer stack, alpha, 304 * and position, call {@link #show} if appropriate, and close the transaction. 305 * 306 * @param session The surface session, must not be null. 307 * @param name The surface name, must not be null. 308 * @param w The surface initial width. 309 * @param h The surface initial height. 310 * @param flags The surface creation flags. Should always include {@link #HIDDEN} 311 * in the creation flags. 312 * @hide 313 */ Surface(SurfaceSession session, String name, int w, int h, int format, int flags)314 public Surface(SurfaceSession session, 315 String name, int w, int h, int format, int flags) 316 throws OutOfResourcesException { 317 if (session == null) { 318 throw new IllegalArgumentException("session must not be null"); 319 } 320 if (name == null) { 321 throw new IllegalArgumentException("name must not be null"); 322 } 323 324 if ((flags & HIDDEN) == 0) { 325 Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set " 326 + "to ensure that they are not made visible prematurely before " 327 + "all of the surface's properties have been configured. " 328 + "Set the other properties and make the surface visible within " 329 + "a transaction. New surface name: " + name, 330 new Throwable()); 331 } 332 333 checkHeadless(); 334 335 mName = name; 336 mWidth = w; 337 mHeight = h; 338 nativeCreate(session, name, w, h, format, flags); 339 340 mCloseGuard.open("release"); 341 } 342 343 /** 344 * Create Surface from a {@link SurfaceTexture}. 345 * 346 * Images drawn to the Surface will be made available to the {@link 347 * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link 348 * SurfaceTexture#updateTexImage}. 349 * 350 * @param surfaceTexture The {@link SurfaceTexture} that is updated by this 351 * Surface. 352 */ Surface(SurfaceTexture surfaceTexture)353 public Surface(SurfaceTexture surfaceTexture) { 354 if (surfaceTexture == null) { 355 throw new IllegalArgumentException("surfaceTexture must not be null"); 356 } 357 358 checkHeadless(); 359 360 mName = surfaceTexture.toString(); 361 try { 362 nativeCreateFromSurfaceTexture(surfaceTexture); 363 } catch (OutOfResourcesException ex) { 364 // We can't throw OutOfResourcesException because it would be an API change. 365 throw new RuntimeException(ex); 366 } 367 368 mCloseGuard.open("release"); 369 } 370 371 @Override finalize()372 protected void finalize() throws Throwable { 373 try { 374 if (mCloseGuard != null) { 375 mCloseGuard.warnIfOpen(); 376 } 377 nativeRelease(); 378 } finally { 379 super.finalize(); 380 } 381 } 382 383 /** 384 * Release the local reference to the server-side surface. 385 * Always call release() when you're done with a Surface. 386 * This will make the surface invalid. 387 */ release()388 public void release() { 389 nativeRelease(); 390 mCloseGuard.close(); 391 } 392 393 /** 394 * Free all server-side state associated with this surface and 395 * release this object's reference. This method can only be 396 * called from the process that created the service. 397 * @hide 398 */ destroy()399 public void destroy() { 400 nativeDestroy(); 401 mCloseGuard.close(); 402 } 403 404 /** 405 * Returns true if this object holds a valid surface. 406 * 407 * @return True if it holds a physical surface, so lockCanvas() will succeed. 408 * Otherwise returns false. 409 */ isValid()410 public boolean isValid() { 411 return nativeIsValid(); 412 } 413 414 /** 415 * Gets the generation number of this surface, incremented each time 416 * the native surface contained within this object changes. 417 * 418 * @return The current generation number. 419 * @hide 420 */ getGenerationId()421 public int getGenerationId() { 422 return mGenerationId; 423 } 424 425 /** 426 * Returns true if the consumer of this Surface is running behind the producer. 427 * 428 * @return True if the consumer is more than one buffer ahead of the producer. 429 * @hide 430 */ isConsumerRunningBehind()431 public boolean isConsumerRunningBehind() { 432 return nativeIsConsumerRunningBehind(); 433 } 434 435 /** 436 * Gets a {@link Canvas} for drawing into this surface. 437 * 438 * After drawing into the provided {@link Canvas}, the caller should 439 * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 440 * 441 * @param dirty A rectangle that represents the dirty region that the caller wants 442 * to redraw. This function may choose to expand the dirty rectangle if for example 443 * the surface has been resized or if the previous contents of the surface were 444 * not available. The caller should redraw the entire dirty region as represented 445 * by the contents of the dirty rect upon return from this function. 446 * The caller may also pass <code>null</code> instead, in the case where the 447 * entire surface should be redrawn. 448 * @return A canvas for drawing into the surface. 449 */ lockCanvas(Rect dirty)450 public Canvas lockCanvas(Rect dirty) 451 throws OutOfResourcesException, IllegalArgumentException { 452 return nativeLockCanvas(dirty); 453 } 454 455 /** 456 * Posts the new contents of the {@link Canvas} to the surface and 457 * releases the {@link Canvas}. 458 * 459 * @param canvas The canvas previously obtained from {@link #lockCanvas}. 460 */ unlockCanvasAndPost(Canvas canvas)461 public void unlockCanvasAndPost(Canvas canvas) { 462 nativeUnlockCanvasAndPost(canvas); 463 } 464 465 /** 466 * @deprecated This API has been removed and is not supported. Do not use. 467 */ 468 @Deprecated unlockCanvas(Canvas canvas)469 public void unlockCanvas(Canvas canvas) { 470 throw new UnsupportedOperationException(); 471 } 472 473 /** 474 * Sets the translator used to scale canvas's width/height in compatibility 475 * mode. 476 */ setCompatibilityTranslator(Translator translator)477 void setCompatibilityTranslator(Translator translator) { 478 if (translator != null) { 479 float appScale = translator.applicationScale; 480 mCompatibleMatrix = new Matrix(); 481 mCompatibleMatrix.setScale(appScale, appScale); 482 } 483 } 484 485 /** 486 * Like {@link #screenshot(int, int, int, int)} but includes all 487 * Surfaces in the screenshot. 488 * 489 * @hide 490 */ screenshot(int width, int height)491 public static Bitmap screenshot(int width, int height) { 492 // TODO: should take the display as a parameter 493 IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN); 494 return nativeScreenshot(displayToken, width, height, 0, 0, true); 495 } 496 497 /** 498 * Copy the current screen contents into a bitmap and return it. 499 * 500 * @param width The desired width of the returned bitmap; the raw 501 * screen will be scaled down to this size. 502 * @param height The desired height of the returned bitmap; the raw 503 * screen will be scaled down to this size. 504 * @param minLayer The lowest (bottom-most Z order) surface layer to 505 * include in the screenshot. 506 * @param maxLayer The highest (top-most Z order) surface layer to 507 * include in the screenshot. 508 * @return Returns a Bitmap containing the screen contents, or null 509 * if an error occurs. 510 * 511 * @hide 512 */ screenshot(int width, int height, int minLayer, int maxLayer)513 public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) { 514 // TODO: should take the display as a parameter 515 IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN); 516 return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false); 517 } 518 519 /* 520 * set surface parameters. 521 * needs to be inside open/closeTransaction block 522 */ 523 524 /** start a transaction @hide */ openTransaction()525 public static void openTransaction() { 526 nativeOpenTransaction(); 527 } 528 529 /** end a transaction @hide */ closeTransaction()530 public static void closeTransaction() { 531 nativeCloseTransaction(); 532 } 533 534 /** flag the transaction as an animation @hide */ setAnimationTransaction()535 public static void setAnimationTransaction() { 536 nativeSetAnimationTransaction(); 537 } 538 539 /** @hide */ setLayer(int zorder)540 public void setLayer(int zorder) { 541 nativeSetLayer(zorder); 542 } 543 544 /** @hide */ setPosition(int x, int y)545 public void setPosition(int x, int y) { 546 nativeSetPosition(x, y); 547 } 548 549 /** @hide */ setPosition(float x, float y)550 public void setPosition(float x, float y) { 551 nativeSetPosition(x, y); 552 } 553 554 /** @hide */ setSize(int w, int h)555 public void setSize(int w, int h) { 556 mWidth = w; 557 mHeight = h; 558 nativeSetSize(w, h); 559 } 560 561 /** @hide */ getWidth()562 public int getWidth() { 563 return mWidth; 564 } 565 566 /** @hide */ getHeight()567 public int getHeight() { 568 return mHeight; 569 } 570 571 /** @hide */ hide()572 public void hide() { 573 nativeSetFlags(SURFACE_HIDDEN, SURFACE_HIDDEN); 574 } 575 576 /** @hide */ show()577 public void show() { 578 nativeSetFlags(0, SURFACE_HIDDEN); 579 } 580 581 /** @hide */ setTransparentRegionHint(Region region)582 public void setTransparentRegionHint(Region region) { 583 nativeSetTransparentRegionHint(region); 584 } 585 586 /** @hide */ setAlpha(float alpha)587 public void setAlpha(float alpha) { 588 nativeSetAlpha(alpha); 589 } 590 591 /** @hide */ setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)592 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 593 nativeSetMatrix(dsdx, dtdx, dsdy, dtdy); 594 } 595 596 /** @hide */ setFlags(int flags, int mask)597 public void setFlags(int flags, int mask) { 598 nativeSetFlags(flags, mask); 599 } 600 601 /** @hide */ setWindowCrop(Rect crop)602 public void setWindowCrop(Rect crop) { 603 nativeSetWindowCrop(crop); 604 } 605 606 /** @hide */ setLayerStack(int layerStack)607 public void setLayerStack(int layerStack) { 608 nativeSetLayerStack(layerStack); 609 } 610 611 /** @hide */ getBuiltInDisplay(int builtInDisplayId)612 public static IBinder getBuiltInDisplay(int builtInDisplayId) { 613 return nativeGetBuiltInDisplay(builtInDisplayId); 614 } 615 616 /** @hide */ createDisplay(String name, boolean secure)617 public static IBinder createDisplay(String name, boolean secure) { 618 if (name == null) { 619 throw new IllegalArgumentException("name must not be null"); 620 } 621 return nativeCreateDisplay(name, secure); 622 } 623 624 /** @hide */ setDisplaySurface(IBinder displayToken, Surface surface)625 public static void setDisplaySurface(IBinder displayToken, Surface surface) { 626 if (displayToken == null) { 627 throw new IllegalArgumentException("displayToken must not be null"); 628 } 629 nativeSetDisplaySurface(displayToken, surface); 630 } 631 632 /** @hide */ setDisplayLayerStack(IBinder displayToken, int layerStack)633 public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { 634 if (displayToken == null) { 635 throw new IllegalArgumentException("displayToken must not be null"); 636 } 637 nativeSetDisplayLayerStack(displayToken, layerStack); 638 } 639 640 /** @hide */ setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)641 public static void setDisplayProjection(IBinder displayToken, 642 int orientation, Rect layerStackRect, Rect displayRect) { 643 if (displayToken == null) { 644 throw new IllegalArgumentException("displayToken must not be null"); 645 } 646 if (layerStackRect == null) { 647 throw new IllegalArgumentException("layerStackRect must not be null"); 648 } 649 if (displayRect == null) { 650 throw new IllegalArgumentException("displayRect must not be null"); 651 } 652 nativeSetDisplayProjection(displayToken, orientation, layerStackRect, displayRect); 653 } 654 655 /** @hide */ getDisplayInfo(IBinder displayToken, PhysicalDisplayInfo outInfo)656 public static boolean getDisplayInfo(IBinder displayToken, PhysicalDisplayInfo outInfo) { 657 if (displayToken == null) { 658 throw new IllegalArgumentException("displayToken must not be null"); 659 } 660 if (outInfo == null) { 661 throw new IllegalArgumentException("outInfo must not be null"); 662 } 663 return nativeGetDisplayInfo(displayToken, outInfo); 664 } 665 666 /** @hide */ blankDisplay(IBinder displayToken)667 public static void blankDisplay(IBinder displayToken) { 668 if (displayToken == null) { 669 throw new IllegalArgumentException("displayToken must not be null"); 670 } 671 nativeBlankDisplay(displayToken); 672 } 673 674 /** @hide */ unblankDisplay(IBinder displayToken)675 public static void unblankDisplay(IBinder displayToken) { 676 if (displayToken == null) { 677 throw new IllegalArgumentException("displayToken must not be null"); 678 } 679 nativeUnblankDisplay(displayToken); 680 } 681 682 /** 683 * Copy another surface to this one. This surface now holds a reference 684 * to the same data as the original surface, and is -not- the owner. 685 * This is for use by the window manager when returning a window surface 686 * back from a client, converting it from the representation being managed 687 * by the window manager to the representation the client uses to draw 688 * in to it. 689 * @hide 690 */ copyFrom(Surface other)691 public void copyFrom(Surface other) { 692 if (other == null) { 693 throw new IllegalArgumentException("other must not be null"); 694 } 695 if (other != this) { 696 nativeCopyFrom(other); 697 } 698 } 699 700 /** 701 * Transfer the native state from 'other' to this surface, releasing it 702 * from 'other'. This is for use in the client side for drawing into a 703 * surface; not guaranteed to work on the window manager side. 704 * This is for use by the client to move the underlying surface from 705 * one Surface object to another, in particular in SurfaceFlinger. 706 * @hide. 707 */ transferFrom(Surface other)708 public void transferFrom(Surface other) { 709 if (other == null) { 710 throw new IllegalArgumentException("other must not be null"); 711 } 712 if (other != this) { 713 nativeTransferFrom(other); 714 } 715 } 716 717 @Override describeContents()718 public int describeContents() { 719 return 0; 720 } 721 readFromParcel(Parcel source)722 public void readFromParcel(Parcel source) { 723 if (source == null) { 724 throw new IllegalArgumentException("source must not be null"); 725 } 726 727 mName = source.readString(); 728 nativeReadFromParcel(source); 729 } 730 731 @Override writeToParcel(Parcel dest, int flags)732 public void writeToParcel(Parcel dest, int flags) { 733 if (dest == null) { 734 throw new IllegalArgumentException("dest must not be null"); 735 } 736 737 dest.writeString(mName); 738 nativeWriteToParcel(dest); 739 if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { 740 release(); 741 } 742 } 743 744 @Override toString()745 public String toString() { 746 return "Surface(name=" + mName + ", identity=" + nativeGetIdentity() + ")"; 747 } 748 checkHeadless()749 private static void checkHeadless() { 750 if (HEADLESS) { 751 throw new UnsupportedOperationException("Device is headless"); 752 } 753 } 754 755 /** 756 * Exception thrown when a surface couldn't be created or resized. 757 */ 758 public static class OutOfResourcesException extends Exception { OutOfResourcesException()759 public OutOfResourcesException() { 760 } 761 OutOfResourcesException(String name)762 public OutOfResourcesException(String name) { 763 super(name); 764 } 765 } 766 767 /** 768 * Describes the properties of a physical display known to surface flinger. 769 * @hide 770 */ 771 public static final class PhysicalDisplayInfo { 772 public int width; 773 public int height; 774 public float refreshRate; 775 public float density; 776 public float xDpi; 777 public float yDpi; 778 public boolean secure; 779 PhysicalDisplayInfo()780 public PhysicalDisplayInfo() { 781 } 782 PhysicalDisplayInfo(PhysicalDisplayInfo other)783 public PhysicalDisplayInfo(PhysicalDisplayInfo other) { 784 copyFrom(other); 785 } 786 787 @Override equals(Object o)788 public boolean equals(Object o) { 789 return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); 790 } 791 equals(PhysicalDisplayInfo other)792 public boolean equals(PhysicalDisplayInfo other) { 793 return other != null 794 && width == other.width 795 && height == other.height 796 && refreshRate == other.refreshRate 797 && density == other.density 798 && xDpi == other.xDpi 799 && yDpi == other.yDpi 800 && secure == other.secure; 801 } 802 803 @Override hashCode()804 public int hashCode() { 805 return 0; // don't care 806 } 807 copyFrom(PhysicalDisplayInfo other)808 public void copyFrom(PhysicalDisplayInfo other) { 809 width = other.width; 810 height = other.height; 811 refreshRate = other.refreshRate; 812 density = other.density; 813 xDpi = other.xDpi; 814 yDpi = other.yDpi; 815 secure = other.secure; 816 } 817 818 // For debugging purposes 819 @Override toString()820 public String toString() { 821 return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " 822 + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure 823 + "}"; 824 } 825 } 826 827 /** 828 * A Canvas class that can handle the compatibility mode. 829 * This does two things differently. 830 * <ul> 831 * <li>Returns the width and height of the target metrics, rather than 832 * native. For example, the canvas returns 320x480 even if an app is running 833 * in WVGA high density. 834 * <li>Scales the matrix in setMatrix by the application scale, except if 835 * the matrix looks like obtained from getMatrix. This is a hack to handle 836 * the case that an application uses getMatrix to keep the original matrix, 837 * set matrix of its own, then set the original matrix back. There is no 838 * perfect solution that works for all cases, and there are a lot of cases 839 * that this model does not work, but we hope this works for many apps. 840 * </ul> 841 */ 842 private final class CompatibleCanvas extends Canvas { 843 // A temp matrix to remember what an application obtained via {@link getMatrix} 844 private Matrix mOrigMatrix = null; 845 846 @Override getWidth()847 public int getWidth() { 848 int w = super.getWidth(); 849 if (mCompatibilityTranslator != null) { 850 w = (int)(w * mCompatibilityTranslator.applicationInvertedScale + .5f); 851 } 852 return w; 853 } 854 855 @Override getHeight()856 public int getHeight() { 857 int h = super.getHeight(); 858 if (mCompatibilityTranslator != null) { 859 h = (int)(h * mCompatibilityTranslator.applicationInvertedScale + .5f); 860 } 861 return h; 862 } 863 864 @Override setMatrix(Matrix matrix)865 public void setMatrix(Matrix matrix) { 866 if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) { 867 // don't scale the matrix if it's not compatibility mode, or 868 // the matrix was obtained from getMatrix. 869 super.setMatrix(matrix); 870 } else { 871 Matrix m = new Matrix(mCompatibleMatrix); 872 m.preConcat(matrix); 873 super.setMatrix(m); 874 } 875 } 876 877 @Override getMatrix(Matrix m)878 public void getMatrix(Matrix m) { 879 super.getMatrix(m); 880 if (mOrigMatrix == null) { 881 mOrigMatrix = new Matrix(); 882 } 883 mOrigMatrix.set(m); 884 } 885 } 886 } 887