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 * set display parameters. 458 * needs to be inside open/closeTransaction block 459 */ 460 461 /** 462 * Describes the properties of a physical display known to surface flinger. 463 */ 464 public static final class PhysicalDisplayInfo { 465 public int width; 466 public int height; 467 public float refreshRate; 468 public float density; 469 public float xDpi; 470 public float yDpi; 471 public boolean secure; 472 public long appVsyncOffsetNanos; 473 public long presentationDeadlineNanos; 474 PhysicalDisplayInfo()475 public PhysicalDisplayInfo() { 476 } 477 PhysicalDisplayInfo(PhysicalDisplayInfo other)478 public PhysicalDisplayInfo(PhysicalDisplayInfo other) { 479 copyFrom(other); 480 } 481 482 @Override equals(Object o)483 public boolean equals(Object o) { 484 return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); 485 } 486 equals(PhysicalDisplayInfo other)487 public boolean equals(PhysicalDisplayInfo other) { 488 return other != null 489 && width == other.width 490 && height == other.height 491 && refreshRate == other.refreshRate 492 && density == other.density 493 && xDpi == other.xDpi 494 && yDpi == other.yDpi 495 && secure == other.secure 496 && appVsyncOffsetNanos == other.appVsyncOffsetNanos 497 && presentationDeadlineNanos == other.presentationDeadlineNanos; 498 } 499 500 @Override hashCode()501 public int hashCode() { 502 return 0; // don't care 503 } 504 copyFrom(PhysicalDisplayInfo other)505 public void copyFrom(PhysicalDisplayInfo other) { 506 width = other.width; 507 height = other.height; 508 refreshRate = other.refreshRate; 509 density = other.density; 510 xDpi = other.xDpi; 511 yDpi = other.yDpi; 512 secure = other.secure; 513 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 514 presentationDeadlineNanos = other.presentationDeadlineNanos; 515 } 516 517 // For debugging purposes 518 @Override toString()519 public String toString() { 520 return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " 521 + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure 522 + ", appVsyncOffset " + appVsyncOffsetNanos 523 + ", bufferDeadline " + presentationDeadlineNanos + "}"; 524 } 525 } 526 setDisplayPowerMode(IBinder displayToken, int mode)527 public static void setDisplayPowerMode(IBinder displayToken, int mode) { 528 if (displayToken == null) { 529 throw new IllegalArgumentException("displayToken must not be null"); 530 } 531 nativeSetDisplayPowerMode(displayToken, mode); 532 } 533 getDisplayConfigs(IBinder displayToken)534 public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) { 535 if (displayToken == null) { 536 throw new IllegalArgumentException("displayToken must not be null"); 537 } 538 return nativeGetDisplayConfigs(displayToken); 539 } 540 getActiveConfig(IBinder displayToken)541 public static int getActiveConfig(IBinder displayToken) { 542 if (displayToken == null) { 543 throw new IllegalArgumentException("displayToken must not be null"); 544 } 545 return nativeGetActiveConfig(displayToken); 546 } 547 setActiveConfig(IBinder displayToken, int id)548 public static boolean setActiveConfig(IBinder displayToken, int id) { 549 if (displayToken == null) { 550 throw new IllegalArgumentException("displayToken must not be null"); 551 } 552 return nativeSetActiveConfig(displayToken, id); 553 } 554 setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)555 public static void setDisplayProjection(IBinder displayToken, 556 int orientation, Rect layerStackRect, Rect displayRect) { 557 if (displayToken == null) { 558 throw new IllegalArgumentException("displayToken must not be null"); 559 } 560 if (layerStackRect == null) { 561 throw new IllegalArgumentException("layerStackRect must not be null"); 562 } 563 if (displayRect == null) { 564 throw new IllegalArgumentException("displayRect must not be null"); 565 } 566 nativeSetDisplayProjection(displayToken, orientation, 567 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, 568 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom); 569 } 570 setDisplayLayerStack(IBinder displayToken, int layerStack)571 public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { 572 if (displayToken == null) { 573 throw new IllegalArgumentException("displayToken must not be null"); 574 } 575 nativeSetDisplayLayerStack(displayToken, layerStack); 576 } 577 setDisplaySurface(IBinder displayToken, Surface surface)578 public static void setDisplaySurface(IBinder displayToken, Surface surface) { 579 if (displayToken == null) { 580 throw new IllegalArgumentException("displayToken must not be null"); 581 } 582 583 if (surface != null) { 584 synchronized (surface.mLock) { 585 nativeSetDisplaySurface(displayToken, surface.mNativeObject); 586 } 587 } else { 588 nativeSetDisplaySurface(displayToken, 0); 589 } 590 } 591 setDisplaySize(IBinder displayToken, int width, int height)592 public static void setDisplaySize(IBinder displayToken, int width, int height) { 593 if (displayToken == null) { 594 throw new IllegalArgumentException("displayToken must not be null"); 595 } 596 if (width <= 0 || height <= 0) { 597 throw new IllegalArgumentException("width and height must be positive"); 598 } 599 600 nativeSetDisplaySize(displayToken, width, height); 601 } 602 createDisplay(String name, boolean secure)603 public static IBinder createDisplay(String name, boolean secure) { 604 if (name == null) { 605 throw new IllegalArgumentException("name must not be null"); 606 } 607 return nativeCreateDisplay(name, secure); 608 } 609 destroyDisplay(IBinder displayToken)610 public static void destroyDisplay(IBinder displayToken) { 611 if (displayToken == null) { 612 throw new IllegalArgumentException("displayToken must not be null"); 613 } 614 nativeDestroyDisplay(displayToken); 615 } 616 getBuiltInDisplay(int builtInDisplayId)617 public static IBinder getBuiltInDisplay(int builtInDisplayId) { 618 return nativeGetBuiltInDisplay(builtInDisplayId); 619 } 620 621 /** 622 * Copy the current screen contents into the provided {@link Surface} 623 * 624 * @param display The display to take the screenshot of. 625 * @param consumer The {@link Surface} to take the screenshot into. 626 * @param width The desired width of the returned bitmap; the raw 627 * screen will be scaled down to this size. 628 * @param height The desired height of the returned bitmap; the raw 629 * screen will be scaled down to this size. 630 * @param minLayer The lowest (bottom-most Z order) surface layer to 631 * include in the screenshot. 632 * @param maxLayer The highest (top-most Z order) surface layer to 633 * include in the screenshot. 634 * @param useIdentityTransform Replace whatever transformation (rotation, 635 * scaling, translation) the surface layers are currently using with the 636 * identity transformation while taking the screenshot. 637 */ screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform)638 public static void screenshot(IBinder display, Surface consumer, 639 int width, int height, int minLayer, int maxLayer, 640 boolean useIdentityTransform) { 641 screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer, 642 false, useIdentityTransform); 643 } 644 645 /** 646 * Copy the current screen contents into the provided {@link Surface} 647 * 648 * @param display The display to take the screenshot of. 649 * @param consumer The {@link Surface} to take the screenshot into. 650 * @param width The desired width of the returned bitmap; the raw 651 * screen will be scaled down to this size. 652 * @param height The desired height of the returned bitmap; the raw 653 * screen will be scaled down to this size. 654 */ screenshot(IBinder display, Surface consumer, int width, int height)655 public static void screenshot(IBinder display, Surface consumer, 656 int width, int height) { 657 screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false); 658 } 659 660 /** 661 * Copy the current screen contents into the provided {@link Surface} 662 * 663 * @param display The display to take the screenshot of. 664 * @param consumer The {@link Surface} to take the screenshot into. 665 */ screenshot(IBinder display, Surface consumer)666 public static void screenshot(IBinder display, Surface consumer) { 667 screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false); 668 } 669 670 /** 671 * Copy the current screen contents into a bitmap and return it. 672 * 673 * CAVEAT: Versions of screenshot that return a {@link Bitmap} can 674 * be extremely slow; avoid use unless absolutely necessary; prefer 675 * the versions that use a {@link Surface} instead, such as 676 * {@link SurfaceControl#screenshot(IBinder, Surface)}. 677 * 678 * @param sourceCrop The portion of the screen to capture into the Bitmap; 679 * caller may pass in 'new Rect()' if no cropping is desired. 680 * @param width The desired width of the returned bitmap; the raw 681 * screen will be scaled down to this size. 682 * @param height The desired height of the returned bitmap; the raw 683 * screen will be scaled down to this size. 684 * @param minLayer The lowest (bottom-most Z order) surface layer to 685 * include in the screenshot. 686 * @param maxLayer The highest (top-most Z order) surface layer to 687 * include in the screenshot. 688 * @param useIdentityTransform Replace whatever transformation (rotation, 689 * scaling, translation) the surface layers are currently using with the 690 * identity transformation while taking the screenshot. 691 * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. 692 * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take 693 * screenshots in its native portrait orientation by default, so this is 694 * useful for returning screenshots that are independent of device 695 * orientation. 696 * @return Returns a Bitmap containing the screen contents, or null 697 * if an error occurs. Make sure to call Bitmap.recycle() as soon as 698 * possible, once its content is not needed anymore. 699 */ screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)700 public static Bitmap screenshot(Rect sourceCrop, int width, int height, 701 int minLayer, int maxLayer, boolean useIdentityTransform, 702 int rotation) { 703 // TODO: should take the display as a parameter 704 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 705 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 706 return nativeScreenshot(displayToken, sourceCrop, width, height, 707 minLayer, maxLayer, false, useIdentityTransform, rotation); 708 } 709 710 /** 711 * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but 712 * includes all Surfaces in the screenshot. 713 * 714 * @param width The desired width of the returned bitmap; the raw 715 * screen will be scaled down to this size. 716 * @param height The desired height of the returned bitmap; the raw 717 * screen will be scaled down to this size. 718 * @return Returns a Bitmap containing the screen contents, or null 719 * if an error occurs. Make sure to call Bitmap.recycle() as soon as 720 * possible, once its content is not needed anymore. 721 */ screenshot(int width, int height)722 public static Bitmap screenshot(int width, int height) { 723 // TODO: should take the display as a parameter 724 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 725 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 726 return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, 727 false, Surface.ROTATION_0); 728 } 729 screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)730 private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, 731 int width, int height, int minLayer, int maxLayer, boolean allLayers, 732 boolean useIdentityTransform) { 733 if (display == null) { 734 throw new IllegalArgumentException("displayToken must not be null"); 735 } 736 if (consumer == null) { 737 throw new IllegalArgumentException("consumer must not be null"); 738 } 739 nativeScreenshot(display, consumer, sourceCrop, width, height, 740 minLayer, maxLayer, allLayers, useIdentityTransform); 741 } 742 } 743