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 static android.graphics.Matrix.MSCALE_X; 20 import static android.graphics.Matrix.MSCALE_Y; 21 import static android.graphics.Matrix.MSKEW_X; 22 import static android.graphics.Matrix.MSKEW_Y; 23 import static android.graphics.Matrix.MTRANS_X; 24 import static android.graphics.Matrix.MTRANS_Y; 25 import static android.view.Surface.ROTATION_270; 26 import static android.view.Surface.ROTATION_90; 27 import static android.view.SurfaceControlProto.HASH_CODE; 28 import static android.view.SurfaceControlProto.NAME; 29 30 import android.annotation.Size; 31 import android.graphics.Bitmap; 32 import android.graphics.GraphicBuffer; 33 import android.graphics.Matrix; 34 import android.graphics.PixelFormat; 35 import android.graphics.Point; 36 import android.graphics.Rect; 37 import android.graphics.Region; 38 import android.os.IBinder; 39 import android.os.Parcel; 40 import android.os.Parcelable; 41 import android.os.Process; 42 import android.os.UserHandle; 43 import android.util.ArrayMap; 44 import android.util.Log; 45 import android.util.proto.ProtoOutputStream; 46 import android.view.Surface.OutOfResourcesException; 47 48 import com.android.internal.annotations.GuardedBy; 49 50 import dalvik.system.CloseGuard; 51 52 import libcore.util.NativeAllocationRegistry; 53 54 import java.io.Closeable; 55 56 /** 57 * SurfaceControl 58 * @hide 59 */ 60 public class SurfaceControl implements Parcelable { 61 private static final String TAG = "SurfaceControl"; 62 nativeCreate(SurfaceSession session, String name, int w, int h, int format, int flags, long parentObject, int windowType, int ownerUid)63 private static native long nativeCreate(SurfaceSession session, String name, 64 int w, int h, int format, int flags, long parentObject, int windowType, int ownerUid) 65 throws OutOfResourcesException; nativeReadFromParcel(Parcel in)66 private static native long nativeReadFromParcel(Parcel in); nativeWriteToParcel(long nativeObject, Parcel out)67 private static native void nativeWriteToParcel(long nativeObject, Parcel out); nativeRelease(long nativeObject)68 private static native void nativeRelease(long nativeObject); nativeDestroy(long nativeObject)69 private static native void nativeDestroy(long nativeObject); nativeDisconnect(long nativeObject)70 private static native void nativeDisconnect(long nativeObject); 71 nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform, int rotation)72 private static native Bitmap nativeScreenshot(IBinder displayToken, 73 Rect sourceCrop, int width, int height, int minLayer, int maxLayer, 74 boolean allLayers, boolean useIdentityTransform, int rotation); nativeScreenshotToBuffer(IBinder displayToken, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform, int rotation, boolean captureSecureLayers)75 private static native GraphicBuffer nativeScreenshotToBuffer(IBinder displayToken, 76 Rect sourceCrop, int width, int height, int minLayer, int maxLayer, 77 boolean allLayers, boolean useIdentityTransform, int rotation, 78 boolean captureSecureLayers); nativeScreenshot(IBinder displayToken, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)79 private static native void nativeScreenshot(IBinder displayToken, Surface consumer, 80 Rect sourceCrop, int width, int height, int minLayer, int maxLayer, 81 boolean allLayers, boolean useIdentityTransform); nativeCaptureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale)82 private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken, 83 Rect sourceCrop, float frameScale); 84 nativeCreateTransaction()85 private static native long nativeCreateTransaction(); nativeGetNativeTransactionFinalizer()86 private static native long nativeGetNativeTransactionFinalizer(); nativeApplyTransaction(long transactionObj, boolean sync)87 private static native void nativeApplyTransaction(long transactionObj, boolean sync); nativeMergeTransaction(long transactionObj, long otherTransactionObj)88 private static native void nativeMergeTransaction(long transactionObj, 89 long otherTransactionObj); nativeSetAnimationTransaction(long transactionObj)90 private static native void nativeSetAnimationTransaction(long transactionObj); nativeSetEarlyWakeup(long transactionObj)91 private static native void nativeSetEarlyWakeup(long transactionObj); 92 nativeSetLayer(long transactionObj, long nativeObject, int zorder)93 private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder); nativeSetRelativeLayer(long transactionObj, long nativeObject, IBinder relativeTo, int zorder)94 private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject, 95 IBinder relativeTo, int zorder); nativeSetPosition(long transactionObj, long nativeObject, float x, float y)96 private static native void nativeSetPosition(long transactionObj, long nativeObject, 97 float x, float y); nativeSetGeometryAppliesWithResize(long transactionObj, long nativeObject)98 private static native void nativeSetGeometryAppliesWithResize(long transactionObj, 99 long nativeObject); nativeSetSize(long transactionObj, long nativeObject, int w, int h)100 private static native void nativeSetSize(long transactionObj, long nativeObject, int w, int h); nativeSetTransparentRegionHint(long transactionObj, long nativeObject, Region region)101 private static native void nativeSetTransparentRegionHint(long transactionObj, 102 long nativeObject, Region region); nativeSetAlpha(long transactionObj, long nativeObject, float alpha)103 private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha); nativeSetMatrix(long transactionObj, long nativeObject, float dsdx, float dtdx, float dtdy, float dsdy)104 private static native void nativeSetMatrix(long transactionObj, long nativeObject, 105 float dsdx, float dtdx, 106 float dtdy, float dsdy); nativeSetColor(long transactionObj, long nativeObject, float[] color)107 private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color); nativeSetFlags(long transactionObj, long nativeObject, int flags, int mask)108 private static native void nativeSetFlags(long transactionObj, long nativeObject, 109 int flags, int mask); nativeSetWindowCrop(long transactionObj, long nativeObject, int l, int t, int r, int b)110 private static native void nativeSetWindowCrop(long transactionObj, long nativeObject, 111 int l, int t, int r, int b); nativeSetFinalCrop(long transactionObj, long nativeObject, int l, int t, int r, int b)112 private static native void nativeSetFinalCrop(long transactionObj, long nativeObject, 113 int l, int t, int r, int b); nativeSetLayerStack(long transactionObj, long nativeObject, int layerStack)114 private static native void nativeSetLayerStack(long transactionObj, long nativeObject, 115 int layerStack); 116 nativeClearContentFrameStats(long nativeObject)117 private static native boolean nativeClearContentFrameStats(long nativeObject); nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats)118 private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats); nativeClearAnimationFrameStats()119 private static native boolean nativeClearAnimationFrameStats(); nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats)120 private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats); 121 nativeGetBuiltInDisplay(int physicalDisplayId)122 private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId); nativeCreateDisplay(String name, boolean secure)123 private static native IBinder nativeCreateDisplay(String name, boolean secure); nativeDestroyDisplay(IBinder displayToken)124 private static native void nativeDestroyDisplay(IBinder displayToken); nativeSetDisplaySurface(long transactionObj, IBinder displayToken, long nativeSurfaceObject)125 private static native void nativeSetDisplaySurface(long transactionObj, 126 IBinder displayToken, long nativeSurfaceObject); nativeSetDisplayLayerStack(long transactionObj, IBinder displayToken, int layerStack)127 private static native void nativeSetDisplayLayerStack(long transactionObj, 128 IBinder displayToken, int layerStack); nativeSetDisplayProjection(long transactionObj, IBinder displayToken, int orientation, int l, int t, int r, int b, int L, int T, int R, int B)129 private static native void nativeSetDisplayProjection(long transactionObj, 130 IBinder displayToken, int orientation, 131 int l, int t, int r, int b, 132 int L, int T, int R, int B); nativeSetDisplaySize(long transactionObj, IBinder displayToken, int width, int height)133 private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken, 134 int width, int height); nativeGetDisplayConfigs( IBinder displayToken)135 private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs( 136 IBinder displayToken); nativeGetActiveConfig(IBinder displayToken)137 private static native int nativeGetActiveConfig(IBinder displayToken); nativeSetActiveConfig(IBinder displayToken, int id)138 private static native boolean nativeSetActiveConfig(IBinder displayToken, int id); nativeGetDisplayColorModes(IBinder displayToken)139 private static native int[] nativeGetDisplayColorModes(IBinder displayToken); nativeGetActiveColorMode(IBinder displayToken)140 private static native int nativeGetActiveColorMode(IBinder displayToken); nativeSetActiveColorMode(IBinder displayToken, int colorMode)141 private static native boolean nativeSetActiveColorMode(IBinder displayToken, 142 int colorMode); nativeSetDisplayPowerMode( IBinder displayToken, int mode)143 private static native void nativeSetDisplayPowerMode( 144 IBinder displayToken, int mode); nativeDeferTransactionUntil(long transactionObj, long nativeObject, IBinder handle, long frame)145 private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject, 146 IBinder handle, long frame); nativeDeferTransactionUntilSurface(long transactionObj, long nativeObject, long surfaceObject, long frame)147 private static native void nativeDeferTransactionUntilSurface(long transactionObj, 148 long nativeObject, 149 long surfaceObject, long frame); nativeReparentChildren(long transactionObj, long nativeObject, IBinder handle)150 private static native void nativeReparentChildren(long transactionObj, long nativeObject, 151 IBinder handle); nativeReparent(long transactionObj, long nativeObject, IBinder parentHandle)152 private static native void nativeReparent(long transactionObj, long nativeObject, 153 IBinder parentHandle); nativeSeverChildren(long transactionObj, long nativeObject)154 private static native void nativeSeverChildren(long transactionObj, long nativeObject); nativeSetOverrideScalingMode(long transactionObj, long nativeObject, int scalingMode)155 private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject, 156 int scalingMode); nativeDestroy(long transactionObj, long nativeObject)157 private static native void nativeDestroy(long transactionObj, long nativeObject); nativeGetHandle(long nativeObject)158 private static native IBinder nativeGetHandle(long nativeObject); nativeGetTransformToDisplayInverse(long nativeObject)159 private static native boolean nativeGetTransformToDisplayInverse(long nativeObject); 160 nativeGetHdrCapabilities(IBinder displayToken)161 private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken); 162 163 164 private final CloseGuard mCloseGuard = CloseGuard.get(); 165 private final String mName; 166 long mNativeObject; // package visibility only for Surface.java access 167 168 // TODO: Move this to native. 169 private final Object mSizeLock = new Object(); 170 @GuardedBy("mSizeLock") 171 private int mWidth; 172 @GuardedBy("mSizeLock") 173 private int mHeight; 174 175 static Transaction sGlobalTransaction; 176 static long sTransactionNestCount = 0; 177 178 /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ 179 180 /** 181 * Surface creation flag: Surface is created hidden 182 */ 183 public static final int HIDDEN = 0x00000004; 184 185 /** 186 * Surface creation flag: The surface contains secure content, special 187 * measures will be taken to disallow the surface's content to be copied 188 * from another process. In particular, screenshots and VNC servers will 189 * be disabled, but other measures can take place, for instance the 190 * surface might not be hardware accelerated. 191 * 192 */ 193 public static final int SECURE = 0x00000080; 194 195 /** 196 * Surface creation flag: Creates a surface where color components are interpreted 197 * as "non pre-multiplied" by their alpha channel. Of course this flag is 198 * meaningless for surfaces without an alpha channel. By default 199 * surfaces are pre-multiplied, which means that each color component is 200 * already multiplied by its alpha value. In this case the blending 201 * equation used is: 202 * <p> 203 * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code> 204 * <p> 205 * By contrast, non pre-multiplied surfaces use the following equation: 206 * <p> 207 * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code> 208 * <p> 209 * pre-multiplied surfaces must always be used if transparent pixels are 210 * composited on top of each-other into the surface. A pre-multiplied 211 * surface can never lower the value of the alpha component of a given 212 * pixel. 213 * <p> 214 * In some rare situations, a non pre-multiplied surface is preferable. 215 * 216 */ 217 public static final int NON_PREMULTIPLIED = 0x00000100; 218 219 /** 220 * Surface creation flag: Indicates that the surface must be considered opaque, 221 * even if its pixel format contains an alpha channel. This can be useful if an 222 * application needs full RGBA 8888 support for instance but will 223 * still draw every pixel opaque. 224 * <p> 225 * This flag is ignored if setAlpha() is used to make the surface non-opaque. 226 * Combined effects are (assuming a buffer format with an alpha channel): 227 * <ul> 228 * <li>OPAQUE + alpha(1.0) == opaque composition 229 * <li>OPAQUE + alpha(0.x) == blended composition 230 * <li>!OPAQUE + alpha(1.0) == blended composition 231 * <li>!OPAQUE + alpha(0.x) == blended composition 232 * </ul> 233 * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively 234 * set automatically. 235 */ 236 public static final int OPAQUE = 0x00000400; 237 238 /** 239 * Surface creation flag: Application requires a hardware-protected path to an 240 * external display sink. If a hardware-protected path is not available, 241 * then this surface will not be displayed on the external sink. 242 * 243 */ 244 public static final int PROTECTED_APP = 0x00000800; 245 246 // 0x1000 is reserved for an independent DRM protected flag in framework 247 248 /** 249 * Surface creation flag: Window represents a cursor glyph. 250 */ 251 public static final int CURSOR_WINDOW = 0x00002000; 252 253 /** 254 * Surface creation flag: Creates a normal surface. 255 * This is the default. 256 * 257 */ 258 public static final int FX_SURFACE_NORMAL = 0x00000000; 259 260 /** 261 * Surface creation flag: Creates a Dim surface. 262 * Everything behind this surface is dimmed by the amount specified 263 * in {@link #setAlpha}. It is an error to lock a Dim surface, since it 264 * doesn't have a backing store. 265 * 266 */ 267 public static final int FX_SURFACE_DIM = 0x00020000; 268 269 /** 270 * Mask used for FX values above. 271 * 272 */ 273 public static final int FX_SURFACE_MASK = 0x000F0000; 274 275 /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ 276 277 /** 278 * Surface flag: Hide the surface. 279 * Equivalent to calling hide(). 280 * Updates the value set during Surface creation (see {@link #HIDDEN}). 281 */ 282 private static final int SURFACE_HIDDEN = 0x01; 283 284 /** 285 * Surface flag: composite without blending when possible. 286 * Updates the value set during Surface creation (see {@link #OPAQUE}). 287 */ 288 private static final int SURFACE_OPAQUE = 0x02; 289 290 291 /* built-in physical display ids (keep in sync with ISurfaceComposer.h) 292 * these are different from the logical display ids used elsewhere in the framework */ 293 294 /** 295 * Built-in physical display id: Main display. 296 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. 297 */ 298 public static final int BUILT_IN_DISPLAY_ID_MAIN = 0; 299 300 /** 301 * Built-in physical display id: Attached HDMI display. 302 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. 303 */ 304 public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; 305 306 /* Display power modes * / 307 308 /** 309 * Display power mode off: used while blanking the screen. 310 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 311 */ 312 public static final int POWER_MODE_OFF = 0; 313 314 /** 315 * Display power mode doze: used while putting the screen into low power mode. 316 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 317 */ 318 public static final int POWER_MODE_DOZE = 1; 319 320 /** 321 * Display power mode normal: used while unblanking the screen. 322 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 323 */ 324 public static final int POWER_MODE_NORMAL = 2; 325 326 /** 327 * Display power mode doze: used while putting the screen into a suspended 328 * low power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. 329 */ 330 public static final int POWER_MODE_DOZE_SUSPEND = 3; 331 332 /** 333 * Display power mode on: used while putting the screen into a suspended 334 * full power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. 335 */ 336 public static final int POWER_MODE_ON_SUSPEND = 4; 337 338 /** 339 * A value for windowType used to indicate that the window should be omitted from screenshots 340 * and display mirroring. A temporary workaround until we express such things with 341 * the hierarchy. 342 * TODO: b/64227542 343 * @hide 344 */ 345 public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731; 346 347 /** 348 * Builder class for {@link SurfaceControl} objects. 349 */ 350 public static class Builder { 351 private SurfaceSession mSession; 352 private int mFlags = HIDDEN; 353 private int mWidth; 354 private int mHeight; 355 private int mFormat = PixelFormat.OPAQUE; 356 private String mName; 357 private SurfaceControl mParent; 358 private int mWindowType = -1; 359 private int mOwnerUid = -1; 360 361 /** 362 * Begin building a SurfaceControl with a given {@link SurfaceSession}. 363 * 364 * @param session The {@link SurfaceSession} with which to eventually construct the surface. 365 */ Builder(SurfaceSession session)366 public Builder(SurfaceSession session) { 367 mSession = session; 368 } 369 370 /** 371 * Construct a new {@link SurfaceControl} with the set parameters. 372 */ build()373 public SurfaceControl build() { 374 if (mWidth <= 0 || mHeight <= 0) { 375 throw new IllegalArgumentException( 376 "width and height must be set"); 377 } 378 return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, 379 mFlags, mParent, mWindowType, mOwnerUid); 380 } 381 382 /** 383 * Set a debugging-name for the SurfaceControl. 384 * 385 * @param name A name to identify the Surface in debugging. 386 */ setName(String name)387 public Builder setName(String name) { 388 mName = name; 389 return this; 390 } 391 392 /** 393 * Set the initial size of the controlled surface's buffers in pixels. 394 * 395 * @param width The buffer width in pixels. 396 * @param height The buffer height in pixels. 397 */ setSize(int width, int height)398 public Builder setSize(int width, int height) { 399 if (width <= 0 || height <= 0) { 400 throw new IllegalArgumentException( 401 "width and height must be positive"); 402 } 403 mWidth = width; 404 mHeight = height; 405 return this; 406 } 407 408 /** 409 * Set the pixel format of the controlled surface's buffers, using constants from 410 * {@link android.graphics.PixelFormat}. 411 */ setFormat(@ixelFormat.Format int format)412 public Builder setFormat(@PixelFormat.Format int format) { 413 mFormat = format; 414 return this; 415 } 416 417 /** 418 * Specify if the app requires a hardware-protected path to 419 * an external display sync. If protected content is enabled, but 420 * such a path is not available, then the controlled Surface will 421 * not be displayed. 422 * 423 * @param protectedContent Whether to require a protected sink. 424 */ setProtected(boolean protectedContent)425 public Builder setProtected(boolean protectedContent) { 426 if (protectedContent) { 427 mFlags |= PROTECTED_APP; 428 } else { 429 mFlags &= ~PROTECTED_APP; 430 } 431 return this; 432 } 433 434 /** 435 * Specify whether the Surface contains secure content. If true, the system 436 * will prevent the surfaces content from being copied by another process. In 437 * particular screenshots and VNC servers will be disabled. This is however 438 * not a complete prevention of readback as {@link #setProtected}. 439 */ setSecure(boolean secure)440 public Builder setSecure(boolean secure) { 441 if (secure) { 442 mFlags |= SECURE; 443 } else { 444 mFlags &= ~SECURE; 445 } 446 return this; 447 } 448 449 /** 450 * Indicates whether the surface must be considered opaque, 451 * even if its pixel format is set to translucent. This can be useful if an 452 * application needs full RGBA 8888 support for instance but will 453 * still draw every pixel opaque. 454 * <p> 455 * This flag only determines whether opacity will be sampled from the alpha channel. 456 * Plane-alpha from calls to setAlpha() can still result in blended composition 457 * regardless of the opaque setting. 458 * 459 * Combined effects are (assuming a buffer format with an alpha channel): 460 * <ul> 461 * <li>OPAQUE + alpha(1.0) == opaque composition 462 * <li>OPAQUE + alpha(0.x) == blended composition 463 * <li>OPAQUE + alpha(0.0) == no composition 464 * <li>!OPAQUE + alpha(1.0) == blended composition 465 * <li>!OPAQUE + alpha(0.x) == blended composition 466 * <li>!OPAQUE + alpha(0.0) == no composition 467 * </ul> 468 * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) 469 * were set automatically. 470 * @param opaque Whether the Surface is OPAQUE. 471 */ setOpaque(boolean opaque)472 public Builder setOpaque(boolean opaque) { 473 if (opaque) { 474 mFlags |= OPAQUE; 475 } else { 476 mFlags &= ~OPAQUE; 477 } 478 return this; 479 } 480 481 /** 482 * Set a parent surface for our new SurfaceControl. 483 * 484 * Child surfaces are constrained to the onscreen region of their parent. 485 * Furthermore they stack relatively in Z order, and inherit the transformation 486 * of the parent. 487 * 488 * @param parent The parent control. 489 */ setParent(SurfaceControl parent)490 public Builder setParent(SurfaceControl parent) { 491 mParent = parent; 492 return this; 493 } 494 495 /** 496 * Set surface metadata. 497 * 498 * Currently these are window-types as per {@link WindowManager.LayoutParams} and 499 * owner UIDs. Child surfaces inherit their parents 500 * metadata so only the WindowManager needs to set this on root Surfaces. 501 * 502 * @param windowType A window-type 503 * @param ownerUid UID of the window owner. 504 */ setMetadata(int windowType, int ownerUid)505 public Builder setMetadata(int windowType, int ownerUid) { 506 if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) { 507 throw new UnsupportedOperationException( 508 "It only makes sense to set Surface metadata from the WindowManager"); 509 } 510 mWindowType = windowType; 511 mOwnerUid = ownerUid; 512 return this; 513 } 514 515 /** 516 * Indicate whether a 'ColorLayer' is to be constructed. 517 * 518 * Color layers will not have an associated BufferQueue and will instead always render a 519 * solid color (that is, solid before plane alpha). Currently that color is black. 520 * 521 * @param isColorLayer Whether to create a color layer. 522 */ setColorLayer(boolean isColorLayer)523 public Builder setColorLayer(boolean isColorLayer) { 524 if (isColorLayer) { 525 mFlags |= FX_SURFACE_DIM; 526 } else { 527 mFlags &= ~FX_SURFACE_DIM; 528 } 529 return this; 530 } 531 532 /** 533 * Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}. 534 * 535 * TODO: Finish conversion to individual builder methods? 536 * @param flags The combined flags 537 */ setFlags(int flags)538 public Builder setFlags(int flags) { 539 mFlags = flags; 540 return this; 541 } 542 } 543 544 /** 545 * Create a surface with a name. 546 * <p> 547 * The surface creation flags specify what kind of surface to create and 548 * certain options such as whether the surface can be assumed to be opaque 549 * and whether it should be initially hidden. Surfaces should always be 550 * created with the {@link #HIDDEN} flag set to ensure that they are not 551 * made visible prematurely before all of the surface's properties have been 552 * configured. 553 * <p> 554 * Good practice is to first create the surface with the {@link #HIDDEN} flag 555 * specified, open a transaction, set the surface layer, layer stack, alpha, 556 * and position, call {@link #show} if appropriate, and close the transaction. 557 * 558 * @param session The surface session, must not be null. 559 * @param name The surface name, must not be null. 560 * @param w The surface initial width. 561 * @param h The surface initial height. 562 * @param flags The surface creation flags. Should always include {@link #HIDDEN} 563 * in the creation flags. 564 * @param windowType The type of the window as specified in WindowManager.java. 565 * @param ownerUid A unique per-app ID. 566 * 567 * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. 568 */ SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, int windowType, int ownerUid)569 private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, 570 SurfaceControl parent, int windowType, int ownerUid) 571 throws OutOfResourcesException, IllegalArgumentException { 572 if (session == null) { 573 throw new IllegalArgumentException("session must not be null"); 574 } 575 if (name == null) { 576 throw new IllegalArgumentException("name must not be null"); 577 } 578 579 if ((flags & SurfaceControl.HIDDEN) == 0) { 580 Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set " 581 + "to ensure that they are not made visible prematurely before " 582 + "all of the surface's properties have been configured. " 583 + "Set the other properties and make the surface visible within " 584 + "a transaction. New surface name: " + name, 585 new Throwable()); 586 } 587 588 mName = name; 589 mWidth = w; 590 mHeight = h; 591 mNativeObject = nativeCreate(session, name, w, h, format, flags, 592 parent != null ? parent.mNativeObject : 0, windowType, ownerUid); 593 if (mNativeObject == 0) { 594 throw new OutOfResourcesException( 595 "Couldn't allocate SurfaceControl native object"); 596 } 597 598 mCloseGuard.open("release"); 599 } 600 601 // This is a transfer constructor, useful for transferring a live SurfaceControl native 602 // object to another Java wrapper which could have some different behavior, e.g. 603 // event logging. SurfaceControl(SurfaceControl other)604 public SurfaceControl(SurfaceControl other) { 605 mName = other.mName; 606 mWidth = other.mWidth; 607 mHeight = other.mHeight; 608 mNativeObject = other.mNativeObject; 609 other.mCloseGuard.close(); 610 other.mNativeObject = 0; 611 mCloseGuard.open("release"); 612 } 613 SurfaceControl(Parcel in)614 private SurfaceControl(Parcel in) { 615 mName = in.readString(); 616 mWidth = in.readInt(); 617 mHeight = in.readInt(); 618 mNativeObject = nativeReadFromParcel(in); 619 if (mNativeObject == 0) { 620 throw new IllegalArgumentException("Couldn't read SurfaceControl from parcel=" + in); 621 } 622 mCloseGuard.open("release"); 623 } 624 625 @Override describeContents()626 public int describeContents() { 627 return 0; 628 } 629 630 @Override writeToParcel(Parcel dest, int flags)631 public void writeToParcel(Parcel dest, int flags) { 632 dest.writeString(mName); 633 dest.writeInt(mWidth); 634 dest.writeInt(mHeight); 635 nativeWriteToParcel(mNativeObject, dest); 636 } 637 638 /** 639 * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link 640 * android.view.SurfaceControlProto}. 641 * 642 * @param proto Stream to write the SurfaceControl object to. 643 * @param fieldId Field Id of the SurfaceControl as defined in the parent message. 644 * @hide 645 */ writeToProto(ProtoOutputStream proto, long fieldId)646 public void writeToProto(ProtoOutputStream proto, long fieldId) { 647 final long token = proto.start(fieldId); 648 proto.write(HASH_CODE, System.identityHashCode(this)); 649 proto.write(NAME, mName); 650 proto.end(token); 651 } 652 653 public static final Creator<SurfaceControl> CREATOR 654 = new Creator<SurfaceControl>() { 655 public SurfaceControl createFromParcel(Parcel in) { 656 return new SurfaceControl(in); 657 } 658 659 public SurfaceControl[] newArray(int size) { 660 return new SurfaceControl[size]; 661 } 662 }; 663 664 @Override finalize()665 protected void finalize() throws Throwable { 666 try { 667 if (mCloseGuard != null) { 668 mCloseGuard.warnIfOpen(); 669 } 670 if (mNativeObject != 0) { 671 nativeRelease(mNativeObject); 672 } 673 } finally { 674 super.finalize(); 675 } 676 } 677 678 /** 679 * Release the local reference to the server-side surface. 680 * Always call release() when you're done with a Surface. 681 * This will make the surface invalid. 682 */ release()683 public void release() { 684 if (mNativeObject != 0) { 685 nativeRelease(mNativeObject); 686 mNativeObject = 0; 687 } 688 mCloseGuard.close(); 689 } 690 691 /** 692 * Free all server-side state associated with this surface and 693 * release this object's reference. This method can only be 694 * called from the process that created the service. 695 */ destroy()696 public void destroy() { 697 if (mNativeObject != 0) { 698 nativeDestroy(mNativeObject); 699 mNativeObject = 0; 700 } 701 mCloseGuard.close(); 702 } 703 704 /** 705 * Disconnect any client still connected to the surface. 706 */ disconnect()707 public void disconnect() { 708 if (mNativeObject != 0) { 709 nativeDisconnect(mNativeObject); 710 } 711 } 712 checkNotReleased()713 private void checkNotReleased() { 714 if (mNativeObject == 0) throw new NullPointerException( 715 "mNativeObject is null. Have you called release() already?"); 716 } 717 718 /* 719 * set surface parameters. 720 * needs to be inside open/closeTransaction block 721 */ 722 723 /** start a transaction */ openTransaction()724 public static void openTransaction() { 725 synchronized (SurfaceControl.class) { 726 if (sGlobalTransaction == null) { 727 sGlobalTransaction = new Transaction(); 728 } 729 synchronized(SurfaceControl.class) { 730 sTransactionNestCount++; 731 } 732 } 733 } 734 closeTransaction(boolean sync)735 private static void closeTransaction(boolean sync) { 736 synchronized(SurfaceControl.class) { 737 if (sTransactionNestCount == 0) { 738 Log.e(TAG, "Call to SurfaceControl.closeTransaction without matching openTransaction"); 739 } else if (--sTransactionNestCount > 0) { 740 return; 741 } 742 sGlobalTransaction.apply(sync); 743 } 744 } 745 746 /** 747 * Merge the supplied transaction in to the deprecated "global" transaction. 748 * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}. 749 * <p> 750 * This is a utility for interop with legacy-code and will go away with the Global Transaction. 751 */ 752 @Deprecated mergeToGlobalTransaction(Transaction t)753 public static void mergeToGlobalTransaction(Transaction t) { 754 synchronized(SurfaceControl.class) { 755 sGlobalTransaction.merge(t); 756 } 757 } 758 759 /** end a transaction */ closeTransaction()760 public static void closeTransaction() { 761 closeTransaction(false); 762 } 763 closeTransactionSync()764 public static void closeTransactionSync() { 765 closeTransaction(true); 766 } 767 deferTransactionUntil(IBinder handle, long frame)768 public void deferTransactionUntil(IBinder handle, long frame) { 769 synchronized(SurfaceControl.class) { 770 sGlobalTransaction.deferTransactionUntil(this, handle, frame); 771 } 772 } 773 deferTransactionUntil(Surface barrier, long frame)774 public void deferTransactionUntil(Surface barrier, long frame) { 775 synchronized(SurfaceControl.class) { 776 sGlobalTransaction.deferTransactionUntilSurface(this, barrier, frame); 777 } 778 } 779 reparentChildren(IBinder newParentHandle)780 public void reparentChildren(IBinder newParentHandle) { 781 synchronized(SurfaceControl.class) { 782 sGlobalTransaction.reparentChildren(this, newParentHandle); 783 } 784 } 785 reparent(IBinder newParentHandle)786 public void reparent(IBinder newParentHandle) { 787 synchronized(SurfaceControl.class) { 788 sGlobalTransaction.reparent(this, newParentHandle); 789 } 790 } 791 detachChildren()792 public void detachChildren() { 793 synchronized(SurfaceControl.class) { 794 sGlobalTransaction.detachChildren(this); 795 } 796 } 797 setOverrideScalingMode(int scalingMode)798 public void setOverrideScalingMode(int scalingMode) { 799 checkNotReleased(); 800 synchronized(SurfaceControl.class) { 801 sGlobalTransaction.setOverrideScalingMode(this, scalingMode); 802 } 803 } 804 getHandle()805 public IBinder getHandle() { 806 return nativeGetHandle(mNativeObject); 807 } 808 setAnimationTransaction()809 public static void setAnimationTransaction() { 810 synchronized (SurfaceControl.class) { 811 sGlobalTransaction.setAnimationTransaction(); 812 } 813 } 814 setLayer(int zorder)815 public void setLayer(int zorder) { 816 checkNotReleased(); 817 synchronized(SurfaceControl.class) { 818 sGlobalTransaction.setLayer(this, zorder); 819 } 820 } 821 setRelativeLayer(SurfaceControl relativeTo, int zorder)822 public void setRelativeLayer(SurfaceControl relativeTo, int zorder) { 823 checkNotReleased(); 824 synchronized(SurfaceControl.class) { 825 sGlobalTransaction.setRelativeLayer(this, relativeTo, zorder); 826 } 827 } 828 setPosition(float x, float y)829 public void setPosition(float x, float y) { 830 checkNotReleased(); 831 synchronized(SurfaceControl.class) { 832 sGlobalTransaction.setPosition(this, x, y); 833 } 834 } 835 setGeometryAppliesWithResize()836 public void setGeometryAppliesWithResize() { 837 checkNotReleased(); 838 synchronized(SurfaceControl.class) { 839 sGlobalTransaction.setGeometryAppliesWithResize(this); 840 } 841 } 842 setSize(int w, int h)843 public void setSize(int w, int h) { 844 checkNotReleased(); 845 synchronized(SurfaceControl.class) { 846 sGlobalTransaction.setSize(this, w, h); 847 } 848 } 849 hide()850 public void hide() { 851 checkNotReleased(); 852 synchronized(SurfaceControl.class) { 853 sGlobalTransaction.hide(this); 854 } 855 } 856 show()857 public void show() { 858 checkNotReleased(); 859 synchronized(SurfaceControl.class) { 860 sGlobalTransaction.show(this); 861 } 862 } 863 setTransparentRegionHint(Region region)864 public void setTransparentRegionHint(Region region) { 865 checkNotReleased(); 866 synchronized(SurfaceControl.class) { 867 sGlobalTransaction.setTransparentRegionHint(this, region); 868 } 869 } 870 clearContentFrameStats()871 public boolean clearContentFrameStats() { 872 checkNotReleased(); 873 return nativeClearContentFrameStats(mNativeObject); 874 } 875 getContentFrameStats(WindowContentFrameStats outStats)876 public boolean getContentFrameStats(WindowContentFrameStats outStats) { 877 checkNotReleased(); 878 return nativeGetContentFrameStats(mNativeObject, outStats); 879 } 880 clearAnimationFrameStats()881 public static boolean clearAnimationFrameStats() { 882 return nativeClearAnimationFrameStats(); 883 } 884 getAnimationFrameStats(WindowAnimationFrameStats outStats)885 public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) { 886 return nativeGetAnimationFrameStats(outStats); 887 } 888 setAlpha(float alpha)889 public void setAlpha(float alpha) { 890 checkNotReleased(); 891 synchronized(SurfaceControl.class) { 892 sGlobalTransaction.setAlpha(this, alpha); 893 } 894 } 895 setColor(@ize3) float[] color)896 public void setColor(@Size(3) float[] color) { 897 checkNotReleased(); 898 synchronized (SurfaceControl.class) { 899 sGlobalTransaction.setColor(this, color); 900 } 901 } 902 setMatrix(float dsdx, float dtdx, float dtdy, float dsdy)903 public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) { 904 checkNotReleased(); 905 synchronized(SurfaceControl.class) { 906 sGlobalTransaction.setMatrix(this, dsdx, dtdx, dtdy, dsdy); 907 } 908 } 909 910 /** 911 * Sets the transform and position of a {@link SurfaceControl} from a 3x3 transformation matrix. 912 * 913 * @param matrix The matrix to apply. 914 * @param float9 An array of 9 floats to be used to extract the values from the matrix. 915 */ setMatrix(Matrix matrix, float[] float9)916 public void setMatrix(Matrix matrix, float[] float9) { 917 checkNotReleased(); 918 matrix.getValues(float9); 919 synchronized (SurfaceControl.class) { 920 sGlobalTransaction.setMatrix(this, float9[MSCALE_X], float9[MSKEW_Y], 921 float9[MSKEW_X], float9[MSCALE_Y]); 922 sGlobalTransaction.setPosition(this, float9[MTRANS_X], float9[MTRANS_Y]); 923 } 924 } 925 setWindowCrop(Rect crop)926 public void setWindowCrop(Rect crop) { 927 checkNotReleased(); 928 synchronized (SurfaceControl.class) { 929 sGlobalTransaction.setWindowCrop(this, crop); 930 } 931 } 932 setFinalCrop(Rect crop)933 public void setFinalCrop(Rect crop) { 934 checkNotReleased(); 935 synchronized (SurfaceControl.class) { 936 sGlobalTransaction.setFinalCrop(this, crop); 937 } 938 } 939 setLayerStack(int layerStack)940 public void setLayerStack(int layerStack) { 941 checkNotReleased(); 942 synchronized(SurfaceControl.class) { 943 sGlobalTransaction.setLayerStack(this, layerStack); 944 } 945 } 946 setOpaque(boolean isOpaque)947 public void setOpaque(boolean isOpaque) { 948 checkNotReleased(); 949 950 synchronized (SurfaceControl.class) { 951 sGlobalTransaction.setOpaque(this, isOpaque); 952 } 953 } 954 setSecure(boolean isSecure)955 public void setSecure(boolean isSecure) { 956 checkNotReleased(); 957 958 synchronized (SurfaceControl.class) { 959 sGlobalTransaction.setSecure(this, isSecure); 960 } 961 } 962 getWidth()963 public int getWidth() { 964 synchronized (mSizeLock) { 965 return mWidth; 966 } 967 } 968 getHeight()969 public int getHeight() { 970 synchronized (mSizeLock) { 971 return mHeight; 972 } 973 } 974 975 @Override toString()976 public String toString() { 977 return "Surface(name=" + mName + ")/@0x" + 978 Integer.toHexString(System.identityHashCode(this)); 979 } 980 981 /* 982 * set display parameters. 983 * needs to be inside open/closeTransaction block 984 */ 985 986 /** 987 * Describes the properties of a physical display known to surface flinger. 988 */ 989 public static final class PhysicalDisplayInfo { 990 public int width; 991 public int height; 992 public float refreshRate; 993 public float density; 994 public float xDpi; 995 public float yDpi; 996 public boolean secure; 997 public long appVsyncOffsetNanos; 998 public long presentationDeadlineNanos; 999 PhysicalDisplayInfo()1000 public PhysicalDisplayInfo() { 1001 } 1002 PhysicalDisplayInfo(PhysicalDisplayInfo other)1003 public PhysicalDisplayInfo(PhysicalDisplayInfo other) { 1004 copyFrom(other); 1005 } 1006 1007 @Override equals(Object o)1008 public boolean equals(Object o) { 1009 return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); 1010 } 1011 equals(PhysicalDisplayInfo other)1012 public boolean equals(PhysicalDisplayInfo other) { 1013 return other != null 1014 && width == other.width 1015 && height == other.height 1016 && refreshRate == other.refreshRate 1017 && density == other.density 1018 && xDpi == other.xDpi 1019 && yDpi == other.yDpi 1020 && secure == other.secure 1021 && appVsyncOffsetNanos == other.appVsyncOffsetNanos 1022 && presentationDeadlineNanos == other.presentationDeadlineNanos; 1023 } 1024 1025 @Override hashCode()1026 public int hashCode() { 1027 return 0; // don't care 1028 } 1029 copyFrom(PhysicalDisplayInfo other)1030 public void copyFrom(PhysicalDisplayInfo other) { 1031 width = other.width; 1032 height = other.height; 1033 refreshRate = other.refreshRate; 1034 density = other.density; 1035 xDpi = other.xDpi; 1036 yDpi = other.yDpi; 1037 secure = other.secure; 1038 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 1039 presentationDeadlineNanos = other.presentationDeadlineNanos; 1040 } 1041 1042 // For debugging purposes 1043 @Override toString()1044 public String toString() { 1045 return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " 1046 + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure 1047 + ", appVsyncOffset " + appVsyncOffsetNanos 1048 + ", bufferDeadline " + presentationDeadlineNanos + "}"; 1049 } 1050 } 1051 setDisplayPowerMode(IBinder displayToken, int mode)1052 public static void setDisplayPowerMode(IBinder displayToken, int mode) { 1053 if (displayToken == null) { 1054 throw new IllegalArgumentException("displayToken must not be null"); 1055 } 1056 nativeSetDisplayPowerMode(displayToken, mode); 1057 } 1058 getDisplayConfigs(IBinder displayToken)1059 public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) { 1060 if (displayToken == null) { 1061 throw new IllegalArgumentException("displayToken must not be null"); 1062 } 1063 return nativeGetDisplayConfigs(displayToken); 1064 } 1065 getActiveConfig(IBinder displayToken)1066 public static int getActiveConfig(IBinder displayToken) { 1067 if (displayToken == null) { 1068 throw new IllegalArgumentException("displayToken must not be null"); 1069 } 1070 return nativeGetActiveConfig(displayToken); 1071 } 1072 setActiveConfig(IBinder displayToken, int id)1073 public static boolean setActiveConfig(IBinder displayToken, int id) { 1074 if (displayToken == null) { 1075 throw new IllegalArgumentException("displayToken must not be null"); 1076 } 1077 return nativeSetActiveConfig(displayToken, id); 1078 } 1079 getDisplayColorModes(IBinder displayToken)1080 public static int[] getDisplayColorModes(IBinder displayToken) { 1081 if (displayToken == null) { 1082 throw new IllegalArgumentException("displayToken must not be null"); 1083 } 1084 return nativeGetDisplayColorModes(displayToken); 1085 } 1086 getActiveColorMode(IBinder displayToken)1087 public static int getActiveColorMode(IBinder displayToken) { 1088 if (displayToken == null) { 1089 throw new IllegalArgumentException("displayToken must not be null"); 1090 } 1091 return nativeGetActiveColorMode(displayToken); 1092 } 1093 setActiveColorMode(IBinder displayToken, int colorMode)1094 public static boolean setActiveColorMode(IBinder displayToken, int colorMode) { 1095 if (displayToken == null) { 1096 throw new IllegalArgumentException("displayToken must not be null"); 1097 } 1098 return nativeSetActiveColorMode(displayToken, colorMode); 1099 } 1100 setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)1101 public static void setDisplayProjection(IBinder displayToken, 1102 int orientation, Rect layerStackRect, Rect displayRect) { 1103 synchronized (SurfaceControl.class) { 1104 sGlobalTransaction.setDisplayProjection(displayToken, orientation, 1105 layerStackRect, displayRect); 1106 } 1107 } 1108 setDisplayLayerStack(IBinder displayToken, int layerStack)1109 public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { 1110 synchronized (SurfaceControl.class) { 1111 sGlobalTransaction.setDisplayLayerStack(displayToken, layerStack); 1112 } 1113 } 1114 setDisplaySurface(IBinder displayToken, Surface surface)1115 public static void setDisplaySurface(IBinder displayToken, Surface surface) { 1116 synchronized (SurfaceControl.class) { 1117 sGlobalTransaction.setDisplaySurface(displayToken, surface); 1118 } 1119 } 1120 setDisplaySize(IBinder displayToken, int width, int height)1121 public static void setDisplaySize(IBinder displayToken, int width, int height) { 1122 synchronized (SurfaceControl.class) { 1123 sGlobalTransaction.setDisplaySize(displayToken, width, height); 1124 } 1125 } 1126 getHdrCapabilities(IBinder displayToken)1127 public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) { 1128 if (displayToken == null) { 1129 throw new IllegalArgumentException("displayToken must not be null"); 1130 } 1131 return nativeGetHdrCapabilities(displayToken); 1132 } 1133 createDisplay(String name, boolean secure)1134 public static IBinder createDisplay(String name, boolean secure) { 1135 if (name == null) { 1136 throw new IllegalArgumentException("name must not be null"); 1137 } 1138 return nativeCreateDisplay(name, secure); 1139 } 1140 destroyDisplay(IBinder displayToken)1141 public static void destroyDisplay(IBinder displayToken) { 1142 if (displayToken == null) { 1143 throw new IllegalArgumentException("displayToken must not be null"); 1144 } 1145 nativeDestroyDisplay(displayToken); 1146 } 1147 getBuiltInDisplay(int builtInDisplayId)1148 public static IBinder getBuiltInDisplay(int builtInDisplayId) { 1149 return nativeGetBuiltInDisplay(builtInDisplayId); 1150 } 1151 1152 /** 1153 * Copy the current screen contents into the provided {@link Surface} 1154 * 1155 * @param display The display to take the screenshot of. 1156 * @param consumer The {@link Surface} to take the screenshot into. 1157 * @param width The desired width of the returned bitmap; the raw 1158 * screen will be scaled down to this size. 1159 * @param height The desired height of the returned bitmap; the raw 1160 * screen will be scaled down to this size. 1161 * @param minLayer The lowest (bottom-most Z order) surface layer to 1162 * include in the screenshot. 1163 * @param maxLayer The highest (top-most Z order) surface layer to 1164 * include in the screenshot. 1165 * @param useIdentityTransform Replace whatever transformation (rotation, 1166 * scaling, translation) the surface layers are currently using with the 1167 * identity transformation while taking the screenshot. 1168 */ screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform)1169 public static void screenshot(IBinder display, Surface consumer, 1170 int width, int height, int minLayer, int maxLayer, 1171 boolean useIdentityTransform) { 1172 screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer, 1173 false, useIdentityTransform); 1174 } 1175 1176 /** 1177 * Copy the current screen contents into the provided {@link Surface} 1178 * 1179 * @param display The display to take the screenshot of. 1180 * @param consumer The {@link Surface} to take the screenshot into. 1181 * @param width The desired width of the returned bitmap; the raw 1182 * screen will be scaled down to this size. 1183 * @param height The desired height of the returned bitmap; the raw 1184 * screen will be scaled down to this size. 1185 */ screenshot(IBinder display, Surface consumer, int width, int height)1186 public static void screenshot(IBinder display, Surface consumer, 1187 int width, int height) { 1188 screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false); 1189 } 1190 1191 /** 1192 * Copy the current screen contents into the provided {@link Surface} 1193 * 1194 * @param display The display to take the screenshot of. 1195 * @param consumer The {@link Surface} to take the screenshot into. 1196 */ screenshot(IBinder display, Surface consumer)1197 public static void screenshot(IBinder display, Surface consumer) { 1198 screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false); 1199 } 1200 1201 /** 1202 * Copy the current screen contents into a hardware bitmap and return it. 1203 * Note: If you want to modify the Bitmap in software, you will need to copy the Bitmap into 1204 * a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)} 1205 * 1206 * CAVEAT: Versions of screenshot that return a {@link Bitmap} can 1207 * be extremely slow; avoid use unless absolutely necessary; prefer 1208 * the versions that use a {@link Surface} instead, such as 1209 * {@link SurfaceControl#screenshot(IBinder, Surface)}. 1210 * 1211 * @param sourceCrop The portion of the screen to capture into the Bitmap; 1212 * caller may pass in 'new Rect()' if no cropping is desired. 1213 * @param width The desired width of the returned bitmap; the raw 1214 * screen will be scaled down to this size. 1215 * @param height The desired height of the returned bitmap; the raw 1216 * screen will be scaled down to this size. 1217 * @param minLayer The lowest (bottom-most Z order) surface layer to 1218 * include in the screenshot. 1219 * @param maxLayer The highest (top-most Z order) surface layer to 1220 * include in the screenshot. 1221 * @param useIdentityTransform Replace whatever transformation (rotation, 1222 * scaling, translation) the surface layers are currently using with the 1223 * identity transformation while taking the screenshot. 1224 * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. 1225 * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take 1226 * screenshots in its native portrait orientation by default, so this is 1227 * useful for returning screenshots that are independent of device 1228 * orientation. 1229 * @return Returns a hardware Bitmap containing the screen contents, or null 1230 * if an error occurs. Make sure to call Bitmap.recycle() as soon as 1231 * possible, once its content is not needed anymore. 1232 */ screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)1233 public static Bitmap screenshot(Rect sourceCrop, int width, int height, 1234 int minLayer, int maxLayer, boolean useIdentityTransform, 1235 int rotation) { 1236 // TODO: should take the display as a parameter 1237 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 1238 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 1239 return nativeScreenshot(displayToken, sourceCrop, width, height, 1240 minLayer, maxLayer, false, useIdentityTransform, rotation); 1241 } 1242 1243 /** 1244 * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)} 1245 * but returns a GraphicBuffer. 1246 */ screenshotToBuffer(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)1247 public static GraphicBuffer screenshotToBuffer(Rect sourceCrop, int width, int height, 1248 int minLayer, int maxLayer, boolean useIdentityTransform, 1249 int rotation) { 1250 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 1251 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 1252 return nativeScreenshotToBuffer(displayToken, sourceCrop, width, height, 1253 minLayer, maxLayer, false, useIdentityTransform, rotation, 1254 false /* captureSecureLayers */); 1255 } 1256 1257 /** 1258 * Like screenshotToBuffer, but if the caller is AID_SYSTEM, allows 1259 * for the capture of secure layers. This is used for the screen rotation 1260 * animation where the system server takes screenshots but does 1261 * not persist them or allow them to leave the server. However in other 1262 * cases in the system server, we mostly want to omit secure layers 1263 * like when we take a screenshot on behalf of the assistant. 1264 * 1265 * @hide 1266 */ screenshotToBufferWithSecureLayersUnsafe(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)1267 public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(Rect sourceCrop, 1268 int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, 1269 int rotation) { 1270 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 1271 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 1272 return nativeScreenshotToBuffer(displayToken, sourceCrop, width, height, 1273 minLayer, maxLayer, false, useIdentityTransform, rotation, 1274 true /* captureSecureLayers */); 1275 } 1276 1277 /** 1278 * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)} but 1279 * includes all Surfaces in the screenshot. This will also update the orientation so it 1280 * sends the correct coordinates to SF based on the rotation value. 1281 * 1282 * @param sourceCrop The portion of the screen to capture into the Bitmap; 1283 * caller may pass in 'new Rect()' if no cropping is desired. 1284 * @param width The desired width of the returned bitmap; the raw 1285 * screen will be scaled down to this size. 1286 * @param height The desired height of the returned bitmap; the raw 1287 * screen will be scaled down to this size. 1288 * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. 1289 * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take 1290 * screenshots in its native portrait orientation by default, so this is 1291 * useful for returning screenshots that are independent of device 1292 * orientation. 1293 * @return Returns a Bitmap containing the screen contents, or null 1294 * if an error occurs. Make sure to call Bitmap.recycle() as soon as 1295 * possible, once its content is not needed anymore. 1296 */ screenshot(Rect sourceCrop, int width, int height, int rotation)1297 public static Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) { 1298 // TODO: should take the display as a parameter 1299 IBinder displayToken = SurfaceControl.getBuiltInDisplay( 1300 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); 1301 if (rotation == ROTATION_90 || rotation == ROTATION_270) { 1302 rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90; 1303 } 1304 1305 SurfaceControl.rotateCropForSF(sourceCrop, rotation); 1306 return nativeScreenshot(displayToken, sourceCrop, width, height, 0, 0, true, 1307 false, rotation); 1308 } 1309 screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)1310 private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, 1311 int width, int height, int minLayer, int maxLayer, boolean allLayers, 1312 boolean useIdentityTransform) { 1313 if (display == null) { 1314 throw new IllegalArgumentException("displayToken must not be null"); 1315 } 1316 if (consumer == null) { 1317 throw new IllegalArgumentException("consumer must not be null"); 1318 } 1319 nativeScreenshot(display, consumer, sourceCrop, width, height, 1320 minLayer, maxLayer, allLayers, useIdentityTransform); 1321 } 1322 rotateCropForSF(Rect crop, int rot)1323 private static void rotateCropForSF(Rect crop, int rot) { 1324 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { 1325 int tmp = crop.top; 1326 crop.top = crop.left; 1327 crop.left = tmp; 1328 tmp = crop.right; 1329 crop.right = crop.bottom; 1330 crop.bottom = tmp; 1331 } 1332 } 1333 1334 /** 1335 * Captures a layer and its children and returns a {@link GraphicBuffer} with the content. 1336 * 1337 * @param layerHandleToken The root layer to capture. 1338 * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new 1339 * Rect()' or null if no cropping is desired. 1340 * @param frameScale The desired scale of the returned buffer; the raw 1341 * screen will be scaled up/down. 1342 * 1343 * @return Returns a GraphicBuffer that contains the layer capture. 1344 */ captureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale)1345 public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, 1346 float frameScale) { 1347 return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale); 1348 } 1349 1350 public static class Transaction implements Closeable { 1351 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( 1352 Transaction.class.getClassLoader(), 1353 nativeGetNativeTransactionFinalizer(), 512); 1354 private long mNativeObject; 1355 1356 private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>(); 1357 Runnable mFreeNativeResources; 1358 Transaction()1359 public Transaction() { 1360 mNativeObject = nativeCreateTransaction(); 1361 mFreeNativeResources 1362 = sRegistry.registerNativeAllocation(this, mNativeObject); 1363 } 1364 1365 /** 1366 * Apply the transaction, clearing it's state, and making it usable 1367 * as a new transaction. 1368 */ apply()1369 public void apply() { 1370 apply(false); 1371 } 1372 1373 /** 1374 * Close the transaction, if the transaction was not already applied this will cancel the 1375 * transaction. 1376 */ 1377 @Override close()1378 public void close() { 1379 mFreeNativeResources.run(); 1380 mNativeObject = 0; 1381 } 1382 1383 /** 1384 * Jankier version of apply. Avoid use (b/28068298). 1385 */ apply(boolean sync)1386 public void apply(boolean sync) { 1387 applyResizedSurfaces(); 1388 nativeApplyTransaction(mNativeObject, sync); 1389 } 1390 applyResizedSurfaces()1391 private void applyResizedSurfaces() { 1392 for (int i = mResizedSurfaces.size() - 1; i >= 0; i--) { 1393 final Point size = mResizedSurfaces.valueAt(i); 1394 final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i); 1395 synchronized (surfaceControl.mSizeLock) { 1396 surfaceControl.mWidth = size.x; 1397 surfaceControl.mHeight = size.y; 1398 } 1399 } 1400 mResizedSurfaces.clear(); 1401 } 1402 show(SurfaceControl sc)1403 public Transaction show(SurfaceControl sc) { 1404 sc.checkNotReleased(); 1405 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN); 1406 return this; 1407 } 1408 hide(SurfaceControl sc)1409 public Transaction hide(SurfaceControl sc) { 1410 sc.checkNotReleased(); 1411 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN); 1412 return this; 1413 } 1414 setPosition(SurfaceControl sc, float x, float y)1415 public Transaction setPosition(SurfaceControl sc, float x, float y) { 1416 sc.checkNotReleased(); 1417 nativeSetPosition(mNativeObject, sc.mNativeObject, x, y); 1418 return this; 1419 } 1420 setSize(SurfaceControl sc, int w, int h)1421 public Transaction setSize(SurfaceControl sc, int w, int h) { 1422 sc.checkNotReleased(); 1423 mResizedSurfaces.put(sc, new Point(w, h)); 1424 nativeSetSize(mNativeObject, sc.mNativeObject, w, h); 1425 return this; 1426 } 1427 setLayer(SurfaceControl sc, int z)1428 public Transaction setLayer(SurfaceControl sc, int z) { 1429 sc.checkNotReleased(); 1430 nativeSetLayer(mNativeObject, sc.mNativeObject, z); 1431 return this; 1432 } 1433 setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z)1434 public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) { 1435 sc.checkNotReleased(); 1436 nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, 1437 relativeTo.getHandle(), z); 1438 return this; 1439 } 1440 setTransparentRegionHint(SurfaceControl sc, Region transparentRegion)1441 public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) { 1442 sc.checkNotReleased(); 1443 nativeSetTransparentRegionHint(mNativeObject, 1444 sc.mNativeObject, transparentRegion); 1445 return this; 1446 } 1447 setAlpha(SurfaceControl sc, float alpha)1448 public Transaction setAlpha(SurfaceControl sc, float alpha) { 1449 sc.checkNotReleased(); 1450 nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha); 1451 return this; 1452 } 1453 setMatrix(SurfaceControl sc, float dsdx, float dtdx, float dtdy, float dsdy)1454 public Transaction setMatrix(SurfaceControl sc, 1455 float dsdx, float dtdx, float dtdy, float dsdy) { 1456 sc.checkNotReleased(); 1457 nativeSetMatrix(mNativeObject, sc.mNativeObject, 1458 dsdx, dtdx, dtdy, dsdy); 1459 return this; 1460 } 1461 setMatrix(SurfaceControl sc, Matrix matrix, float[] float9)1462 public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) { 1463 matrix.getValues(float9); 1464 setMatrix(sc, float9[MSCALE_X], float9[MSKEW_Y], 1465 float9[MSKEW_X], float9[MSCALE_Y]); 1466 setPosition(sc, float9[MTRANS_X], float9[MTRANS_Y]); 1467 return this; 1468 } 1469 setWindowCrop(SurfaceControl sc, Rect crop)1470 public Transaction setWindowCrop(SurfaceControl sc, Rect crop) { 1471 sc.checkNotReleased(); 1472 if (crop != null) { 1473 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 1474 crop.left, crop.top, crop.right, crop.bottom); 1475 } else { 1476 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0); 1477 } 1478 1479 return this; 1480 } 1481 setFinalCrop(SurfaceControl sc, Rect crop)1482 public Transaction setFinalCrop(SurfaceControl sc, Rect crop) { 1483 sc.checkNotReleased(); 1484 if (crop != null) { 1485 nativeSetFinalCrop(mNativeObject, sc.mNativeObject, 1486 crop.left, crop.top, crop.right, crop.bottom); 1487 } else { 1488 nativeSetFinalCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0); 1489 } 1490 1491 return this; 1492 } 1493 setLayerStack(SurfaceControl sc, int layerStack)1494 public Transaction setLayerStack(SurfaceControl sc, int layerStack) { 1495 sc.checkNotReleased(); 1496 nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack); 1497 return this; 1498 } 1499 deferTransactionUntil(SurfaceControl sc, IBinder handle, long frameNumber)1500 public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle, 1501 long frameNumber) { 1502 if (frameNumber < 0) { 1503 return this; 1504 } 1505 sc.checkNotReleased(); 1506 nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, handle, frameNumber); 1507 return this; 1508 } 1509 deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface, long frameNumber)1510 public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface, 1511 long frameNumber) { 1512 if (frameNumber < 0) { 1513 return this; 1514 } 1515 sc.checkNotReleased(); 1516 nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject, 1517 barrierSurface.mNativeObject, frameNumber); 1518 return this; 1519 } 1520 reparentChildren(SurfaceControl sc, IBinder newParentHandle)1521 public Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) { 1522 sc.checkNotReleased(); 1523 nativeReparentChildren(mNativeObject, sc.mNativeObject, newParentHandle); 1524 return this; 1525 } 1526 1527 /** Re-parents a specific child layer to a new parent */ reparent(SurfaceControl sc, IBinder newParentHandle)1528 public Transaction reparent(SurfaceControl sc, IBinder newParentHandle) { 1529 sc.checkNotReleased(); 1530 nativeReparent(mNativeObject, sc.mNativeObject, 1531 newParentHandle); 1532 return this; 1533 } 1534 detachChildren(SurfaceControl sc)1535 public Transaction detachChildren(SurfaceControl sc) { 1536 sc.checkNotReleased(); 1537 nativeSeverChildren(mNativeObject, sc.mNativeObject); 1538 return this; 1539 } 1540 setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode)1541 public Transaction setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode) { 1542 sc.checkNotReleased(); 1543 nativeSetOverrideScalingMode(mNativeObject, sc.mNativeObject, 1544 overrideScalingMode); 1545 return this; 1546 } 1547 1548 /** 1549 * Sets a color for the Surface. 1550 * @param color A float array with three values to represent r, g, b in range [0..1] 1551 */ setColor(SurfaceControl sc, @Size(3) float[] color)1552 public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) { 1553 sc.checkNotReleased(); 1554 nativeSetColor(mNativeObject, sc.mNativeObject, color); 1555 return this; 1556 } 1557 1558 /** 1559 * If the buffer size changes in this transaction, position and crop updates specified 1560 * in this transaction will not complete until a buffer of the new size 1561 * arrives. As transform matrix and size are already frozen in this fashion, 1562 * this enables totally freezing the surface until the resize has completed 1563 * (at which point the geometry influencing aspects of this transaction will then occur) 1564 */ setGeometryAppliesWithResize(SurfaceControl sc)1565 public Transaction setGeometryAppliesWithResize(SurfaceControl sc) { 1566 sc.checkNotReleased(); 1567 nativeSetGeometryAppliesWithResize(mNativeObject, sc.mNativeObject); 1568 return this; 1569 } 1570 1571 /** 1572 * Sets the security of the surface. Setting the flag is equivalent to creating the 1573 * Surface with the {@link #SECURE} flag. 1574 */ setSecure(SurfaceControl sc, boolean isSecure)1575 public Transaction setSecure(SurfaceControl sc, boolean isSecure) { 1576 sc.checkNotReleased(); 1577 if (isSecure) { 1578 nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE); 1579 } else { 1580 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE); 1581 } 1582 return this; 1583 } 1584 1585 /** 1586 * Sets the opacity of the surface. Setting the flag is equivalent to creating the 1587 * Surface with the {@link #OPAQUE} flag. 1588 */ setOpaque(SurfaceControl sc, boolean isOpaque)1589 public Transaction setOpaque(SurfaceControl sc, boolean isOpaque) { 1590 sc.checkNotReleased(); 1591 if (isOpaque) { 1592 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE); 1593 } else { 1594 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_OPAQUE); 1595 } 1596 return this; 1597 } 1598 1599 /** 1600 * Same as {@link #destroy()} except this is invoked in a transaction instead of 1601 * immediately. 1602 */ destroy(SurfaceControl sc)1603 public Transaction destroy(SurfaceControl sc) { 1604 sc.checkNotReleased(); 1605 1606 /** 1607 * Perhaps it's safer to transfer the close guard to the Transaction 1608 * but then we have a whole wonky scenario regarding merging, multiple 1609 * close-guards per transaction etc...the whole scenario is kind of wonky 1610 * and it seems really we'd like to just be able to call release here 1611 * but the WindowManager has some code that looks like 1612 * --- destroyInTransaction(a) 1613 * --- reparentChildrenInTransaction(a) 1614 * so we need to ensure the SC remains valid until the transaction 1615 * is applied. 1616 */ 1617 sc.mCloseGuard.close(); 1618 1619 nativeDestroy(mNativeObject, sc.mNativeObject); 1620 return this; 1621 } 1622 setDisplaySurface(IBinder displayToken, Surface surface)1623 public Transaction setDisplaySurface(IBinder displayToken, Surface surface) { 1624 if (displayToken == null) { 1625 throw new IllegalArgumentException("displayToken must not be null"); 1626 } 1627 1628 if (surface != null) { 1629 synchronized (surface.mLock) { 1630 nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject); 1631 } 1632 } else { 1633 nativeSetDisplaySurface(mNativeObject, displayToken, 0); 1634 } 1635 return this; 1636 } 1637 setDisplayLayerStack(IBinder displayToken, int layerStack)1638 public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) { 1639 if (displayToken == null) { 1640 throw new IllegalArgumentException("displayToken must not be null"); 1641 } 1642 nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack); 1643 return this; 1644 } 1645 setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)1646 public Transaction setDisplayProjection(IBinder displayToken, 1647 int orientation, Rect layerStackRect, Rect displayRect) { 1648 if (displayToken == null) { 1649 throw new IllegalArgumentException("displayToken must not be null"); 1650 } 1651 if (layerStackRect == null) { 1652 throw new IllegalArgumentException("layerStackRect must not be null"); 1653 } 1654 if (displayRect == null) { 1655 throw new IllegalArgumentException("displayRect must not be null"); 1656 } 1657 nativeSetDisplayProjection(mNativeObject, displayToken, orientation, 1658 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, 1659 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom); 1660 return this; 1661 } 1662 setDisplaySize(IBinder displayToken, int width, int height)1663 public Transaction setDisplaySize(IBinder displayToken, int width, int height) { 1664 if (displayToken == null) { 1665 throw new IllegalArgumentException("displayToken must not be null"); 1666 } 1667 if (width <= 0 || height <= 0) { 1668 throw new IllegalArgumentException("width and height must be positive"); 1669 } 1670 1671 nativeSetDisplaySize(mNativeObject, displayToken, width, height); 1672 return this; 1673 } 1674 1675 /** flag the transaction as an animation */ setAnimationTransaction()1676 public Transaction setAnimationTransaction() { 1677 nativeSetAnimationTransaction(mNativeObject); 1678 return this; 1679 } 1680 1681 /** 1682 * Indicate that SurfaceFlinger should wake up earlier than usual as a result of this 1683 * transaction. This should be used when the caller thinks that the scene is complex enough 1684 * that it's likely to hit GL composition, and thus, SurfaceFlinger needs to more time in 1685 * order not to miss frame deadlines. 1686 * <p> 1687 * Corresponds to setting ISurfaceComposer::eEarlyWakeup 1688 */ setEarlyWakeup()1689 public Transaction setEarlyWakeup() { 1690 nativeSetEarlyWakeup(mNativeObject); 1691 return this; 1692 } 1693 1694 /** 1695 * Merge the other transaction into this transaction, clearing the 1696 * other transaction as if it had been applied. 1697 */ merge(Transaction other)1698 public Transaction merge(Transaction other) { 1699 mResizedSurfaces.putAll(other.mResizedSurfaces); 1700 other.mResizedSurfaces.clear(); 1701 nativeMergeTransaction(mNativeObject, other.mNativeObject); 1702 return this; 1703 } 1704 } 1705 } 1706