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