blob: c0c29eba41d1ff2078d461ae1170be7b9ccb72f3 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
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.FloatRange;
31import android.annotation.IntRange;
32import android.annotation.NonNull;
33import android.annotation.Nullable;
34import android.annotation.Size;
35import android.annotation.TestApi;
36import android.compat.annotation.UnsupportedAppUsage;
37import android.graphics.Bitmap;
38import android.graphics.ColorSpace;
39import android.graphics.GraphicBuffer;
40import android.graphics.Matrix;
41import android.graphics.PixelFormat;
42import android.graphics.Point;
43import android.graphics.Rect;
44import android.graphics.Region;
45import android.hardware.display.DeviceProductInfo;
46import android.hardware.display.DisplayedContentSample;
47import android.hardware.display.DisplayedContentSamplingAttributes;
48import android.os.Build;
49import android.os.IBinder;
50import android.os.Parcel;
51import android.os.Parcelable;
52import android.util.ArrayMap;
53import android.util.Log;
54import android.util.SparseIntArray;
55import android.util.proto.ProtoOutputStream;
56import android.view.Surface.OutOfResourcesException;
57
58import com.android.internal.annotations.GuardedBy;
59
60import dalvik.system.CloseGuard;
61
62import libcore.util.NativeAllocationRegistry;
63
64import java.io.Closeable;
65import java.nio.ByteBuffer;
66import java.nio.ByteOrder;
67import java.util.Objects;
68
69/**
70 * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is
71 * a combination of a buffer source, and metadata about how to display the buffers.
72 * By constructing a {@link Surface} from this SurfaceControl you can submit buffers to be
73 * composited. Using {@link SurfaceControl.Transaction} you can manipulate various
74 * properties of how the buffer will be displayed on-screen. SurfaceControl's are
75 * arranged into a scene-graph like hierarchy, and as such any SurfaceControl may have
76 * a parent. Geometric properties like transform, crop, and Z-ordering will be inherited
77 * from the parent, as if the child were content in the parents buffer stream.
78 */
79public final class SurfaceControl implements Parcelable {
80 private static final String TAG = "SurfaceControl";
81
82 private static native long nativeCreate(SurfaceSession session, String name,
83 int w, int h, int format, int flags, long parentObject, Parcel metadata)
84 throws OutOfResourcesException;
85 private static native long nativeReadFromParcel(Parcel in);
86 private static native long nativeCopyFromSurfaceControl(long nativeObject);
87 private static native void nativeWriteToParcel(long nativeObject, Parcel out);
88 private static native void nativeRelease(long nativeObject);
89 private static native void nativeDisconnect(long nativeObject);
90
91 private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
92 Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
93 boolean captureSecureLayers);
94 private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
95 long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects,
96 int format);
97 private static native long nativeMirrorSurface(long mirrorOfObject);
98 private static native long nativeCreateTransaction();
99 private static native long nativeGetNativeTransactionFinalizer();
100 private static native void nativeApplyTransaction(long transactionObj, boolean sync);
101 private static native void nativeMergeTransaction(long transactionObj,
102 long otherTransactionObj);
103 private static native void nativeSetAnimationTransaction(long transactionObj);
104 private static native void nativeSetEarlyWakeup(long transactionObj);
105
106 private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
107 private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
108 long relativeToObject, int zorder);
109 private static native void nativeSetPosition(long transactionObj, long nativeObject,
110 float x, float y);
111 private static native void nativeSetSize(long transactionObj, long nativeObject, int w, int h);
112 private static native void nativeSetTransparentRegionHint(long transactionObj,
113 long nativeObject, Region region);
114 private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha);
115 private static native void nativeSetMatrix(long transactionObj, long nativeObject,
116 float dsdx, float dtdx,
117 float dtdy, float dsdy);
118 private static native void nativeSetColorTransform(long transactionObj, long nativeObject,
119 float[] matrix, float[] translation);
120 private static native void nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject,
121 boolean agnostic);
122 private static native void nativeSetGeometry(long transactionObj, long nativeObject,
123 Rect sourceCrop, Rect dest, long orientation);
124 private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
125 private static native void nativeSetFlags(long transactionObj, long nativeObject,
126 int flags, int mask);
127 private static native void nativeSetFrameRateSelectionPriority(long transactionObj,
128 long nativeObject, int priority);
129 private static native void nativeSetWindowCrop(long transactionObj, long nativeObject,
130 int l, int t, int r, int b);
131 private static native void nativeSetCornerRadius(long transactionObj, long nativeObject,
132 float cornerRadius);
133 private static native void nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject,
134 int blurRadius);
135 private static native void nativeSetLayerStack(long transactionObj, long nativeObject,
136 int layerStack);
137
138 private static native boolean nativeClearContentFrameStats(long nativeObject);
139 private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
140 private static native boolean nativeClearAnimationFrameStats();
141 private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
142
143 private static native long[] nativeGetPhysicalDisplayIds();
144 private static native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId);
145 private static native IBinder nativeCreateDisplay(String name, boolean secure);
146 private static native void nativeDestroyDisplay(IBinder displayToken);
147 private static native void nativeSetDisplaySurface(long transactionObj,
148 IBinder displayToken, long nativeSurfaceObject);
149 private static native void nativeSetDisplayLayerStack(long transactionObj,
150 IBinder displayToken, int layerStack);
151 private static native void nativeSetDisplayProjection(long transactionObj,
152 IBinder displayToken, int orientation,
153 int l, int t, int r, int b,
154 int L, int T, int R, int B);
155 private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken,
156 int width, int height);
157 private static native SurfaceControl.DisplayInfo nativeGetDisplayInfo(IBinder displayToken);
158 private static native SurfaceControl.DisplayConfig[] nativeGetDisplayConfigs(
159 IBinder displayToken);
160 private static native DisplayedContentSamplingAttributes
161 nativeGetDisplayedContentSamplingAttributes(IBinder displayToken);
162 private static native boolean nativeSetDisplayedContentSamplingEnabled(IBinder displayToken,
163 boolean enable, int componentMask, int maxFrames);
164 private static native DisplayedContentSample nativeGetDisplayedContentSample(
165 IBinder displayToken, long numFrames, long timestamp);
166 private static native int nativeGetActiveConfig(IBinder displayToken);
167 private static native boolean nativeSetDesiredDisplayConfigSpecs(IBinder displayToken,
168 SurfaceControl.DesiredDisplayConfigSpecs desiredDisplayConfigSpecs);
169 private static native SurfaceControl.DesiredDisplayConfigSpecs
170 nativeGetDesiredDisplayConfigSpecs(IBinder displayToken);
171 private static native int[] nativeGetDisplayColorModes(IBinder displayToken);
172 private static native SurfaceControl.DisplayPrimaries nativeGetDisplayNativePrimaries(
173 IBinder displayToken);
174 private static native int[] nativeGetCompositionDataspaces();
175 private static native int nativeGetActiveColorMode(IBinder displayToken);
176 private static native boolean nativeSetActiveColorMode(IBinder displayToken,
177 int colorMode);
178 private static native void nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on);
179 private static native void nativeSetGameContentType(IBinder displayToken, boolean on);
180 private static native void nativeSetDisplayPowerMode(
181 IBinder displayToken, int mode);
182 private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject,
183 long barrierObject, long frame);
184 private static native void nativeDeferTransactionUntilSurface(long transactionObj,
185 long nativeObject,
186 long surfaceObject, long frame);
187 private static native void nativeReparentChildren(long transactionObj, long nativeObject,
188 long newParentObject);
189 private static native void nativeReparent(long transactionObj, long nativeObject,
190 long newParentNativeObject);
191 private static native void nativeSeverChildren(long transactionObj, long nativeObject);
192 private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
193 int scalingMode);
194
195 private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
196
197 private static native boolean nativeGetAutoLowLatencyModeSupport(IBinder displayToken);
198 private static native boolean nativeGetGameContentTypeSupport(IBinder displayToken);
199
200 private static native void nativeSetInputWindowInfo(long transactionObj, long nativeObject,
201 InputWindowHandle handle);
202
203 private static native boolean nativeGetProtectedContentSupport();
204 private static native void nativeSetMetadata(long transactionObj, long nativeObject, int key,
205 Parcel data);
206 private static native void nativeSyncInputWindows(long transactionObj);
207 private static native boolean nativeGetDisplayBrightnessSupport(IBinder displayToken);
208 private static native boolean nativeSetDisplayBrightness(IBinder displayToken,
209 float brightness);
210 private static native long nativeReadTransactionFromParcel(Parcel in);
211 private static native void nativeWriteTransactionToParcel(long nativeObject, Parcel out);
212 private static native void nativeSetShadowRadius(long transactionObj, long nativeObject,
213 float shadowRadius);
214 private static native void nativeSetGlobalShadowSettings(@Size(4) float[] ambientColor,
215 @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius);
216
217 private static native void nativeSetFrameRate(
218 long transactionObj, long nativeObject, float frameRate, int compatibility);
219 private static native long nativeGetHandle(long nativeObject);
220
221 private static native long nativeAcquireFrameRateFlexibilityToken();
222 private static native void nativeReleaseFrameRateFlexibilityToken(long token);
223
224 private final CloseGuard mCloseGuard = CloseGuard.get();
225 private String mName;
226 /**
227 * @hide
228 */
229 public long mNativeObject;
230 private long mNativeHandle;
231 private Throwable mReleaseStack = null;
232
233 // TODO: Move this to native.
234 private final Object mSizeLock = new Object();
235 @GuardedBy("mSizeLock")
236 private int mWidth;
237 @GuardedBy("mSizeLock")
238 private int mHeight;
239
240 static Transaction sGlobalTransaction;
241 static long sTransactionNestCount = 0;
242
243 /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
244
245 /**
246 * Surface creation flag: Surface is created hidden
247 * @hide
248 */
249 @UnsupportedAppUsage
250 public static final int HIDDEN = 0x00000004;
251
252 /**
253 * Surface creation flag: The surface contains secure content, special
254 * measures will be taken to disallow the surface's content to be copied
255 * from another process. In particular, screenshots and VNC servers will
256 * be disabled, but other measures can take place, for instance the
257 * surface might not be hardware accelerated.
258 * @hide
259 */
260 public static final int SECURE = 0x00000080;
261
262 /**
263 * Surface creation flag: Creates a surface where color components are interpreted
264 * as "non pre-multiplied" by their alpha channel. Of course this flag is
265 * meaningless for surfaces without an alpha channel. By default
266 * surfaces are pre-multiplied, which means that each color component is
267 * already multiplied by its alpha value. In this case the blending
268 * equation used is:
269 * <p>
270 * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code>
271 * <p>
272 * By contrast, non pre-multiplied surfaces use the following equation:
273 * <p>
274 * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code>
275 * <p>
276 * pre-multiplied surfaces must always be used if transparent pixels are
277 * composited on top of each-other into the surface. A pre-multiplied
278 * surface can never lower the value of the alpha component of a given
279 * pixel.
280 * <p>
281 * In some rare situations, a non pre-multiplied surface is preferable.
282 * @hide
283 */
284 public static final int NON_PREMULTIPLIED = 0x00000100;
285
286 /**
287 * Surface creation flag: Indicates that the surface must be considered opaque,
288 * even if its pixel format contains an alpha channel. This can be useful if an
289 * application needs full RGBA 8888 support for instance but will
290 * still draw every pixel opaque.
291 * <p>
292 * This flag is ignored if setAlpha() is used to make the surface non-opaque.
293 * Combined effects are (assuming a buffer format with an alpha channel):
294 * <ul>
295 * <li>OPAQUE + alpha(1.0) == opaque composition
296 * <li>OPAQUE + alpha(0.x) == blended composition
297 * <li>!OPAQUE + alpha(1.0) == blended composition
298 * <li>!OPAQUE + alpha(0.x) == blended composition
299 * </ul>
300 * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively
301 * set automatically.
302 * @hide
303 */
304 public static final int OPAQUE = 0x00000400;
305
306 /**
307 * Surface creation flag: Application requires a hardware-protected path to an
308 * external display sink. If a hardware-protected path is not available,
309 * then this surface will not be displayed on the external sink.
310 *
311 * @hide
312 */
313 public static final int PROTECTED_APP = 0x00000800;
314
315 // 0x1000 is reserved for an independent DRM protected flag in framework
316
317 /**
318 * Surface creation flag: Window represents a cursor glyph.
319 * @hide
320 */
321 public static final int CURSOR_WINDOW = 0x00002000;
322
323 /**
324 * Surface creation flag: Creates a normal surface.
325 * This is the default.
326 *
327 * @hide
328 */
329 public static final int FX_SURFACE_NORMAL = 0x00000000;
330
331 /**
332 * Surface creation flag: Creates a effect surface which
333 * represents a solid color and or shadows.
334 *
335 * @hide
336 */
337 public static final int FX_SURFACE_EFFECT = 0x00020000;
338
339 /**
340 * Surface creation flag: Creates a container surface.
341 * This surface will have no buffers and will only be used
342 * as a container for other surfaces, or for its InputInfo.
343 * @hide
344 */
345 public static final int FX_SURFACE_CONTAINER = 0x00080000;
346
347 /**
348 * @hide
349 */
350 public static final int FX_SURFACE_BLAST = 0x00040000;
351
352 /**
353 * Mask used for FX values above.
354 *
355 * @hide
356 */
357 public static final int FX_SURFACE_MASK = 0x000F0000;
358
359 /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
360
361 /**
362 * Surface flag: Hide the surface.
363 * Equivalent to calling hide().
364 * Updates the value set during Surface creation (see {@link #HIDDEN}).
365 */
366 private static final int SURFACE_HIDDEN = 0x01;
367
368 /**
369 * Surface flag: composite without blending when possible.
370 * Updates the value set during Surface creation (see {@link #OPAQUE}).
371 */
372 private static final int SURFACE_OPAQUE = 0x02;
373
374 // Display power modes.
375 /**
376 * Display power mode off: used while blanking the screen.
377 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
378 * @hide
379 */
380 public static final int POWER_MODE_OFF = 0;
381
382 /**
383 * Display power mode doze: used while putting the screen into low power mode.
384 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
385 * @hide
386 */
387 public static final int POWER_MODE_DOZE = 1;
388
389 /**
390 * Display power mode normal: used while unblanking the screen.
391 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
392 * @hide
393 */
394 public static final int POWER_MODE_NORMAL = 2;
395
396 /**
397 * Display power mode doze: used while putting the screen into a suspended
398 * low power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}.
399 * @hide
400 */
401 public static final int POWER_MODE_DOZE_SUSPEND = 3;
402
403 /**
404 * Display power mode on: used while putting the screen into a suspended
405 * full power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}.
406 * @hide
407 */
408 public static final int POWER_MODE_ON_SUSPEND = 4;
409
410 /**
411 * A value for windowType used to indicate that the window should be omitted from screenshots
412 * and display mirroring. A temporary workaround until we express such things with
413 * the hierarchy.
414 * TODO: b/64227542
415 * @hide
416 */
417 public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731;
418
419 /**
420 * internal representation of how to interpret pixel value, used only to convert to ColorSpace.
421 */
422 private static final int INTERNAL_DATASPACE_SRGB = 142671872;
423 private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
424 private static final int INTERNAL_DATASPACE_SCRGB = 411107328;
425
426 private void assignNativeObject(long nativeObject) {
427 if (mNativeObject != 0) {
428 release();
429 }
430 if (nativeObject != 0) {
431 mCloseGuard.open("release");
432 }
433 mNativeObject = nativeObject;
434 mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
435 if (mNativeObject == 0) {
436 if (Build.IS_DEBUGGABLE) {
437 mReleaseStack = new Throwable("assigned zero nativeObject here");
438 }
439 } else {
440 mReleaseStack = null;
441 }
442 }
443
444 /**
445 * @hide
446 */
447 public void copyFrom(@NonNull SurfaceControl other) {
448 mName = other.mName;
449 mWidth = other.mWidth;
450 mHeight = other.mHeight;
451 assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject));
452 }
453
454 /**
455 * owner UID.
456 * @hide
457 */
458 public static final int METADATA_OWNER_UID = 1;
459
460 /**
461 * Window type as per {@link WindowManager.LayoutParams}.
462 * @hide
463 */
464 public static final int METADATA_WINDOW_TYPE = 2;
465
466 /**
467 * Task id to allow association between surfaces and task.
468 * @hide
469 */
470 public static final int METADATA_TASK_ID = 3;
471
472 /**
473 * The style of mouse cursor and hotspot.
474 * @hide
475 */
476 public static final int METADATA_MOUSE_CURSOR = 4;
477
478 /**
479 * Accessibility ID to allow association between surfaces and accessibility tree.
480 * @hide
481 */
482 public static final int METADATA_ACCESSIBILITY_ID = 5;
483
484 /**
485 * A wrapper around GraphicBuffer that contains extra information about how to
486 * interpret the screenshot GraphicBuffer.
487 * @hide
488 */
489 public static class ScreenshotGraphicBuffer {
490 private final GraphicBuffer mGraphicBuffer;
491 private final ColorSpace mColorSpace;
492 private final boolean mContainsSecureLayers;
493
494 public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace,
495 boolean containsSecureLayers) {
496 mGraphicBuffer = graphicBuffer;
497 mColorSpace = colorSpace;
498 mContainsSecureLayers = containsSecureLayers;
499 }
500
501 /**
502 * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object.
503 * @param width The width in pixels of the buffer
504 * @param height The height in pixels of the buffer
505 * @param format The format of each pixel as specified in {@link PixelFormat}
506 * @param usage Hint indicating how the buffer will be used
507 * @param unwrappedNativeObject The native object of GraphicBuffer
508 * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
509 * @param containsSecureLayer Indicates whether this graphic buffer contains captured contents
510 * of secure layers, in which case the screenshot should not be persisted.
511 */
512 private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
513 int usage, long unwrappedNativeObject, int namedColorSpace,
514 boolean containsSecureLayers) {
515 GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
516 usage, unwrappedNativeObject);
517 ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
518 return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace, containsSecureLayers);
519 }
520
521 public ColorSpace getColorSpace() {
522 return mColorSpace;
523 }
524
525 public GraphicBuffer getGraphicBuffer() {
526 return mGraphicBuffer;
527 }
528
529 public boolean containsSecureLayers() {
530 return mContainsSecureLayers;
531 }
532 }
533
534 /**
535 * Builder class for {@link SurfaceControl} objects.
536 *
537 * By default the surface will be hidden, and have "unset" bounds, meaning it can
538 * be as large as the bounds of its parent if a buffer or child so requires.
539 *
540 * It is necessary to set at least a name via {@link Builder#setName}
541 */
542 public static class Builder {
543 private SurfaceSession mSession;
544 private int mFlags = HIDDEN;
545 private int mWidth;
546 private int mHeight;
547 private int mFormat = PixelFormat.OPAQUE;
548 private String mName;
549 private SurfaceControl mParent;
550 private SparseIntArray mMetadata;
551
552 /**
553 * Begin building a SurfaceControl with a given {@link SurfaceSession}.
554 *
555 * @param session The {@link SurfaceSession} with which to eventually construct the surface.
556 * @hide
557 */
558 public Builder(SurfaceSession session) {
559 mSession = session;
560 }
561
562 /**
563 * Begin building a SurfaceControl.
564 */
565 public Builder() {
566 }
567
568 /**
569 * Construct a new {@link SurfaceControl} with the set parameters. The builder
570 * remains valid.
571 */
572 @NonNull
573 public SurfaceControl build() {
574 if (mWidth < 0 || mHeight < 0) {
575 throw new IllegalStateException(
576 "width and height must be positive or unset");
577 }
578 if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) {
579 throw new IllegalStateException(
580 "Only buffer layers can set a valid buffer size.");
581 }
582 return new SurfaceControl(
583 mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata);
584 }
585
586 /**
587 * Set a debugging-name for the SurfaceControl.
588 *
589 * @param name A name to identify the Surface in debugging.
590 */
591 @NonNull
592 public Builder setName(@NonNull String name) {
593 mName = name;
594 return this;
595 }
596
597 /**
598 * Set the initial size of the controlled surface's buffers in pixels.
599 *
600 * @param width The buffer width in pixels.
601 * @param height The buffer height in pixels.
602 */
603 @NonNull
604 public Builder setBufferSize(@IntRange(from = 0) int width,
605 @IntRange(from = 0) int height) {
606 if (width < 0 || height < 0) {
607 throw new IllegalArgumentException(
608 "width and height must be positive");
609 }
610 mWidth = width;
611 mHeight = height;
612 // set this as a buffer layer since we are specifying a buffer size.
613 return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK);
614 }
615
616 /**
617 * Set the initial size of the controlled surface's buffers in pixels.
618 */
619 private void unsetBufferSize() {
620 mWidth = 0;
621 mHeight = 0;
622 }
623
624 /**
625 * Set the pixel format of the controlled surface's buffers, using constants from
626 * {@link android.graphics.PixelFormat}.
627 */
628 @NonNull
629 public Builder setFormat(@PixelFormat.Format int format) {
630 mFormat = format;
631 return this;
632 }
633
634 /**
635 * Specify if the app requires a hardware-protected path to
636 * an external display sync. If protected content is enabled, but
637 * such a path is not available, then the controlled Surface will
638 * not be displayed.
639 *
640 * @param protectedContent Whether to require a protected sink.
641 * @hide
642 */
643 @NonNull
644 public Builder setProtected(boolean protectedContent) {
645 if (protectedContent) {
646 mFlags |= PROTECTED_APP;
647 } else {
648 mFlags &= ~PROTECTED_APP;
649 }
650 return this;
651 }
652
653 /**
654 * Specify whether the Surface contains secure content. If true, the system
655 * will prevent the surfaces content from being copied by another process. In
656 * particular screenshots and VNC servers will be disabled. This is however
657 * not a complete prevention of readback as {@link #setProtected}.
658 * @hide
659 */
660 @NonNull
661 public Builder setSecure(boolean secure) {
662 if (secure) {
663 mFlags |= SECURE;
664 } else {
665 mFlags &= ~SECURE;
666 }
667 return this;
668 }
669
670 /**
671 * Indicates whether the surface must be considered opaque,
672 * even if its pixel format is set to translucent. This can be useful if an
673 * application needs full RGBA 8888 support for instance but will
674 * still draw every pixel opaque.
675 * <p>
676 * This flag only determines whether opacity will be sampled from the alpha channel.
677 * Plane-alpha from calls to setAlpha() can still result in blended composition
678 * regardless of the opaque setting.
679 *
680 * Combined effects are (assuming a buffer format with an alpha channel):
681 * <ul>
682 * <li>OPAQUE + alpha(1.0) == opaque composition
683 * <li>OPAQUE + alpha(0.x) == blended composition
684 * <li>OPAQUE + alpha(0.0) == no composition
685 * <li>!OPAQUE + alpha(1.0) == blended composition
686 * <li>!OPAQUE + alpha(0.x) == blended composition
687 * <li>!OPAQUE + alpha(0.0) == no composition
688 * </ul>
689 * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true)
690 * were set automatically.
691 * @param opaque Whether the Surface is OPAQUE.
692 */
693 @NonNull
694 public Builder setOpaque(boolean opaque) {
695 if (opaque) {
696 mFlags |= OPAQUE;
697 } else {
698 mFlags &= ~OPAQUE;
699 }
700 return this;
701 }
702
703 /**
704 * Set the initial visibility for the SurfaceControl.
705 *
706 * @param hidden Whether the Surface is initially HIDDEN.
707 * @hide
708 */
709 @NonNull
710 public Builder setHidden(boolean hidden) {
711 if (hidden) {
712 mFlags |= HIDDEN;
713 } else {
714 mFlags &= ~HIDDEN;
715 }
716 return this;
717 }
718
719 /**
720 * Set a parent surface for our new SurfaceControl.
721 *
722 * Child surfaces are constrained to the onscreen region of their parent.
723 * Furthermore they stack relatively in Z order, and inherit the transformation
724 * of the parent.
725 *
726 * @param parent The parent control.
727 */
728 @NonNull
729 public Builder setParent(@Nullable SurfaceControl parent) {
730 mParent = parent;
731 return this;
732 }
733
734 /**
735 * Sets a metadata int.
736 *
737 * @param key metadata key
738 * @param data associated data
739 * @hide
740 */
741 public Builder setMetadata(int key, int data) {
742 if (mMetadata == null) {
743 mMetadata = new SparseIntArray();
744 }
745 mMetadata.put(key, data);
746 return this;
747 }
748
749 /**
750 * Indicate whether a 'ColorLayer' is to be constructed.
751 *
752 * Color layers will not have an associated BufferQueue and will instead always render a
753 * solid color (that is, solid before plane alpha). Currently that color is black.
754 *
755 * @hide
756 */
757 public Builder setColorLayer() {
758 unsetBufferSize();
759 return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK);
760 }
761
762 private boolean isColorLayerSet() {
763 return (mFlags & FX_SURFACE_EFFECT) == FX_SURFACE_EFFECT;
764 }
765
766 /**
767 * @hide
768 */
769 public Builder setBLASTLayer() {
770 unsetBufferSize();
771 return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK);
772 }
773
774 /**
775 * Indicates whether a 'ContainerLayer' is to be constructed.
776 *
777 * Container layers will not be rendered in any fashion and instead are used
778 * as a parent of renderable layers.
779 *
780 * @hide
781 */
782 public Builder setContainerLayer() {
783 unsetBufferSize();
784 return setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK);
785 }
786
787 private boolean isContainerLayerSet() {
788 return (mFlags & FX_SURFACE_CONTAINER) == FX_SURFACE_CONTAINER;
789 }
790
791 /**
792 * Set 'Surface creation flags' such as {@link #HIDDEN}, {@link #SECURE}.
793 *
794 * TODO: Finish conversion to individual builder methods?
795 * @param flags The combined flags
796 * @hide
797 */
798 public Builder setFlags(int flags) {
799 mFlags = flags;
800 return this;
801 }
802
803 private Builder setFlags(int flags, int mask) {
804 mFlags = (mFlags & ~mask) | flags;
805 return this;
806 }
807 }
808
809 /**
810 * Create a surface with a name.
811 * <p>
812 * The surface creation flags specify what kind of surface to create and
813 * certain options such as whether the surface can be assumed to be opaque
814 * and whether it should be initially hidden. Surfaces should always be
815 * created with the {@link #HIDDEN} flag set to ensure that they are not
816 * made visible prematurely before all of the surface's properties have been
817 * configured.
818 * <p>
819 * Good practice is to first create the surface with the {@link #HIDDEN} flag
820 * specified, open a transaction, set the surface layer, layer stack, alpha,
821 * and position, call {@link Transaction#show(SurfaceControl)} if appropriate, and close the
822 * transaction.
823 * <p>
824 * Bounds of the surface is determined by its crop and its buffer size. If the
825 * surface has no buffer or crop, the surface is boundless and only constrained
826 * by the size of its parent bounds.
827 *
828 * @param session The surface session, must not be null.
829 * @param name The surface name, must not be null.
830 * @param w The surface initial width.
831 * @param h The surface initial height.
832 * @param flags The surface creation flags.
833 * @param metadata Initial metadata.
834 * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
835 */
836 private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
837 SurfaceControl parent, SparseIntArray metadata)
838 throws OutOfResourcesException, IllegalArgumentException {
839 if (name == null) {
840 throw new IllegalArgumentException("name must not be null");
841 }
842
843 mName = name;
844 mWidth = w;
845 mHeight = h;
846 Parcel metaParcel = Parcel.obtain();
847 try {
848 if (metadata != null && metadata.size() > 0) {
849 metaParcel.writeInt(metadata.size());
850 for (int i = 0; i < metadata.size(); ++i) {
851 metaParcel.writeInt(metadata.keyAt(i));
852 metaParcel.writeByteArray(
853 ByteBuffer.allocate(4).order(ByteOrder.nativeOrder())
854 .putInt(metadata.valueAt(i)).array());
855 }
856 metaParcel.setDataPosition(0);
857 }
858 mNativeObject = nativeCreate(session, name, w, h, format, flags,
859 parent != null ? parent.mNativeObject : 0, metaParcel);
860 } finally {
861 metaParcel.recycle();
862 }
863 if (mNativeObject == 0) {
864 throw new OutOfResourcesException(
865 "Couldn't allocate SurfaceControl native object");
866 }
867 mNativeHandle = nativeGetHandle(mNativeObject);
868 mCloseGuard.open("release");
869 }
870
871 /**
872 * Copy constructor. Creates a new native object pointing to the same surface as {@code other}.
873 *
874 * @param other The object to copy the surface from.
875 * @hide
876 */
877 @TestApi
878 public SurfaceControl(@NonNull SurfaceControl other) {
879 copyFrom(other);
880 }
881
882 private SurfaceControl(Parcel in) {
883 readFromParcel(in);
884 }
885
886 /**
887 * @hide
888 */
889 public SurfaceControl() {
890 }
891
892 public void readFromParcel(Parcel in) {
893 if (in == null) {
894 throw new IllegalArgumentException("source must not be null");
895 }
896
897 mName = in.readString8();
898 mWidth = in.readInt();
899 mHeight = in.readInt();
900
901 long object = 0;
902 if (in.readInt() != 0) {
903 object = nativeReadFromParcel(in);
904 }
905 assignNativeObject(object);
906 }
907
908 @Override
909 public int describeContents() {
910 return 0;
911 }
912
913 @Override
914 public void writeToParcel(Parcel dest, int flags) {
915 dest.writeString8(mName);
916 dest.writeInt(mWidth);
917 dest.writeInt(mHeight);
918 if (mNativeObject == 0) {
919 dest.writeInt(0);
920 } else {
921 dest.writeInt(1);
922 }
923 nativeWriteToParcel(mNativeObject, dest);
924
925 if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
926 release();
927 }
928 }
929
930 /**
931 * Checks whether two {@link SurfaceControl} objects represent the same surface.
932 *
933 * @param other The other object to check
934 * @return {@code true} if these two {@link SurfaceControl} objects represent the same surface.
935 * @hide
936 */
937 @TestApi
938 public boolean isSameSurface(@NonNull SurfaceControl other) {
939 return other.mNativeHandle == mNativeHandle;
940 }
941
942 /**
943 * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
944 * android.view.SurfaceControlProto}.
945 *
946 * @param proto Stream to write the SurfaceControl object to.
947 * @param fieldId Field Id of the SurfaceControl as defined in the parent message.
948 * @hide
949 */
950 public void dumpDebug(ProtoOutputStream proto, long fieldId) {
951 final long token = proto.start(fieldId);
952 proto.write(HASH_CODE, System.identityHashCode(this));
953 proto.write(NAME, mName);
954 proto.end(token);
955 }
956
957 public static final @android.annotation.NonNull Creator<SurfaceControl> CREATOR
958 = new Creator<SurfaceControl>() {
959 public SurfaceControl createFromParcel(Parcel in) {
960 return new SurfaceControl(in);
961 }
962
963 public SurfaceControl[] newArray(int size) {
964 return new SurfaceControl[size];
965 }
966 };
967
968 /**
969 * @hide
970 */
971 @Override
972 protected void finalize() throws Throwable {
973 try {
974 if (mCloseGuard != null) {
975 mCloseGuard.warnIfOpen();
976 }
977 if (mNativeObject != 0) {
978 nativeRelease(mNativeObject);
979 }
980 } finally {
981 super.finalize();
982 }
983 }
984
985 /**
986 * Release the local reference to the server-side surface. The surface
987 * may continue to exist on-screen as long as its parent continues
988 * to exist. To explicitly remove a surface from the screen use
989 * {@link Transaction#reparent} with a null-parent. After release,
990 * {@link #isValid} will return false and other methods will throw
991 * an exception.
992 *
993 * Always call release() when you're done with a SurfaceControl.
994 */
995 public void release() {
996 if (mNativeObject != 0) {
997 nativeRelease(mNativeObject);
998 mNativeObject = 0;
999 mNativeHandle = 0;
1000 if (Build.IS_DEBUGGABLE) {
1001 mReleaseStack = new Throwable("released here");
1002 }
1003 mCloseGuard.close();
1004 }
1005 }
1006
1007 /**
1008 * Returns the call stack that assigned mNativeObject to zero.
1009 * @hide
1010 */
1011 public Throwable getReleaseStack() {
1012 return mReleaseStack;
1013 }
1014
1015 /**
1016 * Disconnect any client still connected to the surface.
1017 * @hide
1018 */
1019 public void disconnect() {
1020 if (mNativeObject != 0) {
1021 nativeDisconnect(mNativeObject);
1022 }
1023 }
1024
1025 private void checkNotReleased() {
1026 if (mNativeObject == 0) {
1027 Log.wtf(TAG, "Invalid " + this + " caused by:", mReleaseStack);
1028 throw new NullPointerException(
1029 "mNativeObject of " + this + " is null. Have you called release() already?");
1030 }
1031 }
1032
1033 /**
1034 * Check whether this instance points to a valid layer with the system-compositor. For
1035 * example this may be false if construction failed, or the layer was released
1036 * ({@link #release}).
1037 *
1038 * @return Whether this SurfaceControl is valid.
1039 */
1040 public boolean isValid() {
1041 return mNativeObject != 0;
1042 }
1043
1044 /*
1045 * set surface parameters.
1046 * needs to be inside open/closeTransaction block
1047 */
1048
1049 /** start a transaction
1050 * @hide
1051 */
1052 @UnsupportedAppUsage
1053 public static void openTransaction() {
1054 synchronized (SurfaceControl.class) {
1055 if (sGlobalTransaction == null) {
1056 sGlobalTransaction = new Transaction();
1057 }
1058 synchronized(SurfaceControl.class) {
1059 sTransactionNestCount++;
1060 }
1061 }
1062 }
1063
1064 /**
1065 * Merge the supplied transaction in to the deprecated "global" transaction.
1066 * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}.
1067 * <p>
1068 * This is a utility for interop with legacy-code and will go away with the Global Transaction.
1069 * @hide
1070 */
1071 @Deprecated
1072 public static void mergeToGlobalTransaction(Transaction t) {
1073 synchronized(SurfaceControl.class) {
1074 sGlobalTransaction.merge(t);
1075 }
1076 }
1077
1078 /** end a transaction
1079 * @hide
1080 */
1081 @UnsupportedAppUsage
1082 public static void closeTransaction() {
1083 synchronized(SurfaceControl.class) {
1084 if (sTransactionNestCount == 0) {
1085 Log.e(TAG,
1086 "Call to SurfaceControl.closeTransaction without matching openTransaction");
1087 } else if (--sTransactionNestCount > 0) {
1088 return;
1089 }
1090 sGlobalTransaction.apply();
1091 }
1092 }
1093
1094 /**
1095 * @hide
1096 */
1097 public void deferTransactionUntil(SurfaceControl barrier, long frame) {
1098 synchronized(SurfaceControl.class) {
1099 sGlobalTransaction.deferTransactionUntil(this, barrier, frame);
1100 }
1101 }
1102
1103 /**
1104 * @hide
1105 */
1106 public void reparentChildren(SurfaceControl newParent) {
1107 synchronized(SurfaceControl.class) {
1108 sGlobalTransaction.reparentChildren(this, newParent);
1109 }
1110 }
1111
1112 /**
1113 * @hide
1114 */
1115 public void detachChildren() {
1116 synchronized(SurfaceControl.class) {
1117 sGlobalTransaction.detachChildren(this);
1118 }
1119 }
1120
1121 /**
1122 * @hide
1123 */
1124 public void setOverrideScalingMode(int scalingMode) {
1125 checkNotReleased();
1126 synchronized(SurfaceControl.class) {
1127 sGlobalTransaction.setOverrideScalingMode(this, scalingMode);
1128 }
1129 }
1130
1131 /**
1132 * @hide
1133 */
1134 @UnsupportedAppUsage
1135 public void setLayer(int zorder) {
1136 checkNotReleased();
1137 synchronized(SurfaceControl.class) {
1138 sGlobalTransaction.setLayer(this, zorder);
1139 }
1140 }
1141
1142 /**
1143 * @hide
1144 */
1145 @UnsupportedAppUsage
1146 public void setPosition(float x, float y) {
1147 checkNotReleased();
1148 synchronized(SurfaceControl.class) {
1149 sGlobalTransaction.setPosition(this, x, y);
1150 }
1151 }
1152
1153 /**
1154 * @hide
1155 */
1156 public void setBufferSize(int w, int h) {
1157 checkNotReleased();
1158 synchronized(SurfaceControl.class) {
1159 sGlobalTransaction.setBufferSize(this, w, h);
1160 }
1161 }
1162
1163 /**
1164 * @hide
1165 */
1166 @UnsupportedAppUsage
1167 public void hide() {
1168 checkNotReleased();
1169 synchronized(SurfaceControl.class) {
1170 sGlobalTransaction.hide(this);
1171 }
1172 }
1173
1174 /**
1175 * @hide
1176 */
1177 @UnsupportedAppUsage
1178 public void show() {
1179 checkNotReleased();
1180 synchronized(SurfaceControl.class) {
1181 sGlobalTransaction.show(this);
1182 }
1183 }
1184
1185 /**
1186 * @hide
1187 */
1188 public void setTransparentRegionHint(Region region) {
1189 checkNotReleased();
1190 synchronized(SurfaceControl.class) {
1191 sGlobalTransaction.setTransparentRegionHint(this, region);
1192 }
1193 }
1194
1195 /**
1196 * @hide
1197 */
1198 public boolean clearContentFrameStats() {
1199 checkNotReleased();
1200 return nativeClearContentFrameStats(mNativeObject);
1201 }
1202
1203 /**
1204 * @hide
1205 */
1206 public boolean getContentFrameStats(WindowContentFrameStats outStats) {
1207 checkNotReleased();
1208 return nativeGetContentFrameStats(mNativeObject, outStats);
1209 }
1210
1211 /**
1212 * @hide
1213 */
1214 public static boolean clearAnimationFrameStats() {
1215 return nativeClearAnimationFrameStats();
1216 }
1217
1218 /**
1219 * @hide
1220 */
1221 public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) {
1222 return nativeGetAnimationFrameStats(outStats);
1223 }
1224
1225 /**
1226 * @hide
1227 */
1228 public void setAlpha(float alpha) {
1229 checkNotReleased();
1230 synchronized(SurfaceControl.class) {
1231 sGlobalTransaction.setAlpha(this, alpha);
1232 }
1233 }
1234
1235 /**
1236 * @hide
1237 */
1238 public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
1239 checkNotReleased();
1240 synchronized(SurfaceControl.class) {
1241 sGlobalTransaction.setMatrix(this, dsdx, dtdx, dtdy, dsdy);
1242 }
1243 }
1244
1245 /**
1246 * Sets the Surface to be color space agnostic. If a surface is color space agnostic,
1247 * the color can be interpreted in any color space.
1248 * @param agnostic A boolean to indicate whether the surface is color space agnostic
1249 * @hide
1250 */
1251 public void setColorSpaceAgnostic(boolean agnostic) {
1252 checkNotReleased();
1253 synchronized (SurfaceControl.class) {
1254 sGlobalTransaction.setColorSpaceAgnostic(this, agnostic);
1255 }
1256 }
1257
1258 /**
1259 * Bounds the surface and its children to the bounds specified. Size of the surface will be
1260 * ignored and only the crop and buffer size will be used to determine the bounds of the
1261 * surface. If no crop is specified and the surface has no buffer, the surface bounds is only
1262 * constrained by the size of its parent bounds.
1263 *
1264 * @param crop Bounds of the crop to apply.
1265 * @hide
1266 */
1267 public void setWindowCrop(Rect crop) {
1268 checkNotReleased();
1269 synchronized (SurfaceControl.class) {
1270 sGlobalTransaction.setWindowCrop(this, crop);
1271 }
1272 }
1273
1274 /**
1275 * @hide
1276 */
1277 public void setOpaque(boolean isOpaque) {
1278 checkNotReleased();
1279
1280 synchronized (SurfaceControl.class) {
1281 sGlobalTransaction.setOpaque(this, isOpaque);
1282 }
1283 }
1284
1285 /**
1286 * @hide
1287 */
1288 public void setSecure(boolean isSecure) {
1289 checkNotReleased();
1290
1291 synchronized (SurfaceControl.class) {
1292 sGlobalTransaction.setSecure(this, isSecure);
1293 }
1294 }
1295
1296 /**
1297 * @hide
1298 */
1299 public int getWidth() {
1300 synchronized (mSizeLock) {
1301 return mWidth;
1302 }
1303 }
1304
1305 /**
1306 * @hide
1307 */
1308 public int getHeight() {
1309 synchronized (mSizeLock) {
1310 return mHeight;
1311 }
1312 }
1313
1314 @Override
1315 public String toString() {
1316 return "Surface(name=" + mName + ")/@0x" +
1317 Integer.toHexString(System.identityHashCode(this));
1318 }
1319
1320 /**
1321 * Immutable information about physical display.
1322 *
1323 * @hide
1324 */
1325 public static final class DisplayInfo {
1326 public boolean isInternal;
1327 public float density;
1328 public boolean secure;
1329 public DeviceProductInfo deviceProductInfo;
1330
1331 @Override
1332 public String toString() {
1333 return "DisplayInfo{isInternal=" + isInternal
1334 + ", density=" + density
1335 + ", secure=" + secure
1336 + ", deviceProductInfo=" + deviceProductInfo + "}";
1337 }
1338 }
1339
1340 /**
1341 * Configuration supported by physical display.
1342 *
1343 * @hide
1344 */
1345 public static final class DisplayConfig {
1346 /**
1347 * Invalid display config id.
1348 */
1349 public static final int INVALID_DISPLAY_CONFIG_ID = -1;
1350
1351 public int width;
1352 public int height;
1353 public float xDpi;
1354 public float yDpi;
1355
1356 public float refreshRate;
1357 public long appVsyncOffsetNanos;
1358 public long presentationDeadlineNanos;
1359
1360 /**
1361 * The config group ID this config is associated to.
1362 * Configs in the same group are similar from vendor's perspective and switching between
1363 * configs within the same group can be done seamlessly in most cases.
1364 * @see: android.hardware.graphics.composer@2.4::IComposerClient::Attribute::CONFIG_GROUP
1365 */
1366 public int configGroup;
1367
1368 @Override
1369 public String toString() {
1370 return "DisplayConfig{width=" + width
1371 + ", height=" + height
1372 + ", xDpi=" + xDpi
1373 + ", yDpi=" + yDpi
1374 + ", refreshRate=" + refreshRate
1375 + ", appVsyncOffsetNanos=" + appVsyncOffsetNanos
1376 + ", presentationDeadlineNanos=" + presentationDeadlineNanos
1377 + ", configGroup=" + configGroup + "}";
1378 }
1379 }
1380
1381 /**
1382 * @hide
1383 */
1384 public static void setDisplayPowerMode(IBinder displayToken, int mode) {
1385 if (displayToken == null) {
1386 throw new IllegalArgumentException("displayToken must not be null");
1387 }
1388 nativeSetDisplayPowerMode(displayToken, mode);
1389 }
1390
1391 /**
1392 * @hide
1393 */
1394 public static SurfaceControl.DisplayInfo getDisplayInfo(IBinder displayToken) {
1395 if (displayToken == null) {
1396 throw new IllegalArgumentException("displayToken must not be null");
1397 }
1398 return nativeGetDisplayInfo(displayToken);
1399 }
1400
1401 /**
1402 * @hide
1403 */
1404 public static SurfaceControl.DisplayConfig[] getDisplayConfigs(IBinder displayToken) {
1405 if (displayToken == null) {
1406 throw new IllegalArgumentException("displayToken must not be null");
1407 }
1408 return nativeGetDisplayConfigs(displayToken);
1409 }
1410
1411 /**
1412 * @hide
1413 */
1414 public static int getActiveConfig(IBinder displayToken) {
1415 if (displayToken == null) {
1416 throw new IllegalArgumentException("displayToken must not be null");
1417 }
1418 return nativeGetActiveConfig(displayToken);
1419 }
1420
1421 /**
1422 * @hide
1423 */
1424 public static DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes(
1425 IBinder displayToken) {
1426 if (displayToken == null) {
1427 throw new IllegalArgumentException("displayToken must not be null");
1428 }
1429 return nativeGetDisplayedContentSamplingAttributes(displayToken);
1430 }
1431
1432 /**
1433 * @hide
1434 */
1435 public static boolean setDisplayedContentSamplingEnabled(
1436 IBinder displayToken, boolean enable, int componentMask, int maxFrames) {
1437 if (displayToken == null) {
1438 throw new IllegalArgumentException("displayToken must not be null");
1439 }
1440 final int maxColorComponents = 4;
1441 if ((componentMask >> maxColorComponents) != 0) {
1442 throw new IllegalArgumentException("invalid componentMask when enabling sampling");
1443 }
1444 return nativeSetDisplayedContentSamplingEnabled(
1445 displayToken, enable, componentMask, maxFrames);
1446 }
1447
1448 /**
1449 * @hide
1450 */
1451 public static DisplayedContentSample getDisplayedContentSample(
1452 IBinder displayToken, long maxFrames, long timestamp) {
1453 if (displayToken == null) {
1454 throw new IllegalArgumentException("displayToken must not be null");
1455 }
1456 return nativeGetDisplayedContentSample(displayToken, maxFrames, timestamp);
1457 }
1458
1459
1460 /**
1461 * Contains information about desired display configuration.
1462 *
1463 * @hide
1464 */
1465 public static final class DesiredDisplayConfigSpecs {
1466 public int defaultConfig;
1467 /**
1468 * The primary refresh rate range represents display manager's general guidance on the
1469 * display configs surface flinger will consider when switching refresh rates. Unless
1470 * surface flinger has a specific reason to do otherwise, it will stay within this range.
1471 */
1472 public float primaryRefreshRateMin;
1473 public float primaryRefreshRateMax;
1474 /**
1475 * The app request refresh rate range allows surface flinger to consider more display
1476 * configs when switching refresh rates. Although surface flinger will generally stay within
1477 * the primary range, specific considerations, such as layer frame rate settings specified
1478 * via the setFrameRate() api, may cause surface flinger to go outside the primary
1479 * range. Surface flinger never goes outside the app request range. The app request range
1480 * will be greater than or equal to the primary refresh rate range, never smaller.
1481 */
1482 public float appRequestRefreshRateMin;
1483 public float appRequestRefreshRateMax;
1484
1485 public DesiredDisplayConfigSpecs() {}
1486
1487 public DesiredDisplayConfigSpecs(DesiredDisplayConfigSpecs other) {
1488 copyFrom(other);
1489 }
1490
1491 public DesiredDisplayConfigSpecs(int defaultConfig, float primaryRefreshRateMin,
1492 float primaryRefreshRateMax, float appRequestRefreshRateMin,
1493 float appRequestRefreshRateMax) {
1494 this.defaultConfig = defaultConfig;
1495 this.primaryRefreshRateMin = primaryRefreshRateMin;
1496 this.primaryRefreshRateMax = primaryRefreshRateMax;
1497 this.appRequestRefreshRateMin = appRequestRefreshRateMin;
1498 this.appRequestRefreshRateMax = appRequestRefreshRateMax;
1499 }
1500
1501 @Override
1502 public boolean equals(Object o) {
1503 return o instanceof DesiredDisplayConfigSpecs && equals((DesiredDisplayConfigSpecs) o);
1504 }
1505
1506 /**
1507 * Tests for equality.
1508 */
1509 public boolean equals(DesiredDisplayConfigSpecs other) {
1510 return other != null && defaultConfig == other.defaultConfig
1511 && primaryRefreshRateMin == other.primaryRefreshRateMin
1512 && primaryRefreshRateMax == other.primaryRefreshRateMax
1513 && appRequestRefreshRateMin == other.appRequestRefreshRateMin
1514 && appRequestRefreshRateMax == other.appRequestRefreshRateMax;
1515 }
1516
1517 @Override
1518 public int hashCode() {
1519 return 0; // don't care
1520 }
1521
1522 /**
1523 * Copies the supplied object's values to this object.
1524 */
1525 public void copyFrom(DesiredDisplayConfigSpecs other) {
1526 defaultConfig = other.defaultConfig;
1527 primaryRefreshRateMin = other.primaryRefreshRateMin;
1528 primaryRefreshRateMax = other.primaryRefreshRateMax;
1529 appRequestRefreshRateMin = other.appRequestRefreshRateMin;
1530 appRequestRefreshRateMax = other.appRequestRefreshRateMax;
1531 }
1532
1533 @Override
1534 public String toString() {
1535 return String.format("defaultConfig=%d primaryRefreshRateRange=[%.0f %.0f]"
1536 + " appRequestRefreshRateRange=[%.0f %.0f]",
1537 defaultConfig, primaryRefreshRateMin, primaryRefreshRateMax,
1538 appRequestRefreshRateMin, appRequestRefreshRateMax);
1539 }
1540 }
1541
1542 /**
1543 * @hide
1544 */
1545 public static boolean setDesiredDisplayConfigSpecs(IBinder displayToken,
1546 SurfaceControl.DesiredDisplayConfigSpecs desiredDisplayConfigSpecs) {
1547 if (displayToken == null) {
1548 throw new IllegalArgumentException("displayToken must not be null");
1549 }
1550
1551 return nativeSetDesiredDisplayConfigSpecs(displayToken, desiredDisplayConfigSpecs);
1552 }
1553
1554 /**
1555 * @hide
1556 */
1557 public static SurfaceControl.DesiredDisplayConfigSpecs getDesiredDisplayConfigSpecs(
1558 IBinder displayToken) {
1559 if (displayToken == null) {
1560 throw new IllegalArgumentException("displayToken must not be null");
1561 }
1562
1563 return nativeGetDesiredDisplayConfigSpecs(displayToken);
1564 }
1565
1566 /**
1567 * @hide
1568 */
1569 public static int[] getDisplayColorModes(IBinder displayToken) {
1570 if (displayToken == null) {
1571 throw new IllegalArgumentException("displayToken must not be null");
1572 }
1573 return nativeGetDisplayColorModes(displayToken);
1574 }
1575
1576 /**
1577 * Color coordinates in CIE1931 XYZ color space
1578 *
1579 * @hide
1580 */
1581 public static final class CieXyz {
1582 /**
1583 * @hide
1584 */
1585 public float X;
1586
1587 /**
1588 * @hide
1589 */
1590 public float Y;
1591
1592 /**
1593 * @hide
1594 */
1595 public float Z;
1596 }
1597
1598 /**
1599 * Contains a display's color primaries
1600 *
1601 * @hide
1602 */
1603 public static final class DisplayPrimaries {
1604 /**
1605 * @hide
1606 */
1607 public CieXyz red;
1608
1609 /**
1610 * @hide
1611 */
1612 public CieXyz green;
1613
1614 /**
1615 * @hide
1616 */
1617 public CieXyz blue;
1618
1619 /**
1620 * @hide
1621 */
1622 public CieXyz white;
1623
1624 /**
1625 * @hide
1626 */
1627 public DisplayPrimaries() {
1628 }
1629 }
1630
1631 /**
1632 * @hide
1633 */
1634 public static SurfaceControl.DisplayPrimaries getDisplayNativePrimaries(
1635 IBinder displayToken) {
1636 if (displayToken == null) {
1637 throw new IllegalArgumentException("displayToken must not be null");
1638 }
1639
1640 return nativeGetDisplayNativePrimaries(displayToken);
1641 }
1642
1643 /**
1644 * @hide
1645 */
1646 public static int getActiveColorMode(IBinder displayToken) {
1647 if (displayToken == null) {
1648 throw new IllegalArgumentException("displayToken must not be null");
1649 }
1650 return nativeGetActiveColorMode(displayToken);
1651 }
1652
1653 /**
1654 * @hide
1655 */
1656 public static boolean setActiveColorMode(IBinder displayToken, int colorMode) {
1657 if (displayToken == null) {
1658 throw new IllegalArgumentException("displayToken must not be null");
1659 }
1660 return nativeSetActiveColorMode(displayToken, colorMode);
1661 }
1662
1663 /**
1664 * Returns an array of color spaces with 2 elements. The first color space is the
1665 * default color space and second one is wide color gamut color space.
1666 * @hide
1667 */
1668 public static ColorSpace[] getCompositionColorSpaces() {
1669 int[] dataspaces = nativeGetCompositionDataspaces();
1670 ColorSpace srgb = ColorSpace.get(ColorSpace.Named.SRGB);
1671 ColorSpace[] colorSpaces = { srgb, srgb };
1672 if (dataspaces.length == 2) {
1673 for (int i = 0; i < 2; ++i) {
1674 switch(dataspaces[i]) {
1675 case INTERNAL_DATASPACE_DISPLAY_P3:
1676 colorSpaces[i] = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
1677 break;
1678 case INTERNAL_DATASPACE_SCRGB:
1679 colorSpaces[i] = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB);
1680 break;
1681 case INTERNAL_DATASPACE_SRGB:
1682 // Other dataspace is not recognized, use SRGB color space instead,
1683 // the default value of the array is already SRGB, thus do nothing.
1684 default:
1685 break;
1686 }
1687 }
1688 }
1689 return colorSpaces;
1690 }
1691
1692 /**
1693 * @hide
1694 */
1695 public static void setAutoLowLatencyMode(IBinder displayToken, boolean on) {
1696 if (displayToken == null) {
1697 throw new IllegalArgumentException("displayToken must not be null");
1698 }
1699
1700 nativeSetAutoLowLatencyMode(displayToken, on);
1701 }
1702
1703 /**
1704 * @hide
1705 */
1706 public static void setGameContentType(IBinder displayToken, boolean on) {
1707 if (displayToken == null) {
1708 throw new IllegalArgumentException("displayToken must not be null");
1709 }
1710
1711 nativeSetGameContentType(displayToken, on);
1712 }
1713
1714 /**
1715 * @hide
1716 */
1717 @UnsupportedAppUsage
1718 public static void setDisplayProjection(IBinder displayToken,
1719 int orientation, Rect layerStackRect, Rect displayRect) {
1720 synchronized (SurfaceControl.class) {
1721 sGlobalTransaction.setDisplayProjection(displayToken, orientation,
1722 layerStackRect, displayRect);
1723 }
1724 }
1725
1726 /**
1727 * @hide
1728 */
1729 @UnsupportedAppUsage
1730 public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
1731 synchronized (SurfaceControl.class) {
1732 sGlobalTransaction.setDisplayLayerStack(displayToken, layerStack);
1733 }
1734 }
1735
1736 /**
1737 * @hide
1738 */
1739 @UnsupportedAppUsage
1740 public static void setDisplaySurface(IBinder displayToken, Surface surface) {
1741 synchronized (SurfaceControl.class) {
1742 sGlobalTransaction.setDisplaySurface(displayToken, surface);
1743 }
1744 }
1745
1746 /**
1747 * @hide
1748 */
1749 public static void setDisplaySize(IBinder displayToken, int width, int height) {
1750 synchronized (SurfaceControl.class) {
1751 sGlobalTransaction.setDisplaySize(displayToken, width, height);
1752 }
1753 }
1754
1755 /**
1756 * @hide
1757 */
1758 public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) {
1759 if (displayToken == null) {
1760 throw new IllegalArgumentException("displayToken must not be null");
1761 }
1762 return nativeGetHdrCapabilities(displayToken);
1763 }
1764
1765 /**
1766 * @hide
1767 */
1768 public static boolean getAutoLowLatencyModeSupport(IBinder displayToken) {
1769 if (displayToken == null) {
1770 throw new IllegalArgumentException("displayToken must not be null");
1771 }
1772
1773 return nativeGetAutoLowLatencyModeSupport(displayToken);
1774 }
1775
1776 /**
1777 * @hide
1778 */
1779 public static boolean getGameContentTypeSupport(IBinder displayToken) {
1780 if (displayToken == null) {
1781 throw new IllegalArgumentException("displayToken must not be null");
1782 }
1783
1784 return nativeGetGameContentTypeSupport(displayToken);
1785 }
1786
1787 /**
1788 * @hide
1789 */
1790 @UnsupportedAppUsage
1791 public static IBinder createDisplay(String name, boolean secure) {
1792 if (name == null) {
1793 throw new IllegalArgumentException("name must not be null");
1794 }
1795 return nativeCreateDisplay(name, secure);
1796 }
1797
1798 /**
1799 * @hide
1800 */
1801 @UnsupportedAppUsage
1802 public static void destroyDisplay(IBinder displayToken) {
1803 if (displayToken == null) {
1804 throw new IllegalArgumentException("displayToken must not be null");
1805 }
1806 nativeDestroyDisplay(displayToken);
1807 }
1808
1809 /**
1810 * @hide
1811 */
1812 public static long[] getPhysicalDisplayIds() {
1813 return nativeGetPhysicalDisplayIds();
1814 }
1815
1816 /**
1817 * @hide
1818 */
1819 public static IBinder getPhysicalDisplayToken(long physicalDisplayId) {
1820 return nativeGetPhysicalDisplayToken(physicalDisplayId);
1821 }
1822
1823 /**
1824 * TODO(b/116025192): Remove this stopgap once framework is display-agnostic.
1825 *
1826 * @hide
1827 */
1828 public static IBinder getInternalDisplayToken() {
1829 final long[] physicalDisplayIds = getPhysicalDisplayIds();
1830 if (physicalDisplayIds.length == 0) {
1831 return null;
1832 }
1833 return getPhysicalDisplayToken(physicalDisplayIds[0]);
1834 }
1835
1836 /**
1837 * @see SurfaceControl#screenshot(IBinder, Surface, Rect, int, int, boolean, int)
1838 * @hide
1839 */
1840 public static void screenshot(IBinder display, Surface consumer) {
1841 screenshot(display, consumer, new Rect(), 0, 0, false, 0);
1842 }
1843
1844 /**
1845 * Copy the current screen contents into the provided {@link Surface}
1846 *
1847 * @param consumer The {@link Surface} to take the screenshot into.
1848 * @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)
1849 * @hide
1850 */
1851 public static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width,
1852 int height, boolean useIdentityTransform, int rotation) {
1853 if (consumer == null) {
1854 throw new IllegalArgumentException("consumer must not be null");
1855 }
1856
1857 final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
1858 height, useIdentityTransform, rotation);
1859 try {
1860 consumer.attachAndQueueBufferWithColorSpace(buffer.getGraphicBuffer(),
1861 buffer.getColorSpace());
1862 } catch (RuntimeException e) {
1863 Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
1864 }
1865 }
1866
1867 /**
1868 * @see SurfaceControl#screenshot(Rect, int, int, boolean, int)}
1869 * @hide
1870 */
1871 @UnsupportedAppUsage
1872 public static Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) {
1873 return screenshot(sourceCrop, width, height, false, rotation);
1874 }
1875
1876 /**
1877 * Copy the current screen contents into a hardware bitmap and return it.
1878 * Note: If you want to modify the Bitmap in software, you will need to copy the Bitmap into
1879 * a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)}
1880 *
1881 * CAVEAT: Versions of screenshot that return a {@link Bitmap} can be extremely slow; avoid use
1882 * unless absolutely necessary; prefer the versions that use a {@link Surface} such as
1883 * {@link SurfaceControl#screenshot(IBinder, Surface)} or {@link GraphicBuffer} such as
1884 * {@link SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)}.
1885 *
1886 * @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)}
1887 * @hide
1888 */
1889 @UnsupportedAppUsage
1890 public static Bitmap screenshot(Rect sourceCrop, int width, int height,
1891 boolean useIdentityTransform, int rotation) {
1892 // TODO: should take the display as a parameter
1893 final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
1894 if (displayToken == null) {
1895 Log.w(TAG, "Failed to take screenshot because internal display is disconnected");
1896 return null;
1897 }
1898
1899 if (rotation == ROTATION_90 || rotation == ROTATION_270) {
1900 rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90;
1901 }
1902
1903 SurfaceControl.rotateCropForSF(sourceCrop, rotation);
1904 final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width,
1905 height, useIdentityTransform, rotation);
1906
1907 if (buffer == null) {
1908 Log.w(TAG, "Failed to take screenshot");
1909 return null;
1910 }
1911 return Bitmap.wrapHardwareBuffer(buffer.getGraphicBuffer(), buffer.getColorSpace());
1912 }
1913
1914 /**
1915 * Captures all the surfaces in a display and returns a {@link GraphicBuffer} with the content.
1916 *
1917 * @param display The display to take the screenshot of.
1918 * @param sourceCrop The portion of the screen to capture into the Bitmap; caller may
1919 * pass in 'new Rect()' if no cropping is desired.
1920 * @param width The desired width of the returned bitmap; the raw screen will be
1921 * scaled down to this size; caller may pass in 0 if no scaling is
1922 * desired.
1923 * @param height The desired height of the returned bitmap; the raw screen will
1924 * be scaled down to this size; caller may pass in 0 if no scaling
1925 * is desired.
1926 * @param useIdentityTransform Replace whatever transformation (rotation, scaling, translation)
1927 * the surface layers are currently using with the identity
1928 * transformation while taking the screenshot.
1929 * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
1930 * Surface.ROTATION_0,90,180,270. SurfaceFlinger will always take
1931 * screenshots in its native portrait orientation by default, so
1932 * this is useful for returning screenshots that are independent of
1933 * device orientation.
1934 * @return Returns a GraphicBuffer that contains the captured content.
1935 * @hide
1936 */
1937 public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop,
1938 int width, int height, boolean useIdentityTransform, int rotation) {
1939 if (display == null) {
1940 throw new IllegalArgumentException("displayToken must not be null");
1941 }
1942
1943 return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
1944 false /* captureSecureLayers */);
1945 }
1946
1947 /**
1948 * Like screenshotToBuffer, but if the caller is AID_SYSTEM, allows
1949 * for the capture of secure layers. This is used for the screen rotation
1950 * animation where the system server takes screenshots but does
1951 * not persist them or allow them to leave the server. However in other
1952 * cases in the system server, we mostly want to omit secure layers
1953 * like when we take a screenshot on behalf of the assistant.
1954 *
1955 * @hide
1956 */
1957 public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
1958 Rect sourceCrop, int width, int height, boolean useIdentityTransform,
1959 int rotation) {
1960 if (display == null) {
1961 throw new IllegalArgumentException("displayToken must not be null");
1962 }
1963
1964 return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
1965 true /* captureSecureLayers */);
1966 }
1967
1968 private static void rotateCropForSF(Rect crop, int rot) {
1969 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
1970 int tmp = crop.top;
1971 crop.top = crop.left;
1972 crop.left = tmp;
1973 tmp = crop.right;
1974 crop.right = crop.bottom;
1975 crop.bottom = tmp;
1976 }
1977 }
1978
1979 /**
1980 * Captures a layer and its children and returns a {@link GraphicBuffer} with the content.
1981 *
1982 * @param layer The root layer to capture.
1983 * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new
1984 * Rect()' or null if no cropping is desired. If the root layer does not
1985 * have a buffer or a crop set, then a non-empty source crop must be
1986 * specified.
1987 * @param frameScale The desired scale of the returned buffer; the raw
1988 * screen will be scaled up/down.
1989 *
1990 * @return Returns a GraphicBuffer that contains the layer capture.
1991 * @hide
1992 */
1993 public static ScreenshotGraphicBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
1994 float frameScale) {
1995 return captureLayers(layer, sourceCrop, frameScale, PixelFormat.RGBA_8888);
1996 }
1997
1998 /**
1999 * Captures a layer and its children and returns a {@link GraphicBuffer} with the content.
2000 *
2001 * @param layer The root layer to capture.
2002 * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new
2003 * Rect()' or null if no cropping is desired. If the root layer does not
2004 * have a buffer or a crop set, then a non-empty source crop must be
2005 * specified.
2006 * @param frameScale The desired scale of the returned buffer; the raw
2007 * screen will be scaled up/down.
2008 * @param format The desired pixel format of the returned buffer.
2009 *
2010 * @return Returns a GraphicBuffer that contains the layer capture.
2011 * @hide
2012 */
2013 public static ScreenshotGraphicBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
2014 float frameScale, int format) {
2015 final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
2016 return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, null,
2017 format);
2018 }
2019
2020 /**
2021 * Like {@link captureLayers} but with an array of layer handles to exclude.
2022 * @hide
2023 */
2024 public static ScreenshotGraphicBuffer captureLayersExcluding(SurfaceControl layer,
2025 Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
2026 final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
2027 long[] nativeExcludeObjects = new long[exclude.length];
2028 for (int i = 0; i < exclude.length; i++) {
2029 nativeExcludeObjects[i] = exclude[i].mNativeObject;
2030 }
2031 return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale,
2032 nativeExcludeObjects, PixelFormat.RGBA_8888);
2033 }
2034
2035 /**
2036 * Returns whether protected content is supported in GPU composition.
2037 * @hide
2038 */
2039 public static boolean getProtectedContentSupport() {
2040 return nativeGetProtectedContentSupport();
2041 }
2042
2043 /**
2044 * Returns whether brightness operations are supported on a display.
2045 *
2046 * @param displayToken
2047 * The token for the display.
2048 *
2049 * @return Whether brightness operations are supported on the display.
2050 *
2051 * @hide
2052 */
2053 public static boolean getDisplayBrightnessSupport(IBinder displayToken) {
2054 return nativeGetDisplayBrightnessSupport(displayToken);
2055 }
2056
2057 /**
2058 * Sets the brightness of a display.
2059 *
2060 * @param displayToken
2061 * The token for the display whose brightness is set.
2062 * @param brightness
2063 * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to
2064 * turn the backlight off.
2065 *
2066 * @return Whether the method succeeded or not.
2067 *
2068 * @throws IllegalArgumentException if:
2069 * - displayToken is null;
2070 * - brightness is NaN or greater than 1.0f.
2071 *
2072 * @hide
2073 */
2074 public static boolean setDisplayBrightness(IBinder displayToken, float brightness) {
2075 Objects.requireNonNull(displayToken);
2076 if (Float.isNaN(brightness) || brightness > 1.0f
2077 || (brightness < 0.0f && brightness != -1.0f)) {
2078 throw new IllegalArgumentException("brightness must be a number between 0.0f and 1.0f,"
2079 + " or -1 to turn the backlight off.");
2080 }
2081 return nativeSetDisplayBrightness(displayToken, brightness);
2082 }
2083
2084 /**
2085 * Creates a mirrored hierarchy for the mirrorOf {@link SurfaceControl}
2086 *
2087 * Real Hierarchy Mirror
2088 * SC (value that's returned)
2089 * |
2090 * A A'
2091 * | |
2092 * B B'
2093 *
2094 * @param mirrorOf The root of the hierarchy that should be mirrored.
2095 * @return A SurfaceControl that's the parent of the root of the mirrored hierarchy.
2096 *
2097 * @hide
2098 */
2099 public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) {
2100 long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject);
2101 SurfaceControl sc = new SurfaceControl();
2102 sc.assignNativeObject(nativeObj);
2103 return sc;
2104 }
2105
2106 private static void validateColorArg(@Size(4) float[] color) {
2107 final String msg = "Color must be specified as a float array with"
2108 + " four values to represent r, g, b, a in range [0..1]";
2109 if (color.length != 4) {
2110 throw new IllegalArgumentException(msg);
2111 }
2112 for (float c:color) {
2113 if ((c < 0.f) || (c > 1.f)) {
2114 throw new IllegalArgumentException(msg);
2115 }
2116 }
2117 }
2118
2119 /**
2120 * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows
2121 * material design guidelines.
2122 *
2123 * @param ambientColor Color applied to the ambient shadow. The alpha is premultiplied. A
2124 * float array with four values to represent r, g, b, a in range [0..1]
2125 * @param spotColor Color applied to the spot shadow. The alpha is premultiplied. The position
2126 * of the spot shadow depends on the light position. A float array with
2127 * four values to represent r, g, b, a in range [0..1]
2128 * @param lightPosY Y axis position of the light used to cast the spot shadow in pixels.
2129 * @param lightPosZ Z axis position of the light used to cast the spot shadow in pixels. The X
2130 * axis position is set to the display width / 2.
2131 * @param lightRadius Radius of the light casting the shadow in pixels.
2132 *[
2133 * @hide
2134 */
2135 public static void setGlobalShadowSettings(@Size(4) float[] ambientColor,
2136 @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius) {
2137 validateColorArg(ambientColor);
2138 validateColorArg(spotColor);
2139 nativeSetGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
2140 }
2141
2142 /**
2143 * An atomic set of changes to a set of SurfaceControl.
2144 */
2145 public static class Transaction implements Closeable, Parcelable {
2146 /**
2147 * @hide
2148 */
2149 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
2150 Transaction.class.getClassLoader(),
2151 nativeGetNativeTransactionFinalizer(), 512);
2152 /**
2153 * @hide
2154 */
2155 public long mNativeObject;
2156
2157 private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>();
2158 Runnable mFreeNativeResources;
2159 private static final float[] INVALID_COLOR = {-1, -1, -1};
2160
2161 /**
2162 * @hide
2163 */
2164 protected void checkPreconditions(SurfaceControl sc) {
2165 sc.checkNotReleased();
2166 }
2167
2168 /**
2169 * Open a new transaction object. The transaction may be filed with commands to
2170 * manipulate {@link SurfaceControl} instances, and then applied atomically with
2171 * {@link #apply}. Eventually the user should invoke {@link #close}, when the object
2172 * is no longer required. Note however that re-using a transaction after a call to apply
2173 * is allowed as a convenience.
2174 */
2175 public Transaction() {
2176 mNativeObject = nativeCreateTransaction();
2177 mFreeNativeResources
2178 = sRegistry.registerNativeAllocation(this, mNativeObject);
2179 }
2180
2181 private Transaction(Parcel in) {
2182 readFromParcel(in);
2183 }
2184
2185 /**
2186 * Apply the transaction, clearing it's state, and making it usable
2187 * as a new transaction.
2188 */
2189 public void apply() {
2190 apply(false);
2191 }
2192
2193 /**
2194 * Release the native transaction object, without applying it.
2195 */
2196 @Override
2197 public void close() {
2198 mFreeNativeResources.run();
2199 mNativeObject = 0;
2200 }
2201
2202 /**
2203 * Jankier version of apply. Avoid use (b/28068298).
2204 * @hide
2205 */
2206 public void apply(boolean sync) {
2207 applyResizedSurfaces();
2208 nativeApplyTransaction(mNativeObject, sync);
2209 }
2210
2211 private void applyResizedSurfaces() {
2212 for (int i = mResizedSurfaces.size() - 1; i >= 0; i--) {
2213 final Point size = mResizedSurfaces.valueAt(i);
2214 final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i);
2215 synchronized (surfaceControl.mSizeLock) {
2216 surfaceControl.mWidth = size.x;
2217 surfaceControl.mHeight = size.y;
2218 }
2219 }
2220 mResizedSurfaces.clear();
2221 }
2222
2223 /**
2224 * Toggle the visibility of a given Layer and it's sub-tree.
2225 *
2226 * @param sc The SurfaceControl for which to set the visibility
2227 * @param visible The new visibility
2228 * @return This transaction object.
2229 */
2230 @NonNull
2231 public Transaction setVisibility(@NonNull SurfaceControl sc, boolean visible) {
2232 checkPreconditions(sc);
2233 if (visible) {
2234 return show(sc);
2235 } else {
2236 return hide(sc);
2237 }
2238 }
2239
2240 /**
2241 * This information is passed to SurfaceFlinger to decide which window should have a
2242 * priority when deciding about the refresh rate of the display. All windows have the
2243 * lowest priority by default.
2244 * @hide
2245 */
2246 @NonNull
2247 public Transaction setFrameRateSelectionPriority(@NonNull SurfaceControl sc, int priority) {
2248 sc.checkNotReleased();
2249 nativeSetFrameRateSelectionPriority(mNativeObject, sc.mNativeObject, priority);
2250 return this;
2251 }
2252
2253 /**
2254 * Request that a given surface and it's sub-tree be shown.
2255 *
2256 * @param sc The surface to show.
2257 * @return This transaction.
2258 * @hide
2259 */
2260 @UnsupportedAppUsage
2261 public Transaction show(SurfaceControl sc) {
2262 checkPreconditions(sc);
2263 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN);
2264 return this;
2265 }
2266
2267 /**
2268 * Request that a given surface and it's sub-tree be hidden.
2269 *
2270 * @param sc The surface to hidden.
2271 * @return This transaction.
2272 * @hide
2273 */
2274 @UnsupportedAppUsage
2275 public Transaction hide(SurfaceControl sc) {
2276 checkPreconditions(sc);
2277 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
2278 return this;
2279 }
2280
2281 /**
2282 * @hide
2283 */
2284 @UnsupportedAppUsage
2285 public Transaction setPosition(SurfaceControl sc, float x, float y) {
2286 checkPreconditions(sc);
2287 nativeSetPosition(mNativeObject, sc.mNativeObject, x, y);
2288 return this;
2289 }
2290
2291 /**
2292 * Set the default buffer size for the SurfaceControl, if there is a
2293 * {@link Surface} associated with the control, then
2294 * this will be the default size for buffers dequeued from it.
2295 * @param sc The surface to set the buffer size for.
2296 * @param w The default width
2297 * @param h The default height
2298 * @return This Transaction
2299 */
2300 @NonNull
2301 public Transaction setBufferSize(@NonNull SurfaceControl sc,
2302 @IntRange(from = 0) int w, @IntRange(from = 0) int h) {
2303 checkPreconditions(sc);
2304 mResizedSurfaces.put(sc, new Point(w, h));
2305 nativeSetSize(mNativeObject, sc.mNativeObject, w, h);
2306 return this;
2307 }
2308
2309 /**
2310 * Set the Z-order for a given SurfaceControl, relative to it's siblings.
2311 * If two siblings share the same Z order the ordering is undefined. Surfaces
2312 * with a negative Z will be placed below the parent surface.
2313 *
2314 * @param sc The SurfaceControl to set the Z order on
2315 * @param z The Z-order
2316 * @return This Transaction.
2317 */
2318 @NonNull
2319 public Transaction setLayer(@NonNull SurfaceControl sc,
2320 @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z) {
2321 checkPreconditions(sc);
2322 nativeSetLayer(mNativeObject, sc.mNativeObject, z);
2323 return this;
2324 }
2325
2326 /**
2327 * @hide
2328 */
2329 public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) {
2330 checkPreconditions(sc);
2331 nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, relativeTo.mNativeObject, z);
2332 return this;
2333 }
2334
2335 /**
2336 * @hide
2337 */
2338 public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) {
2339 checkPreconditions(sc);
2340 nativeSetTransparentRegionHint(mNativeObject,
2341 sc.mNativeObject, transparentRegion);
2342 return this;
2343 }
2344
2345 /**
2346 * Set the alpha for a given surface. If the alpha is non-zero the SurfaceControl
2347 * will be blended with the Surfaces under it according to the specified ratio.
2348 *
2349 * @param sc The given SurfaceControl.
2350 * @param alpha The alpha to set.
2351 */
2352 @NonNull
2353 public Transaction setAlpha(@NonNull SurfaceControl sc,
2354 @FloatRange(from = 0.0, to = 1.0) float alpha) {
2355 checkPreconditions(sc);
2356 nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha);
2357 return this;
2358 }
2359
2360 /**
2361 * @hide
2362 */
2363 public Transaction setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle) {
2364 checkPreconditions(sc);
2365 nativeSetInputWindowInfo(mNativeObject, sc.mNativeObject, handle);
2366 return this;
2367 }
2368
2369 /**
2370 * Waits until any changes to input windows have been sent from SurfaceFlinger to
2371 * InputFlinger before returning.
2372 *
2373 * @hide
2374 */
2375 public Transaction syncInputWindows() {
2376 nativeSyncInputWindows(mNativeObject);
2377 return this;
2378 }
2379
2380 /**
2381 * Specify how the buffer assosciated with this Surface is mapped in to the
2382 * parent coordinate space. The source frame will be scaled to fit the destination
2383 * frame, after being rotated according to the orientation parameter.
2384 *
2385 * @param sc The SurfaceControl to specify the geometry of
2386 * @param sourceCrop The source rectangle in buffer space. Or null for the entire buffer.
2387 * @param destFrame The destination rectangle in parent space. Or null for the source frame.
2388 * @param orientation The buffer rotation
2389 * @return This transaction object.
2390 */
2391 @NonNull
2392 public Transaction setGeometry(@NonNull SurfaceControl sc, @Nullable Rect sourceCrop,
2393 @Nullable Rect destFrame, @Surface.Rotation int orientation) {
2394 checkPreconditions(sc);
2395 nativeSetGeometry(mNativeObject, sc.mNativeObject, sourceCrop, destFrame, orientation);
2396 return this;
2397 }
2398
2399 /**
2400 * @hide
2401 */
2402 @UnsupportedAppUsage
2403 public Transaction setMatrix(SurfaceControl sc,
2404 float dsdx, float dtdx, float dtdy, float dsdy) {
2405 checkPreconditions(sc);
2406 nativeSetMatrix(mNativeObject, sc.mNativeObject,
2407 dsdx, dtdx, dtdy, dsdy);
2408 return this;
2409 }
2410
2411 /**
2412 * Sets the transform and position of a {@link SurfaceControl} from a 3x3 transformation
2413 * matrix.
2414 *
2415 * @param sc SurfaceControl to set matrix of
2416 * @param matrix The matrix to apply.
2417 * @param float9 An array of 9 floats to be used to extract the values from the matrix.
2418 * @hide
2419 */
2420 @UnsupportedAppUsage
2421 public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) {
2422 matrix.getValues(float9);
2423 setMatrix(sc, float9[MSCALE_X], float9[MSKEW_Y],
2424 float9[MSKEW_X], float9[MSCALE_Y]);
2425 setPosition(sc, float9[MTRANS_X], float9[MTRANS_Y]);
2426 return this;
2427 }
2428
2429 /**
2430 * Sets the color transform for the Surface.
2431 *
2432 * @param sc SurfaceControl to set color transform of
2433 * @param matrix A float array with 9 values represents a 3x3 transform matrix
2434 * @param translation A float array with 3 values represents a translation vector
2435 * @hide
2436 */
2437 public Transaction setColorTransform(SurfaceControl sc, @Size(9) float[] matrix,
2438 @Size(3) float[] translation) {
2439 checkPreconditions(sc);
2440 nativeSetColorTransform(mNativeObject, sc.mNativeObject, matrix, translation);
2441 return this;
2442 }
2443
2444 /**
2445 * Sets the Surface to be color space agnostic. If a surface is color space agnostic,
2446 * the color can be interpreted in any color space.
2447 * @param agnostic A boolean to indicate whether the surface is color space agnostic
2448 * @hide
2449 */
2450 public Transaction setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic) {
2451 checkPreconditions(sc);
2452 nativeSetColorSpaceAgnostic(mNativeObject, sc.mNativeObject, agnostic);
2453 return this;
2454 }
2455
2456 /**
2457 * Bounds the surface and its children to the bounds specified. Size of the surface will be
2458 * ignored and only the crop and buffer size will be used to determine the bounds of the
2459 * surface. If no crop is specified and the surface has no buffer, the surface bounds is
2460 * only constrained by the size of its parent bounds.
2461 *
2462 * @param sc SurfaceControl to set crop of.
2463 * @param crop Bounds of the crop to apply.
2464 * @hide
2465 */
2466 @UnsupportedAppUsage
2467 public Transaction setWindowCrop(SurfaceControl sc, Rect crop) {
2468 checkPreconditions(sc);
2469 if (crop != null) {
2470 nativeSetWindowCrop(mNativeObject, sc.mNativeObject,
2471 crop.left, crop.top, crop.right, crop.bottom);
2472 } else {
2473 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
2474 }
2475
2476 return this;
2477 }
2478
2479 /**
2480 * Same as {@link Transaction#setWindowCrop(SurfaceControl, Rect)} but sets the crop rect
2481 * top left at 0, 0.
2482 *
2483 * @param sc SurfaceControl to set crop of.
2484 * @param width width of crop rect
2485 * @param height height of crop rect
2486 * @hide
2487 */
2488 public Transaction setWindowCrop(SurfaceControl sc, int width, int height) {
2489 checkPreconditions(sc);
2490 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, width, height);
2491 return this;
2492 }
2493
2494 /**
2495 * Sets the corner radius of a {@link SurfaceControl}.
2496 * @param sc SurfaceControl
2497 * @param cornerRadius Corner radius in pixels.
2498 * @return Itself.
2499 * @hide
2500 */
2501 @UnsupportedAppUsage
2502 public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) {
2503 checkPreconditions(sc);
2504 nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius);
2505
2506 return this;
2507 }
2508
2509 /**
2510 * Sets the background blur radius of the {@link SurfaceControl}.
2511 *
2512 * @param sc SurfaceControl.
2513 * @param radius Blur radius in pixels.
2514 * @return itself.
2515 * @hide
2516 */
2517 public Transaction setBackgroundBlurRadius(SurfaceControl sc, int radius) {
2518 checkPreconditions(sc);
2519 nativeSetBackgroundBlurRadius(mNativeObject, sc.mNativeObject, radius);
2520 return this;
2521 }
2522
2523 /**
2524 * @hide
2525 */
2526 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
2527 public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
2528 checkPreconditions(sc);
2529 nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
2530 return this;
2531 }
2532
2533 /**
2534 * @hide
2535 */
2536 @UnsupportedAppUsage
2537 public Transaction deferTransactionUntil(SurfaceControl sc, SurfaceControl barrier,
2538 long frameNumber) {
2539 if (frameNumber < 0) {
2540 return this;
2541 }
2542 checkPreconditions(sc);
2543 nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, barrier.mNativeObject,
2544 frameNumber);
2545 return this;
2546 }
2547
2548 /**
2549 * @hide
2550 */
2551 @Deprecated
2552 @UnsupportedAppUsage
2553 public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface,
2554 long frameNumber) {
2555 if (frameNumber < 0) {
2556 return this;
2557 }
2558 checkPreconditions(sc);
2559 nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject,
2560 barrierSurface.mNativeObject, frameNumber);
2561 return this;
2562 }
2563
2564 /**
2565 * @hide
2566 */
2567 public Transaction reparentChildren(SurfaceControl sc, SurfaceControl newParent) {
2568 checkPreconditions(sc);
2569 nativeReparentChildren(mNativeObject, sc.mNativeObject, newParent.mNativeObject);
2570 return this;
2571 }
2572
2573 /**
2574 * Re-parents a given layer to a new parent. Children inherit transform (position, scaling)
2575 * crop, visibility, and Z-ordering from their parents, as if the children were pixels within the
2576 * parent Surface.
2577 *
2578 * @param sc The SurfaceControl to reparent
2579 * @param newParent The new parent for the given control.
2580 * @return This Transaction
2581 */
2582 @NonNull
2583 public Transaction reparent(@NonNull SurfaceControl sc,
2584 @Nullable SurfaceControl newParent) {
2585 checkPreconditions(sc);
2586 long otherObject = 0;
2587 if (newParent != null) {
2588 newParent.checkNotReleased();
2589 otherObject = newParent.mNativeObject;
2590 }
2591 nativeReparent(mNativeObject, sc.mNativeObject, otherObject);
2592 return this;
2593 }
2594
2595 /**
2596 * @hide
2597 */
2598 public Transaction detachChildren(SurfaceControl sc) {
2599 checkPreconditions(sc);
2600 nativeSeverChildren(mNativeObject, sc.mNativeObject);
2601 return this;
2602 }
2603
2604 /**
2605 * @hide
2606 */
2607 public Transaction setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode) {
2608 checkPreconditions(sc);
2609 nativeSetOverrideScalingMode(mNativeObject, sc.mNativeObject,
2610 overrideScalingMode);
2611 return this;
2612 }
2613
2614 /**
2615 * Fills the surface with the specified color.
2616 * @param color A float array with three values to represent r, g, b in range [0..1]. An
2617 * invalid color will remove the color fill.
2618 * @hide
2619 */
2620 @UnsupportedAppUsage
2621 public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) {
2622 checkPreconditions(sc);
2623 nativeSetColor(mNativeObject, sc.mNativeObject, color);
2624 return this;
2625 }
2626
2627 /**
2628 * Removes color fill.
2629 * @hide
2630 */
2631 public Transaction unsetColor(SurfaceControl sc) {
2632 checkPreconditions(sc);
2633 nativeSetColor(mNativeObject, sc.mNativeObject, INVALID_COLOR);
2634 return this;
2635 }
2636
2637 /**
2638 * Sets the security of the surface. Setting the flag is equivalent to creating the
2639 * Surface with the {@link #SECURE} flag.
2640 * @hide
2641 */
2642 public Transaction setSecure(SurfaceControl sc, boolean isSecure) {
2643 checkPreconditions(sc);
2644 if (isSecure) {
2645 nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE);
2646 } else {
2647 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE);
2648 }
2649 return this;
2650 }
2651
2652 /**
2653 * Sets the opacity of the surface. Setting the flag is equivalent to creating the
2654 * Surface with the {@link #OPAQUE} flag.
2655 * @hide
2656 */
2657 public Transaction setOpaque(SurfaceControl sc, boolean isOpaque) {
2658 checkPreconditions(sc);
2659 if (isOpaque) {
2660 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE);
2661 } else {
2662 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_OPAQUE);
2663 }
2664 return this;
2665 }
2666
2667 /**
2668 * @hide
2669 */
2670 public Transaction setDisplaySurface(IBinder displayToken, Surface surface) {
2671 if (displayToken == null) {
2672 throw new IllegalArgumentException("displayToken must not be null");
2673 }
2674
2675 if (surface != null) {
2676 synchronized (surface.mLock) {
2677 nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject);
2678 }
2679 } else {
2680 nativeSetDisplaySurface(mNativeObject, displayToken, 0);
2681 }
2682 return this;
2683 }
2684
2685 /**
2686 * @hide
2687 */
2688 public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) {
2689 if (displayToken == null) {
2690 throw new IllegalArgumentException("displayToken must not be null");
2691 }
2692 nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack);
2693 return this;
2694 }
2695
2696 /**
2697 * @hide
2698 */
2699 public Transaction setDisplayProjection(IBinder displayToken,
2700 int orientation, Rect layerStackRect, Rect displayRect) {
2701 if (displayToken == null) {
2702 throw new IllegalArgumentException("displayToken must not be null");
2703 }
2704 if (layerStackRect == null) {
2705 throw new IllegalArgumentException("layerStackRect must not be null");
2706 }
2707 if (displayRect == null) {
2708 throw new IllegalArgumentException("displayRect must not be null");
2709 }
2710 nativeSetDisplayProjection(mNativeObject, displayToken, orientation,
2711 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
2712 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
2713 return this;
2714 }
2715
2716 /**
2717 * @hide
2718 */
2719 public Transaction setDisplaySize(IBinder displayToken, int width, int height) {
2720 if (displayToken == null) {
2721 throw new IllegalArgumentException("displayToken must not be null");
2722 }
2723 if (width <= 0 || height <= 0) {
2724 throw new IllegalArgumentException("width and height must be positive");
2725 }
2726
2727 nativeSetDisplaySize(mNativeObject, displayToken, width, height);
2728 return this;
2729 }
2730
2731 /** flag the transaction as an animation
2732 * @hide
2733 */
2734 public Transaction setAnimationTransaction() {
2735 nativeSetAnimationTransaction(mNativeObject);
2736 return this;
2737 }
2738
2739 /**
2740 * Indicate that SurfaceFlinger should wake up earlier than usual as a result of this
2741 * transaction. This should be used when the caller thinks that the scene is complex enough
2742 * that it's likely to hit GL composition, and thus, SurfaceFlinger needs to more time in
2743 * order not to miss frame deadlines.
2744 * <p>
2745 * Corresponds to setting ISurfaceComposer::eEarlyWakeup
2746 * @hide
2747 */
2748 public Transaction setEarlyWakeup() {
2749 nativeSetEarlyWakeup(mNativeObject);
2750 return this;
2751 }
2752
2753 /**
2754 * Sets an arbitrary piece of metadata on the surface. This is a helper for int data.
2755 * @hide
2756 */
2757 public Transaction setMetadata(SurfaceControl sc, int key, int data) {
2758 Parcel parcel = Parcel.obtain();
2759 parcel.writeInt(data);
2760 try {
2761 setMetadata(sc, key, parcel);
2762 } finally {
2763 parcel.recycle();
2764 }
2765 return this;
2766 }
2767
2768 /**
2769 * Sets an arbitrary piece of metadata on the surface.
2770 * @hide
2771 */
2772 public Transaction setMetadata(SurfaceControl sc, int key, Parcel data) {
2773 checkPreconditions(sc);
2774 nativeSetMetadata(mNativeObject, sc.mNativeObject, key, data);
2775 return this;
2776 }
2777
2778 /**
2779 * Draws shadows of length {@code shadowRadius} around the surface {@link SurfaceControl}.
2780 * If the length is 0.0f then the shadows will not be drawn.
2781 *
2782 * Shadows are drawn around the screen bounds, these are the post transformed cropped
2783 * bounds. They can draw over their parent bounds and will be occluded by layers with a
2784 * higher z-order. The shadows will respect the surface's corner radius if the
2785 * rounded corner bounds (transformed source bounds) are within the screen bounds.
2786 *
2787 * A shadow will only be drawn on buffer and color layers. If the radius is applied on a
2788 * container layer, it will be passed down the hierarchy to be applied on buffer and color
2789 * layers but not its children. A scenario where this is useful is when SystemUI animates
2790 * a task by controlling a leash to it, can draw a shadow around the app surface by
2791 * setting a shadow on the leash. This is similar to how rounded corners are set.
2792 *
2793 * @hide
2794 */
2795 public Transaction setShadowRadius(SurfaceControl sc, float shadowRadius) {
2796 checkPreconditions(sc);
2797 nativeSetShadowRadius(mNativeObject, sc.mNativeObject, shadowRadius);
2798 return this;
2799 }
2800
2801 /**
2802 * Sets the intended frame rate for the surface {@link SurfaceControl}.
2803 * <p>
2804 * On devices that are capable of running the display at different refresh rates, the system
2805 * may choose a display refresh rate to better match this surface's frame rate. Usage of
2806 * this API won't directly affect the application's frame production pipeline. However,
2807 * because the system may change the display refresh rate, calls to this function may result
2808 * in changes to Choreographer callback timings, and changes to the time interval at which
2809 * the system releases buffers back to the application.
2810 *
2811 * @param sc The SurfaceControl to specify the frame rate of.
2812 * @param frameRate The intended frame rate for this surface, in frames per second. 0 is a
2813 * special value that indicates the app will accept the system's choice for
2814 * the display frame rate, which is the default behavior if this function
2815 * isn't called. The frameRate param does <em>not</em> need to be a valid
2816 * refresh rate for this device's display - e.g., it's fine to pass 30fps
2817 * to a device that can only run the display at 60fps.
2818 * @param compatibility The frame rate compatibility of this surface. The compatibility
2819 * value may influence the system's choice of display frame rate. See
2820 * the Surface.FRAME_RATE_COMPATIBILITY_* values for more info.
2821 * @return This transaction object.
2822 */
2823 @NonNull
2824 public Transaction setFrameRate(@NonNull SurfaceControl sc,
2825 @FloatRange(from = 0.0) float frameRate,
2826 @Surface.FrameRateCompatibility int compatibility) {
2827 checkPreconditions(sc);
2828 nativeSetFrameRate(mNativeObject, sc.mNativeObject, frameRate, compatibility);
2829 return this;
2830 }
2831
2832 /**
2833 * Merge the other transaction into this transaction, clearing the
2834 * other transaction as if it had been applied.
2835 *
2836 * @param other The transaction to merge in to this one.
2837 * @return This transaction.
2838 */
2839 @NonNull
2840 public Transaction merge(@NonNull Transaction other) {
2841 if (this == other) {
2842 return this;
2843 }
2844 mResizedSurfaces.putAll(other.mResizedSurfaces);
2845 other.mResizedSurfaces.clear();
2846 nativeMergeTransaction(mNativeObject, other.mNativeObject);
2847 return this;
2848 }
2849
2850 /**
2851 * Equivalent to reparent with a null parent, in that it removes
2852 * the SurfaceControl from the scene, but it also releases
2853 * the local resources (by calling {@link SurfaceControl#release})
2854 * after this method returns, {@link SurfaceControl#isValid} will return
2855 * false for the argument.
2856 *
2857 * @param sc The surface to remove and release.
2858 * @return This transaction
2859 * @hide
2860 */
2861 @NonNull
2862 public Transaction remove(@NonNull SurfaceControl sc) {
2863 reparent(sc, null);
2864 sc.release();
2865 return this;
2866 }
2867
2868 /**
2869 * Writes the transaction to parcel, clearing the transaction as if it had been applied so
2870 * it can be used to store future transactions. It's the responsibility of the parcel
2871 * reader to apply the original transaction.
2872 *
2873 * @param dest parcel to write the transaction to
2874 * @param flags
2875 */
2876 @Override
2877 public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
2878 if (mNativeObject == 0) {
2879 dest.writeInt(0);
2880 } else {
2881 dest.writeInt(1);
2882 }
2883 nativeWriteTransactionToParcel(mNativeObject, dest);
2884 }
2885
2886 private void readFromParcel(Parcel in) {
2887 mNativeObject = 0;
2888 if (in.readInt() != 0) {
2889 mNativeObject = nativeReadTransactionFromParcel(in);
2890 mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject);
2891 }
2892 }
2893
2894 @Override
2895 public int describeContents() {
2896 return 0;
2897 }
2898
2899 public static final @NonNull Creator<Transaction> CREATOR = new Creator<Transaction>() {
2900 @Override
2901 public Transaction createFromParcel(Parcel in) {
2902 return new Transaction(in);
2903 }
2904 @Override
2905 public Transaction[] newArray(int size) {
2906 return new Transaction[size];
2907 }
2908 };
2909 }
2910
2911 /**
2912 * A debugging utility subclass of SurfaceControl.Transaction. At construction
2913 * you can pass in a monitor object, and all the other methods will throw an exception
2914 * if the monitor is not held when they are called.
2915 * @hide
2916 */
2917 public static class LockDebuggingTransaction extends SurfaceControl.Transaction {
2918 Object mMonitor;
2919
2920 public LockDebuggingTransaction(Object o) {
2921 mMonitor = o;
2922 }
2923
2924 @Override
2925 protected void checkPreconditions(SurfaceControl sc) {
2926 super.checkPreconditions(sc);
2927 if (!Thread.holdsLock(mMonitor)) {
2928 throw new RuntimeException(
2929 "Unlocked access to synchronized SurfaceControl.Transaction");
2930 }
2931 }
2932 }
2933
2934 /**
2935 * Acquire a frame rate flexibility token, which allows surface flinger to freely switch display
2936 * frame rates. This is used by CTS tests to put the device in a consistent state. See
2937 * ISurfaceComposer::acquireFrameRateFlexibilityToken(). The caller must have the
2938 * ACCESS_SURFACE_FLINGER permission, or else the call will fail, returning 0.
2939 * @hide
2940 */
2941 @TestApi
2942 public static long acquireFrameRateFlexibilityToken() {
2943 return nativeAcquireFrameRateFlexibilityToken();
2944 }
2945
2946 /**
2947 * Release a frame rate flexibility token.
2948 * @hide
2949 */
2950 @TestApi
2951 public static void releaseFrameRateFlexibilityToken(long token) {
2952 nativeReleaseFrameRateFlexibilityToken(token);
2953 }
2954}