1 /* 2 * Copyright (C) 2013 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 import android.graphics.Bitmap; 21 import android.graphics.Rect; 22 import android.graphics.Region; 23 import android.os.IBinder; 24 import android.util.Log; 25 import android.view.Surface.OutOfResourcesException; 26 27 /** 28 * SurfaceControl 29 * @hide 30 */ 31 public class SurfaceControl { 32 private static final String TAG = "SurfaceControl"; 33 nativeCreate(SurfaceSession session, String name, int w, int h, int format, int flags)34 private static native long nativeCreate(SurfaceSession session, String name, 35 int w, int h, int format, int flags) 36 throws OutOfResourcesException; nativeRelease(long nativeObject)37 private static native void nativeRelease(long nativeObject); nativeDestroy(long nativeObject)38 private static native void nativeDestroy(long nativeObject); 39 nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform, int rotation)40 private static native Bitmap nativeScreenshot(IBinder displayToken, 41 Rect sourceCrop, int width, int height, int minLayer, int maxLayer, 42 boolean allLayers, boolean useIdentityTransform, int rotation); nativeScreenshot(IBinder displayToken, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)43 private static native void nativeScreenshot(IBinder displayToken, Surface consumer, 44 Rect sourceCrop, int width, int height, int minLayer, int maxLayer, 45 boolean allLayers, boolean useIdentityTransform); 46 nativeOpenTransaction()47 private static native void nativeOpenTransaction(); nativeCloseTransaction()48 private static native void nativeCloseTransaction(); nativeSetAnimationTransaction()49 private static native void nativeSetAnimationTransaction(); 50 nativeSetLayer(long nativeObject, int zorder)51 private static native void nativeSetLayer(long nativeObject, int zorder); nativeSetPosition(long nativeObject, float x, float y)52 private static native void nativeSetPosition(long nativeObject, float x, float y); nativeSetSize(long nativeObject, int w, int h)53 private static native void nativeSetSize(long nativeObject, int w, int h); nativeSetTransparentRegionHint(long nativeObject, Region region)54 private static native void nativeSetTransparentRegionHint(long nativeObject, Region region); nativeSetAlpha(long nativeObject, float alpha)55 private static native void nativeSetAlpha(long nativeObject, float alpha); nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy)56 private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy); nativeSetFlags(long nativeObject, int flags, int mask)57 private static native void nativeSetFlags(long nativeObject, int flags, int mask); nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b)58 private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b); nativeSetLayerStack(long nativeObject, int layerStack)59 private static native void nativeSetLayerStack(long nativeObject, int layerStack); 60 nativeClearContentFrameStats(long nativeObject)61 private static native boolean nativeClearContentFrameStats(long nativeObject); nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats)62 private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats); nativeClearAnimationFrameStats()63 private static native boolean nativeClearAnimationFrameStats(); nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats)64 private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats); 65 nativeGetBuiltInDisplay(int physicalDisplayId)66 private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId); nativeCreateDisplay(String name, boolean secure)67 private static native IBinder nativeCreateDisplay(String name, boolean secure); nativeDestroyDisplay(IBinder displayToken)68 private static native void nativeDestroyDisplay(IBinder displayToken); nativeSetDisplaySurface( IBinder displayToken, long nativeSurfaceObject)69 private static native void nativeSetDisplaySurface( 70 IBinder displayToken, long nativeSurfaceObject); nativeSetDisplayLayerStack( IBinder displayToken, int layerStack)71 private static native void nativeSetDisplayLayerStack( 72 IBinder displayToken, int layerStack); nativeSetDisplayProjection( IBinder displayToken, int orientation, int l, int t, int r, int b, int L, int T, int R, int B)73 private static native void nativeSetDisplayProjection( 74 IBinder displayToken, int orientation, 75 int l, int t, int r, int b, 76 int L, int T, int R, int B); nativeSetDisplaySize(IBinder displayToken, int width, int height)77 private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height); nativeGetDisplayConfigs( IBinder displayToken)78 private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs( 79 IBinder displayToken); nativeGetActiveConfig(IBinder displayToken)80 private static native int nativeGetActiveConfig(IBinder displayToken); nativeSetActiveConfig(IBinder displayToken, int id)81 private static native boolean nativeSetActiveConfig(IBinder displayToken, int id); nativeSetDisplayPowerMode( IBinder displayToken, int mode)82 private static native void nativeSetDisplayPowerMode( 83 IBinder displayToken, int mode); 84 85 86 private final CloseGuard mCloseGuard = CloseGuard.get(); 87 private final String mName; 88 long mNativeObject; // package visibility only for Surface.java access 89 90 /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ 91 92 /** 93 * Surface creation flag: Surface is created hidden 94 */ 95 public static final int HIDDEN = 0x00000004; 96 97 /** 98 * Surface creation flag: The surface contains secure content, special 99 * measures will be taken to disallow the surface's content to be copied 100 * from another process. In particular, screenshots and VNC servers will 101 * be disabled, but other measures can take place, for instance the 102 * surface might not be hardware accelerated. 103 * 104 */ 105 public static final int SECURE = 0x00000080; 106 107 /** 108 * Surface creation flag: Creates a surface where color components are interpreted 109 * as "non pre-multiplied" by their alpha channel. Of course this flag is 110 * meaningless for surfaces without an alpha channel. By default 111 * surfaces are pre-multiplied, which means that each color component is 112 * already multiplied by its alpha value. In this case the blending 113 * equation used is: 114 * <p> 115 * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code> 116 * <p> 117 * By contrast, non pre-multiplied surfaces use the following equation: 118 * <p> 119 * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code> 120 * <p> 121 * pre-multiplied surfaces must always be used if transparent pixels are 122 * composited on top of each-other into the surface. A pre-multiplied 123 * surface can never lower the value of the alpha component of a given 124 * pixel. 125 * <p> 126 * In some rare situations, a non pre-multiplied surface is preferable. 127 * 128 */ 129 public static final int NON_PREMULTIPLIED = 0x00000100; 130 131 /** 132 * Surface creation flag: Indicates that the surface must be considered opaque, 133 * even if its pixel format is set to translucent. This can be useful if an 134 * application needs full RGBA 8888 support for instance but will 135 * still draw every pixel opaque. 136 * <p> 137 * This flag is ignored if setAlpha() is used to make the surface non-opaque. 138 * Combined effects are (assuming a buffer format with an alpha channel): 139 * <ul> 140 * <li>OPAQUE + alpha(1.0) == opaque composition 141 * <li>OPAQUE + alpha(0.x) == blended composition 142 * <li>!OPAQUE + alpha(1.0) == blended composition 143 * <li>!OPAQUE + alpha(0.x) == blended composition 144 * </ul> 145 * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively 146 * set automatically. 147 */ 148 public static final int OPAQUE = 0x00000400; 149 150 /** 151 * Surface creation flag: Application requires a hardware-protected path to an 152 * external display sink. If a hardware-protected path is not available, 153 * then this surface will not be displayed on the external sink. 154 * 155 */ 156 public static final int PROTECTED_APP = 0x00000800; 157 158 // 0x1000 is reserved for an independent DRM protected flag in framework 159 160 /** 161 * Surface creation flag: Window represents a cursor glyph. 162 */ 163 public static final int CURSOR_WINDOW = 0x00002000; 164 165 /** 166 * Surface creation flag: Creates a normal surface. 167 * This is the default. 168 * 169 */ 170 public static final int FX_SURFACE_NORMAL = 0x00000000; 171 172 /** 173 * Surface creation flag: Creates a Dim surface. 174 * Everything behind this surface is dimmed by the amount specified 175 * in {@link #setAlpha}. It is an error to lock a Dim surface, since it 176 * doesn't have a backing store. 177 * 178 */ 179 public static final int FX_SURFACE_DIM = 0x00020000; 180 181 /** 182 * Mask used for FX values above. 183 * 184 */ 185 public static final int FX_SURFACE_MASK = 0x000F0000; 186 187 /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ 188 189 /** 190 * Surface flag: Hide the surface. 191 * Equivalent to calling hide(). 192 * Updates the value set during Surface creation (see {@link #HIDDEN}). 193 */ 194 private static final int SURFACE_HIDDEN = 0x01; 195 196 /** 197 * Surface flag: composite without blending when possible. 198 * Updates the value set during Surface creation (see {@link #OPAQUE}). 199 */ 200 private static final int SURFACE_OPAQUE = 0x02; 201 202 203 /* built-in physical display ids (keep in sync with ISurfaceComposer.h) 204 * these are different from the logical display ids used elsewhere in the framework */ 205 206 /** 207 * Built-in physical display id: Main display. 208 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. 209 */ 210 public static final int BUILT_IN_DISPLAY_ID_MAIN = 0; 211 212 /** 213 * Built-in physical display id: Attached HDMI display. 214 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. 215 */ 216 public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; 217 218 /* Display power modes * / 219 220 /** 221 * Display power mode off: used while blanking the screen. 222 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 223 */ 224 public static final int POWER_MODE_OFF = 0; 225 226 /** 227 * Display power mode doze: used while putting the screen into low power mode. 228 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 229 */ 230 public static final int POWER_MODE_DOZE = 1; 231 232 /** 233 * Display power mode normal: used while unblanking the screen. 234 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 235 */ 236 public static final int POWER_MODE_NORMAL = 2; 237 238 /** 239 * Display power mode doze: used while putting the screen into a suspended 240 * low power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. 241 */ 242 public static final int POWER_MODE_DOZE_SUSPEND = 3; 243 244 /** 245 * Create a surface with a name. 246 * <p> 247 * The surface creation flags specify what kind of surface to create and 248 * certain options such as whether the surface can be assumed to be opaque 249 * and whether it should be initially hidden. Surfaces should always be 250 * created with the {@link #HIDDEN} flag set to ensure that they are not 251 * made visible prematurely before all of the surface's properties have been 252 * configured. 253 * <p> 254 * Good practice is to first create the surface with the {@link #HIDDEN} flag 255 * specified, open a transaction, set the surface layer, layer stack, alpha, 256 * and position, call {@link #show} if appropriate, and close the transaction. 257 * 258 * @param session The surface session, must not be null. 259 * @param name The surface name, must not be null. 260 * @param w The surface initial width. 261 * @param h The surface initial height. 262 * @param flags The surface creation flags. Should always include {@link #HIDDEN} 263 * in the creation flags. 264 * 265 * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. 266 */ SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags)267 public SurfaceControl(SurfaceSession session, 268 String name, int w, int h, int format, int flags) 269 throws OutOfResourcesException { 270 if (session == null) { 271 throw new IllegalArgumentException("session must not be null"); 272 } 273 if (name == null) { 274 throw new IllegalArgumentException("name must not be null"); 275 } 276 277 if ((flags & SurfaceControl.HIDDEN) == 0) { 278 Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set " 279 + "to ensure that they are not made visible prematurely before " 280 + "all of the surface's properties have been configured. " 281 + "Set the other properties and make the surface visible within " 282 + "a transaction. New surface name: " + name, 283 new Throwable()); 284 } 285 286 mName = name; 287 mNativeObject = nativeCreate(session, name, w, h, format, flags); 288 if (mNativeObject == 0) { 289 throw new OutOfResourcesException( 290 "Couldn't allocate SurfaceControl native object"); 291 } 292 293 mCloseGuard.open("release"); 294 } 295 296 @Override finalize()297 protected void finalize() throws Throwable { 298 try { 299 if (mCloseGuard != null) { 300 mCloseGuard.warnIfOpen(); 301 } 302 if (mNativeObject != 0) { 303 nativeRelease(mNativeObject); 304 } 305 } finally { 306 super.finalize(); 307 } 308 } 309 310 @Override toString()311 public String toString() { 312 return "Surface(name=" + mName + ")"; 313 } 314 315 /** 316 * Release the local reference to the server-side surface. 317 * Always call release() when you're done with a Surface. 318 * This will make the surface invalid. 319 */ release()320 public void release() { 321 if (mNativeObject != 0) { 322 nativeRelease(mNativeObject); 323 mNativeObject = 0; 324 } 325 mCloseGuard.close(); 326 } 327 328 /** 329 * Free all server-side state associated with this surface and 330 * release this object's reference. This method can only be 331 * called from the process that created the service. 332 */ destroy()333 public void destroy() { 334 if (mNativeObject != 0) { 335 nativeDestroy(mNativeObject); 336 mNativeObject = 0; 337 } 338 mCloseGuard.close(); 339 } 340 checkNotReleased()341 private void checkNotReleased() { 342 if (mNativeObject == 0) throw new NullPointerException( 343 "mNativeObject is null. Have you called release() already?"); 344 } 345 346 /* 347 * set surface parameters. 348 * needs to be inside open/closeTransaction block 349 */ 350 351 /** start a transaction */ openTransaction()352 public static void openTransaction() { 353 nativeOpenTransaction(); 354 } 355 356 /** end a transaction */ closeTransaction()357 public static void closeTransaction() { 358 nativeCloseTransaction(); 359 } 360 361 /** flag the transaction as an animation */ setAnimationTransaction()362 public static void setAnimationTransaction() { 363 nativeSetAnimationTransaction(); 364 } 365 setLayer(int zorder)366 public void setLayer(int zorder) { 367 checkNotReleased(); 368 nativeSetLayer(mNativeObject, zorder); 369 } 370 setPosition(float x, float y)371 public void setPosition(float x, float y) { 372 checkNotReleased(); 373 nativeSetPosition(mNativeObject, x, y); 374 } 375 setSize(int w, int h)376 public void setSize(int w, int h) { 377 checkNotReleased(); 378 nativeSetSize(mNativeObject, w, h); 379 } 380 hide()381 public void hide() { 382 checkNotReleased(); 383 nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN); 384 } 385 show()386 public void show() { 387 checkNotReleased(); 388 nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN); 389 } 390 setTransparentRegionHint(Region region)391 public void setTransparentRegionHint(Region region) { 392 checkNotReleased(); 393 nativeSetTransparentRegionHint(mNativeObject, region); 394 } 395 clearContentFrameStats()396 public boolean clearContentFrameStats() { 397 checkNotReleased(); 398 return nativeClearContentFrameStats(mNativeObject); 399 } 400 getContentFrameStats(WindowContentFrameStats outStats)401 public boolean getContentFrameStats(WindowContentFrameStats outStats) { 402 checkNotReleased(); 403 return nativeGetContentFrameStats(mNativeObject, outStats); 404 } 405 clearAnimationFrameStats()406 public static boolean clearAnimationFrameStats() { 407 return nativeClearAnimationFrameStats(); 408 } 409 getAnimationFrameStats(WindowAnimationFrameStats outStats)410 public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) { 411 return nativeGetAnimationFrameStats(outStats); 412 } 413 414 /** 415 * Sets an alpha value for the entire Surface. This value is combined with the 416 * per-pixel alpha. It may be used with opaque Surfaces. 417 */ setAlpha(float alpha)418 public void setAlpha(float alpha) { 419 checkNotReleased(); 420 nativeSetAlpha(mNativeObject, alpha); 421 } 422 setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)423 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 424 checkNotReleased(); 425 nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy); 426 } 427 setWindowCrop(Rect crop)428 public void setWindowCrop(Rect crop) { 429 checkNotReleased(); 430 if (crop != null) { 431 nativeSetWindowCrop(mNativeObject, 432 crop.left, crop.top, crop.right, crop.bottom); 433 } else { 434 nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0); 435 } 436 } 437 setLayerStack(int layerStack)438 public void setLayerStack(int layerStack) { 439 checkNotReleased(); 440 nativeSetLayerStack(mNativeObject, layerStack); 441 } 442 443 /** 444 * Sets the opacity of the surface. Setting the flag is equivalent to creating the 445 * Surface with the {@link #OPAQUE} flag. 446 */ setOpaque(boolean isOpaque)447 public void setOpaque(boolean isOpaque) { 448 checkNotReleased(); 449 if (isOpaque) { 450 nativeSetFlags(mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE); 451 } else { 452 nativeSetFlags(mNativeObject, 0, SURFACE_OPAQUE); 453 } 454 } 455 456 /** 457 * Sets the security of the surface. Setting the flag is equivalent to creating the 458 * Surface with the {@link #SECURE} flag. 459 */ setSecure(boolean isSecure)460 public void setSecure(boolean isSecure) { 461 checkNotReleased(); 462 if (isSecure) { 463 nativeSetFlags(mNativeObject, SECURE, SECURE); 464 } else { 465 nativeSetFlags(mNativeObject, 0, SECURE); 466 } 467 } 468 469 /* 470 * set display parameters. 471 * needs to be inside open/closeTransaction block 472 */ 473 474 /** 475 * Describes the properties of a physical display known to surface flinger. 476 */ 477 public static final class PhysicalDisplayInfo { 478 public int width; 479 public int height; 480 public float refreshRate; 481 public float density; 482 public float xDpi; 483 public float yDpi; 484 public boolean secure; 485 public long appVsyncOffsetNanos; 486 public long presentationDeadlineNanos; 487 PhysicalDisplayInfo()488 public PhysicalDisplayInfo() { 489 } 490 PhysicalDisplayInfo(PhysicalDisplayInfo other)491 public PhysicalDisplayInfo(PhysicalDisplayInfo other) { 492 copyFrom(other); 493 } 494 495 @Override equals(Object o)496 public boolean equals(Object o) { 497 return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); 498 } 499 equals(PhysicalDisplayInfo other)500 public boolean equals(PhysicalDisplayInfo other) { 501 return other != null 502 && width == other.width 503 && height == other.height 504 && refreshRate == other.refreshRate 505 && density == other.density 506 && xDpi == other.xDpi 507 && yDpi == other.yDpi 508 && secure == other.secure 509 && appVsyncOffsetNanos == other.appVsyncOffsetNanos 510 && presentationDeadlineNanos == other.presentationDeadlineNanos; 511 } 512 513 @Override hashCode()514 public int hashCode() { 515 return 0; // don't care 516 } 517 copyFrom(PhysicalDisplayInfo other)518 public void copyFrom(PhysicalDisplayInfo other) { 519 width = other.width; 520 height = other.height; 521 refreshRate = other.refreshRate; 522 density = other.density; 523 xDpi = other.xDpi; 524 yDpi = other.yDpi; 525 secure = other.secure; 526 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 527 presentationDeadlineNanos = other.presentationDeadlineNanos; 528 } 529 530 // For debugging purposes 531 @Override toString()532 public String toString() { 533 return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " 534 + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure 535 + ", appVsyncOffset " + appVsyncOffsetNanos 536 + ", bufferDeadline " + presentationDeadlineNanos + "}"; 537 } 538 } 539 setDisplayPowerMode(IBinder displayToken, int mode)540 public static void setDisplayPowerMode(IBinder displayToken, int mode) { 541 if (displayToken == null) { 542 throw new IllegalArgumentException("displayToken must not be null"); 543 } 544 nativeSetDisplayPowerMode(displayToken, mode); 545 } 546 getDisplayConfigs(IBinder displayToken)547 public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) { 548 if (displayToken == null) { 549 throw new IllegalArgumentException("displayToken must not be null"); 550 } 551 return nativeGetDisplayConfigs(displayToken); 552 } 553 getActiveConfig(IBinder displayToken)554 public static int getActiveConfig(IBinder displayToken) { 555 if (displayToken == null) { 556 throw new IllegalArgumentException("displayToken must not be null"); 557 } 558 return nativeGetActiveConfig(displayToken); 559 } 560 setActiveConfig(IBinder displayToken, int id)561 public static boolean setActiveConfig(IBinder displayToken, int id) { 562 if (displayToken == null) { 563 throw new IllegalArgumentException("displayToken must not be null"); 564 } 565 return nativeSetActiveConfig(displayToken, id); 566 } 567 setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)568 public static void setDisplayProjection(IBinder displayToken, 569 int orientation, Rect layerStackRect, Rect displayRect) { 570 if (displayToken == null) { 571 throw new IllegalArgumentException("displayToken must not be null"); 572 } 573 if (layerStackRect == null) { 574 throw new IllegalArgumentException("layerStackRect must not be null"); 575 } 576 if (displayRect == null) { 577 throw new IllegalArgumentException("displayRect must not be null"); 578 } 579 nativeSetDisplayProjection(displayToken, orientation, 580 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, 581 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom); 582 } 583 setDisplayLayerStack(IBinder displayToken, int layerStack)584 public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { 585 if (displayToken == null) { 586 throw new IllegalArgumentException("displayToken must not be null"); 587 } 588 nativeSetDisplayLayerStack(displayToken, layerStack); 589 } 590 setDisplaySurface(IBinder displayToken, Surface surface)591 public static void setDisplaySurface(IBinder displayToken, Surface surface) { 592 if (displayToken == null) { 593 throw new IllegalArgumentException("displayToken must not be null"); 594 } 595 596 if (surface != null) { 597 synchronized (surface.mLock) { 598 nativeSetDisplaySurface(displayToken, surface.mNativeObject); 599 } 600 } else { 601 nativeSetDisplaySurface(displayToken, 0); 602 } 603 } 604 setDisplaySize(IBinder displayToken, int width, int height)605 public static void setDisplaySize(IBinder displayToken, int width, int height) { 606 if (displayToken == null) { 607 throw new IllegalArgumentException("displayToken must not be null"); 608 } 609 if (width <= 0 || height <= 0) { 610 throw new IllegalArgumentException("width and height must be positive"); 611 } 612 613 nativeSetDisplaySize(displayToken, width, height); 614 } 615 createDisplay(String name, boolean secure)616 public static IBinder createDisplay(String name, boolean secure) { 617 if (name == null) { 618 throw new IllegalArgumentException("name must not be null"); 619 } 620 return nativeCreateDisplay(name, secure); 621 } 622 destroyDisplay(IBinder displayToken)623 public static void destroyDisplay(IBinder displayToken) { 624 if (displayToken == null) { 625 throw new IllegalArgumentException("displayToken must not be null"); 626 } 627 nativeDestroyDisplay(displayToken); 628 } 629 getBuiltInDisplay(int builtInDisplayId)630 public static IBinder getBuiltInDisplay(int builtInDisplayId) { 631 return nativeGetBuiltInDisplay(builtInDisplayId); 632 } 633 634 /** 635 * Copy the current screen contents into the provided {@link Surface} 636 * 637 * @param display The display to take the screenshot of. 638 * @param consumer The {@link Surface} to take the screenshot into. 639 * @param width The desired width of the returned bitmap; the raw 640 * screen will be scaled down to this size. 641 * @param height The desired height of the returned bitmap; the raw 642 * screen will be scaled down to this size. 643 * @param minLayer The lowest (bottom-most Z order) surface layer to 644 * include in the screenshot. 645 * @param maxLayer The highest (top-most Z order) surface layer to 646 * include in the screenshot. 647 * @param useIdentityTransform Replace whatever transformation (rotation, 648 * scaling, translation) the surface layers are currently using with the 649 * identity transformation while taking the screenshot. 650 */ screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform)651 public static void screenshot(IBinder display, Surface consumer, 652 int width, int height, int minLayer, int maxLayer, 653 boolean useIdentityTransform) { 654 screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer, 655 false, useIdentityTransform); 656 } 657 658 /** 659 * Copy the current screen contents into the provided {@link Surface} 660 * 661 * @param display The display to take the screenshot of. 662 * @param consumer The {@link Surface} to take the screenshot into. 663 * @param width The desired width of the returned bitmap; the raw 664 * screen will be scaled down to this size. 665 * @param height The desired height of the returned bitmap; the raw 666 * screen will be scaled down to this size. 667 */ screenshot(IBinder display, Surface consumer, int width, int height)668 public static void screenshot(IBinder display, Surface consumer, 669 int width, int height) { 670 screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false); 671 } 672 673 /** 674 * Copy the current screen contents into the provided {@link Surface} 675 * 676 * @param display The display to take the screenshot of. 677 * @param consumer The {@link Surface} to take the screenshot into. 678 */ screenshot(IBinder display, Surface consumer)679 public static void screenshot(IBinder display, Surface consumer) { 680 screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false); 681 } 682 683 /** 684 * Copy the current screen contents into a bitmap and return it. 685 * 686 * CAVEAT: Versions of screenshot that return a {@link Bitmap} can 687 * be extremely slow; avoid use unless absolutely necessary; prefer 688 * the versions that use a {@link Surface} instead, such as 689 * {@link SurfaceControl#screenshot(IBinder, Surface)}. 690 * 691 * @param sourceCrop The portion of the screen to capture into the Bitmap; 692 * caller may pass in 'new Rect()' if no cropping is desired. 693 * @param width The desired width of the returned bitmap; the raw 694 * screen will be scaled down to this size. 695 * @param height The desired height of the returned bitmap; the raw 696 * screen will be scaled down to this size. 697 * @param minLayer The lowest (bottom-most Z order) surface layer to 698 * include in the screenshot. 699 * @param maxLayer The highest (top-most Z order) surface layer to 700 * include in the screenshot. 701 * @param useIdentityTransform Replace whatever transformation (rotation, 702 * scaling, translation) the surface layers are currently using with the 703 * identity transformation while taking the screenshot. 704 * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. 705 * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take 706 * screenshots in its native portrait orientation by default, so this is 707 * useful for returning screenshots that are independent of device 708 * orientation. 709 * @return Returns a Bitmap containing the screen contents, or null 710 * if an error occurs. Make sure to call Bitmap.recycle() as soon as 711 * possible, once its content is not needed anymore. 712 */ screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)713 public static Bitmap screenshot(Rect sourceCrop, int width, int height, 714 int minLayer, int maxLayer, boolean useIdentityTransform, 715 int rotation) { 716 // TODO: should take the display as a parameter 717 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 718 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 719 return nativeScreenshot(displayToken, sourceCrop, width, height, 720 minLayer, maxLayer, false, useIdentityTransform, rotation); 721 } 722 723 /** 724 * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but 725 * includes all Surfaces in the screenshot. 726 * 727 * @param width The desired width of the returned bitmap; the raw 728 * screen will be scaled down to this size. 729 * @param height The desired height of the returned bitmap; the raw 730 * screen will be scaled down to this size. 731 * @return Returns a Bitmap containing the screen contents, or null 732 * if an error occurs. Make sure to call Bitmap.recycle() as soon as 733 * possible, once its content is not needed anymore. 734 */ screenshot(int width, int height)735 public static Bitmap screenshot(int width, int height) { 736 // TODO: should take the display as a parameter 737 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 738 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 739 return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, 740 false, Surface.ROTATION_0); 741 } 742 screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)743 private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, 744 int width, int height, int minLayer, int maxLayer, boolean allLayers, 745 boolean useIdentityTransform) { 746 if (display == null) { 747 throw new IllegalArgumentException("displayToken must not be null"); 748 } 749 if (consumer == null) { 750 throw new IllegalArgumentException("consumer must not be null"); 751 } 752 nativeScreenshot(display, consumer, sourceCrop, width, height, 753 minLayer, maxLayer, allLayers, useIdentityTransform); 754 } 755 } 756