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