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