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