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