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