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