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