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.SurfaceControlProto.HASH_CODE;
26 import static android.view.SurfaceControlProto.LAYER_ID;
27 import static android.view.SurfaceControlProto.NAME;
28 
29 import android.Manifest;
30 import android.annotation.CallbackExecutor;
31 import android.annotation.FlaggedApi;
32 import android.annotation.FloatRange;
33 import android.annotation.IntDef;
34 import android.annotation.IntRange;
35 import android.annotation.NonNull;
36 import android.annotation.Nullable;
37 import android.annotation.RequiresPermission;
38 import android.annotation.Size;
39 import android.annotation.TestApi;
40 import android.compat.annotation.UnsupportedAppUsage;
41 import android.graphics.ColorSpace;
42 import android.graphics.GraphicBuffer;
43 import android.graphics.Matrix;
44 import android.graphics.PixelFormat;
45 import android.graphics.Point;
46 import android.graphics.Rect;
47 import android.graphics.Region;
48 import android.gui.DropInputMode;
49 import android.gui.StalledTransactionInfo;
50 import android.gui.TrustedOverlay;
51 import android.hardware.DataSpace;
52 import android.hardware.HardwareBuffer;
53 import android.hardware.OverlayProperties;
54 import android.hardware.SyncFence;
55 import android.hardware.display.DeviceProductInfo;
56 import android.hardware.display.DisplayedContentSample;
57 import android.hardware.display.DisplayedContentSamplingAttributes;
58 import android.hardware.graphics.common.DisplayDecorationSupport;
59 import android.opengl.EGLDisplay;
60 import android.opengl.EGLSync;
61 import android.os.Build;
62 import android.os.IBinder;
63 import android.os.Looper;
64 import android.os.Parcel;
65 import android.os.Parcelable;
66 import android.util.ArrayMap;
67 import android.util.Log;
68 import android.util.Slog;
69 import android.util.SparseIntArray;
70 import android.util.proto.ProtoOutputStream;
71 import android.view.Surface.OutOfResourcesException;
72 
73 import com.android.internal.annotations.GuardedBy;
74 import com.android.internal.util.Preconditions;
75 import com.android.internal.util.VirtualRefBasePtr;
76 import com.android.window.flags.Flags;
77 
78 import dalvik.system.CloseGuard;
79 
80 import libcore.util.NativeAllocationRegistry;
81 
82 import java.io.Closeable;
83 import java.lang.annotation.Retention;
84 import java.lang.annotation.RetentionPolicy;
85 import java.lang.ref.WeakReference;
86 import java.nio.ByteBuffer;
87 import java.nio.ByteOrder;
88 import java.util.ArrayList;
89 import java.util.Arrays;
90 import java.util.Objects;
91 import java.util.concurrent.Executor;
92 import java.util.function.Consumer;
93 
94 /**
95  * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is
96  * a combination of a buffer source, and metadata about how to display the buffers.
97  * By constructing a {@link Surface} from this SurfaceControl you can submit buffers to be
98  * composited. Using {@link SurfaceControl.Transaction} you can manipulate various
99  * properties of how the buffer will be displayed on-screen. SurfaceControl's are
100  * arranged into a scene-graph like hierarchy, and as such any SurfaceControl may have
101  * a parent. Geometric properties like transform, crop, and Z-ordering will be inherited
102  * from the parent, as if the child were content in the parents buffer stream.
103  */
104 public final class SurfaceControl implements Parcelable {
105     private static final String TAG = "SurfaceControl";
106 
nativeCreate(SurfaceSession session, String name, int w, int h, int format, int flags, long parentObject, Parcel metadata)107     private static native long nativeCreate(SurfaceSession session, String name,
108             int w, int h, int format, int flags, long parentObject, Parcel metadata)
109             throws OutOfResourcesException;
nativeReadFromParcel(Parcel in)110     private static native long nativeReadFromParcel(Parcel in);
nativeCopyFromSurfaceControl(long nativeObject)111     private static native long nativeCopyFromSurfaceControl(long nativeObject);
nativeWriteToParcel(long nativeObject, Parcel out)112     private static native void nativeWriteToParcel(long nativeObject, Parcel out);
nativeGetNativeSurfaceControlFinalizer()113     private static native long nativeGetNativeSurfaceControlFinalizer();
nativeDisconnect(long nativeObject)114     private static native void nativeDisconnect(long nativeObject);
nativeUpdateDefaultBufferSize(long nativeObject, int width, int height)115     private static native void nativeUpdateDefaultBufferSize(long nativeObject, int width, int height);
116 
nativeMirrorSurface(long mirrorOfObject)117     private static native long nativeMirrorSurface(long mirrorOfObject);
nativeCreateTransaction()118     private static native long nativeCreateTransaction();
nativeGetNativeTransactionFinalizer()119     private static native long nativeGetNativeTransactionFinalizer();
nativeApplyTransaction(long transactionObj, boolean sync, boolean oneWay)120     private static native void nativeApplyTransaction(long transactionObj, boolean sync,
121             boolean oneWay);
nativeMergeTransaction(long transactionObj, long otherTransactionObj)122     private static native void nativeMergeTransaction(long transactionObj,
123             long otherTransactionObj);
nativeClearTransaction(long transactionObj)124     private static native void nativeClearTransaction(long transactionObj);
nativeSetAnimationTransaction(long transactionObj)125     private static native void nativeSetAnimationTransaction(long transactionObj);
nativeSetEarlyWakeupStart(long transactionObj)126     private static native void nativeSetEarlyWakeupStart(long transactionObj);
nativeSetEarlyWakeupEnd(long transactionObj)127     private static native void nativeSetEarlyWakeupEnd(long transactionObj);
nativeGetTransactionId(long transactionObj)128     private static native long nativeGetTransactionId(long transactionObj);
129 
nativeSetLayer(long transactionObj, long nativeObject, int zorder)130     private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
nativeSetRelativeLayer(long transactionObj, long nativeObject, long relativeToObject, int zorder)131     private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
132             long relativeToObject, int zorder);
nativeSetPosition(long transactionObj, long nativeObject, float x, float y)133     private static native void nativeSetPosition(long transactionObj, long nativeObject,
134             float x, float y);
nativeSetScale(long transactionObj, long nativeObject, float x, float y)135     private static native void nativeSetScale(long transactionObj, long nativeObject,
136             float x, float y);
nativeSetTransparentRegionHint(long transactionObj, long nativeObject, Region region)137     private static native void nativeSetTransparentRegionHint(long transactionObj,
138             long nativeObject, Region region);
nativeSetAlpha(long transactionObj, long nativeObject, float alpha)139     private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha);
nativeSetMatrix(long transactionObj, long nativeObject, float dsdx, float dtdx, float dtdy, float dsdy)140     private static native void nativeSetMatrix(long transactionObj, long nativeObject,
141             float dsdx, float dtdx,
142             float dtdy, float dsdy);
nativeSetColorTransform(long transactionObj, long nativeObject, float[] matrix, float[] translation)143     private static native void nativeSetColorTransform(long transactionObj, long nativeObject,
144             float[] matrix, float[] translation);
nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject, boolean agnostic)145     private static native void nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject,
146             boolean agnostic);
nativeSetGeometry(long transactionObj, long nativeObject, Rect sourceCrop, Rect dest, long orientation)147     private static native void nativeSetGeometry(long transactionObj, long nativeObject,
148             Rect sourceCrop, Rect dest, long orientation);
nativeSetColor(long transactionObj, long nativeObject, float[] color)149     private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
nativeSetFlags(long transactionObj, long nativeObject, int flags, int mask)150     private static native void nativeSetFlags(long transactionObj, long nativeObject,
151             int flags, int mask);
nativeSetFrameRateSelectionPriority(long transactionObj, long nativeObject, int priority)152     private static native void nativeSetFrameRateSelectionPriority(long transactionObj,
153             long nativeObject, int priority);
nativeSetWindowCrop(long transactionObj, long nativeObject, int l, int t, int r, int b)154     private static native void nativeSetWindowCrop(long transactionObj, long nativeObject,
155             int l, int t, int r, int b);
nativeSetCornerRadius(long transactionObj, long nativeObject, float cornerRadius)156     private static native void nativeSetCornerRadius(long transactionObj, long nativeObject,
157             float cornerRadius);
nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject, int blurRadius)158     private static native void nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject,
159             int blurRadius);
nativeSetLayerStack(long transactionObj, long nativeObject, int layerStack)160     private static native void nativeSetLayerStack(long transactionObj, long nativeObject,
161             int layerStack);
nativeSetBlurRegions(long transactionObj, long nativeObj, float[][] regions, int length)162     private static native void nativeSetBlurRegions(long transactionObj, long nativeObj,
163             float[][] regions, int length);
nativeSetStretchEffect(long transactionObj, long nativeObj, float width, float height, float vecX, float vecY, float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)164     private static native void nativeSetStretchEffect(long transactionObj, long nativeObj,
165             float width, float height, float vecX, float vecY,
166             float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft,
167             float childRelativeTop, float childRelativeRight, float childRelativeBottom);
nativeSetTrustedOverlay(long transactionObj, long nativeObject, int isTrustedOverlay)168     private static native void nativeSetTrustedOverlay(long transactionObj, long nativeObject,
169             int isTrustedOverlay);
nativeSetDropInputMode( long transactionObj, long nativeObject, int flags)170     private static native void nativeSetDropInputMode(
171             long transactionObj, long nativeObject, int flags);
nativeSetCanOccludePresentation(long transactionObj, long nativeObject, boolean canOccludePresentation)172     private static native void nativeSetCanOccludePresentation(long transactionObj,
173             long nativeObject, boolean canOccludePresentation);
nativeSurfaceFlushJankData(long nativeSurfaceObject)174     private static native void nativeSurfaceFlushJankData(long nativeSurfaceObject);
nativeClearContentFrameStats(long nativeObject)175     private static native boolean nativeClearContentFrameStats(long nativeObject);
nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats)176     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
nativeClearAnimationFrameStats()177     private static native boolean nativeClearAnimationFrameStats();
nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats)178     private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
179 
nativeSetDisplaySurface(long transactionObj, IBinder displayToken, long nativeSurfaceObject)180     private static native void nativeSetDisplaySurface(long transactionObj,
181             IBinder displayToken, long nativeSurfaceObject);
nativeSetDisplayLayerStack(long transactionObj, IBinder displayToken, int layerStack)182     private static native void nativeSetDisplayLayerStack(long transactionObj,
183             IBinder displayToken, int layerStack);
nativeSetDisplayFlags(long transactionObj, IBinder displayToken, int flags)184     private static native void nativeSetDisplayFlags(long transactionObj,
185             IBinder displayToken, int flags);
nativeSetDisplayProjection(long transactionObj, IBinder displayToken, int orientation, int l, int t, int r, int b, int L, int T, int R, int B)186     private static native void nativeSetDisplayProjection(long transactionObj,
187             IBinder displayToken, int orientation,
188             int l, int t, int r, int b,
189             int L, int T, int R, int B);
nativeSetDisplaySize(long transactionObj, IBinder displayToken, int width, int height)190     private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken,
191             int width, int height);
nativeGetStaticDisplayInfo(long displayId)192     private static native StaticDisplayInfo nativeGetStaticDisplayInfo(long displayId);
nativeGetDynamicDisplayInfo(long displayId)193     private static native DynamicDisplayInfo nativeGetDynamicDisplayInfo(long displayId);
194     private static native DisplayedContentSamplingAttributes
nativeGetDisplayedContentSamplingAttributes(IBinder displayToken)195             nativeGetDisplayedContentSamplingAttributes(IBinder displayToken);
nativeSetDisplayedContentSamplingEnabled(IBinder displayToken, boolean enable, int componentMask, int maxFrames)196     private static native boolean nativeSetDisplayedContentSamplingEnabled(IBinder displayToken,
197             boolean enable, int componentMask, int maxFrames);
nativeGetDisplayedContentSample( IBinder displayToken, long numFrames, long timestamp)198     private static native DisplayedContentSample nativeGetDisplayedContentSample(
199             IBinder displayToken, long numFrames, long timestamp);
nativeSetDesiredDisplayModeSpecs(IBinder displayToken, DesiredDisplayModeSpecs desiredDisplayModeSpecs)200     private static native boolean nativeSetDesiredDisplayModeSpecs(IBinder displayToken,
201             DesiredDisplayModeSpecs desiredDisplayModeSpecs);
202     private static native DesiredDisplayModeSpecs
nativeGetDesiredDisplayModeSpecs(IBinder displayToken)203             nativeGetDesiredDisplayModeSpecs(IBinder displayToken);
nativeGetDisplayNativePrimaries( IBinder displayToken)204     private static native DisplayPrimaries nativeGetDisplayNativePrimaries(
205             IBinder displayToken);
nativeGetCompositionDataspaces()206     private static native int[] nativeGetCompositionDataspaces();
nativeGetOverlaySupport()207     private static native OverlayProperties nativeGetOverlaySupport();
nativeSetActiveColorMode(IBinder displayToken, int colorMode)208     private static native boolean nativeSetActiveColorMode(IBinder displayToken,
209             int colorMode);
nativeGetBootDisplayModeSupport()210     private static native boolean nativeGetBootDisplayModeSupport();
nativeSetBootDisplayMode(IBinder displayToken, int displayMode)211     private static native void nativeSetBootDisplayMode(IBinder displayToken, int displayMode);
nativeClearBootDisplayMode(IBinder displayToken)212     private static native void nativeClearBootDisplayMode(IBinder displayToken);
nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on)213     private static native void nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on);
nativeSetGameContentType(IBinder displayToken, boolean on)214     private static native void nativeSetGameContentType(IBinder displayToken, boolean on);
nativeSetDisplayPowerMode( IBinder displayToken, int mode)215     private static native void nativeSetDisplayPowerMode(
216             IBinder displayToken, int mode);
nativeReparent(long transactionObj, long nativeObject, long newParentNativeObject)217     private static native void nativeReparent(long transactionObj, long nativeObject,
218             long newParentNativeObject);
nativeSetBuffer(long transactionObj, long nativeObject, HardwareBuffer buffer, long fencePtr, Consumer<SyncFence> releaseCallback)219     private static native void nativeSetBuffer(long transactionObj, long nativeObject,
220             HardwareBuffer buffer, long fencePtr, Consumer<SyncFence> releaseCallback);
nativeUnsetBuffer(long transactionObj, long nativeObject)221     private static native void nativeUnsetBuffer(long transactionObj, long nativeObject);
nativeSetBufferTransform(long transactionObj, long nativeObject, int transform)222     private static native void nativeSetBufferTransform(long transactionObj, long nativeObject,
223             int transform);
nativeSetDataSpace(long transactionObj, long nativeObject, @DataSpace.NamedDataSpace int dataSpace)224     private static native void nativeSetDataSpace(long transactionObj, long nativeObject,
225             @DataSpace.NamedDataSpace int dataSpace);
nativeSetExtendedRangeBrightness(long transactionObj, long nativeObject, float currentBufferRatio, float desiredRatio)226     private static native void nativeSetExtendedRangeBrightness(long transactionObj,
227             long nativeObject, float currentBufferRatio, float desiredRatio);
nativeSetDesiredHdrHeadroom(long transactionObj, long nativeObject, float desiredRatio)228     private static native void nativeSetDesiredHdrHeadroom(long transactionObj,
229             long nativeObject, float desiredRatio);
230 
nativeSetCachingHint(long transactionObj, long nativeObject, int cachingHint)231     private static native void nativeSetCachingHint(long transactionObj,
232             long nativeObject, int cachingHint);
nativeSetDamageRegion(long transactionObj, long nativeObject, Region region)233     private static native void nativeSetDamageRegion(long transactionObj, long nativeObject,
234             Region region);
nativeSetDimmingEnabled(long transactionObj, long nativeObject, boolean dimmingEnabled)235     private static native void nativeSetDimmingEnabled(long transactionObj, long nativeObject,
236             boolean dimmingEnabled);
237 
nativeSetInputWindowInfo(long transactionObj, long nativeObject, InputWindowHandle handle)238     private static native void nativeSetInputWindowInfo(long transactionObj, long nativeObject,
239             InputWindowHandle handle);
240 
nativeGetProtectedContentSupport()241     private static native boolean nativeGetProtectedContentSupport();
nativeSetMetadata(long transactionObj, long nativeObject, int key, Parcel data)242     private static native void nativeSetMetadata(long transactionObj, long nativeObject, int key,
243             Parcel data);
nativeAddWindowInfosReportedListener(long transactionObj, Runnable listener)244     private static native void nativeAddWindowInfosReportedListener(long transactionObj,
245             Runnable listener);
nativeGetDisplayBrightnessSupport(IBinder displayToken)246     private static native boolean nativeGetDisplayBrightnessSupport(IBinder displayToken);
nativeSetDisplayBrightness(IBinder displayToken, float sdrBrightness, float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits)247     private static native boolean nativeSetDisplayBrightness(IBinder displayToken,
248             float sdrBrightness, float sdrBrightnessNits, float displayBrightness,
249             float displayBrightnessNits);
nativeReadTransactionFromParcel(Parcel in)250     private static native long nativeReadTransactionFromParcel(Parcel in);
nativeWriteTransactionToParcel(long nativeObject, Parcel out)251     private static native void nativeWriteTransactionToParcel(long nativeObject, Parcel out);
nativeSetShadowRadius(long transactionObj, long nativeObject, float shadowRadius)252     private static native void nativeSetShadowRadius(long transactionObj, long nativeObject,
253             float shadowRadius);
nativeSetGlobalShadowSettings(@ize4) float[] ambientColor, @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius)254     private static native void nativeSetGlobalShadowSettings(@Size(4) float[] ambientColor,
255             @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius);
nativeGetDisplayDecorationSupport( IBinder displayToken)256     private static native DisplayDecorationSupport nativeGetDisplayDecorationSupport(
257             IBinder displayToken);
258 
nativeSetFrameRate(long transactionObj, long nativeObject, float frameRate, int compatibility, int changeFrameRateStrategy)259     private static native void nativeSetFrameRate(long transactionObj, long nativeObject,
260             float frameRate, int compatibility, int changeFrameRateStrategy);
nativeSetDefaultFrameRateCompatibility(long transactionObj, long nativeObject, int compatibility)261     private static native void nativeSetDefaultFrameRateCompatibility(long transactionObj,
262             long nativeObject, int compatibility);
nativeSetFrameRateCategory( long transactionObj, long nativeObject, int category, boolean smoothSwitchOnly)263     private static native void nativeSetFrameRateCategory(
264             long transactionObj, long nativeObject, int category, boolean smoothSwitchOnly);
nativeSetFrameRateSelectionStrategy( long transactionObj, long nativeObject, int strategy)265     private static native void nativeSetFrameRateSelectionStrategy(
266             long transactionObj, long nativeObject, int strategy);
nativeGetHandle(long nativeObject)267     private static native long nativeGetHandle(long nativeObject);
268 
nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint)269     private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject,
270             int transformHint);
nativeRemoveCurrentInputFocus(long nativeObject, int displayId)271     private static native void nativeRemoveCurrentInputFocus(long nativeObject, int displayId);
nativeSetFocusedWindow(long transactionObj, IBinder toToken, String windowName, int displayId)272     private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken,
273             String windowName, int displayId);
nativeSetFrameTimelineVsync(long transactionObj, long frameTimelineVsyncId)274     private static native void nativeSetFrameTimelineVsync(long transactionObj,
275             long frameTimelineVsyncId);
nativeAddJankDataListener(long nativeListener, long nativeSurfaceControl)276     private static native void nativeAddJankDataListener(long nativeListener,
277             long nativeSurfaceControl);
nativeRemoveJankDataListener(long nativeListener)278     private static native void nativeRemoveJankDataListener(long nativeListener);
nativeCreateJankDataListenerWrapper(OnJankDataListener listener)279     private static native long nativeCreateJankDataListenerWrapper(OnJankDataListener listener);
nativeGetGPUContextPriority()280     private static native int nativeGetGPUContextPriority();
nativeSetTransformHint(long nativeObject, @SurfaceControl.BufferTransform int transformHint)281     private static native void nativeSetTransformHint(long nativeObject,
282             @SurfaceControl.BufferTransform int transformHint);
nativeGetTransformHint(long nativeObject)283     private static native int nativeGetTransformHint(long nativeObject);
nativeGetLayerId(long nativeObject)284     private static native int nativeGetLayerId(long nativeObject);
nativeAddTransactionCommittedListener(long nativeObject, TransactionCommittedListener listener)285     private static native void nativeAddTransactionCommittedListener(long nativeObject,
286             TransactionCommittedListener listener);
nativeAddTransactionCompletedListener(long nativeObject, Consumer<TransactionStats> listener)287     private static native void nativeAddTransactionCompletedListener(long nativeObject,
288             Consumer<TransactionStats> listener);
nativeSanitize(long transactionObject, int pid, int uid)289     private static native void nativeSanitize(long transactionObject, int pid, int uid);
nativeSetDestinationFrame(long transactionObj, long nativeObject, int l, int t, int r, int b)290     private static native void nativeSetDestinationFrame(long transactionObj, long nativeObject,
291             int l, int t, int r, int b);
nativeSetDefaultApplyToken(IBinder token)292     private static native void nativeSetDefaultApplyToken(IBinder token);
nativeGetDefaultApplyToken()293     private static native IBinder nativeGetDefaultApplyToken();
nativeBootFinished()294     private static native boolean nativeBootFinished();
nativeCreateTpc(TrustedPresentationCallback callback)295     private static native long nativeCreateTpc(TrustedPresentationCallback callback);
getNativeTrustedPresentationCallbackFinalizer()296     private static native long getNativeTrustedPresentationCallbackFinalizer();
nativeSetTrustedPresentationCallback(long transactionObj, long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds)297     private static native void nativeSetTrustedPresentationCallback(long transactionObj,
298             long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds);
nativeClearTrustedPresentationCallback(long transactionObj, long nativeObject)299     private static native void nativeClearTrustedPresentationCallback(long transactionObj,
300             long nativeObject);
nativeGetStalledTransactionInfo(int pid)301     private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid);
nativeSetDesiredPresentTimeNanos(long transactionObj, long desiredPresentTimeNanos)302     private static native void nativeSetDesiredPresentTimeNanos(long transactionObj,
303                                                                 long desiredPresentTimeNanos);
nativeSetFrameTimeline(long transactionObj, long vsyncId)304     private static native void nativeSetFrameTimeline(long transactionObj,
305                                                            long vsyncId);
nativeNotifyShutdown()306     private static native void nativeNotifyShutdown();
307 
308     /**
309      * Transforms that can be applied to buffers as they are displayed to a window.
310      *
311      * Supported transforms are any combination of horizontal mirror, vertical mirror, and
312      * clock-wise 90 degree rotation, in that order. Rotations of 180 and 270 degrees are made up
313      * of those basic transforms.
314      * Mirrors {@code ANativeWindowTransform} definitions.
315      * @hide
316      */
317     @Retention(RetentionPolicy.SOURCE)
318     @IntDef(prefix = {"BUFFER_TRANSFORM_"},
319             value = {BUFFER_TRANSFORM_IDENTITY, BUFFER_TRANSFORM_MIRROR_HORIZONTAL,
320                     BUFFER_TRANSFORM_MIRROR_VERTICAL, BUFFER_TRANSFORM_ROTATE_90,
321                     BUFFER_TRANSFORM_ROTATE_180, BUFFER_TRANSFORM_ROTATE_270,
322                     BUFFER_TRANSFORM_MIRROR_HORIZONTAL | BUFFER_TRANSFORM_ROTATE_90,
323                     BUFFER_TRANSFORM_MIRROR_VERTICAL | BUFFER_TRANSFORM_ROTATE_90})
324     public @interface BufferTransform {
325     }
326 
327     /**
328      * Identity transform.
329      *
330      * These transforms that can be applied to buffers as they are displayed to a window.
331      * @see HardwareBuffer
332      *
333      * Supported transforms are any combination of horizontal mirror, vertical mirror, and
334      * clock-wise 90 degree rotation, in that order. Rotations of 180 and 270 degrees are
335      * made up of those basic transforms.
336      */
337     public static final int BUFFER_TRANSFORM_IDENTITY = 0x00;
338     /**
339      * Mirror horizontally. Can be combined with {@link #BUFFER_TRANSFORM_MIRROR_VERTICAL}
340      * and {@link #BUFFER_TRANSFORM_ROTATE_90}.
341      */
342     public static final int BUFFER_TRANSFORM_MIRROR_HORIZONTAL = 0x01;
343     /**
344      * Mirror vertically. Can be combined with {@link #BUFFER_TRANSFORM_MIRROR_HORIZONTAL}
345      * and {@link #BUFFER_TRANSFORM_ROTATE_90}.
346      */
347     public static final int BUFFER_TRANSFORM_MIRROR_VERTICAL = 0x02;
348     /**
349      * Rotate 90 degrees clock-wise. Can be combined with {@link
350      * #BUFFER_TRANSFORM_MIRROR_HORIZONTAL} and {@link #BUFFER_TRANSFORM_MIRROR_VERTICAL}.
351      */
352     public static final int BUFFER_TRANSFORM_ROTATE_90 = 0x04;
353     /**
354      * Rotate 180 degrees clock-wise. Cannot be combined with other transforms.
355      */
356     public static final int BUFFER_TRANSFORM_ROTATE_180 =
357             BUFFER_TRANSFORM_MIRROR_HORIZONTAL | BUFFER_TRANSFORM_MIRROR_VERTICAL;
358     /**
359      * Rotate 270 degrees clock-wise. Cannot be combined with other transforms.
360      */
361     public static final int BUFFER_TRANSFORM_ROTATE_270 =
362             BUFFER_TRANSFORM_ROTATE_180 | BUFFER_TRANSFORM_ROTATE_90;
363 
364     /**
365      * @hide
366      */
rotationToBufferTransform(@urface.Rotation int rotation)367     public static @BufferTransform int rotationToBufferTransform(@Surface.Rotation int rotation) {
368         switch (rotation) {
369             case Surface.ROTATION_0: return BUFFER_TRANSFORM_IDENTITY;
370             case Surface.ROTATION_90: return BUFFER_TRANSFORM_ROTATE_90;
371             case Surface.ROTATION_180: return BUFFER_TRANSFORM_ROTATE_180;
372             case Surface.ROTATION_270: return BUFFER_TRANSFORM_ROTATE_270;
373         }
374         Log.e(TAG, "Trying to convert unknown rotation=" + rotation);
375         return BUFFER_TRANSFORM_IDENTITY;
376     }
377 
378     @Nullable
379     @GuardedBy("mLock")
380     private ArrayList<OnReparentListener> mReparentListeners;
381 
382     /**
383      * Listener to observe surface reparenting.
384      *
385      * @hide
386      */
387     public interface OnReparentListener {
388 
389         /**
390          * Callback for reparenting surfaces.
391          *
392          * Important: You should only interact with the provided surface control
393          * only if you have a contract with its owner to avoid them closing it
394          * under you or vise versa.
395          *
396          * @param transaction The transaction that would commit reparenting.
397          * @param parent The future parent surface.
398          */
onReparent(@onNull Transaction transaction, @Nullable SurfaceControl parent)399         void onReparent(@NonNull Transaction transaction, @Nullable SurfaceControl parent);
400     }
401 
402     /**
403      * Jank information to be fed back via {@link OnJankDataListener}.
404      * @hide
405      */
406     public static class JankData {
407 
408         /** @hide */
409         @IntDef(flag = true, value = {JANK_NONE,
410                 DISPLAY_HAL,
411                 JANK_SURFACEFLINGER_DEADLINE_MISSED,
412                 JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED,
413                 JANK_APP_DEADLINE_MISSED,
414                 PREDICTION_ERROR,
415                 SURFACE_FLINGER_SCHEDULING})
416         @Retention(RetentionPolicy.SOURCE)
417         public @interface JankType {}
418 
419         // Needs to be kept in sync with frameworks/native/libs/gui/include/gui/JankInfo.h
420 
421         // No Jank
422         public static final int JANK_NONE = 0x0;
423 
424         // Jank not related to SurfaceFlinger or the App
425         public static final int DISPLAY_HAL = 0x1;
426         // SF took too long on the CPU
427         public static final int JANK_SURFACEFLINGER_DEADLINE_MISSED = 0x2;
428         // SF took too long on the GPU
429         public static final int JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED = 0x4;
430         // Either App or GPU took too long on the frame
431         public static final int JANK_APP_DEADLINE_MISSED = 0x8;
432         // Vsync predictions have drifted beyond the threshold from the actual HWVsync
433         public static final int PREDICTION_ERROR = 0x10;
434         // Latching a buffer early might cause an early present of the frame
435         public static final int SURFACE_FLINGER_SCHEDULING = 0x20;
436         // A buffer is said to be stuffed if it was expected to be presented on a vsync but was
437         // presented later because the previous buffer was presented in its expected vsync. This
438         // usually happens if there is an unexpectedly long frame causing the rest of the buffers
439         // to enter a stuffed state.
440         public static final int BUFFER_STUFFING = 0x40;
441         // Jank due to unknown reasons.
442         public static final int UNKNOWN = 0x80;
443 
JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs)444         public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs) {
445             this.frameVsyncId = frameVsyncId;
446             this.jankType = jankType;
447             this.frameIntervalNs = frameIntervalNs;
448 
449         }
450 
451         public final long frameVsyncId;
452         public final @JankType int jankType;
453         public final long frameIntervalNs;
454     }
455 
456     /**
457      * Listener interface to be informed about SurfaceFlinger's jank classification for a specific
458      * surface.
459      *
460      * @see JankData
461      * @see #addJankDataListener
462      * @hide
463      */
464     public static abstract class OnJankDataListener {
465         private final VirtualRefBasePtr mNativePtr;
466 
OnJankDataListener()467         public OnJankDataListener() {
468             mNativePtr = new VirtualRefBasePtr(nativeCreateJankDataListenerWrapper(this));
469         }
470 
471         /**
472          * Called when new jank classifications are available.
473          */
onJankDataAvailable(JankData[] jankStats)474         public abstract void onJankDataAvailable(JankData[] jankStats);
475     }
476 
477     private final CloseGuard mCloseGuard = CloseGuard.get();
478     private String mName;
479     private String mCallsite;
480 
481      /**
482      * Note: do not rename, this field is used by native code.
483      * @hide
484      */
485     public long mNativeObject;
486     private long mNativeHandle;
487 
488     private final Object mChoreographerLock = new Object();
489     @GuardedBy("mChoreographerLock")
490     private Choreographer mChoreographer;
491 
492     // TODO: Move width/height to native and fix locking through out.
493     private final Object mLock = new Object();
494     @GuardedBy("mLock")
495     private int mWidth;
496     @GuardedBy("mLock")
497     private int mHeight;
498 
499     private TrustedPresentationCallback mTrustedPresentationCallback;
500 
501     private WeakReference<View> mLocalOwnerView;
502 
503     // A throwable with the stack filled when this SurfaceControl is released (only if
504     // sDebugUsageAfterRelease) is enabled
505     private Throwable mReleaseStack = null;
506 
507     // Triggers the stack to be saved when any SurfaceControl in this process is released, which can
508     // be dumped as additional context
509     private static volatile boolean sDebugUsageAfterRelease = false;
510 
511     private static final NativeAllocationRegistry sRegistry =
512             NativeAllocationRegistry.createMalloced(SurfaceControl.class.getClassLoader(),
513                     nativeGetNativeSurfaceControlFinalizer());
514 
515     private Runnable mFreeNativeResources;
516 
517     /**
518      * Adds a reparenting listener.
519      *
520      * @param listener The listener.
521      * @return Whether listener was added.
522      *
523      * @hide
524      */
addOnReparentListener(@onNull OnReparentListener listener)525     public boolean addOnReparentListener(@NonNull OnReparentListener listener) {
526         synchronized (mLock) {
527             if (mReparentListeners == null) {
528                 mReparentListeners = new ArrayList<>(1);
529             }
530             return mReparentListeners.add(listener);
531         }
532     }
533 
534     /**
535      * Removes a reparenting listener.
536      *
537      * @param listener The listener.
538      * @return Whether listener was removed.
539      *
540      * @hide
541      */
removeOnReparentListener(@onNull OnReparentListener listener)542     public boolean removeOnReparentListener(@NonNull OnReparentListener listener) {
543         synchronized (mLock) {
544             final boolean removed = mReparentListeners.remove(listener);
545             if (mReparentListeners.isEmpty()) {
546                 mReparentListeners = null;
547             }
548             return removed;
549         }
550     }
551 
552     /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
553 
554     /**
555      * Surface creation flag: Surface is created hidden
556      * @hide
557      */
558     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
559     public static final int HIDDEN = 0x00000004;
560 
561     /**
562      * Surface creation flag: Skip this layer and its children when taking a screenshot. This
563      * also includes mirroring and screen recording, so the layers with flag SKIP_SCREENSHOT
564      * will not be included on non primary displays.
565      * @hide
566      */
567     public static final int SKIP_SCREENSHOT = 0x00000040;
568 
569     /**
570      * Surface creation flag: Special measures will be taken to disallow the surface's content to
571      * be copied. In particular, screenshots and secondary, non-secure displays will render black
572      * content instead of the surface content.
573      *
574      * @see com.android.server.display.DisplayControl#createDisplay(String, boolean)
575      * @hide
576      */
577     public static final int SECURE = 0x00000080;
578 
579 
580     /**
581      * Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is
582      * set. This blocks the client until all the buffers have been presented. If the buffers
583      * have presentation timestamps, then we may drop buffers.
584      * @hide
585      */
586     public static final int ENABLE_BACKPRESSURE = 0x00000100;
587 
588     /**
589      * Buffers from this SurfaceControl should be considered display decorations.
590      *
591      * If the hardware has optimizations for display decorations (e.g. rounded corners, camera
592      * cutouts, etc), it should use them for this layer.
593      * @hide
594      */
595     public static final int DISPLAY_DECORATION = 0x00000200;
596 
597     /**
598      * Ignore any destination frame set on the layer. This is used when the buffer scaling mode
599      * is freeze and the destination frame is applied asynchronously with the buffer submission.
600      * This is needed to maintain compatibility for SurfaceView scaling behavior.
601      * See SurfaceView scaling behavior for more details.
602      * @hide
603      */
604     public static final int IGNORE_DESTINATION_FRAME = 0x00000400;
605 
606     /**
607      * Special casing for layer that is a refresh rate indicator
608      * @hide
609      */
610     public static final int LAYER_IS_REFRESH_RATE_INDICATOR = 0x00000800;
611 
612     /**
613      * Sets a property on this layer indicating that its visible region should be considered when
614      * computing TrustedPresentation Thresholds
615      * @hide
616      */
617     public static final int CAN_OCCLUDE_PRESENTATION = 0x00001000;
618 
619     /**
620      * Surface creation flag: Creates a surface where color components are interpreted
621      * as "non pre-multiplied" by their alpha channel. Of course this flag is
622      * meaningless for surfaces without an alpha channel. By default
623      * surfaces are pre-multiplied, which means that each color component is
624      * already multiplied by its alpha value. In this case the blending
625      * equation used is:
626      * <p>
627      *    <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code>
628      * <p>
629      * By contrast, non pre-multiplied surfaces use the following equation:
630      * <p>
631      *    <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code>
632      * <p>
633      * pre-multiplied surfaces must always be used if transparent pixels are
634      * composited on top of each-other into the surface. A pre-multiplied
635      * surface can never lower the value of the alpha component of a given
636      * pixel.
637      * <p>
638      * In some rare situations, a non pre-multiplied surface is preferable.
639      * @hide
640      */
641     public static final int NON_PREMULTIPLIED = 0x00000100;
642 
643     /**
644      * Surface creation flag: Indicates that the surface must be considered opaque,
645      * even if its pixel format contains an alpha channel. This can be useful if an
646      * application needs full RGBA 8888 support for instance but will
647      * still draw every pixel opaque.
648      * <p>
649      * This flag is ignored if setAlpha() is used to make the surface non-opaque.
650      * Combined effects are (assuming a buffer format with an alpha channel):
651      * <ul>
652      * <li>OPAQUE + alpha(1.0) == opaque composition
653      * <li>OPAQUE + alpha(0.x) == blended composition
654      * <li>!OPAQUE + alpha(1.0) == blended composition
655      * <li>!OPAQUE + alpha(0.x) == blended composition
656      * </ul>
657      * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively
658      * set automatically.
659      * @hide
660      */
661     public static final int OPAQUE = 0x00000400;
662 
663     /**
664      * Surface creation flag: Application requires a hardware-protected path to an
665      * external display sink. If a hardware-protected path is not available,
666      * then this surface will not be displayed on the external sink.
667      *
668      * @hide
669      */
670     public static final int PROTECTED_APP = 0x00000800;
671 
672     // 0x1000 is reserved for an independent DRM protected flag in framework
673 
674     /**
675      * Surface creation flag: Window represents a cursor glyph.
676      * @hide
677      */
678     public static final int CURSOR_WINDOW = 0x00002000;
679 
680     /**
681      * Surface creation flag: Indicates the effect layer will not have a color fill on
682      * creation.
683      *
684      * @hide
685      */
686     public static final int NO_COLOR_FILL = 0x00004000;
687 
688     /**
689      * Surface creation flag: Creates a normal surface.
690      * This is the default.
691      *
692      * @hide
693      */
694     public static final int FX_SURFACE_NORMAL   = 0x00000000;
695 
696     /**
697      * Surface creation flag: Creates a effect surface which
698      * represents a solid color and or shadows.
699      *
700      * @hide
701      */
702     public static final int FX_SURFACE_EFFECT = 0x00020000;
703 
704     /**
705      * Surface creation flag: Creates a container surface.
706      * This surface will have no buffers and will only be used
707      * as a container for other surfaces, or for its InputInfo.
708      * @hide
709      */
710     public static final int FX_SURFACE_CONTAINER = 0x00080000;
711 
712     /**
713      * @hide
714      */
715     public static final int FX_SURFACE_BLAST = 0x00040000;
716 
717     /**
718      * Mask used for FX values above.
719      *
720      * @hide
721      */
722     public static final int FX_SURFACE_MASK = 0x000F0000;
723 
724     /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
725 
726     /**
727      * Surface flag: Hide the surface.
728      * Equivalent to calling hide().
729      * Updates the value set during Surface creation (see {@link #HIDDEN}).
730      */
731     private static final int SURFACE_HIDDEN = 0x01;
732 
733     /**
734      * Surface flag: composite without blending when possible.
735      * Updates the value set during Surface creation (see {@link #OPAQUE}).
736      */
737     private static final int SURFACE_OPAQUE = 0x02;
738 
739     /* flags used with setDisplayFlags() (keep in sync with DisplayDevice.h) */
740 
741     /**
742      * DisplayDevice flag: This display's transform is sent to inputflinger and used for input
743      * dispatch. This flag is used to disambiguate displays which share a layerstack.
744      * @hide
745      */
746     public static final int DISPLAY_RECEIVES_INPUT = 0x01;
747 
748     // Display power modes.
749     /**
750      * Display power mode off: used while blanking the screen.
751      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
752      * @hide
753      */
754     public static final int POWER_MODE_OFF = 0;
755 
756     /**
757      * Display power mode doze: used while putting the screen into low power mode.
758      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
759      * @hide
760      */
761     public static final int POWER_MODE_DOZE = 1;
762 
763     /**
764      * Display power mode normal: used while unblanking the screen.
765      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
766      * @hide
767      */
768     public static final int POWER_MODE_NORMAL = 2;
769 
770     /**
771      * Display power mode doze: used while putting the screen into a suspended
772      * low power mode.  Use only with {@link SurfaceControl#setDisplayPowerMode}.
773      * @hide
774      */
775     public static final int POWER_MODE_DOZE_SUSPEND = 3;
776 
777     /**
778      * Display power mode on: used while putting the screen into a suspended
779      * full power mode.  Use only with {@link SurfaceControl#setDisplayPowerMode}.
780      * @hide
781      */
782     public static final int POWER_MODE_ON_SUSPEND = 4;
783 
784     /**
785      * Hint that this SurfaceControl should not participate in layer caching within SurfaceFlinger.
786      *
787      * A system layer may request that a layer does not participate in caching when there are known
788      * quality limitations when caching via the compositor's GPU path.
789      * Use only with {@link SurfaceControl.Transaction#setCachingHint}.
790      * @hide
791      */
792     public static final int CACHING_DISABLED = 0;
793 
794     /**
795      * Hint that this SurfaceControl should participate in layer caching within SurfaceFlinger.
796      *
797      * Use only with {@link SurfaceControl.Transaction#setCachingHint}.
798      * @hide
799      */
800     public static final int CACHING_ENABLED = 1;
801 
802     /** @hide */
803     @IntDef(flag = true, value = {CACHING_DISABLED, CACHING_ENABLED})
804     @Retention(RetentionPolicy.SOURCE)
805     public @interface CachingHint {}
806 
assignNativeObject(long nativeObject, String callsite)807     private void assignNativeObject(long nativeObject, String callsite) {
808         if (mNativeObject != 0) {
809             release();
810         }
811         if (nativeObject != 0) {
812             mFreeNativeResources =
813                     sRegistry.registerNativeAllocation(this, nativeObject);
814         }
815         mNativeObject = nativeObject;
816         mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
817         if (sDebugUsageAfterRelease && mNativeObject == 0) {
818             mReleaseStack = new Throwable("Assigned invalid nativeObject");
819         } else {
820             mReleaseStack = null;
821         }
822         setUnreleasedWarningCallSite(callsite);
823         if (nativeObject != 0) {
824             // Only add valid surface controls to the registry. This is called at the end of this
825             // method since its information is dumped if the process threshold is reached.
826             SurfaceControlRegistry.getProcessInstance().add(this);
827         }
828     }
829 
830     /**
831      * @hide
832      */
copyFrom(@onNull SurfaceControl other, String callsite)833     public void copyFrom(@NonNull SurfaceControl other, String callsite) {
834         mName = other.mName;
835         mWidth = other.mWidth;
836         mHeight = other.mHeight;
837         mLocalOwnerView = other.mLocalOwnerView;
838         assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
839     }
840 
841     /**
842      * owner UID.
843      * @hide
844      */
845     public static final int METADATA_OWNER_UID = 1;
846 
847     /**
848      * Window type as per {@link WindowManager.LayoutParams}.
849      * @hide
850      */
851     public static final int METADATA_WINDOW_TYPE = 2;
852 
853     /**
854      * Task id to allow association between surfaces and task.
855      * @hide
856      */
857     public static final int METADATA_TASK_ID = 3;
858 
859     /**
860      * The style of mouse cursor and hotspot.
861      * @hide
862      */
863     public static final int METADATA_MOUSE_CURSOR = 4;
864 
865     /**
866      * Accessibility ID to allow association between surfaces and accessibility tree.
867      * @hide
868      */
869     public static final int METADATA_ACCESSIBILITY_ID = 5;
870 
871     /**
872      * owner PID.
873      * @hide
874      */
875     public static final int METADATA_OWNER_PID = 6;
876 
877     /**
878      * game mode for the layer - used for metrics
879      * @hide
880      */
881     public static final int METADATA_GAME_MODE = 8;
882 
883     /** @hide */
884     @Retention(RetentionPolicy.SOURCE)
885     @IntDef(prefix = {"FRAME_RATE_SELECTION_STRATEGY_"},
886             value = {FRAME_RATE_SELECTION_STRATEGY_PROPAGATE,
887                     FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN,
888                     FRAME_RATE_SELECTION_STRATEGY_SELF})
889     public @interface FrameRateSelectionStrategy {}
890 
891     // From window.h. Keep these in sync.
892     /**
893      * Default value. The layer uses its own frame rate specifications, assuming it has any
894      * specifications, instead of its parent's. If it does not have its own frame rate
895      * specifications, it will try to use its parent's. It will propagate its specifications to any
896      * descendants that do not have their own.
897      *
898      * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor layer
899      * supersedes this behavior, meaning that this layer will inherit frame rate specifications
900      * regardless of whether it has its own.
901      * @hide
902      */
903     public static final int FRAME_RATE_SELECTION_STRATEGY_PROPAGATE = 0;
904 
905     /**
906      * The layer's frame rate specifications will propagate to and override those of its descendant
907      * layers.
908      *
909      * The layer itself has the {@link #FRAME_RATE_SELECTION_STRATEGY_PROPAGATE} behavior.
910      * Thus, ancestor layer that also has the strategy
911      * {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} will override this layer's
912      * frame rate specifications.
913      * @hide
914      */
915     public static final int FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN = 1;
916 
917     /**
918      * The layer's frame rate specifications will not propagate to its descendant
919      * layers, even if the descendant layer has no frame rate specifications.
920      * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor
921      * layer supersedes this behavior.
922      * @hide
923      */
924     public static final int FRAME_RATE_SELECTION_STRATEGY_SELF = 2;
925 
926     /**
927      * Builder class for {@link SurfaceControl} objects.
928      *
929      * By default the surface will be hidden, and have "unset" bounds, meaning it can
930      * be as large as the bounds of its parent if a buffer or child so requires.
931      *
932      * It is necessary to set at least a name via {@link Builder#setName}
933      */
934     public static class Builder {
935         private SurfaceSession mSession;
936         private int mFlags = HIDDEN;
937         private int mWidth;
938         private int mHeight;
939         private int mFormat = PixelFormat.OPAQUE;
940         private String mName;
941         private WeakReference<View> mLocalOwnerView;
942         private SurfaceControl mParent;
943         private SparseIntArray mMetadata;
944         private String mCallsite = "SurfaceControl.Builder";
945 
946         /**
947          * Begin building a SurfaceControl with a given {@link SurfaceSession}.
948          *
949          * @param session The {@link SurfaceSession} with which to eventually construct the surface.
950          * @hide
951          */
Builder(SurfaceSession session)952         public Builder(SurfaceSession session) {
953             mSession = session;
954         }
955 
956         /**
957          * Begin building a SurfaceControl.
958          */
Builder()959         public Builder() {
960         }
961 
962         /**
963          * Construct a new {@link SurfaceControl} with the set parameters. The builder
964          * remains valid.
965          */
966         @NonNull
build()967         public SurfaceControl build() {
968             if (mWidth < 0 || mHeight < 0) {
969                 throw new IllegalStateException(
970                         "width and height must be positive or unset");
971             }
972             if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) {
973                 throw new IllegalStateException(
974                         "Only buffer layers can set a valid buffer size.");
975             }
976 
977             if (mName == null) {
978                 Log.w(TAG, "Missing name for SurfaceControl", new Throwable());
979             }
980 
981             if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
982                 setBLASTLayer();
983             }
984 
985             return new SurfaceControl(
986                     mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
987                     mLocalOwnerView, mCallsite);
988         }
989 
990         /**
991          * Set a debugging-name for the SurfaceControl.
992          *
993          * @param name A name to identify the Surface in debugging.
994          */
995         @NonNull
setName(@onNull String name)996         public Builder setName(@NonNull String name) {
997             mName = name;
998             return this;
999         }
1000 
1001         /**
1002          * Set the local owner view for the surface. This view is only
1003          * valid in the same process and is not transferred in an IPC.
1004          *
1005          * Note: This is used for cases where we want to know the view
1006          * that manages the surface control while intercepting reparenting.
1007          * A specific example is InlineContentView which exposes is surface
1008          * control for reparenting as a way to implement clipping of several
1009          * InlineContentView instances within a certain area.
1010          *
1011          * @param view The owner view.
1012          * @return This builder.
1013          *
1014          * @hide
1015          */
1016         @NonNull
setLocalOwnerView(@onNull View view)1017         public Builder setLocalOwnerView(@NonNull View view) {
1018             mLocalOwnerView = new WeakReference<>(view);
1019             return this;
1020         }
1021 
1022         /**
1023          * Set the initial size of the controlled surface's buffers in pixels.
1024          *
1025          * @param width The buffer width in pixels.
1026          * @param height The buffer height in pixels.
1027          */
1028         @NonNull
setBufferSize(@ntRangefrom = 0) int width, @IntRange(from = 0) int height)1029         public Builder setBufferSize(@IntRange(from = 0) int width,
1030                 @IntRange(from = 0) int height) {
1031             if (width < 0 || height < 0) {
1032                 throw new IllegalArgumentException(
1033                         "width and height must be positive");
1034             }
1035             mWidth = width;
1036             mHeight = height;
1037             // set this as a buffer layer since we are specifying a buffer size.
1038             return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK);
1039         }
1040 
unsetBufferSize()1041         private void unsetBufferSize() {
1042             mWidth = 0;
1043             mHeight = 0;
1044         }
1045 
1046         /**
1047          * Set the pixel format of the controlled surface's buffers, using constants from
1048          * {@link android.graphics.PixelFormat}.
1049          */
1050         @NonNull
setFormat(@ixelFormat.Format int format)1051         public Builder setFormat(@PixelFormat.Format int format) {
1052             mFormat = format;
1053             return this;
1054         }
1055 
1056         /**
1057          * Specify if the app requires a hardware-protected path to
1058          * an external display sync. If protected content is enabled, but
1059          * such a path is not available, then the controlled Surface will
1060          * not be displayed.
1061          *
1062          * @param protectedContent Whether to require a protected sink.
1063          * @hide
1064          */
1065         @NonNull
setProtected(boolean protectedContent)1066         public Builder setProtected(boolean protectedContent) {
1067             if (protectedContent) {
1068                 mFlags |= PROTECTED_APP;
1069             } else {
1070                 mFlags &= ~PROTECTED_APP;
1071             }
1072             return this;
1073         }
1074 
1075         /**
1076          * Specify whether the Surface contains secure content. If true, the system
1077          * will prevent the surfaces content from being copied by another process. In
1078          * particular screenshots and VNC servers will be disabled. This is however
1079          * not a complete prevention of readback as {@link #setProtected}.
1080          * @hide
1081          */
1082         @NonNull
setSecure(boolean secure)1083         public Builder setSecure(boolean secure) {
1084             if (secure) {
1085                 mFlags |= SECURE;
1086             } else {
1087                 mFlags &= ~SECURE;
1088             }
1089             return this;
1090         }
1091 
1092         /**
1093          * Indicates whether the surface must be considered opaque,
1094          * even if its pixel format is set to translucent. This can be useful if an
1095          * application needs full RGBA 8888 support for instance but will
1096          * still draw every pixel opaque.
1097          * <p>
1098          * This flag only determines whether opacity will be sampled from the alpha channel.
1099          * Plane-alpha from calls to setAlpha() can still result in blended composition
1100          * regardless of the opaque setting.
1101          *
1102          * Combined effects are (assuming a buffer format with an alpha channel):
1103          * <ul>
1104          * <li>OPAQUE + alpha(1.0) == opaque composition
1105          * <li>OPAQUE + alpha(0.x) == blended composition
1106          * <li>OPAQUE + alpha(0.0) == no composition
1107          * <li>!OPAQUE + alpha(1.0) == blended composition
1108          * <li>!OPAQUE + alpha(0.x) == blended composition
1109          * <li>!OPAQUE + alpha(0.0) == no composition
1110          * </ul>
1111          * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true)
1112          * were set automatically.
1113          * @param opaque Whether the Surface is OPAQUE.
1114          */
1115         @NonNull
setOpaque(boolean opaque)1116         public Builder setOpaque(boolean opaque) {
1117             if (opaque) {
1118                 mFlags |= OPAQUE;
1119             } else {
1120                 mFlags &= ~OPAQUE;
1121             }
1122             return this;
1123         }
1124 
1125         /**
1126          * Set the initial visibility for the SurfaceControl.
1127          *
1128          * @param hidden Whether the Surface is initially HIDDEN.
1129          */
1130         @NonNull
setHidden(boolean hidden)1131         public Builder setHidden(boolean hidden) {
1132             if (hidden) {
1133                 mFlags |= HIDDEN;
1134             } else {
1135                 mFlags &= ~HIDDEN;
1136             }
1137             return this;
1138         }
1139 
1140         /**
1141          * Set a parent surface for our new SurfaceControl.
1142          *
1143          * Child surfaces are constrained to the onscreen region of their parent.
1144          * Furthermore they stack relatively in Z order, and inherit the transformation
1145          * of the parent.
1146          *
1147          * @param parent The parent control.
1148          */
1149         @NonNull
setParent(@ullable SurfaceControl parent)1150         public Builder setParent(@Nullable SurfaceControl parent) {
1151             mParent = parent;
1152             return this;
1153         }
1154 
1155         /**
1156          * Sets a metadata int.
1157          *
1158          * @param key metadata key
1159          * @param data associated data
1160          * @hide
1161          */
setMetadata(int key, int data)1162         public Builder setMetadata(int key, int data) {
1163             if (mMetadata == null) {
1164                 mMetadata = new SparseIntArray();
1165             }
1166             mMetadata.put(key, data);
1167             return this;
1168         }
1169 
1170         /**
1171          * Indicate whether an 'EffectLayer' is to be constructed.
1172          *
1173          * An effect layer behaves like a container layer by default but it can support
1174          * color fill, shadows and/or blur. These layers will not have an associated buffer.
1175          * When created, this layer has no effects set and will be transparent but the caller
1176          * can render an effect by calling:
1177          *  - {@link Transaction#setColor(SurfaceControl, float[])}
1178          *  - {@link Transaction#setBackgroundBlurRadius(SurfaceControl, int)}
1179          *  - {@link Transaction#setShadowRadius(SurfaceControl, float)}
1180          *
1181          * @hide
1182          */
setEffectLayer()1183         public Builder setEffectLayer() {
1184             mFlags |= NO_COLOR_FILL;
1185             unsetBufferSize();
1186             return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK);
1187         }
1188 
1189         /**
1190          * A convenience function to create an effect layer with a default color fill
1191          * applied to it. Currently that color is black.
1192          *
1193          * @hide
1194          */
setColorLayer()1195         public Builder setColorLayer() {
1196             unsetBufferSize();
1197             return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK);
1198         }
1199 
isEffectLayer()1200         private boolean isEffectLayer() {
1201             return  (mFlags & FX_SURFACE_EFFECT) == FX_SURFACE_EFFECT;
1202         }
1203 
1204         /**
1205          * @hide
1206          */
setBLASTLayer()1207         public Builder setBLASTLayer() {
1208             return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK);
1209         }
1210 
1211         /**
1212          * Indicates whether a 'ContainerLayer' is to be constructed.
1213          *
1214          * Container layers will not be rendered in any fashion and instead are used
1215          * as a parent of renderable layers.
1216          *
1217          * @hide
1218          */
setContainerLayer()1219         public Builder setContainerLayer() {
1220             unsetBufferSize();
1221             return setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK);
1222         }
1223 
isContainerLayer()1224         private boolean isContainerLayer() {
1225             return  (mFlags & FX_SURFACE_CONTAINER) == FX_SURFACE_CONTAINER;
1226         }
1227 
1228         /**
1229          * Set 'Surface creation flags' such as {@link #HIDDEN}, {@link #SECURE}.
1230          *
1231          * TODO: Finish conversion to individual builder methods?
1232          * @param flags The combined flags
1233          * @hide
1234          */
setFlags(int flags)1235         public Builder setFlags(int flags) {
1236             mFlags = flags;
1237             return this;
1238         }
1239 
1240         /**
1241          * Sets the callsite this SurfaceControl is constructed from.
1242          *
1243          * @param callsite String uniquely identifying callsite that created this object. Used for
1244          *                 leakage tracking.
1245          * @hide
1246          */
setCallsite(String callsite)1247         public Builder setCallsite(String callsite) {
1248             mCallsite = callsite;
1249             return this;
1250         }
1251 
setFlags(int flags, int mask)1252         private Builder setFlags(int flags, int mask) {
1253             mFlags = (mFlags & ~mask) | flags;
1254             return this;
1255         }
1256     }
1257 
1258     /**
1259      * Create a surface with a name.
1260      * <p>
1261      * The surface creation flags specify what kind of surface to create and
1262      * certain options such as whether the surface can be assumed to be opaque
1263      * and whether it should be initially hidden.  Surfaces should always be
1264      * created with the {@link #HIDDEN} flag set to ensure that they are not
1265      * made visible prematurely before all of the surface's properties have been
1266      * configured.
1267      * <p>
1268      * Good practice is to first create the surface with the {@link #HIDDEN} flag
1269      * specified, open a transaction, set the surface layer, layer stack, alpha,
1270      * and position, call {@link Transaction#show(SurfaceControl)} if appropriate, and close the
1271      * transaction.
1272      * <p>
1273      * Bounds of the surface is determined by its crop and its buffer size. If the
1274      * surface has no buffer or crop, the surface is boundless and only constrained
1275      * by the size of its parent bounds.
1276      *
1277      * @param session  The surface session.
1278      * @param name     The surface name, must not be null.
1279      * @param w        The surface initial width.
1280      * @param h        The surface initial height.
1281      * @param flags    The surface creation flags.
1282      * @param metadata Initial metadata.
1283      * @param callsite String uniquely identifying callsite that created this object. Used for
1284      *                 leakage tracking.
1285      * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
1286      */
SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView, String callsite)1287     private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
1288             SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
1289             String callsite)
1290                     throws OutOfResourcesException, IllegalArgumentException {
1291         if (name == null) {
1292             throw new IllegalArgumentException("name must not be null");
1293         }
1294 
1295         mName = name;
1296         mWidth = w;
1297         mHeight = h;
1298         mLocalOwnerView = localOwnerView;
1299         Parcel metaParcel = Parcel.obtain();
1300         long nativeObject = 0;
1301         try {
1302             if (metadata != null && metadata.size() > 0) {
1303                 metaParcel.writeInt(metadata.size());
1304                 for (int i = 0; i < metadata.size(); ++i) {
1305                     metaParcel.writeInt(metadata.keyAt(i));
1306                     metaParcel.writeByteArray(
1307                             ByteBuffer.allocate(4).order(ByteOrder.nativeOrder())
1308                                     .putInt(metadata.valueAt(i)).array());
1309                 }
1310                 metaParcel.setDataPosition(0);
1311             }
1312             nativeObject = nativeCreate(session, name, w, h, format, flags,
1313                     parent != null ? parent.mNativeObject : 0, metaParcel);
1314         } finally {
1315             metaParcel.recycle();
1316         }
1317         if (nativeObject == 0) {
1318             throw new OutOfResourcesException(
1319                     "Couldn't allocate SurfaceControl native object");
1320         }
1321         assignNativeObject(nativeObject, callsite);
1322     }
1323 
1324     /**
1325      * Copy constructor. Creates a new native object pointing to the same surface as {@code other}.
1326      *
1327      * @param other The object to copy the surface from.
1328      * @param callsite String uniquely identifying callsite that created this object. Used for
1329      *                 leakage tracking.
1330      * @hide
1331      */
1332     @TestApi
SurfaceControl(@onNull SurfaceControl other, @NonNull String callsite)1333     public SurfaceControl(@NonNull SurfaceControl other, @NonNull String callsite) {
1334         copyFrom(other, callsite);
1335     }
1336 
SurfaceControl(Parcel in)1337     private SurfaceControl(Parcel in) {
1338         readFromParcel(in);
1339     }
1340 
1341     /**
1342      * Note: Most callers should use {@link SurfaceControl.Builder} or one of the other constructors
1343      *       to build an instance of a SurfaceControl. This constructor is mainly used for
1344      *       unparceling and passing into an AIDL call as an out parameter.
1345      * @hide
1346      */
SurfaceControl()1347     public SurfaceControl() {
1348     }
1349 
readFromParcel(Parcel in)1350     public void readFromParcel(Parcel in) {
1351         if (in == null) {
1352             throw new IllegalArgumentException("source must not be null");
1353         }
1354 
1355         mName = in.readString8();
1356         mWidth = in.readInt();
1357         mHeight = in.readInt();
1358 
1359         long object = 0;
1360         if (in.readInt() != 0) {
1361             object = nativeReadFromParcel(in);
1362         }
1363         assignNativeObject(object, "readFromParcel");
1364     }
1365 
1366     @Override
describeContents()1367     public int describeContents() {
1368         return 0;
1369     }
1370 
1371     @Override
writeToParcel(Parcel dest, int flags)1372     public void writeToParcel(Parcel dest, int flags) {
1373         if (sDebugUsageAfterRelease) {
1374             checkNotReleased();
1375         }
1376         dest.writeString8(mName);
1377         dest.writeInt(mWidth);
1378         dest.writeInt(mHeight);
1379         if (mNativeObject == 0) {
1380             dest.writeInt(0);
1381         } else {
1382             dest.writeInt(1);
1383         }
1384         nativeWriteToParcel(mNativeObject, dest);
1385 
1386         if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
1387             release();
1388         }
1389     }
1390 
1391     /**
1392      * Enables additional debug logs to track usage-after-release of all SurfaceControls in this
1393      * process.
1394      * @hide
1395      */
setDebugUsageAfterRelease(boolean debug)1396     public static void setDebugUsageAfterRelease(boolean debug) {
1397         if (!Build.isDebuggable()) {
1398             return;
1399         }
1400         sDebugUsageAfterRelease = debug;
1401     }
1402 
1403     /**
1404      * Provides more information to show about the source of this SurfaceControl if it is finalized
1405      * without being released. This is primarily intended for callers to update the call site after
1406      * receiving a SurfaceControl from another process, which would otherwise get a generic default
1407      * call site.
1408      * @hide
1409      */
setUnreleasedWarningCallSite(@onNull String callsite)1410     public void setUnreleasedWarningCallSite(@NonNull String callsite) {
1411         if (!isValid()) {
1412             return;
1413         }
1414         mCloseGuard.openWithCallSite("release", callsite);
1415         mCallsite = callsite;
1416     }
1417 
1418     /**
1419      * Returns the last provided call site when this SurfaceControl was created.
1420      * @hide
1421      */
getCallsite()1422     @Nullable String getCallsite() {
1423         return mCallsite;
1424     }
1425 
1426     /**
1427      * Returns the name of this SurfaceControl, mainly for debugging purposes.
1428      * @hide
1429      */
getName()1430     @NonNull String getName() {
1431         return mName;
1432     }
1433 
1434     /**
1435      * Checks whether two {@link SurfaceControl} objects represent the same surface.
1436      *
1437      * @param other The other object to check
1438      * @return {@code true} if these two {@link SurfaceControl} objects represent the same surface.
1439      * @hide
1440      */
1441     @TestApi
isSameSurface(@onNull SurfaceControl other)1442     public boolean isSameSurface(@NonNull SurfaceControl other) {
1443         return other.mNativeHandle == mNativeHandle;
1444     }
1445 
1446     /**
1447      * When called for the first time a new instance of the {@link Choreographer} is created
1448      * with a {@link android.os.Looper} of the current thread. Every subsequent call will return
1449      * the same instance of the Choreographer.
1450      *
1451      * @see #getChoreographer(Looper) to create Choreographer with a different
1452      * looper than current thread looper.
1453      *
1454      * @hide
1455      */
1456     @TestApi
getChoreographer()1457     public @NonNull Choreographer getChoreographer() {
1458         checkNotReleased();
1459         synchronized (mChoreographerLock) {
1460             if (mChoreographer == null) {
1461                 return getChoreographer(Looper.myLooper());
1462             }
1463             return mChoreographer;
1464         }
1465     }
1466 
1467     /**
1468      * When called for the first time a new instance of the {@link Choreographer} is created with
1469      * the sourced {@link android.os.Looper}. Every subsequent call will return the same
1470      * instance of the Choreographer.
1471      *
1472      * @see #getChoreographer()
1473      *
1474      * @throws IllegalStateException when a {@link Choreographer} instance exists with a different
1475      * looper than sourced.
1476      * @param looper the choreographer is attached on this looper.
1477      *
1478      * @hide
1479      */
1480     @TestApi
getChoreographer(@onNull Looper looper)1481     public @NonNull Choreographer getChoreographer(@NonNull Looper looper) {
1482         checkNotReleased();
1483         synchronized (mChoreographerLock) {
1484             if (mChoreographer == null) {
1485                 mChoreographer = Choreographer.getInstanceForSurfaceControl(mNativeHandle, looper);
1486             } else if (!mChoreographer.isTheLooperSame(looper)) {
1487                 throw new IllegalStateException(
1488                         "Choreographer already exists with a different looper");
1489             }
1490             return mChoreographer;
1491         }
1492     }
1493 
1494     /**
1495      * Returns true if {@link Choreographer} is present otherwise false.
1496      * To check the validity use {@link #isValid} on the SurfaceControl, a valid SurfaceControl with
1497      * choreographer will have the valid Choreographer.
1498      *
1499      * @hide
1500      */
1501     @TestApi
1502     @UnsupportedAppUsage
hasChoreographer()1503     public boolean hasChoreographer() {
1504         synchronized (mChoreographerLock) {
1505             return mChoreographer != null;
1506         }
1507     }
1508 
1509     /**
1510      * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
1511      * android.view.SurfaceControlProto}.
1512      *
1513      * @param proto Stream to write the SurfaceControl object to.
1514      * @param fieldId Field Id of the SurfaceControl as defined in the parent message.
1515      * @hide
1516      */
dumpDebug(ProtoOutputStream proto, long fieldId)1517     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
1518         final long token = proto.start(fieldId);
1519         proto.write(HASH_CODE, System.identityHashCode(this));
1520         proto.write(NAME, mName);
1521         proto.write(LAYER_ID, getLayerId());
1522         proto.end(token);
1523     }
1524 
1525     public static final @android.annotation.NonNull Creator<SurfaceControl> CREATOR
1526             = new Creator<SurfaceControl>() {
1527         public SurfaceControl createFromParcel(Parcel in) {
1528             return new SurfaceControl(in);
1529         }
1530 
1531         public SurfaceControl[] newArray(int size) {
1532             return new SurfaceControl[size];
1533         }
1534     };
1535 
1536     /**
1537      * @hide
1538      */
1539     @Override
finalize()1540     protected void finalize() throws Throwable {
1541         try {
1542             if (mCloseGuard != null) {
1543                 mCloseGuard.warnIfOpen();
1544             }
1545             SurfaceControlRegistry.getProcessInstance().remove(this);
1546         } finally {
1547             super.finalize();
1548         }
1549     }
1550 
1551     /**
1552      * Release the local reference to the server-side surface. The surface
1553      * may continue to exist on-screen as long as its parent continues
1554      * to exist. To explicitly remove a surface from the screen use
1555      * {@link Transaction#reparent} with a null-parent. After release,
1556      * {@link #isValid} will return false and other methods will throw
1557      * an exception.
1558      *
1559      * Always call release() when you're done with a SurfaceControl.
1560      */
release()1561     public void release() {
1562         if (mNativeObject != 0) {
1563             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
1564                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
1565                         "release", null, this, null);
1566             }
1567             mFreeNativeResources.run();
1568             mNativeObject = 0;
1569             mNativeHandle = 0;
1570             if (sDebugUsageAfterRelease) {
1571                 mReleaseStack = new Throwable("Released");
1572             }
1573             mCloseGuard.close();
1574             synchronized (mChoreographerLock) {
1575                 if (mChoreographer != null) {
1576                     mChoreographer.invalidate();
1577                     mChoreographer = null;
1578                 }
1579             }
1580             SurfaceControlRegistry.getProcessInstance().remove(this);
1581         }
1582     }
1583 
1584     /**
1585      * Disconnect any client still connected to the surface.
1586      * @hide
1587      */
disconnect()1588     public void disconnect() {
1589         if (mNativeObject != 0) {
1590             nativeDisconnect(mNativeObject);
1591         }
1592     }
1593 
checkNotReleased()1594     private void checkNotReleased() {
1595         if (mNativeObject == 0) {
1596             if (mReleaseStack != null) {
1597                 throw new IllegalStateException("Invalid usage after release of " + this,
1598                         mReleaseStack);
1599             } else {
1600                 throw new NullPointerException("mNativeObject of " + this
1601                         + " is null. Have you called release() already?");
1602             }
1603         }
1604     }
1605 
1606     /**
1607      * Check whether this instance points to a valid layer with the system-compositor. For
1608      * example this may be false if construction failed, or the layer was released
1609      * ({@link #release}).
1610      *
1611      * @return Whether this SurfaceControl is valid.
1612      */
isValid()1613     public boolean isValid() {
1614         return mNativeObject != 0;
1615     }
1616 
1617     /** start a transaction
1618      * @hide
1619      * @deprecated Use regular Transaction instead.
1620      */
1621     @Deprecated
1622     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.VANILLA_ICE_CREAM,
1623             publicAlternatives = "Use {@code SurfaceControl.Transaction} instead",
1624             trackingBug = 247078497)
openTransaction()1625     public static void openTransaction() {
1626         // TODO(b/247078497): It was used for global transaction (all usages are removed).
1627         //  Keep the method declaration to avoid breaking reference from legacy access.
1628     }
1629 
1630     /** end a transaction
1631      * @hide
1632      * @deprecated Use regular Transaction instead.
1633      */
1634     @Deprecated
1635     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.VANILLA_ICE_CREAM,
1636             publicAlternatives = "Use {@code SurfaceControl.Transaction} instead",
1637             trackingBug = 247078497)
closeTransaction()1638     public static void closeTransaction() {
1639         // TODO(b/247078497): It was used for global transaction (all usages are removed).
1640         //  Keep the method declaration to avoid breaking reference from legacy access.
1641     }
1642 
1643     /**
1644      * @hide
1645      */
clearContentFrameStats()1646     public boolean clearContentFrameStats() {
1647         checkNotReleased();
1648         return nativeClearContentFrameStats(mNativeObject);
1649     }
1650 
1651     /**
1652      * @hide
1653      */
getContentFrameStats(WindowContentFrameStats outStats)1654     public boolean getContentFrameStats(WindowContentFrameStats outStats) {
1655         checkNotReleased();
1656         return nativeGetContentFrameStats(mNativeObject, outStats);
1657     }
1658 
1659     /**
1660      * @hide
1661      */
clearAnimationFrameStats()1662     public static boolean clearAnimationFrameStats() {
1663         return nativeClearAnimationFrameStats();
1664     }
1665 
1666     /**
1667      * @hide
1668      */
getAnimationFrameStats(WindowAnimationFrameStats outStats)1669     public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) {
1670         return nativeGetAnimationFrameStats(outStats);
1671     }
1672 
1673     /**
1674      * @hide
1675      */
getWidth()1676     public int getWidth() {
1677         synchronized (mLock) {
1678             return mWidth;
1679         }
1680     }
1681 
1682     /**
1683      * @hide
1684      */
getHeight()1685     public int getHeight() {
1686         synchronized (mLock) {
1687             return mHeight;
1688         }
1689     }
1690 
1691     /**
1692      * Gets the local view that owns this surface.
1693      *
1694      * @return The owner view.
1695      *
1696      * @hide
1697      */
getLocalOwnerView()1698     public @Nullable View getLocalOwnerView() {
1699         return (mLocalOwnerView != null) ? mLocalOwnerView.get() : null;
1700     }
1701 
1702     @Override
toString()1703     public String toString() {
1704         return "Surface(name=" + mName + ")/@0x" +
1705                 Integer.toHexString(System.identityHashCode(this));
1706     }
1707 
1708     /**
1709      * Immutable information about physical display.
1710      *
1711      * @hide
1712      */
1713     public static final class StaticDisplayInfo {
1714         public boolean isInternal;
1715         public float density;
1716         public boolean secure;
1717         public DeviceProductInfo deviceProductInfo;
1718         public @Surface.Rotation int installOrientation;
1719 
1720         @Override
toString()1721         public String toString() {
1722             return "StaticDisplayInfo{isInternal=" + isInternal
1723                     + ", density=" + density
1724                     + ", secure=" + secure
1725                     + ", deviceProductInfo=" + deviceProductInfo
1726                     + ", installOrientation=" + installOrientation + "}";
1727         }
1728 
1729         @Override
equals(@ullable Object o)1730         public boolean equals(@Nullable Object o) {
1731             if (this == o) return true;
1732             if (o == null || getClass() != o.getClass()) return false;
1733             StaticDisplayInfo that = (StaticDisplayInfo) o;
1734             return isInternal == that.isInternal
1735                     && density == that.density
1736                     && secure == that.secure
1737                     && Objects.equals(deviceProductInfo, that.deviceProductInfo)
1738                     && installOrientation == that.installOrientation;
1739         }
1740 
1741         @Override
hashCode()1742         public int hashCode() {
1743             return Objects.hash(isInternal, density, secure, deviceProductInfo, installOrientation);
1744         }
1745     }
1746 
1747     /**
1748      * Dynamic information about physical display.
1749      *
1750      * @hide
1751      */
1752     public static final class DynamicDisplayInfo {
1753         public DisplayMode[] supportedDisplayModes;
1754         public int activeDisplayModeId;
1755         public float renderFrameRate;
1756 
1757         public int[] supportedColorModes;
1758         public int activeColorMode;
1759 
1760         public Display.HdrCapabilities hdrCapabilities;
1761 
1762         public boolean autoLowLatencyModeSupported;
1763         public boolean gameContentTypeSupported;
1764 
1765         public int preferredBootDisplayMode;
1766 
1767         @Override
toString()1768         public String toString() {
1769             return "DynamicDisplayInfo{"
1770                     + "supportedDisplayModes=" + Arrays.toString(supportedDisplayModes)
1771                     + ", activeDisplayModeId=" + activeDisplayModeId
1772                     + ", renderFrameRate=" + renderFrameRate
1773                     + ", supportedColorModes=" + Arrays.toString(supportedColorModes)
1774                     + ", activeColorMode=" + activeColorMode
1775                     + ", hdrCapabilities=" + hdrCapabilities
1776                     + ", autoLowLatencyModeSupported=" + autoLowLatencyModeSupported
1777                     + ", gameContentTypeSupported" + gameContentTypeSupported
1778                     + ", preferredBootDisplayMode" + preferredBootDisplayMode + "}";
1779         }
1780 
1781         @Override
equals(@ullable Object o)1782         public boolean equals(@Nullable Object o) {
1783             if (this == o) return true;
1784             if (o == null || getClass() != o.getClass()) return false;
1785             DynamicDisplayInfo that = (DynamicDisplayInfo) o;
1786             return Arrays.equals(supportedDisplayModes, that.supportedDisplayModes)
1787                 && activeDisplayModeId == that.activeDisplayModeId
1788                 && renderFrameRate == that.renderFrameRate
1789                 && Arrays.equals(supportedColorModes, that.supportedColorModes)
1790                 && activeColorMode == that.activeColorMode
1791                 && Objects.equals(hdrCapabilities, that.hdrCapabilities)
1792                 && preferredBootDisplayMode == that.preferredBootDisplayMode;
1793         }
1794 
1795         @Override
hashCode()1796         public int hashCode() {
1797             return Objects.hash(Arrays.hashCode(supportedDisplayModes), activeDisplayModeId,
1798                     renderFrameRate, activeColorMode, hdrCapabilities);
1799         }
1800     }
1801 
1802     /**
1803      * Configuration supported by physical display.
1804      *
1805      * @hide
1806      */
1807     public static final class DisplayMode {
1808         public int id;
1809         public int width;
1810         public int height;
1811         public float xDpi;
1812         public float yDpi;
1813 
1814         // Some modes have peak refresh rate lower than the panel vsync rate.
1815         public float peakRefreshRate;
1816         // Fixed rate of vsync deadlines for the panel.
1817         // This can be higher then the peak refresh rate for some panel technologies
1818         // See: VrrConfig.aidl
1819         public float vsyncRate;
1820         public long appVsyncOffsetNanos;
1821         public long presentationDeadlineNanos;
1822         public int[] supportedHdrTypes;
1823 
1824         /**
1825          * The config group ID this config is associated to.
1826          * Configs in the same group are similar from vendor's perspective and switching between
1827          * configs within the same group can be done seamlessly in most cases.
1828          * @see: android.hardware.graphics.composer@2.4::IComposerClient::Attribute::CONFIG_GROUP
1829          */
1830         public int group;
1831 
1832         @Override
toString()1833         public String toString() {
1834             return "DisplayMode{id=" + id
1835                     + ", width=" + width
1836                     + ", height=" + height
1837                     + ", xDpi=" + xDpi
1838                     + ", yDpi=" + yDpi
1839                     + ", peakRefreshRate=" + peakRefreshRate
1840                     + ", vsyncRate=" + vsyncRate
1841                     + ", appVsyncOffsetNanos=" + appVsyncOffsetNanos
1842                     + ", presentationDeadlineNanos=" + presentationDeadlineNanos
1843                     + ", supportedHdrTypes=" + Arrays.toString(supportedHdrTypes)
1844                     + ", group=" + group + "}";
1845         }
1846 
1847         @Override
equals(Object o)1848         public boolean equals(Object o) {
1849             if (this == o) return true;
1850             if (o == null || getClass() != o.getClass()) return false;
1851             DisplayMode that = (DisplayMode) o;
1852             return id == that.id
1853                     && width == that.width
1854                     && height == that.height
1855                     && Float.compare(that.xDpi, xDpi) == 0
1856                     && Float.compare(that.yDpi, yDpi) == 0
1857                     && Float.compare(that.peakRefreshRate, peakRefreshRate) == 0
1858                     && Float.compare(that.vsyncRate, vsyncRate) == 0
1859                     && appVsyncOffsetNanos == that.appVsyncOffsetNanos
1860                     && presentationDeadlineNanos == that.presentationDeadlineNanos
1861                     && Arrays.equals(supportedHdrTypes, that.supportedHdrTypes)
1862                     && group == that.group;
1863         }
1864 
1865         @Override
hashCode()1866         public int hashCode() {
1867             return Objects.hash(id, width, height, xDpi, yDpi, peakRefreshRate, vsyncRate,
1868                     appVsyncOffsetNanos, presentationDeadlineNanos, group,
1869                     Arrays.hashCode(supportedHdrTypes));
1870         }
1871     }
1872 
1873     /**
1874      * @hide
1875      */
setDisplayPowerMode(IBinder displayToken, int mode)1876     public static void setDisplayPowerMode(IBinder displayToken, int mode) {
1877         if (displayToken == null) {
1878             throw new IllegalArgumentException("displayToken must not be null");
1879         }
1880         nativeSetDisplayPowerMode(displayToken, mode);
1881     }
1882 
1883     /**
1884      * @hide
1885      */
getStaticDisplayInfo(long displayId)1886     public static StaticDisplayInfo getStaticDisplayInfo(long displayId) {
1887         return nativeGetStaticDisplayInfo(displayId);
1888     }
1889 
1890     /**
1891      * @hide
1892      */
getDynamicDisplayInfo(long displayId)1893     public static DynamicDisplayInfo getDynamicDisplayInfo(long displayId) {
1894         return nativeGetDynamicDisplayInfo(displayId);
1895     }
1896 
1897     /**
1898      * @hide
1899      */
getDisplayedContentSamplingAttributes( IBinder displayToken)1900     public static DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes(
1901             IBinder displayToken) {
1902         if (displayToken == null) {
1903             throw new IllegalArgumentException("displayToken must not be null");
1904         }
1905         return nativeGetDisplayedContentSamplingAttributes(displayToken);
1906     }
1907 
1908     /**
1909      * @hide
1910      */
setDisplayedContentSamplingEnabled( IBinder displayToken, boolean enable, int componentMask, int maxFrames)1911     public static boolean setDisplayedContentSamplingEnabled(
1912             IBinder displayToken, boolean enable, int componentMask, int maxFrames) {
1913         if (displayToken == null) {
1914             throw new IllegalArgumentException("displayToken must not be null");
1915         }
1916         final int maxColorComponents = 4;
1917         if ((componentMask >> maxColorComponents) != 0) {
1918             throw new IllegalArgumentException("invalid componentMask when enabling sampling");
1919         }
1920         return nativeSetDisplayedContentSamplingEnabled(
1921                 displayToken, enable, componentMask, maxFrames);
1922     }
1923 
1924     /**
1925      * @hide
1926      */
getDisplayedContentSample( IBinder displayToken, long maxFrames, long timestamp)1927     public static DisplayedContentSample getDisplayedContentSample(
1928             IBinder displayToken, long maxFrames, long timestamp) {
1929         if (displayToken == null) {
1930             throw new IllegalArgumentException("displayToken must not be null");
1931         }
1932         return nativeGetDisplayedContentSample(displayToken, maxFrames, timestamp);
1933     }
1934 
1935     /**
1936      * Information about the min and max refresh rate DM would like to set the display to.
1937      * @hide
1938      */
1939     public static final class RefreshRateRange implements Parcelable {
1940         public static final String TAG = "RefreshRateRange";
1941 
1942         // The tolerance within which we consider something approximately equals.
1943         public static final float FLOAT_TOLERANCE = 0.01f;
1944 
1945         /**
1946          * The lowest desired refresh rate.
1947          */
1948         public float min;
1949 
1950         /**
1951          * The highest desired refresh rate.
1952          */
1953         public float max;
1954 
RefreshRateRange()1955         public RefreshRateRange() {}
1956 
RefreshRateRange(float min, float max)1957         public RefreshRateRange(float min, float max) {
1958             if (min < 0 || max < 0 || min > max + FLOAT_TOLERANCE) {
1959                 Slog.e(TAG, "Wrong values for min and max when initializing RefreshRateRange : "
1960                         + min + " " + max);
1961                 this.min = this.max = 0;
1962                 return;
1963             }
1964             if (min > max) {
1965                 // Min and max are within epsilon of each other, but in the wrong order.
1966                 float t = min;
1967                 min = max;
1968                 max = t;
1969             }
1970             this.min = min;
1971             this.max = max;
1972         }
1973 
1974         /**
1975          * Checks whether the two objects have the same values.
1976          */
1977         @Override
equals(Object other)1978         public boolean equals(Object other) {
1979             if (other == this) {
1980                 return true;
1981             }
1982 
1983             if (!(other instanceof RefreshRateRange)) {
1984                 return false;
1985             }
1986 
1987             RefreshRateRange refreshRateRange = (RefreshRateRange) other;
1988             return (min == refreshRateRange.min && max == refreshRateRange.max);
1989         }
1990 
1991         @Override
hashCode()1992         public int hashCode() {
1993             return Objects.hash(min, max);
1994         }
1995 
1996         @Override
toString()1997         public String toString() {
1998             return "(" + min + " " + max + ")";
1999         }
2000 
2001         /**
2002          * Copies the supplied object's values to this object.
2003          */
copyFrom(RefreshRateRange other)2004         public void copyFrom(RefreshRateRange other) {
2005             this.min = other.min;
2006             this.max = other.max;
2007         }
2008 
2009         /**
2010          * Writes the RefreshRateRange to parce
2011          *
2012          * @param dest parcel to write the transaction to
2013          */
2014         @Override
writeToParcel(@onNull Parcel dest, @WriteFlags int flags)2015         public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
2016             dest.writeFloat(min);
2017             dest.writeFloat(max);
2018         }
2019 
2020         @Override
describeContents()2021         public int describeContents() {
2022             return 0;
2023         }
2024 
2025         public static final @NonNull Creator<RefreshRateRange> CREATOR =
2026                 new Creator<RefreshRateRange>() {
2027                     @Override
2028                     public RefreshRateRange createFromParcel(Parcel in) {
2029                         return new RefreshRateRange(in.readFloat(), in.readFloat());
2030                     }
2031 
2032                     @Override
2033                     public RefreshRateRange[] newArray(int size) {
2034                         return new RefreshRateRange[size];
2035                     }
2036                 };
2037     }
2038 
2039     /**
2040      * Information about the ranges of refresh rates for the display physical refresh rates and the
2041      * render frame rate DM would like to set the policy to.
2042      * @hide
2043      */
2044     public static final class RefreshRateRanges {
2045         public static final String TAG = "RefreshRateRanges";
2046 
2047         /**
2048          *  The range of refresh rates that the display should run at.
2049          */
2050         public final RefreshRateRange physical;
2051 
2052         /**
2053          *  The range of refresh rates that apps should render at.
2054          */
2055         public final RefreshRateRange render;
2056 
RefreshRateRanges()2057         public RefreshRateRanges() {
2058             physical = new RefreshRateRange();
2059             render = new RefreshRateRange();
2060         }
2061 
RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render)2062         public RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render) {
2063             this.physical = new RefreshRateRange(physical.min, physical.max);
2064             this.render = new RefreshRateRange(render.min, render.max);
2065         }
2066 
2067         /**
2068          * Checks whether the two objects have the same values.
2069          */
2070         @Override
equals(Object other)2071         public boolean equals(Object other) {
2072             if (other == this) {
2073                 return true;
2074             }
2075 
2076             if (!(other instanceof RefreshRateRanges)) {
2077                 return false;
2078             }
2079 
2080             RefreshRateRanges rates = (RefreshRateRanges) other;
2081             return physical.equals(rates.physical) && render.equals(
2082                     rates.render);
2083         }
2084 
2085         @Override
hashCode()2086         public int hashCode() {
2087             return Objects.hash(physical, render);
2088         }
2089 
2090         @Override
toString()2091         public String toString() {
2092             return "physical: " + physical + " render:  " + render;
2093         }
2094 
2095         /**
2096          * Copies the supplied object's values to this object.
2097          */
copyFrom(RefreshRateRanges other)2098         public void copyFrom(RefreshRateRanges other) {
2099             this.physical.copyFrom(other.physical);
2100             this.render.copyFrom(other.render);
2101         }
2102     }
2103 
2104     /**
2105      * Contains information of the idle time of the screen after which the refresh rate is to be
2106      * reduced.
2107      *
2108      * @hide
2109      */
2110     public static final class IdleScreenRefreshRateConfig {
2111         /**
2112          *  The time(in ms) after which the refresh rate is to be reduced. Defaults to -1, which
2113          *  means no timeout has been configured for the current conditions
2114          */
2115         public int timeoutMillis;
2116 
IdleScreenRefreshRateConfig()2117         public IdleScreenRefreshRateConfig() {
2118             timeoutMillis = -1;
2119         }
2120 
IdleScreenRefreshRateConfig(int timeoutMillis)2121         public IdleScreenRefreshRateConfig(int timeoutMillis) {
2122             this.timeoutMillis = timeoutMillis;
2123         }
2124 
2125         /**
2126          * Checks whether the two objects have the same values.
2127          */
2128         @Override
equals(Object other)2129         public boolean equals(Object other) {
2130             if (other == this) {
2131                 return true;
2132             }
2133 
2134             if (!(other instanceof IdleScreenRefreshRateConfig) || other == null) {
2135                 return false;
2136             }
2137 
2138             IdleScreenRefreshRateConfig
2139                     idleScreenRefreshRateConfig = (IdleScreenRefreshRateConfig) other;
2140             return timeoutMillis == idleScreenRefreshRateConfig.timeoutMillis;
2141         }
2142 
2143         @Override
hashCode()2144         public int hashCode() {
2145             return Objects.hash(timeoutMillis);
2146         }
2147 
2148         @Override
toString()2149         public String toString() {
2150             return "timeoutMillis: " + timeoutMillis;
2151         }
2152 
2153         /**
2154          * Copies the supplied object's values to this object.
2155          */
copyFrom(IdleScreenRefreshRateConfig other)2156         public void copyFrom(IdleScreenRefreshRateConfig other) {
2157             if (other != null) {
2158                 this.timeoutMillis = other.timeoutMillis;
2159             }
2160         }
2161     }
2162 
2163 
2164     /**
2165      * Contains information about desired display configuration.
2166      *
2167      * @hide
2168      */
2169     public static final class DesiredDisplayModeSpecs {
2170         public int defaultMode;
2171         /**
2172          * If true this will allow switching between modes in different display configuration
2173          * groups. This way the user may see visual interruptions when the display mode changes.
2174          */
2175         public boolean allowGroupSwitching;
2176 
2177         /**
2178          * The primary physical and render refresh rate ranges represent display manager's general
2179          * guidance on the display configs surface flinger will consider when switching refresh
2180          * rates and scheduling the frame rate. Unless surface flinger has a specific reason to do
2181          * otherwise, it will stay within this range.
2182          */
2183         public final RefreshRateRanges primaryRanges;
2184 
2185         /**
2186          * The app request physical and render refresh rate ranges allow surface flinger to consider
2187          * more display configs when switching refresh rates. Although surface flinger will
2188          * generally stay within the primary range, specific considerations, such as layer frame
2189          * rate settings specified via the setFrameRate() api, may cause surface flinger to go
2190          * outside the primary range. Surface flinger never goes outside the app request range.
2191          * The app request range will be greater than or equal to the primary refresh rate range,
2192          * never smaller.
2193          */
2194         public final RefreshRateRanges appRequestRanges;
2195 
2196         /**
2197          * Represents the idle time of the screen after which the associated display's refresh rate
2198          * is to be reduced to preserve power
2199          * Defaults to null, meaning that the device is not configured to have a timeout.
2200          * Timeout value of -1 refers that the current conditions require no timeout
2201          */
2202         @Nullable
2203         public IdleScreenRefreshRateConfig idleScreenRefreshRateConfig;
2204 
DesiredDisplayModeSpecs()2205         public DesiredDisplayModeSpecs() {
2206             this.primaryRanges = new RefreshRateRanges();
2207             this.appRequestRanges = new RefreshRateRanges();
2208         }
2209 
DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other)2210         public DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other) {
2211             this.primaryRanges = new RefreshRateRanges();
2212             this.appRequestRanges = new RefreshRateRanges();
2213             copyFrom(other);
2214         }
2215 
DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching, RefreshRateRanges primaryRanges, RefreshRateRanges appRequestRanges, @Nullable IdleScreenRefreshRateConfig idleScreenRefreshRateConfig)2216         public DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching,
2217                 RefreshRateRanges primaryRanges, RefreshRateRanges appRequestRanges,
2218                 @Nullable IdleScreenRefreshRateConfig idleScreenRefreshRateConfig) {
2219             this.defaultMode = defaultMode;
2220             this.allowGroupSwitching = allowGroupSwitching;
2221             this.primaryRanges =
2222                     new RefreshRateRanges(primaryRanges.physical, primaryRanges.render);
2223             this.appRequestRanges =
2224                     new RefreshRateRanges(appRequestRanges.physical, appRequestRanges.render);
2225             this.idleScreenRefreshRateConfig =
2226                     (idleScreenRefreshRateConfig == null) ? null : new IdleScreenRefreshRateConfig(
2227                             idleScreenRefreshRateConfig.timeoutMillis);
2228         }
2229 
2230         @Override
equals(@ullable Object o)2231         public boolean equals(@Nullable Object o) {
2232             return o instanceof DesiredDisplayModeSpecs && equals((DesiredDisplayModeSpecs) o);
2233         }
2234 
2235         /**
2236          * Tests for equality.
2237          */
equals(DesiredDisplayModeSpecs other)2238         public boolean equals(DesiredDisplayModeSpecs other) {
2239             return other != null && defaultMode == other.defaultMode
2240                     && allowGroupSwitching == other.allowGroupSwitching
2241                     && primaryRanges.equals(other.primaryRanges)
2242                     && appRequestRanges.equals(other.appRequestRanges)
2243                     && Objects.equals(
2244                     idleScreenRefreshRateConfig, other.idleScreenRefreshRateConfig);
2245         }
2246 
2247         @Override
hashCode()2248         public int hashCode() {
2249             return 0; // don't care
2250         }
2251 
2252         /**
2253          * Copies the supplied object's values to this object.
2254          */
copyFrom(DesiredDisplayModeSpecs other)2255         public void copyFrom(DesiredDisplayModeSpecs other) {
2256             defaultMode = other.defaultMode;
2257             allowGroupSwitching = other.allowGroupSwitching;
2258             primaryRanges.copyFrom(other.primaryRanges);
2259             appRequestRanges.copyFrom(other.appRequestRanges);
2260             copyIdleScreenRefreshRateConfig(other.idleScreenRefreshRateConfig);
2261         }
2262 
2263         @Override
toString()2264         public String toString() {
2265             return "defaultMode=" + defaultMode
2266                     + " allowGroupSwitching=" + allowGroupSwitching
2267                     + " primaryRanges=" + primaryRanges
2268                     + " appRequestRanges=" + appRequestRanges
2269                     + " idleScreenRefreshRate=" + String.valueOf(idleScreenRefreshRateConfig);
2270         }
2271 
copyIdleScreenRefreshRateConfig(IdleScreenRefreshRateConfig other)2272         private void copyIdleScreenRefreshRateConfig(IdleScreenRefreshRateConfig other) {
2273             if (idleScreenRefreshRateConfig == null) {
2274                 if (other != null) {
2275                     idleScreenRefreshRateConfig =
2276                             new IdleScreenRefreshRateConfig(other.timeoutMillis);
2277                 }
2278             } else if (other == null) {
2279                 idleScreenRefreshRateConfig = null;
2280             } else {
2281                 idleScreenRefreshRateConfig.copyFrom(other);
2282             }
2283         }
2284     }
2285 
2286     /**
2287      * @hide
2288      */
setDesiredDisplayModeSpecs(IBinder displayToken, DesiredDisplayModeSpecs desiredDisplayModeSpecs)2289     public static boolean setDesiredDisplayModeSpecs(IBinder displayToken,
2290             DesiredDisplayModeSpecs desiredDisplayModeSpecs) {
2291         if (displayToken == null) {
2292             throw new IllegalArgumentException("displayToken must not be null");
2293         }
2294         if (desiredDisplayModeSpecs == null) {
2295             throw new IllegalArgumentException("desiredDisplayModeSpecs must not be null");
2296         }
2297         if (desiredDisplayModeSpecs.defaultMode < 0) {
2298             throw new IllegalArgumentException("defaultMode must be non-negative");
2299         }
2300 
2301         return nativeSetDesiredDisplayModeSpecs(displayToken, desiredDisplayModeSpecs);
2302     }
2303 
2304     /**
2305      * @hide
2306      */
getDesiredDisplayModeSpecs( IBinder displayToken)2307     public static DesiredDisplayModeSpecs getDesiredDisplayModeSpecs(
2308             IBinder displayToken) {
2309         if (displayToken == null) {
2310             throw new IllegalArgumentException("displayToken must not be null");
2311         }
2312 
2313         return nativeGetDesiredDisplayModeSpecs(displayToken);
2314     }
2315 
2316     /**
2317      * Color coordinates in CIE1931 XYZ color space
2318      *
2319      * @hide
2320      */
2321     public static final class CieXyz {
2322         /**
2323          * @hide
2324          */
2325         public float X;
2326 
2327         /**
2328          * @hide
2329          */
2330         public float Y;
2331 
2332         /**
2333          * @hide
2334          */
2335         public float Z;
2336     }
2337 
2338     /**
2339      * Contains a display's color primaries
2340      *
2341      * @hide
2342      */
2343     public static final class DisplayPrimaries {
2344         /**
2345          * @hide
2346          */
2347         public CieXyz red;
2348 
2349         /**
2350          * @hide
2351          */
2352         public CieXyz green;
2353 
2354         /**
2355          * @hide
2356          */
2357         public CieXyz blue;
2358 
2359         /**
2360          * @hide
2361          */
2362         public CieXyz white;
2363 
2364         /**
2365          * @hide
2366          */
DisplayPrimaries()2367         public DisplayPrimaries() {
2368         }
2369     }
2370 
2371     /**
2372      * @hide
2373      */
getDisplayNativePrimaries( IBinder displayToken)2374     public static DisplayPrimaries getDisplayNativePrimaries(
2375             IBinder displayToken) {
2376         if (displayToken == null) {
2377             throw new IllegalArgumentException("displayToken must not be null");
2378         }
2379 
2380         return nativeGetDisplayNativePrimaries(displayToken);
2381     }
2382 
2383     /**
2384      * @hide
2385      */
setActiveColorMode(IBinder displayToken, int colorMode)2386     public static boolean setActiveColorMode(IBinder displayToken, int colorMode) {
2387         if (displayToken == null) {
2388             throw new IllegalArgumentException("displayToken must not be null");
2389         }
2390         return nativeSetActiveColorMode(displayToken, colorMode);
2391     }
2392 
2393     /**
2394      * Returns an array of color spaces with 2 elements. The first color space is the
2395      * default color space and second one is wide color gamut color space.
2396      * @hide
2397      */
getCompositionColorSpaces()2398     public static ColorSpace[] getCompositionColorSpaces() {
2399         int[] dataspaces = nativeGetCompositionDataspaces();
2400         ColorSpace srgb = ColorSpace.get(ColorSpace.Named.SRGB);
2401         ColorSpace[] colorSpaces = { srgb, srgb };
2402         if (dataspaces.length == 2) {
2403             for (int i = 0; i < 2; ++i) {
2404                 ColorSpace cs = ColorSpace.getFromDataSpace(dataspaces[i]);
2405                 if (cs != null) {
2406                     colorSpaces[i] = cs;
2407                 }
2408             }
2409         }
2410         return colorSpaces;
2411     }
2412 
2413     /**
2414      * @return the overlay properties of the device
2415      * @hide
2416      */
getOverlaySupport()2417     public static OverlayProperties getOverlaySupport() {
2418         return nativeGetOverlaySupport();
2419     }
2420 
2421     /**
2422      * @hide
2423      */
getBootDisplayModeSupport()2424     public static boolean getBootDisplayModeSupport() {
2425         return nativeGetBootDisplayModeSupport();
2426     }
2427 
2428     /** There is no associated getter for this method.  When this is set, the display is expected
2429      * to start up in this mode next time the device reboots.
2430      * @hide
2431      */
setBootDisplayMode(IBinder displayToken, int displayModeId)2432     public static void setBootDisplayMode(IBinder displayToken, int displayModeId) {
2433         if (displayToken == null) {
2434             throw new IllegalArgumentException("displayToken must not be null");
2435         }
2436 
2437         nativeSetBootDisplayMode(displayToken, displayModeId);
2438     }
2439 
2440     /**
2441      * @hide
2442      */
clearBootDisplayMode(IBinder displayToken)2443     public static void clearBootDisplayMode(IBinder displayToken) {
2444         if (displayToken == null) {
2445             throw new IllegalArgumentException("displayToken must not be null");
2446         }
2447 
2448         nativeClearBootDisplayMode(displayToken);
2449     }
2450 
2451     /**
2452      * @hide
2453      */
setAutoLowLatencyMode(IBinder displayToken, boolean on)2454     public static void setAutoLowLatencyMode(IBinder displayToken, boolean on) {
2455         if (displayToken == null) {
2456             throw new IllegalArgumentException("displayToken must not be null");
2457         }
2458 
2459         nativeSetAutoLowLatencyMode(displayToken, on);
2460     }
2461 
2462     /**
2463      * @hide
2464      */
setGameContentType(IBinder displayToken, boolean on)2465     public static void setGameContentType(IBinder displayToken, boolean on) {
2466         if (displayToken == null) {
2467             throw new IllegalArgumentException("displayToken must not be null");
2468         }
2469 
2470         nativeSetGameContentType(displayToken, on);
2471     }
2472 
2473     /**
2474      * Returns whether protected content is supported in GPU composition.
2475      * @hide
2476      */
getProtectedContentSupport()2477     public static boolean getProtectedContentSupport() {
2478         return nativeGetProtectedContentSupport();
2479     }
2480 
2481     /**
2482      * Returns whether brightness operations are supported on a display.
2483      *
2484      * @param displayToken
2485      *      The token for the display.
2486      *
2487      * @return Whether brightness operations are supported on the display.
2488      *
2489      * @hide
2490      */
getDisplayBrightnessSupport(IBinder displayToken)2491     public static boolean getDisplayBrightnessSupport(IBinder displayToken) {
2492         return nativeGetDisplayBrightnessSupport(displayToken);
2493     }
2494 
2495     /**
2496      * Sets the brightness of a display.
2497      *
2498      * @param displayToken
2499      *      The token for the display whose brightness is set.
2500      * @param brightness
2501      *      A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to
2502      *      turn the backlight off.
2503      *
2504      * @return Whether the method succeeded or not.
2505      *
2506      * @throws IllegalArgumentException if:
2507      *      - displayToken is null;
2508      *      - brightness is NaN or greater than 1.0f.
2509      *
2510      * @hide
2511      */
setDisplayBrightness(IBinder displayToken, float brightness)2512     public static boolean setDisplayBrightness(IBinder displayToken, float brightness) {
2513         return setDisplayBrightness(displayToken, brightness, -1, brightness, -1);
2514     }
2515 
2516     /**
2517      * Sets the brightness of a display.
2518      *
2519      * @param displayToken
2520      *      The token for the display whose brightness is set.
2521      * @param sdrBrightness
2522      *      A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to
2523      *      turn the backlight off. Specifies the desired brightness of SDR content.
2524      * @param sdrBrightnessNits
2525      *      The value of sdrBrightness converted to calibrated nits. -1 if this isn't available.
2526      * @param displayBrightness
2527      *     A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or
2528      *     -1.0f to turn the backlight off. Specifies the desired brightness of the display itself,
2529      *     used directly for HDR content.
2530      * @param displayBrightnessNits
2531      *      The value of displayBrightness converted to calibrated nits. -1 if this isn't
2532      *      available.
2533      *
2534      * @return Whether the method succeeded or not.
2535      *
2536      * @throws IllegalArgumentException if:
2537      *      - displayToken is null;
2538      *      - brightness is NaN or greater than 1.0f.
2539      *
2540      * @hide
2541      */
setDisplayBrightness(IBinder displayToken, float sdrBrightness, float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits)2542     public static boolean setDisplayBrightness(IBinder displayToken, float sdrBrightness,
2543             float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits) {
2544         Objects.requireNonNull(displayToken);
2545         if (Float.isNaN(displayBrightness) || displayBrightness > 1.0f
2546                 || (displayBrightness < 0.0f && displayBrightness != -1.0f)) {
2547             throw new IllegalArgumentException("displayBrightness must be a number between 0.0f "
2548                     + " and 1.0f, or -1 to turn the backlight off: " + displayBrightness);
2549         }
2550         if (Float.isNaN(sdrBrightness) || sdrBrightness > 1.0f
2551                 || (sdrBrightness < 0.0f && sdrBrightness != -1.0f)) {
2552             throw new IllegalArgumentException("sdrBrightness must be a number between 0.0f "
2553                     + "and 1.0f, or -1 to turn the backlight off: " + sdrBrightness);
2554         }
2555         return nativeSetDisplayBrightness(displayToken, sdrBrightness, sdrBrightnessNits,
2556                 displayBrightness, displayBrightnessNits);
2557     }
2558 
2559     /**
2560      * Creates a mirrored hierarchy for the mirrorOf {@link SurfaceControl}
2561      *
2562      * Real Hierarchy    Mirror
2563      *                     SC (value that's returned)
2564      *                      |
2565      *      A               A'
2566      *      |               |
2567      *      B               B'
2568      *
2569      * @param mirrorOf The root of the hierarchy that should be mirrored.
2570      * @return A SurfaceControl that's the parent of the root of the mirrored hierarchy.
2571      *
2572      * @hide
2573      */
mirrorSurface(SurfaceControl mirrorOf)2574     public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) {
2575         long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject);
2576         SurfaceControl sc = new SurfaceControl();
2577         sc.mName = mirrorOf.mName + " (mirror)";
2578         sc.assignNativeObject(nativeObj, "mirrorSurface");
2579         return sc;
2580     }
2581 
validateColorArg(@ize4) float[] color)2582     private static void validateColorArg(@Size(4) float[] color) {
2583         final String msg = "Color must be specified as a float array with"
2584                 + " four values to represent r, g, b, a in range [0..1]";
2585         if (color.length != 4) {
2586             throw new IllegalArgumentException(msg);
2587         }
2588         for (float c:color) {
2589             if ((c < 0.f) || (c > 1.f)) {
2590                 throw new IllegalArgumentException(msg);
2591             }
2592         }
2593     }
2594 
2595     /**
2596      * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows
2597      * material design guidelines.
2598      *
2599      * @param ambientColor Color applied to the ambient shadow. The alpha is premultiplied. A
2600      *                     float array with four values to represent r, g, b, a in range [0..1]
2601      * @param spotColor Color applied to the spot shadow. The alpha is premultiplied. The position
2602      *                  of the spot shadow depends on the light position. A float array with
2603      *                  four values to represent r, g, b, a in range [0..1]
2604      * @param lightPosY Y axis position of the light used to cast the spot shadow in pixels.
2605      * @param lightPosZ Z axis position of the light used to cast the spot shadow in pixels. The X
2606      *                  axis position is set to the display width / 2.
2607      * @param lightRadius Radius of the light casting the shadow in pixels.
2608      *[
2609      * @hide
2610      */
setGlobalShadowSettings(@ize4) float[] ambientColor, @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius)2611     public static void setGlobalShadowSettings(@Size(4) float[] ambientColor,
2612             @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius) {
2613         validateColorArg(ambientColor);
2614         validateColorArg(spotColor);
2615         nativeSetGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
2616     }
2617 
2618     /**
2619      * Returns whether/how a display supports DISPLAY_DECORATION.
2620      *
2621      * @param displayToken
2622      *      The token for the display.
2623      *
2624      * @return A class describing how the display supports DISPLAY_DECORATION or null if it does
2625      * not.
2626      *
2627      * TODO (b/218524164): Move this out of SurfaceControl.
2628      * @hide
2629      */
getDisplayDecorationSupport(IBinder displayToken)2630     public static DisplayDecorationSupport getDisplayDecorationSupport(IBinder displayToken) {
2631         return nativeGetDisplayDecorationSupport(displayToken);
2632     }
2633 
2634     /**
2635      * Adds a callback to be informed about SF's jank classification for a specific surface.
2636      * @hide
2637      */
addJankDataListener(OnJankDataListener listener, SurfaceControl surface)2638     public static void addJankDataListener(OnJankDataListener listener, SurfaceControl surface) {
2639         nativeAddJankDataListener(listener.mNativePtr.get(), surface.mNativeObject);
2640     }
2641 
2642     /**
2643      * Removes a jank callback previously added with {@link #addJankDataListener}
2644      * @hide
2645      */
removeJankDataListener(OnJankDataListener listener)2646     public static void removeJankDataListener(OnJankDataListener listener) {
2647         nativeRemoveJankDataListener(listener.mNativePtr.get());
2648     }
2649 
2650     /**
2651      * Return GPU Context priority that is set in SurfaceFlinger's Render Engine.
2652      * @hide
2653      */
getGPUContextPriority()2654     public static int getGPUContextPriority() {
2655         return nativeGetGPUContextPriority();
2656     }
2657 
2658     /**
2659      * Lets surfaceFlinger know the boot procedure is completed.
2660      * @hide
2661      */
bootFinished()2662     public static boolean bootFinished() {
2663         return nativeBootFinished();
2664     }
2665 
2666     /**
2667      * Interface to handle request to
2668      * {@link SurfaceControl.Transaction#addTransactionCommittedListener(Executor, TransactionCommittedListener)}
2669      */
2670     public interface TransactionCommittedListener {
2671         /**
2672          * Invoked when the transaction has been committed in SurfaceFlinger.
2673          */
onTransactionCommitted()2674         void onTransactionCommitted();
2675     }
2676 
2677     /**
2678      * Transaction stats given to the listener registered in
2679      * {@link SurfaceControl.Transaction#addTransactionCompletedListener}
2680      */
2681     @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
2682     public static final class TransactionStats {
2683         private long mLatchTimeNanos;
2684         private SyncFence mSyncFence;
2685 
2686         // called from native
TransactionStats(long latchTimeNanos, long presentFencePtr)2687         private TransactionStats(long latchTimeNanos, long presentFencePtr) {
2688             mLatchTimeNanos = latchTimeNanos;
2689             mSyncFence = new SyncFence(presentFencePtr);
2690         }
2691 
2692         /**
2693          * Close the TransactionStats. Called by the framework when the listener returns.
2694          * @hide
2695          */
close()2696         public void close() {
2697             mSyncFence.close();
2698         }
2699 
2700         /**
2701          * Returns the timestamp (in CLOCK_MONOTONIC) of when the frame was latched by the
2702          * framework and queued for presentation.
2703          */
2704         @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
getLatchTimeNanos()2705         public long getLatchTimeNanos() {
2706             return mLatchTimeNanos;
2707         }
2708 
2709         /**
2710          * Returns a new SyncFence that signals when the transaction has been presented.
2711          * The caller takes ownership of the fence and is responsible for closing
2712          * it by calling {@link SyncFence#close}.
2713          * If a device does not support present fences, an empty fence will be returned.
2714          */
2715         @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
getPresentFence()2716         public @NonNull SyncFence getPresentFence() {
2717             return new SyncFence(mSyncFence);
2718         }
2719     };
2720 
2721     /**
2722      * Threshold values that are sent with
2723      * {@link Transaction#setTrustedPresentationCallback(SurfaceControl,
2724      * TrustedPresentationThresholds, Executor, Consumer)}
2725      *
2726      * @deprecated Use {@link android.window.TrustedPresentationThresholds} instead.
2727      */
2728     @Deprecated
2729     public static final class TrustedPresentationThresholds {
2730         private final float mMinAlpha;
2731         private final float mMinFractionRendered;
2732         private final int mStabilityRequirementMs;
2733 
2734         /**
2735          * Creates a TrustedPresentationThresholds that's used when calling
2736          * {@link Transaction#setTrustedPresentationCallback(SurfaceControl,
2737          * TrustedPresentationThresholds, Executor, Consumer)}
2738          *
2739          * @param minAlpha               The min alpha the {@link SurfaceControl} is required to
2740          *                               have to be considered inside the threshold.
2741          * @param minFractionRendered    The min fraction of the SurfaceControl that was presented
2742          *                               to the user to be considered inside the threshold.
2743          * @param stabilityRequirementMs The time in milliseconds required for the
2744          *                               {@link SurfaceControl} to be in the threshold.
2745          * @throws IllegalArgumentException If threshold values are invalid.
2746          */
TrustedPresentationThresholds( @loatRangefrom = 0f, fromInclusive = false, to = 1f) float minAlpha, @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minFractionRendered, @IntRange(from = 1) int stabilityRequirementMs)2747         public TrustedPresentationThresholds(
2748                 @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minAlpha,
2749                 @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minFractionRendered,
2750                 @IntRange(from = 1) int stabilityRequirementMs) {
2751             mMinAlpha = minAlpha;
2752             mMinFractionRendered = minFractionRendered;
2753             mStabilityRequirementMs = stabilityRequirementMs;
2754 
2755             checkValid();
2756         }
2757 
checkValid()2758         private void checkValid() {
2759             if (mMinAlpha <= 0 || mMinFractionRendered <= 0 || mStabilityRequirementMs < 1) {
2760                 throw new IllegalArgumentException(
2761                         "TrustedPresentationThresholds values are invalid");
2762             }
2763         }
2764     }
2765 
2766     /**
2767      * Register a TrustedPresentationCallback for a particular SurfaceControl so it can be notified
2768      * when the specified Threshold has been crossed.
2769      *
2770      * @hide
2771      */
2772     public abstract static class TrustedPresentationCallback {
2773         private final long mNativeObject;
2774 
2775         private static final NativeAllocationRegistry sRegistry =
2776                 NativeAllocationRegistry.createMalloced(
2777                         TrustedPresentationCallback.class.getClassLoader(),
2778                         getNativeTrustedPresentationCallbackFinalizer());
2779 
2780         private final Runnable mFreeNativeResources;
2781 
TrustedPresentationCallback()2782         private TrustedPresentationCallback() {
2783             mNativeObject = nativeCreateTpc(this);
2784             mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject);
2785         }
2786 
2787         /**
2788          * Invoked when the SurfaceControl that this TrustedPresentationCallback was registered for
2789          * enters or exits the threshold bounds.
2790          *
2791          * @param inTrustedPresentationState true when the SurfaceControl entered the
2792          *                                   presentation state, false when it has left.
2793          */
onTrustedPresentationChanged(boolean inTrustedPresentationState)2794         public abstract void onTrustedPresentationChanged(boolean inTrustedPresentationState);
2795     }
2796 
2797     /**
2798      * An atomic set of changes to a set of SurfaceControl.
2799      */
2800     public static class Transaction implements Closeable, Parcelable {
2801         /**
2802          * @hide
2803          */
2804         public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
2805                 Transaction.class.getClassLoader(),
2806                 nativeGetNativeTransactionFinalizer(), 512);
2807         /**
2808          * @hide
2809          */
2810         public long mNativeObject;
2811 
2812         private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>();
2813         private final ArrayMap<SurfaceControl, SurfaceControl> mReparentedSurfaces =
2814                  new ArrayMap<>();
2815 
2816         Runnable mFreeNativeResources;
2817         private static final float[] INVALID_COLOR = {-1, -1, -1};
2818 
2819         /**
2820          * @hide
2821          */
checkPreconditions(SurfaceControl sc)2822         protected void checkPreconditions(SurfaceControl sc) {
2823             sc.checkNotReleased();
2824         }
2825 
2826         /**
2827          * Open a new transaction object. The transaction may be filed with commands to
2828          * manipulate {@link SurfaceControl} instances, and then applied atomically with
2829          * {@link #apply}. Eventually the user should invoke {@link #close}, when the object
2830          * is no longer required. Note however that re-using a transaction after a call to apply
2831          * is allowed as a convenience.
2832          */
Transaction()2833         public Transaction() {
2834             this(nativeCreateTransaction());
2835         }
2836 
Transaction(long nativeObject)2837         private Transaction(long nativeObject) {
2838             mNativeObject = nativeObject;
2839             mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject);
2840             if (!SurfaceControlRegistry.sCallStackDebuggingInitialized) {
2841                 SurfaceControlRegistry.initializeCallStackDebugging();
2842             }
2843         }
2844 
Transaction(Parcel in)2845         private Transaction(Parcel in) {
2846             readFromParcel(in);
2847         }
2848 
2849         /**
2850          *
2851          * @hide
2852          */
setDefaultApplyToken(IBinder token)2853         public static void setDefaultApplyToken(IBinder token) {
2854             nativeSetDefaultApplyToken(token);
2855         }
2856 
2857         /**
2858          *
2859          * @hide
2860          */
getDefaultApplyToken()2861         public static IBinder getDefaultApplyToken() {
2862             return nativeGetDefaultApplyToken();
2863         }
2864 
2865         /**
2866          * Apply the transaction, clearing it's state, and making it usable
2867          * as a new transaction.
2868          */
apply()2869         public void apply() {
2870             apply(/*sync*/ false);
2871         }
2872 
2873         /**
2874          * Applies the transaction as a one way binder call. This transaction will be applied out
2875          * of order with other transactions that are applied synchronously. This method is not
2876          * safe. It should only be used when the order does not matter.
2877          *
2878          * @hide
2879          */
applyAsyncUnsafe()2880         public void applyAsyncUnsafe() {
2881             apply(/*sync*/ false, /*oneWay*/ true);
2882         }
2883 
2884 
2885         /**
2886          * Clear the transaction object, without applying it.
2887          *
2888          * @hide
2889          */
clear()2890         public void clear() {
2891             mResizedSurfaces.clear();
2892             mReparentedSurfaces.clear();
2893             if (mNativeObject != 0) {
2894                 nativeClearTransaction(mNativeObject);
2895             }
2896         }
2897 
2898         /**
2899          * Release the native transaction object, without applying it.
2900          */
2901         @Override
close()2902         public void close() {
2903             mResizedSurfaces.clear();
2904             mReparentedSurfaces.clear();
2905             mFreeNativeResources.run();
2906             mNativeObject = 0;
2907         }
2908 
2909         /**
2910          * Jankier version of apply. Avoid use (b/28068298).
2911          * @hide
2912          */
apply(boolean sync)2913         public void apply(boolean sync) {
2914             apply(sync, /*oneWay*/ false);
2915         }
2916 
apply(boolean sync, boolean oneWay)2917         private void apply(boolean sync, boolean oneWay) {
2918             applyResizedSurfaces();
2919             notifyReparentedSurfaces();
2920             nativeApplyTransaction(mNativeObject, sync, oneWay);
2921 
2922             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
2923                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
2924                         "apply", this, null, null);
2925             }
2926         }
2927 
2928         /**
2929          * @hide
2930          */
applyResizedSurfaces()2931         protected void applyResizedSurfaces() {
2932             for (int i = mResizedSurfaces.size() - 1; i >= 0; i--) {
2933                 final Point size = mResizedSurfaces.valueAt(i);
2934                 final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i);
2935                 synchronized (surfaceControl.mLock) {
2936                     surfaceControl.resize(size.x, size.y);
2937                 }
2938             }
2939             mResizedSurfaces.clear();
2940         }
2941 
2942         /**
2943          * @hide
2944          */
notifyReparentedSurfaces()2945         protected void notifyReparentedSurfaces() {
2946             final int reparentCount = mReparentedSurfaces.size();
2947             for (int i = reparentCount - 1; i >= 0; i--) {
2948                 final SurfaceControl child = mReparentedSurfaces.keyAt(i);
2949                 synchronized (child.mLock) {
2950                     final int listenerCount = (child.mReparentListeners != null)
2951                             ? child.mReparentListeners.size() : 0;
2952                     for (int j = 0; j < listenerCount; j++) {
2953                         final OnReparentListener listener = child.mReparentListeners.get(j);
2954                         listener.onReparent(this, mReparentedSurfaces.valueAt(i));
2955                     }
2956                     mReparentedSurfaces.removeAt(i);
2957                 }
2958             }
2959         }
2960 
2961         /**
2962          * Toggle the visibility of a given Layer and it's sub-tree.
2963          *
2964          * @param sc The SurfaceControl for which to set the visibility
2965          * @param visible The new visibility
2966          * @return This transaction object.
2967          */
2968         @NonNull
setVisibility(@onNull SurfaceControl sc, boolean visible)2969         public Transaction setVisibility(@NonNull SurfaceControl sc, boolean visible) {
2970             checkPreconditions(sc);
2971             if (visible) {
2972                 return show(sc);
2973             } else {
2974                 return hide(sc);
2975             }
2976         }
2977 
2978         /**
2979          * This information is passed to SurfaceFlinger to decide which window should have a
2980          * priority when deciding about the refresh rate of the display. All windows have the
2981          * lowest priority by default.
2982          * @hide
2983          */
2984         @NonNull
setFrameRateSelectionPriority(@onNull SurfaceControl sc, int priority)2985         public Transaction setFrameRateSelectionPriority(@NonNull SurfaceControl sc, int priority) {
2986             checkPreconditions(sc);
2987             nativeSetFrameRateSelectionPriority(mNativeObject, sc.mNativeObject, priority);
2988             return this;
2989         }
2990 
2991         /**
2992          * Request that a given surface and it's sub-tree be shown.
2993          *
2994          * @param sc The surface to show.
2995          * @return This transaction.
2996          * @hide
2997          */
2998         @UnsupportedAppUsage
show(SurfaceControl sc)2999         public Transaction show(SurfaceControl sc) {
3000             checkPreconditions(sc);
3001             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3002                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3003                         "show", this, sc, null);
3004             }
3005             nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN);
3006             return this;
3007         }
3008 
3009         /**
3010          * Request that a given surface and it's sub-tree be hidden.
3011          *
3012          * @param sc The surface to hidden.
3013          * @return This transaction.
3014          * @hide
3015          */
3016         @UnsupportedAppUsage
hide(SurfaceControl sc)3017         public Transaction hide(SurfaceControl sc) {
3018             checkPreconditions(sc);
3019             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3020                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3021                         "hide", this, sc, null);
3022             }
3023             nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
3024             return this;
3025         }
3026 
3027         /**
3028          * Sets the SurfaceControl to the specified position relative to the parent
3029          * SurfaceControl
3030          *
3031          * @param sc The SurfaceControl to change position
3032          * @param x the X position
3033          * @param y the Y position
3034          * @return this transaction
3035          */
3036         @NonNull
setPosition(@onNull SurfaceControl sc, float x, float y)3037         public Transaction setPosition(@NonNull SurfaceControl sc, float x, float y) {
3038             checkPreconditions(sc);
3039             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3040                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3041                         "setPosition", this, sc, "x=" + x + " y=" + y);
3042             }
3043             nativeSetPosition(mNativeObject, sc.mNativeObject, x, y);
3044             return this;
3045         }
3046 
3047         /**
3048          * Sets the SurfaceControl to the specified scale with (0, 0) as the center point
3049          * of the scale.
3050          *
3051          * @param sc The SurfaceControl to change scale
3052          * @param scaleX the X scale
3053          * @param scaleY the Y scale
3054          * @return this transaction
3055          */
3056         @NonNull
setScale(@onNull SurfaceControl sc, float scaleX, float scaleY)3057         public Transaction setScale(@NonNull SurfaceControl sc, float scaleX, float scaleY) {
3058             checkPreconditions(sc);
3059             Preconditions.checkArgument(scaleX >= 0, "Negative value passed in for scaleX");
3060             Preconditions.checkArgument(scaleY >= 0, "Negative value passed in for scaleY");
3061             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3062                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3063                         "setScale", this, sc, "sx=" + scaleX + " sy=" + scaleY);
3064             }
3065             nativeSetScale(mNativeObject, sc.mNativeObject, scaleX, scaleY);
3066             return this;
3067         }
3068 
3069         /**
3070          * Set the default buffer size for the SurfaceControl, if there is a
3071          * {@link Surface} associated with the control, then
3072          * this will be the default size for buffers dequeued from it.
3073          * @param sc The surface to set the buffer size for.
3074          * @param w The default width
3075          * @param h The default height
3076          * @return This Transaction
3077          */
3078         @NonNull
setBufferSize(@onNull SurfaceControl sc, @IntRange(from = 0) int w, @IntRange(from = 0) int h)3079         public Transaction setBufferSize(@NonNull SurfaceControl sc,
3080                 @IntRange(from = 0) int w, @IntRange(from = 0) int h) {
3081             checkPreconditions(sc);
3082             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3083                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3084                         "setBufferSize", this, sc, "w=" + w + " h=" + h);
3085             }
3086             mResizedSurfaces.put(sc, new Point(w, h));
3087             return this;
3088         }
3089 
3090         /**
3091          * Provide the graphic producer a transform hint if the layer and its children are
3092          * in an orientation different from the display's orientation. The caller is responsible
3093          * for clearing this transform hint if the layer is no longer in a fixed orientation.
3094          *
3095          * The transform hint is used to prevent allocating a buffer of different size when a
3096          * layer is rotated. The producer can choose to consume the hint and allocate the buffer
3097          * with the same size.
3098          *
3099          * @return This Transaction.
3100          * @hide
3101          */
3102         @NonNull
setFixedTransformHint(@onNull SurfaceControl sc, @Surface.Rotation int transformHint)3103         public Transaction setFixedTransformHint(@NonNull SurfaceControl sc,
3104                        @Surface.Rotation int transformHint) {
3105             checkPreconditions(sc);
3106             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3107                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3108                         "setFixedTransformHint", this, sc, "hint=" + transformHint);
3109             }
3110             nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, transformHint);
3111             return this;
3112         }
3113 
3114         /**
3115          * Clearing any transform hint if set on this layer.
3116          *
3117          * @return This Transaction.
3118          * @hide
3119          */
3120         @NonNull
unsetFixedTransformHint(@onNull SurfaceControl sc)3121         public Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) {
3122             checkPreconditions(sc);
3123             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3124                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3125                         "unsetFixedTransformHint", this, sc, null);
3126             }
3127             nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, -1/* INVALID_ROTATION */);
3128             return this;
3129         }
3130 
3131         /**
3132          * Set the Z-order for a given SurfaceControl, relative to it's siblings.
3133          * If two siblings share the same Z order the ordering is undefined. Surfaces
3134          * with a negative Z will be placed below the parent surface.
3135          *
3136          * @param sc The SurfaceControl to set the Z order on
3137          * @param z The Z-order
3138          * @return This Transaction.
3139          */
3140         @NonNull
setLayer(@onNull SurfaceControl sc, @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z)3141         public Transaction setLayer(@NonNull SurfaceControl sc,
3142                 @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z) {
3143             checkPreconditions(sc);
3144             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3145                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3146                         "setLayer", this, sc, "z=" + z);
3147             }
3148             nativeSetLayer(mNativeObject, sc.mNativeObject, z);
3149             return this;
3150         }
3151 
3152         /**
3153          * @hide
3154          */
setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z)3155         public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) {
3156             checkPreconditions(sc);
3157             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3158                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3159                         "setRelativeLayer", this, sc, "relTo=" + relativeTo + " z=" + z);
3160             }
3161             nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, relativeTo.mNativeObject, z);
3162             return this;
3163         }
3164 
3165         /**
3166          * @hide
3167          */
setTransparentRegionHint(SurfaceControl sc, Region transparentRegion)3168         public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) {
3169             checkPreconditions(sc);
3170             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3171                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3172                         "unsetFixedTransformHint", this, sc, "region=" + transparentRegion);
3173             }
3174             nativeSetTransparentRegionHint(mNativeObject,
3175                     sc.mNativeObject, transparentRegion);
3176             return this;
3177         }
3178 
3179         /**
3180          * Set the alpha for a given surface. If the alpha is non-zero the SurfaceControl
3181          * will be blended with the Surfaces under it according to the specified ratio.
3182          *
3183          * @param sc The given SurfaceControl.
3184          * @param alpha The alpha to set.
3185          */
3186         @NonNull
setAlpha(@onNull SurfaceControl sc, @FloatRange(from = 0.0, to = 1.0) float alpha)3187         public Transaction setAlpha(@NonNull SurfaceControl sc,
3188                 @FloatRange(from = 0.0, to = 1.0) float alpha) {
3189             checkPreconditions(sc);
3190             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3191                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3192                         "setAlpha", this, sc, "alpha=" + alpha);
3193             }
3194             nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha);
3195             return this;
3196         }
3197 
3198         /**
3199          * @hide
3200          */
setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle)3201         public Transaction setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle) {
3202             checkPreconditions(sc);
3203             nativeSetInputWindowInfo(mNativeObject, sc.mNativeObject, handle);
3204             return this;
3205         }
3206 
3207         /**
3208          * Adds a callback that is called after WindowInfosListeners from the systems server are
3209          * complete. This is primarily used to ensure that InputDispatcher::setInputWindowsLocked
3210          * has been called before running the added callback.
3211          *
3212          * @hide
3213          */
addWindowInfosReportedListener(@onNull Runnable listener)3214         public Transaction addWindowInfosReportedListener(@NonNull Runnable listener) {
3215             nativeAddWindowInfosReportedListener(mNativeObject, listener);
3216             return this;
3217         }
3218 
3219         /**
3220          * Specify how the buffer associated with this Surface is mapped in to the
3221          * parent coordinate space. The source frame will be scaled to fit the destination
3222          * frame, after being rotated according to the orientation parameter.
3223          *
3224          * @param sc The SurfaceControl to specify the geometry of
3225          * @param sourceCrop The source rectangle in buffer space. Or null for the entire buffer.
3226          * @param destFrame The destination rectangle in parent space. Or null for the source frame.
3227          * @param orientation The buffer rotation
3228          * @return This transaction object.
3229          * @deprecated Use {@link #setCrop(SurfaceControl, Rect)},
3230          * {@link #setBufferTransform(SurfaceControl, int)},
3231          * {@link #setPosition(SurfaceControl, float, float)} and
3232          * {@link #setScale(SurfaceControl, float, float)} instead.
3233          */
3234         @NonNull
setGeometry(@onNull SurfaceControl sc, @Nullable Rect sourceCrop, @Nullable Rect destFrame, @Surface.Rotation int orientation)3235         public Transaction setGeometry(@NonNull SurfaceControl sc, @Nullable Rect sourceCrop,
3236                 @Nullable Rect destFrame, @Surface.Rotation int orientation) {
3237             checkPreconditions(sc);
3238             nativeSetGeometry(mNativeObject, sc.mNativeObject, sourceCrop, destFrame, orientation);
3239             return this;
3240         }
3241 
3242         /**
3243          * @hide
3244          */
3245         @UnsupportedAppUsage
setMatrix(SurfaceControl sc, float dsdx, float dtdx, float dtdy, float dsdy)3246         public Transaction setMatrix(SurfaceControl sc,
3247                 float dsdx, float dtdx, float dtdy, float dsdy) {
3248             checkPreconditions(sc);
3249             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3250                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3251                         "setMatrix", this, sc,
3252                         "dsdx=" + dsdx + " dtdx=" + dtdx + " dtdy=" + dtdy + " dsdy=" + dsdy);
3253             }
3254             nativeSetMatrix(mNativeObject, sc.mNativeObject,
3255                     dsdx, dtdx, dtdy, dsdy);
3256             return this;
3257         }
3258 
3259         /**
3260          * Sets the transform and position of a {@link SurfaceControl} from a 3x3 transformation
3261          * matrix.
3262          *
3263          * @param sc     SurfaceControl to set matrix of
3264          * @param matrix The matrix to apply.
3265          * @param float9 An array of 9 floats to be used to extract the values from the matrix.
3266          * @hide
3267          */
3268         @UnsupportedAppUsage
setMatrix(SurfaceControl sc, Matrix matrix, float[] float9)3269         public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) {
3270             matrix.getValues(float9);
3271             setMatrix(sc, float9[MSCALE_X], float9[MSKEW_Y],
3272                     float9[MSKEW_X], float9[MSCALE_Y]);
3273             setPosition(sc, float9[MTRANS_X], float9[MTRANS_Y]);
3274             return this;
3275         }
3276 
3277         /**
3278          * Sets the color transform for the Surface.
3279          *
3280          * @param sc          SurfaceControl to set color transform of
3281          * @param matrix      A float array with 9 values represents a 3x3 transform matrix
3282          * @param translation A float array with 3 values represents a translation vector
3283          * @hide
3284          */
setColorTransform(SurfaceControl sc, @Size(9) float[] matrix, @Size(3) float[] translation)3285         public Transaction setColorTransform(SurfaceControl sc, @Size(9) float[] matrix,
3286                 @Size(3) float[] translation) {
3287             checkPreconditions(sc);
3288             nativeSetColorTransform(mNativeObject, sc.mNativeObject, matrix, translation);
3289             return this;
3290         }
3291 
3292         /**
3293          * Sets the Surface to be color space agnostic. If a surface is color space agnostic,
3294          * the color can be interpreted in any color space.
3295          * @param agnostic A boolean to indicate whether the surface is color space agnostic
3296          * @hide
3297          */
setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic)3298         public Transaction setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic) {
3299             checkPreconditions(sc);
3300             nativeSetColorSpaceAgnostic(mNativeObject, sc.mNativeObject, agnostic);
3301             return this;
3302         }
3303 
3304         /**
3305          * Bounds the surface and its children to the bounds specified. Size of the surface will be
3306          * ignored and only the crop and buffer size will be used to determine the bounds of the
3307          * surface. If no crop is specified and the surface has no buffer, the surface bounds is
3308          * only constrained by the size of its parent bounds.
3309          *
3310          * @param sc   SurfaceControl to set crop of.
3311          * @param crop Bounds of the crop to apply.
3312          * @hide
3313          * @deprecated Use {@link #setCrop(SurfaceControl, Rect)} instead.
3314          */
3315         @Deprecated
3316         @UnsupportedAppUsage
setWindowCrop(SurfaceControl sc, Rect crop)3317         public Transaction setWindowCrop(SurfaceControl sc, Rect crop) {
3318             checkPreconditions(sc);
3319             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3320                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3321                         "setWindowCrop", this, sc, "crop=" + crop);
3322             }
3323             if (crop != null) {
3324                 nativeSetWindowCrop(mNativeObject, sc.mNativeObject,
3325                         crop.left, crop.top, crop.right, crop.bottom);
3326             } else {
3327                 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
3328             }
3329 
3330             return this;
3331         }
3332 
3333         /**
3334          * Bounds the surface and its children to the bounds specified. Size of the surface will be
3335          * ignored and only the crop and buffer size will be used to determine the bounds of the
3336          * surface. If no crop is specified and the surface has no buffer, the surface bounds is
3337          * only constrained by the size of its parent bounds.
3338          *
3339          * @param sc   SurfaceControl to set crop of.
3340          * @param crop Bounds of the crop to apply.
3341          * @return this This transaction for chaining
3342          */
setCrop(@onNull SurfaceControl sc, @Nullable Rect crop)3343         public @NonNull Transaction setCrop(@NonNull SurfaceControl sc, @Nullable Rect crop) {
3344             checkPreconditions(sc);
3345             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3346                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3347                         "setCrop", this, sc, "crop=" + crop);
3348             }
3349             if (crop != null) {
3350                 Preconditions.checkArgument(crop.isValid(), "Crop " + crop
3351                         + " isn't valid");
3352                 nativeSetWindowCrop(mNativeObject, sc.mNativeObject,
3353                         crop.left, crop.top, crop.right, crop.bottom);
3354             } else {
3355                 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
3356             }
3357 
3358             return this;
3359         }
3360 
3361         /**
3362          * Same as {@link Transaction#setWindowCrop(SurfaceControl, Rect)} but sets the crop rect
3363          * top left at 0, 0.
3364          *
3365          * @param sc     SurfaceControl to set crop of.
3366          * @param width  width of crop rect
3367          * @param height height of crop rect
3368          * @hide
3369          */
setWindowCrop(SurfaceControl sc, int width, int height)3370         public Transaction setWindowCrop(SurfaceControl sc, int width, int height) {
3371             checkPreconditions(sc);
3372             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3373                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3374                         "setWindowCrop", this, sc, "w=" + width + " h=" + height);
3375             }
3376             nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, width, height);
3377             return this;
3378         }
3379 
3380         /**
3381          * Sets the corner radius of a {@link SurfaceControl}.
3382          * @param sc SurfaceControl
3383          * @param cornerRadius Corner radius in pixels.
3384          * @return Itself.
3385          * @hide
3386          */
3387         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setCornerRadius(SurfaceControl sc, float cornerRadius)3388         public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) {
3389             checkPreconditions(sc);
3390             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3391                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3392                         "setCornerRadius", this, sc, "cornerRadius=" + cornerRadius);
3393             }
3394             nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius);
3395 
3396             return this;
3397         }
3398 
3399         /**
3400          * Sets the background blur radius of the {@link SurfaceControl}.
3401          *
3402          * @param sc SurfaceControl.
3403          * @param radius Blur radius in pixels.
3404          * @return itself.
3405          * @hide
3406          */
setBackgroundBlurRadius(SurfaceControl sc, int radius)3407         public Transaction setBackgroundBlurRadius(SurfaceControl sc, int radius) {
3408             checkPreconditions(sc);
3409             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3410                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3411                         "setBackgroundBlurRadius", this, sc, "radius=" + radius);
3412             }
3413             nativeSetBackgroundBlurRadius(mNativeObject, sc.mNativeObject, radius);
3414             return this;
3415         }
3416 
3417         /**
3418          * Specify what regions should be blurred on the {@link SurfaceControl}.
3419          *
3420          * @param sc SurfaceControl.
3421          * @param regions List of regions that will have blurs.
3422          * @return itself.
3423          * @see BlurRegion#toFloatArray()
3424          * @hide
3425          */
setBlurRegions(SurfaceControl sc, float[][] regions)3426         public Transaction setBlurRegions(SurfaceControl sc, float[][] regions) {
3427             checkPreconditions(sc);
3428             nativeSetBlurRegions(mNativeObject, sc.mNativeObject, regions, regions.length);
3429             return this;
3430         }
3431 
3432         /**
3433          * @hide
3434          */
setStretchEffect(SurfaceControl sc, float width, float height, float vecX, float vecY, float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)3435         public Transaction setStretchEffect(SurfaceControl sc, float width, float height,
3436                 float vecX, float vecY, float maxStretchAmountX,
3437                 float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight,
3438                 float childRelativeBottom) {
3439             checkPreconditions(sc);
3440             nativeSetStretchEffect(mNativeObject, sc.mNativeObject, width, height,
3441                     vecX, vecY, maxStretchAmountX, maxStretchAmountY, childRelativeLeft, childRelativeTop,
3442                     childRelativeRight, childRelativeBottom);
3443             return this;
3444         }
3445 
3446         /**
3447          * @hide
3448          */
3449         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
setLayerStack(SurfaceControl sc, int layerStack)3450         public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
3451             checkPreconditions(sc);
3452             nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
3453             return this;
3454         }
3455 
3456         /**
3457          * Re-parents a given layer to a new parent. Children inherit transform (position, scaling)
3458          * crop, visibility, and Z-ordering from their parents, as if the children were pixels within the
3459          * parent Surface.
3460          *
3461          * @param sc The SurfaceControl to reparent
3462          * @param newParent The new parent for the given control.
3463          * @return This Transaction
3464          */
3465         @NonNull
reparent(@onNull SurfaceControl sc, @Nullable SurfaceControl newParent)3466         public Transaction reparent(@NonNull SurfaceControl sc,
3467                 @Nullable SurfaceControl newParent) {
3468             checkPreconditions(sc);
3469             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3470                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3471                         "reparent", this, sc, "newParent=" + newParent);
3472             }
3473             long otherObject = 0;
3474             if (newParent != null) {
3475                 newParent.checkNotReleased();
3476                 otherObject = newParent.mNativeObject;
3477             }
3478             nativeReparent(mNativeObject, sc.mNativeObject, otherObject);
3479             mReparentedSurfaces.put(sc, newParent);
3480             return this;
3481         }
3482 
3483         /**
3484          * Fills the surface with the specified color.
3485          * @param color A float array with three values to represent r, g, b in range [0..1]. An
3486          * invalid color will remove the color fill.
3487          * @hide
3488          */
3489         @UnsupportedAppUsage
setColor(SurfaceControl sc, @Size(3) float[] color)3490         public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) {
3491             checkPreconditions(sc);
3492             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3493                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3494                         "reparent", this, sc,
3495                         "r=" + color[0] + " g=" + color[1] + " b=" + color[2]);
3496             }
3497             nativeSetColor(mNativeObject, sc.mNativeObject, color);
3498             return this;
3499         }
3500 
3501         /**
3502          * Removes color fill.
3503         * @hide
3504         */
unsetColor(SurfaceControl sc)3505         public Transaction unsetColor(SurfaceControl sc) {
3506             checkPreconditions(sc);
3507             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3508                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3509                         "unsetColor", this, sc, null);
3510             }
3511             nativeSetColor(mNativeObject, sc.mNativeObject, INVALID_COLOR);
3512             return this;
3513         }
3514 
3515         /**
3516          * Sets the security of the surface.  Setting the flag is equivalent to creating the
3517          * Surface with the {@link #SECURE} flag.
3518          * @hide
3519          */
setSecure(SurfaceControl sc, boolean isSecure)3520         public Transaction setSecure(SurfaceControl sc, boolean isSecure) {
3521             checkPreconditions(sc);
3522             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3523                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3524                         "setSecure", this, sc, "secure=" + isSecure);
3525             }
3526             if (isSecure) {
3527                 nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE);
3528             } else {
3529                 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE);
3530             }
3531             return this;
3532         }
3533 
3534         /**
3535          * Sets whether the surface should take advantage of display decoration optimizations.
3536          * @hide
3537          */
setDisplayDecoration(SurfaceControl sc, boolean displayDecoration)3538         public Transaction setDisplayDecoration(SurfaceControl sc, boolean displayDecoration) {
3539             checkPreconditions(sc);
3540             if (displayDecoration) {
3541                 nativeSetFlags(mNativeObject, sc.mNativeObject, DISPLAY_DECORATION,
3542                         DISPLAY_DECORATION);
3543             } else {
3544                 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, DISPLAY_DECORATION);
3545             }
3546             return this;
3547         }
3548 
3549         /**
3550          * Indicates whether the surface must be considered opaque, even if its pixel format is
3551          * set to translucent. This can be useful if an application needs full RGBA 8888 support
3552          * for instance but will still draw every pixel opaque.
3553          * <p>
3554          * This flag only determines whether opacity will be sampled from the alpha channel.
3555          * Plane-alpha from calls to setAlpha() can still result in blended composition
3556          * regardless of the opaque setting.
3557          *
3558          * Combined effects are (assuming a buffer format with an alpha channel):
3559          * <ul>
3560          * <li>OPAQUE + alpha(1.0) == opaque composition
3561          * <li>OPAQUE + alpha(0.x) == blended composition
3562          * <li>OPAQUE + alpha(0.0) == no composition
3563          * <li>!OPAQUE + alpha(1.0) == blended composition
3564          * <li>!OPAQUE + alpha(0.x) == blended composition
3565          * <li>!OPAQUE + alpha(0.0) == no composition
3566          * </ul>
3567          * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true)
3568          * were set automatically.
3569          *
3570          * @see Builder#setOpaque(boolean)
3571          *
3572          * @param sc The SurfaceControl to update
3573          * @param isOpaque true if the buffer's alpha should be ignored, false otherwise
3574          * @return this
3575          */
3576         @NonNull
setOpaque(@onNull SurfaceControl sc, boolean isOpaque)3577         public Transaction setOpaque(@NonNull SurfaceControl sc, boolean isOpaque) {
3578             checkPreconditions(sc);
3579             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3580                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3581                         "setOpaque", this, sc, "opaque=" + isOpaque);
3582             }
3583             if (isOpaque) {
3584                 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE);
3585             } else {
3586                 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_OPAQUE);
3587             }
3588             return this;
3589         }
3590 
3591         /**
3592          * @hide
3593          */
setDisplaySurface(IBinder displayToken, Surface surface)3594         public Transaction setDisplaySurface(IBinder displayToken, Surface surface) {
3595             if (displayToken == null) {
3596                 throw new IllegalArgumentException("displayToken must not be null");
3597             }
3598 
3599             if (surface != null) {
3600                 synchronized (surface.mLock) {
3601                     nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject);
3602                 }
3603             } else {
3604                 nativeSetDisplaySurface(mNativeObject, displayToken, 0);
3605             }
3606             return this;
3607         }
3608 
3609         /**
3610          * @hide
3611          */
setDisplayLayerStack(IBinder displayToken, int layerStack)3612         public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) {
3613             if (displayToken == null) {
3614                 throw new IllegalArgumentException("displayToken must not be null");
3615             }
3616             nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack);
3617             return this;
3618         }
3619 
3620         /**
3621          * @hide
3622          */
setDisplayFlags(IBinder displayToken, int flags)3623         public Transaction setDisplayFlags(IBinder displayToken, int flags) {
3624             if (displayToken == null) {
3625                 throw new IllegalArgumentException("displayToken must not be null");
3626             }
3627             nativeSetDisplayFlags(mNativeObject, displayToken, flags);
3628             return this;
3629         }
3630 
3631         /**
3632          * @hide
3633          */
setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)3634         public Transaction setDisplayProjection(IBinder displayToken,
3635                 int orientation, Rect layerStackRect, Rect displayRect) {
3636             if (displayToken == null) {
3637                 throw new IllegalArgumentException("displayToken must not be null");
3638             }
3639             if (layerStackRect == null) {
3640                 throw new IllegalArgumentException("layerStackRect must not be null");
3641             }
3642             if (displayRect == null) {
3643                 throw new IllegalArgumentException("displayRect must not be null");
3644             }
3645             nativeSetDisplayProjection(mNativeObject, displayToken, orientation,
3646                     layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
3647                     displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
3648             return this;
3649         }
3650 
3651         /**
3652          * @hide
3653          */
setDisplaySize(IBinder displayToken, int width, int height)3654         public Transaction setDisplaySize(IBinder displayToken, int width, int height) {
3655             if (displayToken == null) {
3656                 throw new IllegalArgumentException("displayToken must not be null");
3657             }
3658             if (width <= 0 || height <= 0) {
3659                 throw new IllegalArgumentException("width and height must be positive");
3660             }
3661 
3662             nativeSetDisplaySize(mNativeObject, displayToken, width, height);
3663             return this;
3664         }
3665 
3666         /** flag the transaction as an animation
3667          * @hide
3668          */
setAnimationTransaction()3669         public Transaction setAnimationTransaction() {
3670             nativeSetAnimationTransaction(mNativeObject);
3671             return this;
3672         }
3673 
3674          /**
3675           * Provides a hint to SurfaceFlinger to change its offset so that SurfaceFlinger wakes up
3676           * earlier to compose surfaces. The caller should use this as a hint to SurfaceFlinger
3677           * when the scene is complex enough to use GPU composition. The hint will remain active
3678           * until until the client calls {@link Transaction#setEarlyWakeupEnd}.
3679           *
3680           * @hide
3681           */
3682         @RequiresPermission(Manifest.permission.WAKEUP_SURFACE_FLINGER)
setEarlyWakeupStart()3683         public Transaction setEarlyWakeupStart() {
3684             nativeSetEarlyWakeupStart(mNativeObject);
3685             return this;
3686         }
3687 
3688         /**
3689          * Removes the early wake up hint set by {@link Transaction#setEarlyWakeupStart}.
3690          *
3691          * @hide
3692          */
3693         @RequiresPermission(Manifest.permission.WAKEUP_SURFACE_FLINGER)
setEarlyWakeupEnd()3694         public Transaction setEarlyWakeupEnd() {
3695             nativeSetEarlyWakeupEnd(mNativeObject);
3696             return this;
3697         }
3698 
3699         /**
3700          * @hide
3701          * @return The transaction's current id.
3702          *         The id changed every time the transaction is applied.
3703          */
getId()3704         public long getId() {
3705             return nativeGetTransactionId(mNativeObject);
3706         }
3707 
3708         /**
3709          * Sets an arbitrary piece of metadata on the surface. This is a helper for int data.
3710          * @hide
3711          */
setMetadata(SurfaceControl sc, int key, int data)3712         public Transaction setMetadata(SurfaceControl sc, int key, int data) {
3713             Parcel parcel = Parcel.obtain();
3714             parcel.writeInt(data);
3715             try {
3716                 setMetadata(sc, key, parcel);
3717             } finally {
3718                 parcel.recycle();
3719             }
3720             return this;
3721         }
3722 
3723         /**
3724          * Sets an arbitrary piece of metadata on the surface.
3725          * @hide
3726          */
setMetadata(SurfaceControl sc, int key, Parcel data)3727         public Transaction setMetadata(SurfaceControl sc, int key, Parcel data) {
3728             checkPreconditions(sc);
3729             nativeSetMetadata(mNativeObject, sc.mNativeObject, key, data);
3730             return this;
3731         }
3732 
3733          /**
3734           * Draws shadows of length {@code shadowRadius} around the surface {@link SurfaceControl}.
3735           * If the length is 0.0f then the shadows will not be drawn.
3736           *
3737           * Shadows are drawn around the screen bounds, these are the post transformed cropped
3738           * bounds. They can draw over their parent bounds and will be occluded by layers with a
3739           * higher z-order. The shadows will respect the surface's corner radius if the
3740           * rounded corner bounds (transformed source bounds) are within the screen bounds.
3741           *
3742           * A shadow will only be drawn on buffer and color layers. If the radius is applied on a
3743           * container layer, it will be passed down the hierarchy to be applied on buffer and color
3744           * layers but not its children. A scenario where this is useful is when SystemUI animates
3745           * a task by controlling a leash to it, can draw a shadow around the app surface by
3746           * setting a shadow on the leash. This is similar to how rounded corners are set.
3747           *
3748           * @hide
3749           */
setShadowRadius(SurfaceControl sc, float shadowRadius)3750         public Transaction setShadowRadius(SurfaceControl sc, float shadowRadius) {
3751             checkPreconditions(sc);
3752             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
3753                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
3754                         "setShadowRadius", this, sc, "radius=" + shadowRadius);
3755             }
3756             nativeSetShadowRadius(mNativeObject, sc.mNativeObject, shadowRadius);
3757             return this;
3758         }
3759 
3760         /**
3761          * Sets the intended frame rate for this surface. Any switching of refresh rates is
3762          * most probably going to be seamless.
3763          *
3764          * @see #setFrameRate(SurfaceControl, float, int, int)
3765          */
3766         @NonNull
setFrameRate(@onNull SurfaceControl sc, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility)3767         public Transaction setFrameRate(@NonNull SurfaceControl sc,
3768                 @FloatRange(from = 0.0) float frameRate,
3769                 @Surface.FrameRateCompatibility int compatibility) {
3770             return setFrameRate(sc, frameRate, compatibility,
3771                     Surface.CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
3772         }
3773 
3774         /**
3775          * Sets the intended frame rate for the surface {@link SurfaceControl}.
3776          * <p>
3777          * On devices that are capable of running the display at different refresh rates, the system
3778          * may choose a display refresh rate to better match this surface's frame rate. Usage of
3779          * this API won't directly affect the application's frame production pipeline. However,
3780          * because the system may change the display refresh rate, calls to this function may result
3781          * in changes to Choreographer callback timings, and changes to the time interval at which
3782          * the system releases buffers back to the application.
3783          * <p>
3784          * Note that this only has an effect for surfaces presented on the display. If this
3785          * surface is consumed by something other than the system compositor, e.g. a media
3786          * codec, this call has no effect.
3787          *
3788          * @param sc The SurfaceControl to specify the frame rate of.
3789          * @param frameRate The intended frame rate for this surface, in frames per second. 0 is a
3790          *                  special value that indicates the app will accept the system's choice for
3791          *                  the display frame rate, which is the default behavior if this function
3792          *                  isn't called. The <code>frameRate</code> param does <em>not</em> need
3793          *                  to be a valid refresh rate for this device's display - e.g., it's fine
3794          *                  to pass 30fps to a device that can only run the display at 60fps.
3795          * @param compatibility The frame rate compatibility of this surface. The compatibility
3796          *                      value may influence the system's choice of display frame rate.
3797          *                      This parameter is ignored when <code>frameRate</code> is 0.
3798          * @param changeFrameRateStrategy Whether display refresh rate transitions caused by this
3799          *                                surface should be seamless. A seamless transition is one
3800          *                                that doesn't have any visual interruptions, such as a
3801          *                                black screen for a second or two. This parameter is
3802          *                                ignored when <code>frameRate</code> is 0.
3803          * @return This transaction object.
3804          *
3805          * @see #clearFrameRate(SurfaceControl)
3806          */
3807         @NonNull
setFrameRate(@onNull SurfaceControl sc, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility, @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy)3808         public Transaction setFrameRate(@NonNull SurfaceControl sc,
3809                 @FloatRange(from = 0.0) float frameRate,
3810                 @Surface.FrameRateCompatibility int compatibility,
3811                 @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) {
3812             checkPreconditions(sc);
3813             nativeSetFrameRate(mNativeObject, sc.mNativeObject, frameRate, compatibility,
3814                     changeFrameRateStrategy);
3815             return this;
3816         }
3817 
3818         /**
3819          * Clears the frame rate which was set for the surface {@link SurfaceControl}.
3820          *
3821          * <p>This is equivalent to calling {@link #setFrameRate(SurfaceControl, float, int, int)}
3822          * using {@code 0} for {@code frameRate}.
3823          * <p>
3824          * Note that this only has an effect for surfaces presented on the display. If this
3825          * surface is consumed by something other than the system compositor, e.g. a media
3826          * codec, this call has no effect.
3827          *
3828          * @param sc The SurfaceControl to clear the frame rate of.
3829          * @return This transaction object.
3830          *
3831          * @see #setFrameRate(SurfaceControl, float, int)
3832          */
3833         @NonNull
clearFrameRate(@onNull SurfaceControl sc)3834         public Transaction clearFrameRate(@NonNull SurfaceControl sc) {
3835             checkPreconditions(sc);
3836             nativeSetFrameRate(mNativeObject, sc.mNativeObject, 0.0f,
3837                     Surface.FRAME_RATE_COMPATIBILITY_DEFAULT,
3838                     Surface.CHANGE_FRAME_RATE_ALWAYS);
3839             return this;
3840         }
3841 
3842         /**
3843          * Sets the default frame rate compatibility for the surface {@link SurfaceControl}
3844          *
3845          * @param sc The SurfaceControl to specify the frame rate of.
3846          * @param compatibility The frame rate compatibility of this surface. The compatibility
3847          *               value may influence the system's choice of display frame rate.
3848          *
3849          * @return This transaction object.
3850          *
3851          * @hide
3852          */
3853         @NonNull
setDefaultFrameRateCompatibility(@onNull SurfaceControl sc, @Surface.FrameRateCompatibility int compatibility)3854         public Transaction setDefaultFrameRateCompatibility(@NonNull SurfaceControl sc,
3855                 @Surface.FrameRateCompatibility int compatibility) {
3856             checkPreconditions(sc);
3857             nativeSetDefaultFrameRateCompatibility(mNativeObject, sc.mNativeObject, compatibility);
3858             return this;
3859         }
3860 
3861         /**
3862          * Sets the frame rate category for the {@link SurfaceControl}.
3863          *
3864          * This helps instruct the system on choosing a display refresh rate based on the surface's
3865          * chosen category, which is a device-specific range of frame rates.
3866          * {@link #setFrameRateCategory} should be used by components such as animations that do not
3867          * require an exact frame rate, but has an opinion on an approximate desirable frame rate.
3868          * The values of {@code category} gives example use cases for which category to choose.
3869          *
3870          * To instead specify an exact frame rate, use
3871          * {@link #setFrameRate(SurfaceControl, float, int, int)}, which is more suitable for
3872          * content that knows specifically which frame rate is optimal.
3873          * Although not a common use case, {@link #setFrameRateCategory} and {@link #setFrameRate}
3874          * can be called together, with both calls potentially influencing the display refresh rate.
3875          * For example, considering only one {@link SurfaceControl}: if {@link #setFrameRate}'s
3876          * value is 24 and {@link #setFrameRateCategory}'s value is
3877          * {@link Surface#FRAME_RATE_CATEGORY_HIGH}, defined to be the range [90,120] fps for an
3878          * example device, then the best refresh rate for the SurfaceControl should be 120 fps.
3879          * This is because 120 fps is a multiple of 24 fps, and 120 fps is in the specified
3880          * category's range.
3881          *
3882          * @param sc The SurfaceControl to specify the frame rate category of.
3883          * @param category The frame rate category of this surface. The category value may influence
3884          * the system's choice of display frame rate.
3885          * @param smoothSwitchOnly Set to {@code true} to indicate the display frame rate should not
3886          * change if changing it would cause jank. Else {@code false}.
3887          * This parameter is ignored when {@code category} is
3888          * {@link Surface#FRAME_RATE_CATEGORY_DEFAULT}.
3889          *
3890          * @return This transaction object.
3891          *
3892          * @see #setFrameRate(SurfaceControl, float, int, int)
3893          *
3894          * @hide
3895          */
3896         @NonNull
setFrameRateCategory(@onNull SurfaceControl sc, @Surface.FrameRateCategory int category, boolean smoothSwitchOnly)3897         public Transaction setFrameRateCategory(@NonNull SurfaceControl sc,
3898                 @Surface.FrameRateCategory int category, boolean smoothSwitchOnly) {
3899             checkPreconditions(sc);
3900             nativeSetFrameRateCategory(mNativeObject, sc.mNativeObject, category, smoothSwitchOnly);
3901             return this;
3902         }
3903 
3904         /**
3905          * Sets the frame rate selection strategy for the {@link SurfaceControl}.
3906          *
3907          * This instructs the system on how to choose a display refresh rate, following the
3908          * strategy for the layer's frame rate specifications relative to other layers'.
3909          *
3910          * @param sc The SurfaceControl to specify the frame rate category of.
3911          * @param strategy The frame rate selection strategy.
3912          *
3913          * @return This transaction object.
3914          *
3915          * @see #setFrameRate(SurfaceControl, float, int, int)
3916          * @see #setFrameRateCategory(SurfaceControl, int)
3917          * @see #setDefaultFrameRateCompatibility(SurfaceControl, int)
3918          *
3919          * @hide
3920          */
3921         @NonNull
setFrameRateSelectionStrategy( @onNull SurfaceControl sc, @FrameRateSelectionStrategy int strategy)3922         public Transaction setFrameRateSelectionStrategy(
3923                 @NonNull SurfaceControl sc, @FrameRateSelectionStrategy int strategy) {
3924             checkPreconditions(sc);
3925             nativeSetFrameRateSelectionStrategy(mNativeObject, sc.mNativeObject, strategy);
3926             return this;
3927         }
3928 
3929         /**
3930          * Sets focus on the window identified by the input {@code token} if the window is focusable
3931          * otherwise the request is dropped.
3932          *
3933          * If the window is not visible, the request will be queued until the window becomes
3934          * visible or the request is overrriden by another request. The currently focused window
3935          * will lose focus immediately. This is to send the newly focused window any focus
3936          * dispatched events that occur while it is completing its first draw.
3937          *
3938          * @hide
3939          */
setFocusedWindow(@onNull IBinder token, String windowName, int displayId)3940         public Transaction setFocusedWindow(@NonNull IBinder token, String windowName,
3941                 int displayId) {
3942             nativeSetFocusedWindow(mNativeObject, token, windowName, displayId);
3943             return this;
3944         }
3945 
3946         /**
3947          * Removes the input focus from the current window which is having the input focus. Should
3948          * only be called when the current focused app is not responding and the current focused
3949          * window is not beloged to the current focused app.
3950          * @hide
3951          */
removeCurrentInputFocus(int displayId)3952         public Transaction removeCurrentInputFocus(int displayId) {
3953             nativeRemoveCurrentInputFocus(mNativeObject, displayId);
3954             return this;
3955         }
3956 
3957         /**
3958          * Adds or removes the flag SKIP_SCREENSHOT of the surface.  Setting the flag is equivalent
3959          * to creating the Surface with the {@link #SKIP_SCREENSHOT} flag.
3960          *
3961          * @hide
3962          */
setSkipScreenshot(SurfaceControl sc, boolean skipScrenshot)3963         public Transaction setSkipScreenshot(SurfaceControl sc, boolean skipScrenshot) {
3964             checkPreconditions(sc);
3965             if (skipScrenshot) {
3966                 nativeSetFlags(mNativeObject, sc.mNativeObject, SKIP_SCREENSHOT, SKIP_SCREENSHOT);
3967             } else {
3968                 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SKIP_SCREENSHOT);
3969             }
3970             return this;
3971         }
3972 
3973         /**
3974          * Set a buffer for a SurfaceControl. This can only be used for SurfaceControls that were
3975          * created as type {@link #FX_SURFACE_BLAST}
3976          *
3977          * @hide
3978          * @deprecated Use {@link #setBuffer(SurfaceControl, HardwareBuffer)} instead
3979          */
3980         @Deprecated
setBuffer(SurfaceControl sc, GraphicBuffer buffer)3981         public Transaction setBuffer(SurfaceControl sc, GraphicBuffer buffer) {
3982             return setBuffer(sc, HardwareBuffer.createFromGraphicBuffer(buffer));
3983         }
3984 
3985         /**
3986          * Updates the HardwareBuffer displayed for the SurfaceControl.
3987          *
3988          * Note that the buffer must be allocated with {@link HardwareBuffer#USAGE_COMPOSER_OVERLAY}
3989          * as well as {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE} as the surface control might
3990          * be composited using either an overlay or using the GPU.
3991          *
3992          * @param sc The SurfaceControl to update
3993          * @param buffer The buffer to be displayed
3994          * @return this
3995          */
setBuffer(@onNull SurfaceControl sc, @Nullable HardwareBuffer buffer)3996         public @NonNull Transaction setBuffer(@NonNull SurfaceControl sc,
3997                 @Nullable HardwareBuffer buffer) {
3998             return setBuffer(sc, buffer, null);
3999         }
4000 
4001         /**
4002          * Unsets the buffer for the SurfaceControl in the current Transaction. This will not clear
4003          * the buffer being rendered, but resets the buffer state in the Transaction only. The call
4004          * will also invoke the release callback.
4005          *
4006          * Note, this call is different from passing a null buffer to
4007          * {@link SurfaceControl.Transaction#setBuffer} which will release the last displayed
4008          * buffer.
4009          *
4010          * @hide
4011          */
unsetBuffer(SurfaceControl sc)4012         public Transaction unsetBuffer(SurfaceControl sc) {
4013             nativeUnsetBuffer(mNativeObject, sc.mNativeObject);
4014             return this;
4015         }
4016 
4017         /**
4018          * Updates the HardwareBuffer displayed for the SurfaceControl.
4019          *
4020          * Note that the buffer must be allocated with {@link HardwareBuffer#USAGE_COMPOSER_OVERLAY}
4021          * as well as {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE} as the surface control might
4022          * be composited using either an overlay or using the GPU.
4023          *
4024          * A presentation fence may be passed to improve performance by allowing the buffer
4025          * to complete rendering while it is waiting for the transaction to be applied.
4026          * For example, if the buffer is being produced by rendering with OpenGL ES then
4027          * a fence created with
4028          * {@link android.opengl.EGLExt#eglDupNativeFenceFDANDROID(EGLDisplay, EGLSync)} can be
4029          * used to allow the GPU rendering to be concurrent with the transaction. The compositor
4030          * will wait for the fence to be signaled before the buffer is displayed. If multiple
4031          * buffers are set as part of the same transaction, the presentation fences of all of them
4032          * must signal before any buffer is displayed. That is, the entire transaction is delayed
4033          * until all presentation fences have signaled, ensuring the transaction remains consistent.
4034          *
4035          * @param sc The SurfaceControl to update
4036          * @param buffer The buffer to be displayed. Pass in a null buffer to release the last
4037          * displayed buffer.
4038          * @param fence The presentation fence. If null or invalid, this is equivalent to
4039          *              {@link #setBuffer(SurfaceControl, HardwareBuffer)}
4040          * @return this
4041          */
setBuffer(@onNull SurfaceControl sc, @Nullable HardwareBuffer buffer, @Nullable SyncFence fence)4042         public @NonNull Transaction setBuffer(@NonNull SurfaceControl sc,
4043                 @Nullable HardwareBuffer buffer, @Nullable SyncFence fence) {
4044             return setBuffer(sc, buffer, fence, null);
4045         }
4046 
4047         /**
4048          * Updates the HardwareBuffer displayed for the SurfaceControl.
4049          *
4050          * Note that the buffer must be allocated with {@link HardwareBuffer#USAGE_COMPOSER_OVERLAY}
4051          * as well as {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE} as the surface control might
4052          * be composited using either an overlay or using the GPU.
4053          *
4054          * A presentation fence may be passed to improve performance by allowing the buffer
4055          * to complete rendering while it is waiting for the transaction to be applied.
4056          * For example, if the buffer is being produced by rendering with OpenGL ES then
4057          * a fence created with
4058          * {@link android.opengl.EGLExt#eglDupNativeFenceFDANDROID(EGLDisplay, EGLSync)} can be
4059          * used to allow the GPU rendering to be concurrent with the transaction. The compositor
4060          * will wait for the fence to be signaled before the buffer is displayed. If multiple
4061          * buffers are set as part of the same transaction, the presentation fences of all of them
4062          * must signal before any buffer is displayed. That is, the entire transaction is delayed
4063          * until all presentation fences have signaled, ensuring the transaction remains consistent.
4064          *
4065          * A releaseCallback may be passed to know when the buffer is safe to be reused. This
4066          * is recommended when attempting to render continuously using SurfaceControl transactions
4067          * instead of through {@link Surface}, as it provides a safe & reliable way to know when
4068          * a buffer can be re-used. The callback will be invoked with a {@link SyncFence} which,
4069          * if {@link SyncFence#isValid() valid}, must be waited on prior to using the buffer. This
4070          * can either be done directly with {@link SyncFence#awaitForever()} or it may be done
4071          * indirectly such as passing it as a release fence to
4072          * {@link android.media.Image#setFence(SyncFence)} when using
4073          * {@link android.media.ImageReader}.
4074          *
4075          * @param sc The SurfaceControl to update
4076          * @param buffer The buffer to be displayed
4077          * @param fence The presentation fence. If null or invalid, this is equivalent to
4078          *              {@link #setBuffer(SurfaceControl, HardwareBuffer)}
4079          * @param releaseCallback The callback to invoke when the buffer being set has been released
4080          *                        by a later transaction. That is, the point at which it is safe
4081          *                        to re-use the buffer.
4082          * @return this
4083          */
setBuffer(@onNull SurfaceControl sc, @Nullable HardwareBuffer buffer, @Nullable SyncFence fence, @Nullable Consumer<SyncFence> releaseCallback)4084         public @NonNull Transaction setBuffer(@NonNull SurfaceControl sc,
4085                 @Nullable HardwareBuffer buffer, @Nullable SyncFence fence,
4086                 @Nullable Consumer<SyncFence> releaseCallback) {
4087             checkPreconditions(sc);
4088             if (fence != null) {
4089                 synchronized (fence.getLock()) {
4090                     nativeSetBuffer(mNativeObject, sc.mNativeObject, buffer,
4091                             fence.getNativeFence(), releaseCallback);
4092                 }
4093             } else {
4094                 nativeSetBuffer(mNativeObject, sc.mNativeObject, buffer, 0, releaseCallback);
4095             }
4096             return this;
4097         }
4098 
4099 
4100         /**
4101          * Sets the buffer transform that should be applied to the current buffer.
4102          *
4103          * This can be used in combination with
4104          * {@link AttachedSurfaceControl#addOnBufferTransformHintChangedListener(AttachedSurfaceControl.OnBufferTransformHintChangedListener)}
4105          * to pre-rotate the buffer for the current display orientation. This can
4106          * improve the performance of displaying the associated buffer.
4107          *
4108          * @param sc The SurfaceControl to update
4109          * @param transform The transform to apply to the buffer.
4110          * @return this
4111          */
setBufferTransform(@onNull SurfaceControl sc, @SurfaceControl.BufferTransform int transform)4112         public @NonNull Transaction setBufferTransform(@NonNull SurfaceControl sc,
4113                 @SurfaceControl.BufferTransform int transform) {
4114             checkPreconditions(sc);
4115             nativeSetBufferTransform(mNativeObject, sc.mNativeObject, transform);
4116             return this;
4117         }
4118 
4119         /**
4120          * Updates the region for the content on this surface updated in this transaction. The
4121          * damage region is the area of the buffer that has changed since the previously
4122          * sent buffer. This can be used to reduce the amount of recomposition that needs
4123          * to happen when only a small region of the buffer is being updated, such as for
4124          * a small blinking cursor or a loading indicator.
4125          *
4126          * @param sc The SurfaceControl on which to set the damage region
4127          * @param region The region to set. If null, the entire buffer is assumed dirty. This is
4128          *               equivalent to not setting a damage region at all.
4129          */
setDamageRegion(@onNull SurfaceControl sc, @Nullable Region region)4130         public @NonNull Transaction setDamageRegion(@NonNull SurfaceControl sc,
4131                 @Nullable Region region) {
4132             nativeSetDamageRegion(mNativeObject, sc.mNativeObject, region);
4133             return this;
4134         }
4135 
4136         /**
4137          * Set if the layer can be dimmed.
4138          *
4139          * <p>Dimming is to adjust brightness of the layer.
4140          * Default value is {@code true}, which means the layer can be dimmed.
4141          * Disabling dimming means the brightness of the layer can not be changed, i.e.,
4142          * keep the white point for the layer same as the display brightness.</p>
4143          *
4144          * @param sc The SurfaceControl on which to enable or disable dimming.
4145          * @param dimmingEnabled The dimming flag.
4146          * @return this.
4147          *
4148          * @hide
4149          */
setDimmingEnabled(@onNull SurfaceControl sc, boolean dimmingEnabled)4150         public @NonNull Transaction setDimmingEnabled(@NonNull SurfaceControl sc,
4151                 boolean dimmingEnabled) {
4152             checkPreconditions(sc);
4153             nativeSetDimmingEnabled(mNativeObject, sc.mNativeObject, dimmingEnabled);
4154             return this;
4155         }
4156 
4157         /**
4158          * Set the color space for the SurfaceControl. The supported color spaces are SRGB
4159          * and Display P3, other color spaces will be treated as SRGB. This can only be used for
4160          * SurfaceControls that were created as type {@link #FX_SURFACE_BLAST}
4161          *
4162          * @hide
4163          * @deprecated use {@link #setDataSpace(SurfaceControl, long)} instead
4164          */
4165         @Deprecated
setColorSpace(SurfaceControl sc, ColorSpace colorSpace)4166         public Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
4167             checkPreconditions(sc);
4168             if (colorSpace.getId() == ColorSpace.Named.DISPLAY_P3.ordinal()) {
4169                 setDataSpace(sc, DataSpace.DATASPACE_DISPLAY_P3);
4170             } else {
4171                 setDataSpace(sc, DataSpace.DATASPACE_SRGB);
4172             }
4173             return this;
4174         }
4175 
4176         /**
4177          * Set the dataspace for the SurfaceControl. This will control how the buffer
4178          * set with {@link #setBuffer(SurfaceControl, HardwareBuffer)} is displayed.
4179          *
4180          * @param sc The SurfaceControl to update
4181          * @param dataspace The dataspace to set it to
4182          * @return this
4183          */
setDataSpace(@onNull SurfaceControl sc, @DataSpace.NamedDataSpace int dataspace)4184         public @NonNull Transaction setDataSpace(@NonNull SurfaceControl sc,
4185                 @DataSpace.NamedDataSpace int dataspace) {
4186             checkPreconditions(sc);
4187             nativeSetDataSpace(mNativeObject, sc.mNativeObject, dataspace);
4188             return this;
4189         }
4190 
4191         /**
4192          * Sets the desired extended range brightness for the layer. This only applies for layers
4193          * whose dataspace has RANGE_EXTENDED.
4194          *
4195          * @param sc The layer whose extended range brightness is being specified
4196          * @param currentBufferRatio The current HDR/SDR ratio of the current buffer. For example
4197          *                           if the buffer was rendered with a target SDR whitepoint of
4198          *                           100 nits and a max display brightness of 200 nits, this should
4199          *                           be set to 2.0f.
4200          *
4201          *                           <p>Default value is 1.0f.
4202          *
4203          *                           <p>Transfer functions that encode their own brightness ranges,
4204          *                           such as HLG or PQ, should also set this to 1.0f and instead
4205          *                           communicate extended content brightness information via
4206          *                           metadata such as CTA861_3 or SMPTE2086.
4207          *
4208          *                           <p>Must be finite && >= 1.0f
4209          *
4210          * @param desiredRatio The desired HDR/SDR ratio. This can be used to communicate the max
4211          *                     desired brightness range. This is similar to the "max luminance"
4212          *                     value in other HDR metadata formats, but represented as a ratio of
4213          *                     the target SDR whitepoint to the max display brightness. The system
4214          *                     may not be able to, or may choose not to, deliver the
4215          *                     requested range.
4216          *
4217          *                     <p>While requesting a large desired ratio will result in the most
4218          *                     dynamic range, voluntarily reducing the requested range can help
4219          *                     improve battery life as well as can improve quality by ensuring
4220          *                     greater bit depth is allocated to the luminance range in use.
4221          *
4222          *                     <p>Default value is 1.0f and indicates that extended range brightness
4223          *                     is not being used, so the resulting SDR or HDR behavior will be
4224          *                     determined entirely by the dataspace being used (ie, typically SDR
4225          *                     however PQ or HLG transfer functions will still result in HDR)
4226          *
4227          *                     <p>Must be finite && >= 1.0f
4228          * @return this
4229          **/
setExtendedRangeBrightness(@onNull SurfaceControl sc, float currentBufferRatio, float desiredRatio)4230         public @NonNull Transaction setExtendedRangeBrightness(@NonNull SurfaceControl sc,
4231                 float currentBufferRatio, float desiredRatio) {
4232             checkPreconditions(sc);
4233             if (!Float.isFinite(currentBufferRatio) || currentBufferRatio < 1.0f) {
4234                 throw new IllegalArgumentException(
4235                         "currentBufferRatio must be finite && >= 1.0f; got " + currentBufferRatio);
4236             }
4237             if (!Float.isFinite(desiredRatio) || desiredRatio < 1.0f) {
4238                 throw new IllegalArgumentException(
4239                         "desiredRatio must be finite && >= 1.0f; got " + desiredRatio);
4240             }
4241             nativeSetExtendedRangeBrightness(mNativeObject, sc.mNativeObject, currentBufferRatio,
4242                     desiredRatio);
4243             return this;
4244         }
4245 
4246         /**
4247          * Sets the desired HDR headroom for the layer.
4248          *
4249          * <p>Prefer using this API over {@link #setExtendedRangeBrightness} for formats that
4250          *. conform to HDR video standards like HLG or HDR10 which do not communicate a HDR/SDR
4251          * ratio as part of generating the buffer.
4252          *
4253          * @param sc The layer whose desired HDR headroom is being specified
4254          *
4255          * @param desiredRatio The desired HDR/SDR ratio. This can be used to communicate the max
4256          *                     desired brightness range. This is similar to the "max luminance"
4257          *                     value in other HDR metadata formats, but represented as a ratio of
4258          *                     the target SDR whitepoint to the max display brightness. The system
4259          *                     may not be able to, or may choose not to, deliver the
4260          *                     requested range.
4261          *
4262          *                     <p>Default value is 0.0f and indicates that the system will choose
4263          *                     the best headroom for this surface control's content. Typically,
4264          *                     this means that HLG/PQ encoded content will be displayed with some
4265          *                     HDR headroom greater than 1.0.
4266          *
4267          *                     <p>When called after {@link #setExtendedRangeBrightness}, the
4268          *                     desiredHeadroom will override the desiredRatio provided by
4269          *                     {@link #setExtendedRangeBrightness}. Conversely, when called
4270          *                     before {@link #setExtendedRangeBrightness}, the desiredRatio provided
4271          *                     by {@link #setExtendedRangeBrightness} will override the
4272          *                     desiredHeadroom.
4273          *
4274          *                     <p>Must be finite && >= 1.0f or 0.0f.
4275          * @return this
4276          * @see #setExtendedRangeBrightness
4277          **/
4278         @FlaggedApi(com.android.graphics.hwui.flags.Flags.FLAG_LIMITED_HDR)
setDesiredHdrHeadroom(@onNull SurfaceControl sc, @FloatRange(from = 0.0f) float desiredRatio)4279         public @NonNull Transaction setDesiredHdrHeadroom(@NonNull SurfaceControl sc,
4280                 @FloatRange(from = 0.0f) float desiredRatio) {
4281             checkPreconditions(sc);
4282             if (!Float.isFinite(desiredRatio) || (desiredRatio != 0 && desiredRatio < 1.0f)) {
4283                 throw new IllegalArgumentException(
4284                         "desiredRatio must be finite && >= 1.0f or 0; got " + desiredRatio);
4285             }
4286             nativeSetDesiredHdrHeadroom(mNativeObject, sc.mNativeObject, desiredRatio);
4287             return this;
4288         }
4289 
4290         /**
4291          * Sets the caching hint for the layer. By default, the caching hint is
4292          * {@link CACHING_ENABLED}.
4293          *
4294          * @param sc The SurfaceControl to update
4295          * @param cachingHint The caching hint to apply to the SurfaceControl. The CachingHint is
4296          *                    not applied to any children of this SurfaceControl.
4297          * @return this
4298          * @hide
4299          */
setCachingHint( @onNull SurfaceControl sc, @CachingHint int cachingHint)4300         public @NonNull Transaction setCachingHint(
4301                 @NonNull SurfaceControl sc, @CachingHint int cachingHint) {
4302             checkPreconditions(sc);
4303             nativeSetCachingHint(mNativeObject, sc.mNativeObject, cachingHint);
4304             return this;
4305         }
4306 
4307         /**
4308          * @see Transaction#setTrustedOverlay(SurfaceControl, int)
4309          * @hide
4310          */
setTrustedOverlay(SurfaceControl sc, boolean isTrustedOverlay)4311         public Transaction setTrustedOverlay(SurfaceControl sc, boolean isTrustedOverlay) {
4312             return setTrustedOverlay(sc,
4313                     isTrustedOverlay ? TrustedOverlay.ENABLED : TrustedOverlay.UNSET);
4314         }
4315 
4316         /**
4317          * Trusted overlay state prevents SurfaceControl from being considered as obscuring for
4318          * input occlusion detection purposes. The caller must hold the
4319          * ACCESS_SURFACE_FLINGER permission. See {@code TrustedOverlay}.
4320          * <p>
4321          * Arguments:
4322          * {@code TrustedOverlay.UNSET} - The default value, SurfaceControl will inherit the state
4323          * from its parents. If the parent state is also {@code TrustedOverlay.UNSET}, the layer
4324          * will be considered as untrusted.
4325          * <p>
4326          * {@code TrustedOverlay.DISABLED} - Treats this SurfaceControl and all its children as an
4327          * untrusted overlay. This will override any state set by its parent SurfaceControl.
4328          * <p>
4329          * {@code TrustedOverlay.ENABLED} - Treats this SurfaceControl and all its children as a
4330          * trusted overlay unless the child SurfaceControl explicitly disables its trusted state
4331          * via {@code TrustedOverlay.DISABLED}.
4332          * <p>
4333          * @hide
4334          */
setTrustedOverlay(SurfaceControl sc, @TrustedOverlay int trustedOverlay)4335         public Transaction setTrustedOverlay(SurfaceControl sc,
4336                                              @TrustedOverlay int trustedOverlay) {
4337             checkPreconditions(sc);
4338             nativeSetTrustedOverlay(mNativeObject, sc.mNativeObject, trustedOverlay);
4339             return this;
4340         }
4341 
4342         /**
4343          * Sets the input event drop mode on this SurfaceControl and its children. The caller must
4344          * hold the ACCESS_SURFACE_FLINGER permission. See {@code InputEventDropMode}.
4345          * @hide
4346          */
setDropInputMode(SurfaceControl sc, @DropInputMode int mode)4347         public Transaction setDropInputMode(SurfaceControl sc, @DropInputMode int mode) {
4348             checkPreconditions(sc);
4349             nativeSetDropInputMode(mNativeObject, sc.mNativeObject, mode);
4350             return this;
4351         }
4352 
4353         /**
4354          * Sets a property on this SurfaceControl and all its children indicating that the visible
4355          * region of this SurfaceControl should be considered when computing TrustedPresentation
4356          * Thresholds.
4357          * <p>
4358          * API Guidance:
4359          * The goal of this API is to identify windows that can be used to occlude content on
4360          * another window. This includes windows controlled by the user or the system. If the window
4361          * is transient, like Toast or notification shade, the window should not set this flag since
4362          * the user or the app cannot use the window to occlude content in a persistent manner. All
4363          * apps should have this flag set.
4364          * <p>
4365          * The caller must hold the ACCESS_SURFACE_FLINGER permission.
4366          * @hide
4367          */
setCanOccludePresentation(SurfaceControl sc, boolean canOccludePresentation)4368         public Transaction setCanOccludePresentation(SurfaceControl sc,
4369                 boolean canOccludePresentation) {
4370             checkPreconditions(sc);
4371             final int value = (canOccludePresentation) ? CAN_OCCLUDE_PRESENTATION : 0;
4372             nativeSetFlags(mNativeObject, sc.mNativeObject, value, CAN_OCCLUDE_PRESENTATION);
4373             return this;
4374         }
4375 
4376         /**
4377          * Sends a flush jank data transaction for the given surface.
4378          * @hide
4379          */
sendSurfaceFlushJankData(SurfaceControl sc)4380         public static void sendSurfaceFlushJankData(SurfaceControl sc) {
4381             sc.checkNotReleased();
4382             nativeSurfaceFlushJankData(sc.mNativeObject);
4383         }
4384 
4385         /**
4386          * @hide
4387          */
sanitize(int pid, int uid)4388         public void sanitize(int pid, int uid) {
4389             nativeSanitize(mNativeObject, pid, uid);
4390         }
4391 
4392         /**
4393          * @hide
4394          */
setDesintationFrame(SurfaceControl sc, @NonNull Rect destinationFrame)4395         public Transaction setDesintationFrame(SurfaceControl sc, @NonNull Rect destinationFrame) {
4396             checkPreconditions(sc);
4397             nativeSetDestinationFrame(mNativeObject, sc.mNativeObject,
4398                     destinationFrame.left, destinationFrame.top, destinationFrame.right,
4399                     destinationFrame.bottom);
4400             return this;
4401         }
4402 
4403         /**
4404          * @hide
4405          */
setDesintationFrame(SurfaceControl sc, int width, int height)4406         public Transaction setDesintationFrame(SurfaceControl sc, int width, int height) {
4407             checkPreconditions(sc);
4408             nativeSetDestinationFrame(mNativeObject, sc.mNativeObject, 0, 0, width, height);
4409             return this;
4410         }
4411 
4412         /**
4413          * Merge the other transaction into this transaction, clearing the
4414          * other transaction as if it had been applied.
4415          *
4416          * @param other The transaction to merge in to this one.
4417          * @return This transaction.
4418          */
4419         @NonNull
merge(@onNull Transaction other)4420         public Transaction merge(@NonNull Transaction other) {
4421             if (this == other) {
4422                 return this;
4423             }
4424             mResizedSurfaces.putAll(other.mResizedSurfaces);
4425             other.mResizedSurfaces.clear();
4426             mReparentedSurfaces.putAll(other.mReparentedSurfaces);
4427             other.mReparentedSurfaces.clear();
4428             nativeMergeTransaction(mNativeObject, other.mNativeObject);
4429             return this;
4430         }
4431 
4432         /**
4433          * Equivalent to reparent with a null parent, in that it removes
4434          * the SurfaceControl from the scene, but it also releases
4435          * the local resources (by calling {@link SurfaceControl#release})
4436          * after this method returns, {@link SurfaceControl#isValid} will return
4437          * false for the argument.
4438          *
4439          * @param sc The surface to remove and release.
4440          * @return This transaction
4441          * @hide
4442          */
4443         @NonNull
remove(@onNull SurfaceControl sc)4444         public Transaction remove(@NonNull SurfaceControl sc) {
4445             reparent(sc, null);
4446             sc.release();
4447             return this;
4448         }
4449 
4450         /**
4451          * Sets the frame timeline to use in SurfaceFlinger.
4452          *
4453          * A frame timeline should be chosen based on the frame deadline the application
4454          * can meet when rendering the frame and the application's desired presentation time.
4455          * By setting a frame timeline, SurfaceFlinger tries to present the frame at the
4456          * corresponding expected presentation time.
4457          *
4458          * To receive frame timelines, a callback must be posted to Choreographer using
4459          * {@link Choreographer#postVsyncCallback} The vsyncId can then be extracted from the
4460          * {@link Choreographer.FrameTimeline#getVsyncId}.
4461          *
4462          * @param vsyncId The vsync ID received from Choreographer, setting the frame's
4463          *                presentation target to the corresponding expected presentation time
4464          *                and deadline from the frame to be rendered. A stale or invalid value
4465          *                will be ignored.
4466          *
4467          */
4468         @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
4469         @NonNull
setFrameTimeline(long vsyncId)4470         public Transaction setFrameTimeline(long vsyncId) {
4471             if (!Flags.sdkDesiredPresentTime()) {
4472                 Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled");
4473                 return this;
4474             }
4475             nativeSetFrameTimelineVsync(mNativeObject, vsyncId);
4476             return this;
4477         }
4478 
4479         /** @hide */
4480         @NonNull
setFrameTimelineVsync(long frameTimelineVsyncId)4481         public Transaction setFrameTimelineVsync(long frameTimelineVsyncId) {
4482             nativeSetFrameTimelineVsync(mNativeObject, frameTimelineVsyncId);
4483             return this;
4484         }
4485 
4486         /**
4487          * Request to add a {@link TransactionCommittedListener}.
4488          *
4489          * The callback is invoked when transaction is applied and the updates are ready to be
4490          * presented. This callback does not mean buffers have been released! It simply means that
4491          * any new transactions applied will not overwrite the transaction for which we are
4492          * receiving a callback and instead will be included in the next frame. If you are trying
4493          * to avoid dropping frames (overwriting transactions), and unable to use timestamps (Which
4494          * provide a more efficient solution), then this method provides a method to pace your
4495          * transaction application.
4496          * The listener is invoked once the transaction is applied, and never again. Multiple
4497          * listeners can be added to the same transaction, however the order the listeners will
4498          * be called is not guaranteed.
4499          *
4500          * @param executor The executor that the callback should be invoked on.
4501          * @param listener The callback that will be invoked when the transaction has been
4502          *                 committed.
4503          */
4504         @NonNull
addTransactionCommittedListener( @onNull @allbackExecutor Executor executor, @NonNull TransactionCommittedListener listener)4505         public Transaction addTransactionCommittedListener(
4506                 @NonNull @CallbackExecutor Executor executor,
4507                 @NonNull TransactionCommittedListener listener) {
4508             TransactionCommittedListener listenerInner =
4509                     () -> executor.execute(listener::onTransactionCommitted);
4510             nativeAddTransactionCommittedListener(mNativeObject, listenerInner);
4511             return this;
4512         }
4513 
4514         /**
4515          * Request to add a TransactionCompletedListener.
4516          *
4517          * The listener is invoked when transaction is presented, and never again. Multiple
4518          * listeners can be added to the same transaction, however the order the listeners will
4519          * be called is not guaranteed.
4520          *
4521          * @param executor The executor that the callback should be invoked on.
4522          * @param listener The callback that will be invoked when the transaction has been
4523          *                 completed.
4524          */
4525         @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
4526         @NonNull
addTransactionCompletedListener( @onNull @allbackExecutor Executor executor, @NonNull Consumer<TransactionStats> listener)4527         public Transaction addTransactionCompletedListener(
4528                 @NonNull @CallbackExecutor Executor executor,
4529                 @NonNull Consumer<TransactionStats> listener) {
4530 
4531             if (!Flags.sdkDesiredPresentTime()) {
4532                 Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled");
4533                 return this;
4534             }
4535             Consumer<TransactionStats> listenerInner = stats -> executor.execute(
4536                                     () -> listener.andThen(TransactionStats::close).accept(stats));
4537             nativeAddTransactionCompletedListener(mNativeObject, listenerInner);
4538             return this;
4539         }
4540 
4541         /**
4542          * Sets a callback to receive feedback about the presentation of a {@link SurfaceControl}.
4543          * When the {@link SurfaceControl} is presented according to the passed in
4544          * {@link TrustedPresentationThresholds}, it is said to "enter the state", and receives the
4545          * callback with {@code true}. When the conditions fall out of thresholds, it is then
4546          * said to leave the state.
4547          * <p>
4548          * There are a few simple thresholds:
4549          * <ul>
4550          *    <li>minAlpha: Lower bound on computed alpha</li>
4551          *    <li>minFractionRendered: Lower bounds on fraction of pixels that were rendered</li>
4552          *    <li>stabilityThresholdMs: A time that alpha and fraction rendered must remain within
4553          *    bounds before we can "enter the state" </li>
4554          * </ul>
4555          * <p>
4556          * The fraction of pixels rendered is a computation based on scale, crop
4557          * and occlusion. The calculation may be somewhat counterintuitive, so we
4558          * can work through an example. Imagine we have a SurfaceControl with a 100x100 buffer
4559          * which is occluded by (10x100) pixels on the left, and cropped by (100x10) pixels
4560          * on the top. Furthermore imagine this SurfaceControl is scaled by 0.9 in both dimensions.
4561          * (c=crop,o=occluded,b=both,x=none)
4562          *
4563          * <blockquote>
4564          * <table>
4565          *   <caption></caption>
4566          *   <tr><td>b</td><td>c</td><td>c</td><td>c</td></tr>
4567          *   <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr>
4568          *   <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr>
4569          *   <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr>
4570          * </table>
4571          * </blockquote>
4572          * <p>
4573          * We first start by computing fr=xscale*yscale=0.9*0.9=0.81, indicating
4574          * that "81%" of the pixels were rendered. This corresponds to what was 100
4575          * pixels being displayed in 81 pixels. This is somewhat of an abuse of
4576          * language, as the information of merged pixels isn't totally lost, but
4577          * we err on the conservative side.
4578          * <p>
4579          * We then repeat a similar process for the crop and covered regions and
4580          * accumulate the results: fr = fr * (fractionNotCropped) * (fractionNotCovered)
4581          * So for this example we would get 0.9*0.9*0.9*0.9=0.65...
4582          * <p>
4583          * Notice that this is not completely accurate, as we have double counted
4584          * the region marked as b. However we only wanted a "lower bound" and so it
4585          * is ok to err in this direction. Selection of the threshold will ultimately
4586          * be somewhat arbitrary, and so there are some somewhat arbitrary decisions in
4587          * this API as well.
4588          * <p>
4589          *
4590          * @param sc         The {@link SurfaceControl} to set the callback on
4591          * @param thresholds The {@link TrustedPresentationThresholds} that will specify when the to
4592          *                   invoke the callback.
4593          * @param executor   The {@link Executor} where the callback will be invoked on.
4594          * @param listener   The {@link Consumer} that will receive the callbacks when entered or
4595          *                   exited the threshold.
4596          * @return This transaction
4597          * @see TrustedPresentationThresholds
4598          * @deprecated Use
4599          * {@link WindowManager#registerTrustedPresentationListener(IBinder,
4600          * android.window.TrustedPresentationThresholds, Executor, Consumer)} instead.
4601          */
4602         @Deprecated
4603         @NonNull
setTrustedPresentationCallback(@onNull SurfaceControl sc, @NonNull TrustedPresentationThresholds thresholds, @NonNull Executor executor, @NonNull Consumer<Boolean> listener)4604         public Transaction setTrustedPresentationCallback(@NonNull SurfaceControl sc,
4605                 @NonNull TrustedPresentationThresholds thresholds, @NonNull Executor executor,
4606                 @NonNull Consumer<Boolean> listener) {
4607             checkPreconditions(sc);
4608             TrustedPresentationCallback tpc = new TrustedPresentationCallback() {
4609                 @Override
4610                 public void onTrustedPresentationChanged(boolean inTrustedPresentationState) {
4611                     executor.execute(
4612                             () -> listener.accept(inTrustedPresentationState));
4613                 }
4614             };
4615 
4616             if (sc.mTrustedPresentationCallback != null) {
4617                 sc.mTrustedPresentationCallback.mFreeNativeResources.run();
4618             }
4619 
4620             nativeSetTrustedPresentationCallback(mNativeObject, sc.mNativeObject,
4621                     tpc.mNativeObject, thresholds);
4622             sc.mTrustedPresentationCallback = tpc;
4623             return this;
4624         }
4625 
4626         /**
4627          * Clears the callback for a specific {@link SurfaceControl}
4628          *
4629          * @param sc The SurfaceControl that the callback should be cleared from
4630          * @return This transaction
4631          * @deprecated Use {@link WindowManager#unregisterTrustedPresentationListener(Consumer)}
4632          * instead.
4633          */
4634         @Deprecated
4635         @NonNull
clearTrustedPresentationCallback(@onNull SurfaceControl sc)4636         public Transaction clearTrustedPresentationCallback(@NonNull SurfaceControl sc) {
4637             checkPreconditions(sc);
4638             nativeClearTrustedPresentationCallback(mNativeObject, sc.mNativeObject);
4639             if (sc.mTrustedPresentationCallback != null) {
4640                 sc.mTrustedPresentationCallback.mFreeNativeResources.run();
4641                 sc.mTrustedPresentationCallback = null;
4642             }
4643             return this;
4644         }
4645 
4646         /**
4647          * Specifies a desiredPresentTimeNanos for the transaction. The framework will try to
4648          * present the transaction at or after the time specified.
4649          *
4650          * Transactions will not be presented until all of their acquire fences have signaled even
4651          * if the app requests an earlier present time.
4652          *
4653          * If an earlier transaction has a desired present time of x, and a later transaction has
4654          * a desired present time that is before x, the later transaction will not preempt the
4655          * earlier transaction.
4656          *
4657          * @param desiredPresentTimeNanos The desired time (in CLOCK_MONOTONIC) for the transaction.
4658          * @return This transaction
4659          */
4660         @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
4661         @NonNull
setDesiredPresentTimeNanos(long desiredPresentTimeNanos)4662         public Transaction setDesiredPresentTimeNanos(long desiredPresentTimeNanos) {
4663             if (!Flags.sdkDesiredPresentTime()) {
4664                 Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled");
4665                 return this;
4666             }
4667             nativeSetDesiredPresentTimeNanos(mNativeObject, desiredPresentTimeNanos);
4668             return this;
4669         }
4670         /**
4671          * Writes the transaction to parcel, clearing the transaction as if it had been applied so
4672          * it can be used to store future transactions. It's the responsibility of the parcel
4673          * reader to apply the original transaction.
4674          *
4675          * @param dest parcel to write the transaction to
4676          * @param flags
4677          */
4678         @Override
writeToParcel(@onNull Parcel dest, @WriteFlags int flags)4679         public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
4680             if (mNativeObject == 0) {
4681                 dest.writeInt(0);
4682                 return;
4683             }
4684 
4685             dest.writeInt(1);
4686             nativeWriteTransactionToParcel(mNativeObject, dest);
4687             if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
4688                 nativeClearTransaction(mNativeObject);
4689             }
4690         }
4691 
readFromParcel(Parcel in)4692         private void readFromParcel(Parcel in) {
4693             mNativeObject = 0;
4694             if (in.readInt() != 0) {
4695                 mNativeObject = nativeReadTransactionFromParcel(in);
4696                 mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject);
4697             }
4698         }
4699 
4700         @Override
describeContents()4701         public int describeContents() {
4702             return 0;
4703         }
4704 
4705         public static final @NonNull Creator<Transaction> CREATOR = new Creator<Transaction>() {
4706                     @Override
4707                     public Transaction createFromParcel(Parcel in) {
4708                         return new Transaction(in);
4709                     }
4710                     @Override
4711                     public Transaction[] newArray(int size) {
4712                         return new Transaction[size];
4713                     }
4714                 };
4715     }
4716 
4717     /**
4718      * A debugging utility subclass of SurfaceControl.Transaction. At construction
4719      * you can pass in a monitor object, and all the other methods will throw an exception
4720      * if the monitor is not held when they are called.
4721      * @hide
4722      */
4723     public static class LockDebuggingTransaction extends SurfaceControl.Transaction {
4724         Object mMonitor;
4725 
LockDebuggingTransaction(Object o)4726         public LockDebuggingTransaction(Object o) {
4727             mMonitor = o;
4728         }
4729 
4730         @Override
checkPreconditions(SurfaceControl sc)4731         protected void checkPreconditions(SurfaceControl sc) {
4732             super.checkPreconditions(sc);
4733             if (!Thread.holdsLock(mMonitor)) {
4734                 throw new RuntimeException(
4735                         "Unlocked access to synchronized SurfaceControl.Transaction");
4736             }
4737         }
4738     }
4739 
4740     /**
4741      * @hide
4742      */
resize(int w, int h)4743     public void resize(int w, int h) {
4744         mWidth = w;
4745         mHeight = h;
4746         nativeUpdateDefaultBufferSize(mNativeObject, w, h);
4747     }
4748 
4749     /**
4750      * @hide
4751      */
getTransformHint()4752     public @SurfaceControl.BufferTransform int getTransformHint() {
4753         checkNotReleased();
4754         return nativeGetTransformHint(mNativeObject);
4755     }
4756 
4757     /**
4758      * Update the transform hint of current SurfaceControl. Only affect if type is
4759      * {@link #FX_SURFACE_BLAST}
4760      *
4761      * The transform hint is used to prevent allocating a buffer of different size when a
4762      * layer is rotated. The producer can choose to consume the hint and allocate the buffer
4763      * with the same size.
4764      * @hide
4765      */
setTransformHint(@urfaceControl.BufferTransform int transformHint)4766     public void setTransformHint(@SurfaceControl.BufferTransform int transformHint) {
4767         nativeSetTransformHint(mNativeObject, transformHint);
4768     }
4769 
4770     /**
4771      * @hide
4772      */
getLayerId()4773     public int getLayerId() {
4774         if (mNativeObject != 0) {
4775             return nativeGetLayerId(mNativeObject);
4776         }
4777 
4778         return -1;
4779     }
4780 
4781     // Called by native
invokeReleaseCallback(Consumer<SyncFence> callback, long nativeFencePtr)4782     private static void invokeReleaseCallback(Consumer<SyncFence> callback, long nativeFencePtr) {
4783         SyncFence fence = new SyncFence(nativeFencePtr);
4784         callback.accept(fence);
4785     }
4786 
4787     /**
4788      * @hide
4789      */
getStalledTransactionInfo(int pid)4790     public static StalledTransactionInfo getStalledTransactionInfo(int pid) {
4791         return nativeGetStalledTransactionInfo(pid);
4792     }
4793 
4794     /**
4795      * Notify the SurfaceFlinger to capture transaction traces when shutdown.
4796      * @hide
4797      */
notifyShutdown()4798     public static void notifyShutdown() {
4799         nativeNotifyShutdown();
4800     }
4801 }
4802