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