Home | History | Annotate | Download | only in view
      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.Size;
     31 import android.graphics.Bitmap;
     32 import android.graphics.GraphicBuffer;
     33 import android.graphics.Matrix;
     34 import android.graphics.PixelFormat;
     35 import android.graphics.Point;
     36 import android.graphics.Rect;
     37 import android.graphics.Region;
     38 import android.os.IBinder;
     39 import android.os.Parcel;
     40 import android.os.Parcelable;
     41 import android.os.Process;
     42 import android.os.UserHandle;
     43 import android.util.ArrayMap;
     44 import android.util.Log;
     45 import android.util.proto.ProtoOutputStream;
     46 import android.view.Surface.OutOfResourcesException;
     47 
     48 import com.android.internal.annotations.GuardedBy;
     49 
     50 import dalvik.system.CloseGuard;
     51 
     52 import libcore.util.NativeAllocationRegistry;
     53 
     54 import java.io.Closeable;
     55 
     56 /**
     57  * SurfaceControl
     58  *  @hide
     59  */
     60 public class SurfaceControl implements Parcelable {
     61     private static final String TAG = "SurfaceControl";
     62 
     63     private static native long nativeCreate(SurfaceSession session, String name,
     64             int w, int h, int format, int flags, long parentObject, int windowType, int ownerUid)
     65             throws OutOfResourcesException;
     66     private static native long nativeReadFromParcel(Parcel in);
     67     private static native void nativeWriteToParcel(long nativeObject, Parcel out);
     68     private static native void nativeRelease(long nativeObject);
     69     private static native void nativeDestroy(long nativeObject);
     70     private static native void nativeDisconnect(long nativeObject);
     71 
     72     private static native Bitmap nativeScreenshot(IBinder displayToken,
     73             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
     74             boolean allLayers, boolean useIdentityTransform, int rotation);
     75     private static native GraphicBuffer nativeScreenshotToBuffer(IBinder displayToken,
     76             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
     77             boolean allLayers, boolean useIdentityTransform, int rotation);
     78     private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
     79             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
     80             boolean allLayers, boolean useIdentityTransform);
     81     private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
     82             Rect sourceCrop, float frameScale);
     83 
     84     private static native long nativeCreateTransaction();
     85     private static native long nativeGetNativeTransactionFinalizer();
     86     private static native void nativeApplyTransaction(long transactionObj, boolean sync);
     87     private static native void nativeMergeTransaction(long transactionObj,
     88             long otherTransactionObj);
     89     private static native void nativeSetAnimationTransaction(long transactionObj);
     90     private static native void nativeSetEarlyWakeup(long transactionObj);
     91 
     92     private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
     93     private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
     94             IBinder relativeTo, int zorder);
     95     private static native void nativeSetPosition(long transactionObj, long nativeObject,
     96             float x, float y);
     97     private static native void nativeSetGeometryAppliesWithResize(long transactionObj,
     98             long nativeObject);
     99     private static native void nativeSetSize(long transactionObj, long nativeObject, int w, int h);
    100     private static native void nativeSetTransparentRegionHint(long transactionObj,
    101             long nativeObject, Region region);
    102     private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha);
    103     private static native void nativeSetMatrix(long transactionObj, long nativeObject,
    104             float dsdx, float dtdx,
    105             float dtdy, float dsdy);
    106     private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
    107     private static native void nativeSetFlags(long transactionObj, long nativeObject,
    108             int flags, int mask);
    109     private static native void nativeSetWindowCrop(long transactionObj, long nativeObject,
    110             int l, int t, int r, int b);
    111     private static native void nativeSetFinalCrop(long transactionObj, long nativeObject,
    112             int l, int t, int r, int b);
    113     private static native void nativeSetLayerStack(long transactionObj, long nativeObject,
    114             int layerStack);
    115 
    116     private static native boolean nativeClearContentFrameStats(long nativeObject);
    117     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
    118     private static native boolean nativeClearAnimationFrameStats();
    119     private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
    120 
    121     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
    122     private static native IBinder nativeCreateDisplay(String name, boolean secure);
    123     private static native void nativeDestroyDisplay(IBinder displayToken);
    124     private static native void nativeSetDisplaySurface(long transactionObj,
    125             IBinder displayToken, long nativeSurfaceObject);
    126     private static native void nativeSetDisplayLayerStack(long transactionObj,
    127             IBinder displayToken, int layerStack);
    128     private static native void nativeSetDisplayProjection(long transactionObj,
    129             IBinder displayToken, int orientation,
    130             int l, int t, int r, int b,
    131             int L, int T, int R, int B);
    132     private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken,
    133             int width, int height);
    134     private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
    135             IBinder displayToken);
    136     private static native int nativeGetActiveConfig(IBinder displayToken);
    137     private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
    138     private static native int[] nativeGetDisplayColorModes(IBinder displayToken);
    139     private static native int nativeGetActiveColorMode(IBinder displayToken);
    140     private static native boolean nativeSetActiveColorMode(IBinder displayToken,
    141             int colorMode);
    142     private static native void nativeSetDisplayPowerMode(
    143             IBinder displayToken, int mode);
    144     private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject,
    145             IBinder handle, long frame);
    146     private static native void nativeDeferTransactionUntilSurface(long transactionObj,
    147             long nativeObject,
    148             long surfaceObject, long frame);
    149     private static native void nativeReparentChildren(long transactionObj, long nativeObject,
    150             IBinder handle);
    151     private static native void nativeReparent(long transactionObj, long nativeObject,
    152             IBinder parentHandle);
    153     private static native void nativeSeverChildren(long transactionObj, long nativeObject);
    154     private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
    155             int scalingMode);
    156     private static native void nativeDestroy(long transactionObj, long nativeObject);
    157     private static native IBinder nativeGetHandle(long nativeObject);
    158     private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);
    159 
    160     private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
    161 
    162 
    163     private final CloseGuard mCloseGuard = CloseGuard.get();
    164     private final String mName;
    165     long mNativeObject; // package visibility only for Surface.java access
    166 
    167     // TODO: Move this to native.
    168     private final Object mSizeLock = new Object();
    169     @GuardedBy("mSizeLock")
    170     private int mWidth;
    171     @GuardedBy("mSizeLock")
    172     private int mHeight;
    173 
    174     static Transaction sGlobalTransaction;
    175     static long sTransactionNestCount = 0;
    176 
    177     /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
    178 
    179     /**
    180      * Surface creation flag: Surface is created hidden
    181      */
    182     public static final int HIDDEN = 0x00000004;
    183 
    184     /**
    185      * Surface creation flag: The surface contains secure content, special
    186      * measures will be taken to disallow the surface's content to be copied
    187      * from another process. In particular, screenshots and VNC servers will
    188      * be disabled, but other measures can take place, for instance the
    189      * surface might not be hardware accelerated.
    190      *
    191      */
    192     public static final int SECURE = 0x00000080;
    193 
    194     /**
    195      * Surface creation flag: Creates a surface where color components are interpreted
    196      * as "non pre-multiplied" by their alpha channel. Of course this flag is
    197      * meaningless for surfaces without an alpha channel. By default
    198      * surfaces are pre-multiplied, which means that each color component is
    199      * already multiplied by its alpha value. In this case the blending
    200      * equation used is:
    201      * <p>
    202      *    <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code>
    203      * <p>
    204      * By contrast, non pre-multiplied surfaces use the following equation:
    205      * <p>
    206      *    <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code>
    207      * <p>
    208      * pre-multiplied surfaces must always be used if transparent pixels are
    209      * composited on top of each-other into the surface. A pre-multiplied
    210      * surface can never lower the value of the alpha component of a given
    211      * pixel.
    212      * <p>
    213      * In some rare situations, a non pre-multiplied surface is preferable.
    214      *
    215      */
    216     public static final int NON_PREMULTIPLIED = 0x00000100;
    217 
    218     /**
    219      * Surface creation flag: Indicates that the surface must be considered opaque,
    220      * even if its pixel format contains an alpha channel. This can be useful if an
    221      * application needs full RGBA 8888 support for instance but will
    222      * still draw every pixel opaque.
    223      * <p>
    224      * This flag is ignored if setAlpha() is used to make the surface non-opaque.
    225      * Combined effects are (assuming a buffer format with an alpha channel):
    226      * <ul>
    227      * <li>OPAQUE + alpha(1.0) == opaque composition
    228      * <li>OPAQUE + alpha(0.x) == blended composition
    229      * <li>!OPAQUE + alpha(1.0) == blended composition
    230      * <li>!OPAQUE + alpha(0.x) == blended composition
    231      * </ul>
    232      * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively
    233      * set automatically.
    234      */
    235     public static final int OPAQUE = 0x00000400;
    236 
    237     /**
    238      * Surface creation flag: Application requires a hardware-protected path to an
    239      * external display sink. If a hardware-protected path is not available,
    240      * then this surface will not be displayed on the external sink.
    241      *
    242      */
    243     public static final int PROTECTED_APP = 0x00000800;
    244 
    245     // 0x1000 is reserved for an independent DRM protected flag in framework
    246 
    247     /**
    248      * Surface creation flag: Window represents a cursor glyph.
    249      */
    250     public static final int CURSOR_WINDOW = 0x00002000;
    251 
    252     /**
    253      * Surface creation flag: Creates a normal surface.
    254      * This is the default.
    255      *
    256      */
    257     public static final int FX_SURFACE_NORMAL   = 0x00000000;
    258 
    259     /**
    260      * Surface creation flag: Creates a Dim surface.
    261      * Everything behind this surface is dimmed by the amount specified
    262      * in {@link #setAlpha}.  It is an error to lock a Dim surface, since it
    263      * doesn't have a backing store.
    264      *
    265      */
    266     public static final int FX_SURFACE_DIM = 0x00020000;
    267 
    268     /**
    269      * Mask used for FX values above.
    270      *
    271      */
    272     public static final int FX_SURFACE_MASK = 0x000F0000;
    273 
    274     /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
    275 
    276     /**
    277      * Surface flag: Hide the surface.
    278      * Equivalent to calling hide().
    279      * Updates the value set during Surface creation (see {@link #HIDDEN}).
    280      */
    281     private static final int SURFACE_HIDDEN = 0x01;
    282 
    283     /**
    284      * Surface flag: composite without blending when possible.
    285      * Updates the value set during Surface creation (see {@link #OPAQUE}).
    286      */
    287     private static final int SURFACE_OPAQUE = 0x02;
    288 
    289 
    290     /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
    291      * these are different from the logical display ids used elsewhere in the framework */
    292 
    293     /**
    294      * Built-in physical display id: Main display.
    295      * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
    296      */
    297     public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
    298 
    299     /**
    300      * Built-in physical display id: Attached HDMI display.
    301      * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
    302      */
    303     public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
    304 
    305     /* Display power modes * /
    306 
    307     /**
    308      * Display power mode off: used while blanking the screen.
    309      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
    310      */
    311     public static final int POWER_MODE_OFF = 0;
    312 
    313     /**
    314      * Display power mode doze: used while putting the screen into low power mode.
    315      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
    316      */
    317     public static final int POWER_MODE_DOZE = 1;
    318 
    319     /**
    320      * Display power mode normal: used while unblanking the screen.
    321      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
    322      */
    323     public static final int POWER_MODE_NORMAL = 2;
    324 
    325     /**
    326      * Display power mode doze: used while putting the screen into a suspended
    327      * low power mode.  Use only with {@link SurfaceControl#setDisplayPowerMode}.
    328      */
    329     public static final int POWER_MODE_DOZE_SUSPEND = 3;
    330 
    331     /**
    332      * Display power mode on: used while putting the screen into a suspended
    333      * full power mode.  Use only with {@link SurfaceControl#setDisplayPowerMode}.
    334      */
    335     public static final int POWER_MODE_ON_SUSPEND = 4;
    336 
    337     /**
    338      * A value for windowType used to indicate that the window should be omitted from screenshots
    339      * and display mirroring. A temporary workaround until we express such things with
    340      * the hierarchy.
    341      * TODO: b/64227542
    342      * @hide
    343      */
    344     public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731;
    345 
    346     /**
    347      * Builder class for {@link SurfaceControl} objects.
    348      */
    349     public static class Builder {
    350         private SurfaceSession mSession;
    351         private int mFlags = HIDDEN;
    352         private int mWidth;
    353         private int mHeight;
    354         private int mFormat = PixelFormat.OPAQUE;
    355         private String mName;
    356         private SurfaceControl mParent;
    357         private int mWindowType = -1;
    358         private int mOwnerUid = -1;
    359 
    360         /**
    361          * Begin building a SurfaceControl with a given {@link SurfaceSession}.
    362          *
    363          * @param session The {@link SurfaceSession} with which to eventually construct the surface.
    364          */
    365         public Builder(SurfaceSession session) {
    366             mSession = session;
    367         }
    368 
    369         /**
    370          * Construct a new {@link SurfaceControl} with the set parameters.
    371          */
    372         public SurfaceControl build() {
    373             if (mWidth <= 0 || mHeight <= 0) {
    374                 throw new IllegalArgumentException(
    375                         "width and height must be set");
    376             }
    377             return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat,
    378                     mFlags, mParent, mWindowType, mOwnerUid);
    379         }
    380 
    381         /**
    382          * Set a debugging-name for the SurfaceControl.
    383          *
    384          * @param name A name to identify the Surface in debugging.
    385          */
    386         public Builder setName(String name) {
    387             mName = name;
    388             return this;
    389         }
    390 
    391         /**
    392          * Set the initial size of the controlled surface's buffers in pixels.
    393          *
    394          * @param width The buffer width in pixels.
    395          * @param height The buffer height in pixels.
    396          */
    397         public Builder setSize(int width, int height) {
    398             if (width <= 0 || height <= 0) {
    399                 throw new IllegalArgumentException(
    400                         "width and height must be positive");
    401             }
    402             mWidth = width;
    403             mHeight = height;
    404             return this;
    405         }
    406 
    407         /**
    408          * Set the pixel format of the controlled surface's buffers, using constants from
    409          * {@link android.graphics.PixelFormat}.
    410          */
    411         public Builder setFormat(@PixelFormat.Format int format) {
    412             mFormat = format;
    413             return this;
    414         }
    415 
    416         /**
    417          * Specify if the app requires a hardware-protected path to
    418          * an external display sync. If protected content is enabled, but
    419          * such a path is not available, then the controlled Surface will
    420          * not be displayed.
    421          *
    422          * @param protectedContent Whether to require a protected sink.
    423          */
    424         public Builder setProtected(boolean protectedContent) {
    425             if (protectedContent) {
    426                 mFlags |= PROTECTED_APP;
    427             } else {
    428                 mFlags &= ~PROTECTED_APP;
    429             }
    430             return this;
    431         }
    432 
    433         /**
    434          * Specify whether the Surface contains secure content. If true, the system
    435          * will prevent the surfaces content from being copied by another process. In
    436          * particular screenshots and VNC servers will be disabled. This is however
    437          * not a complete prevention of readback as {@link #setProtected}.
    438          */
    439         public Builder setSecure(boolean secure) {
    440             if (secure) {
    441                 mFlags |= SECURE;
    442             } else {
    443                 mFlags &= ~SECURE;
    444             }
    445             return this;
    446         }
    447 
    448         /**
    449          * Indicates whether the surface must be considered opaque,
    450          * even if its pixel format is set to translucent. This can be useful if an
    451          * application needs full RGBA 8888 support for instance but will
    452          * still draw every pixel opaque.
    453          * <p>
    454          * This flag only determines whether opacity will be sampled from the alpha channel.
    455          * Plane-alpha from calls to setAlpha() can still result in blended composition
    456          * regardless of the opaque setting.
    457          *
    458          * Combined effects are (assuming a buffer format with an alpha channel):
    459          * <ul>
    460          * <li>OPAQUE + alpha(1.0) == opaque composition
    461          * <li>OPAQUE + alpha(0.x) == blended composition
    462          * <li>OPAQUE + alpha(0.0) == no composition
    463          * <li>!OPAQUE + alpha(1.0) == blended composition
    464          * <li>!OPAQUE + alpha(0.x) == blended composition
    465          * <li>!OPAQUE + alpha(0.0) == no composition
    466          * </ul>
    467          * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true)
    468          * were set automatically.
    469          * @param opaque Whether the Surface is OPAQUE.
    470          */
    471         public Builder setOpaque(boolean opaque) {
    472             if (opaque) {
    473                 mFlags |= OPAQUE;
    474             } else {
    475                 mFlags &= ~OPAQUE;
    476             }
    477             return this;
    478         }
    479 
    480         /**
    481          * Set a parent surface for our new SurfaceControl.
    482          *
    483          * Child surfaces are constrained to the onscreen region of their parent.
    484          * Furthermore they stack relatively in Z order, and inherit the transformation
    485          * of the parent.
    486          *
    487          * @param parent The parent control.
    488          */
    489         public Builder setParent(SurfaceControl parent) {
    490             mParent = parent;
    491             return this;
    492         }
    493 
    494         /**
    495          * Set surface metadata.
    496          *
    497          * Currently these are window-types as per {@link WindowManager.LayoutParams} and
    498          * owner UIDs. Child surfaces inherit their parents
    499          * metadata so only the WindowManager needs to set this on root Surfaces.
    500          *
    501          * @param windowType A window-type
    502          * @param ownerUid UID of the window owner.
    503          */
    504         public Builder setMetadata(int windowType, int ownerUid) {
    505             if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) {
    506                 throw new UnsupportedOperationException(
    507                         "It only makes sense to set Surface metadata from the WindowManager");
    508             }
    509             mWindowType = windowType;
    510             mOwnerUid = ownerUid;
    511             return this;
    512         }
    513 
    514         /**
    515          * Indicate whether a 'ColorLayer' is to be constructed.
    516          *
    517          * Color layers will not have an associated BufferQueue and will instead always render a
    518          * solid color (that is, solid before plane alpha). Currently that color is black.
    519          *
    520          * @param isColorLayer Whether to create a color layer.
    521          */
    522         public Builder setColorLayer(boolean isColorLayer) {
    523             if (isColorLayer) {
    524                 mFlags |= FX_SURFACE_DIM;
    525             } else {
    526                 mFlags &= ~FX_SURFACE_DIM;
    527             }
    528             return this;
    529         }
    530 
    531         /**
    532          * Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}.
    533          *
    534          * TODO: Finish conversion to individual builder methods?
    535          * @param flags The combined flags
    536          */
    537         public Builder setFlags(int flags) {
    538             mFlags = flags;
    539             return this;
    540         }
    541     }
    542 
    543     /**
    544      * Create a surface with a name.
    545      * <p>
    546      * The surface creation flags specify what kind of surface to create and
    547      * certain options such as whether the surface can be assumed to be opaque
    548      * and whether it should be initially hidden.  Surfaces should always be
    549      * created with the {@link #HIDDEN} flag set to ensure that they are not
    550      * made visible prematurely before all of the surface's properties have been
    551      * configured.
    552      * <p>
    553      * Good practice is to first create the surface with the {@link #HIDDEN} flag
    554      * specified, open a transaction, set the surface layer, layer stack, alpha,
    555      * and position, call {@link #show} if appropriate, and close the transaction.
    556      *
    557      * @param session The surface session, must not be null.
    558      * @param name The surface name, must not be null.
    559      * @param w The surface initial width.
    560      * @param h The surface initial height.
    561      * @param flags The surface creation flags.  Should always include {@link #HIDDEN}
    562      * in the creation flags.
    563      * @param windowType The type of the window as specified in WindowManager.java.
    564      * @param ownerUid A unique per-app ID.
    565      *
    566      * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
    567      */
    568     private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
    569             SurfaceControl parent, int windowType, int ownerUid)
    570                     throws OutOfResourcesException, IllegalArgumentException {
    571         if (session == null) {
    572             throw new IllegalArgumentException("session must not be null");
    573         }
    574         if (name == null) {
    575             throw new IllegalArgumentException("name must not be null");
    576         }
    577 
    578         if ((flags & SurfaceControl.HIDDEN) == 0) {
    579             Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
    580                     + "to ensure that they are not made visible prematurely before "
    581                     + "all of the surface's properties have been configured.  "
    582                     + "Set the other properties and make the surface visible within "
    583                     + "a transaction.  New surface name: " + name,
    584                     new Throwable());
    585         }
    586 
    587         mName = name;
    588         mWidth = w;
    589         mHeight = h;
    590         mNativeObject = nativeCreate(session, name, w, h, format, flags,
    591             parent != null ? parent.mNativeObject : 0, windowType, ownerUid);
    592         if (mNativeObject == 0) {
    593             throw new OutOfResourcesException(
    594                     "Couldn't allocate SurfaceControl native object");
    595         }
    596 
    597         mCloseGuard.open("release");
    598     }
    599 
    600     // This is a transfer constructor, useful for transferring a live SurfaceControl native
    601     // object to another Java wrapper which could have some different behavior, e.g.
    602     // event logging.
    603     public SurfaceControl(SurfaceControl other) {
    604         mName = other.mName;
    605         mWidth = other.mWidth;
    606         mHeight = other.mHeight;
    607         mNativeObject = other.mNativeObject;
    608         other.mCloseGuard.close();
    609         other.mNativeObject = 0;
    610         mCloseGuard.open("release");
    611     }
    612 
    613     private SurfaceControl(Parcel in) {
    614         mName = in.readString();
    615         mWidth = in.readInt();
    616         mHeight = in.readInt();
    617         mNativeObject = nativeReadFromParcel(in);
    618         if (mNativeObject == 0) {
    619             throw new IllegalArgumentException("Couldn't read SurfaceControl from parcel=" + in);
    620         }
    621         mCloseGuard.open("release");
    622     }
    623 
    624     @Override
    625     public int describeContents() {
    626         return 0;
    627     }
    628 
    629     @Override
    630     public void writeToParcel(Parcel dest, int flags) {
    631         dest.writeString(mName);
    632         dest.writeInt(mWidth);
    633         dest.writeInt(mHeight);
    634         nativeWriteToParcel(mNativeObject, dest);
    635     }
    636 
    637     /**
    638      * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
    639      * android.view.SurfaceControlProto}.
    640      *
    641      * @param proto Stream to write the SurfaceControl object to.
    642      * @param fieldId Field Id of the SurfaceControl as defined in the parent message.
    643      * @hide
    644      */
    645     public void writeToProto(ProtoOutputStream proto, long fieldId) {
    646         final long token = proto.start(fieldId);
    647         proto.write(HASH_CODE, System.identityHashCode(this));
    648         proto.write(NAME, mName);
    649         proto.end(token);
    650     }
    651 
    652     public static final Creator<SurfaceControl> CREATOR
    653             = new Creator<SurfaceControl>() {
    654         public SurfaceControl createFromParcel(Parcel in) {
    655             return new SurfaceControl(in);
    656         }
    657 
    658         public SurfaceControl[] newArray(int size) {
    659             return new SurfaceControl[size];
    660         }
    661     };
    662 
    663     @Override
    664     protected void finalize() throws Throwable {
    665         try {
    666             if (mCloseGuard != null) {
    667                 mCloseGuard.warnIfOpen();
    668             }
    669             if (mNativeObject != 0) {
    670                 nativeRelease(mNativeObject);
    671             }
    672         } finally {
    673             super.finalize();
    674         }
    675     }
    676 
    677     /**
    678      * Release the local reference to the server-side surface.
    679      * Always call release() when you're done with a Surface.
    680      * This will make the surface invalid.
    681      */
    682     public void release() {
    683         if (mNativeObject != 0) {
    684             nativeRelease(mNativeObject);
    685             mNativeObject = 0;
    686         }
    687         mCloseGuard.close();
    688     }
    689 
    690     /**
    691      * Free all server-side state associated with this surface and
    692      * release this object's reference.  This method can only be
    693      * called from the process that created the service.
    694      */
    695     public void destroy() {
    696         if (mNativeObject != 0) {
    697             nativeDestroy(mNativeObject);
    698             mNativeObject = 0;
    699         }
    700         mCloseGuard.close();
    701     }
    702 
    703     /**
    704      * Disconnect any client still connected to the surface.
    705      */
    706     public void disconnect() {
    707         if (mNativeObject != 0) {
    708             nativeDisconnect(mNativeObject);
    709         }
    710     }
    711 
    712     private void checkNotReleased() {
    713         if (mNativeObject == 0) throw new NullPointerException(
    714                 "mNativeObject is null. Have you called release() already?");
    715     }
    716 
    717     /*
    718      * set surface parameters.
    719      * needs to be inside open/closeTransaction block
    720      */
    721 
    722     /** start a transaction */
    723     public static void openTransaction() {
    724         synchronized (SurfaceControl.class) {
    725             if (sGlobalTransaction == null) {
    726                 sGlobalTransaction = new Transaction();
    727             }
    728             synchronized(SurfaceControl.class) {
    729                 sTransactionNestCount++;
    730             }
    731         }
    732     }
    733 
    734     private static void closeTransaction(boolean sync) {
    735         synchronized(SurfaceControl.class) {
    736             if (sTransactionNestCount == 0) {
    737                 Log.e(TAG, "Call to SurfaceControl.closeTransaction without matching openTransaction");
    738             } else if (--sTransactionNestCount > 0) {
    739                 return;
    740             }
    741             sGlobalTransaction.apply(sync);
    742         }
    743     }
    744 
    745     /**
    746      * Merge the supplied transaction in to the deprecated "global" transaction.
    747      * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}.
    748      * <p>
    749      * This is a utility for interop with legacy-code and will go away with the Global Transaction.
    750      */
    751     @Deprecated
    752     public static void mergeToGlobalTransaction(Transaction t) {
    753         synchronized(SurfaceControl.class) {
    754             sGlobalTransaction.merge(t);
    755         }
    756     }
    757 
    758     /** end a transaction */
    759     public static void closeTransaction() {
    760         closeTransaction(false);
    761     }
    762 
    763     public static void closeTransactionSync() {
    764         closeTransaction(true);
    765     }
    766 
    767     public void deferTransactionUntil(IBinder handle, long frame) {
    768         synchronized(SurfaceControl.class) {
    769             sGlobalTransaction.deferTransactionUntil(this, handle, frame);
    770         }
    771     }
    772 
    773     public void deferTransactionUntil(Surface barrier, long frame) {
    774         synchronized(SurfaceControl.class) {
    775             sGlobalTransaction.deferTransactionUntilSurface(this, barrier, frame);
    776         }
    777     }
    778 
    779     public void reparentChildren(IBinder newParentHandle) {
    780         synchronized(SurfaceControl.class) {
    781             sGlobalTransaction.reparentChildren(this, newParentHandle);
    782         }
    783     }
    784 
    785     public void reparent(IBinder newParentHandle) {
    786         synchronized(SurfaceControl.class) {
    787             sGlobalTransaction.reparent(this, newParentHandle);
    788         }
    789     }
    790 
    791     public void detachChildren() {
    792         synchronized(SurfaceControl.class) {
    793             sGlobalTransaction.detachChildren(this);
    794         }
    795     }
    796 
    797     public void setOverrideScalingMode(int scalingMode) {
    798         checkNotReleased();
    799         synchronized(SurfaceControl.class) {
    800             sGlobalTransaction.setOverrideScalingMode(this, scalingMode);
    801         }
    802     }
    803 
    804     public IBinder getHandle() {
    805         return nativeGetHandle(mNativeObject);
    806     }
    807 
    808     public static void setAnimationTransaction() {
    809         synchronized (SurfaceControl.class) {
    810             sGlobalTransaction.setAnimationTransaction();
    811         }
    812     }
    813 
    814     public void setLayer(int zorder) {
    815         checkNotReleased();
    816         synchronized(SurfaceControl.class) {
    817             sGlobalTransaction.setLayer(this, zorder);
    818         }
    819     }
    820 
    821     public void setRelativeLayer(SurfaceControl relativeTo, int zorder) {
    822         checkNotReleased();
    823         synchronized(SurfaceControl.class) {
    824             sGlobalTransaction.setRelativeLayer(this, relativeTo, zorder);
    825         }
    826     }
    827 
    828     public void setPosition(float x, float y) {
    829         checkNotReleased();
    830         synchronized(SurfaceControl.class) {
    831             sGlobalTransaction.setPosition(this, x, y);
    832         }
    833     }
    834 
    835     public void setGeometryAppliesWithResize() {
    836         checkNotReleased();
    837         synchronized(SurfaceControl.class) {
    838             sGlobalTransaction.setGeometryAppliesWithResize(this);
    839         }
    840     }
    841 
    842     public void setSize(int w, int h) {
    843         checkNotReleased();
    844         synchronized(SurfaceControl.class) {
    845             sGlobalTransaction.setSize(this, w, h);
    846         }
    847     }
    848 
    849     public void hide() {
    850         checkNotReleased();
    851         synchronized(SurfaceControl.class) {
    852             sGlobalTransaction.hide(this);
    853         }
    854     }
    855 
    856     public void show() {
    857         checkNotReleased();
    858         synchronized(SurfaceControl.class) {
    859             sGlobalTransaction.show(this);
    860         }
    861     }
    862 
    863     public void setTransparentRegionHint(Region region) {
    864         checkNotReleased();
    865         synchronized(SurfaceControl.class) {
    866             sGlobalTransaction.setTransparentRegionHint(this, region);
    867         }
    868     }
    869 
    870     public boolean clearContentFrameStats() {
    871         checkNotReleased();
    872         return nativeClearContentFrameStats(mNativeObject);
    873     }
    874 
    875     public boolean getContentFrameStats(WindowContentFrameStats outStats) {
    876         checkNotReleased();
    877         return nativeGetContentFrameStats(mNativeObject, outStats);
    878     }
    879 
    880     public static boolean clearAnimationFrameStats() {
    881         return nativeClearAnimationFrameStats();
    882     }
    883 
    884     public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) {
    885         return nativeGetAnimationFrameStats(outStats);
    886     }
    887 
    888     public void setAlpha(float alpha) {
    889         checkNotReleased();
    890         synchronized(SurfaceControl.class) {
    891             sGlobalTransaction.setAlpha(this, alpha);
    892         }
    893     }
    894 
    895     public void setColor(@Size(3) float[] color) {
    896         checkNotReleased();
    897         synchronized (SurfaceControl.class) {
    898             sGlobalTransaction.setColor(this, color);
    899         }
    900     }
    901 
    902     public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
    903         checkNotReleased();
    904         synchronized(SurfaceControl.class) {
    905             sGlobalTransaction.setMatrix(this, dsdx, dtdx, dtdy, dsdy);
    906         }
    907     }
    908 
    909     /**
    910      * Sets the transform and position of a {@link SurfaceControl} from a 3x3 transformation matrix.
    911      *
    912      * @param matrix The matrix to apply.
    913      * @param float9 An array of 9 floats to be used to extract the values from the matrix.
    914      */
    915     public void setMatrix(Matrix matrix, float[] float9) {
    916         checkNotReleased();
    917         matrix.getValues(float9);
    918         synchronized (SurfaceControl.class) {
    919             sGlobalTransaction.setMatrix(this, float9[MSCALE_X], float9[MSKEW_Y],
    920                     float9[MSKEW_X], float9[MSCALE_Y]);
    921             sGlobalTransaction.setPosition(this, float9[MTRANS_X], float9[MTRANS_Y]);
    922         }
    923     }
    924 
    925     public void setWindowCrop(Rect crop) {
    926         checkNotReleased();
    927         synchronized (SurfaceControl.class) {
    928             sGlobalTransaction.setWindowCrop(this, crop);
    929         }
    930     }
    931 
    932     public void setFinalCrop(Rect crop) {
    933         checkNotReleased();
    934         synchronized (SurfaceControl.class) {
    935             sGlobalTransaction.setFinalCrop(this, crop);
    936         }
    937     }
    938 
    939     public void setLayerStack(int layerStack) {
    940         checkNotReleased();
    941         synchronized(SurfaceControl.class) {
    942             sGlobalTransaction.setLayerStack(this, layerStack);
    943         }
    944     }
    945 
    946     public void setOpaque(boolean isOpaque) {
    947         checkNotReleased();
    948 
    949         synchronized (SurfaceControl.class) {
    950             sGlobalTransaction.setOpaque(this, isOpaque);
    951         }
    952     }
    953 
    954     public void setSecure(boolean isSecure) {
    955         checkNotReleased();
    956 
    957         synchronized (SurfaceControl.class) {
    958             sGlobalTransaction.setSecure(this, isSecure);
    959         }
    960     }
    961 
    962     public int getWidth() {
    963         synchronized (mSizeLock) {
    964             return mWidth;
    965         }
    966     }
    967 
    968     public int getHeight() {
    969         synchronized (mSizeLock) {
    970             return mHeight;
    971         }
    972     }
    973 
    974     @Override
    975     public String toString() {
    976         return "Surface(name=" + mName + ")/@0x" +
    977                 Integer.toHexString(System.identityHashCode(this));
    978     }
    979 
    980     /*
    981      * set display parameters.
    982      * needs to be inside open/closeTransaction block
    983      */
    984 
    985     /**
    986      * Describes the properties of a physical display known to surface flinger.
    987      */
    988     public static final class PhysicalDisplayInfo {
    989         public int width;
    990         public int height;
    991         public float refreshRate;
    992         public float density;
    993         public float xDpi;
    994         public float yDpi;
    995         public boolean secure;
    996         public long appVsyncOffsetNanos;
    997         public long presentationDeadlineNanos;
    998 
    999         public PhysicalDisplayInfo() {
   1000         }
   1001 
   1002         public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
   1003             copyFrom(other);
   1004         }
   1005 
   1006         @Override
   1007         public boolean equals(Object o) {
   1008             return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
   1009         }
   1010 
   1011         public boolean equals(PhysicalDisplayInfo other) {
   1012             return other != null
   1013                     && width == other.width
   1014                     && height == other.height
   1015                     && refreshRate == other.refreshRate
   1016                     && density == other.density
   1017                     && xDpi == other.xDpi
   1018                     && yDpi == other.yDpi
   1019                     && secure == other.secure
   1020                     && appVsyncOffsetNanos == other.appVsyncOffsetNanos
   1021                     && presentationDeadlineNanos == other.presentationDeadlineNanos;
   1022         }
   1023 
   1024         @Override
   1025         public int hashCode() {
   1026             return 0; // don't care
   1027         }
   1028 
   1029         public void copyFrom(PhysicalDisplayInfo other) {
   1030             width = other.width;
   1031             height = other.height;
   1032             refreshRate = other.refreshRate;
   1033             density = other.density;
   1034             xDpi = other.xDpi;
   1035             yDpi = other.yDpi;
   1036             secure = other.secure;
   1037             appVsyncOffsetNanos = other.appVsyncOffsetNanos;
   1038             presentationDeadlineNanos = other.presentationDeadlineNanos;
   1039         }
   1040 
   1041         // For debugging purposes
   1042         @Override
   1043         public String toString() {
   1044             return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
   1045                     + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
   1046                     + ", appVsyncOffset " + appVsyncOffsetNanos
   1047                     + ", bufferDeadline " + presentationDeadlineNanos + "}";
   1048         }
   1049     }
   1050 
   1051     public static void setDisplayPowerMode(IBinder displayToken, int mode) {
   1052         if (displayToken == null) {
   1053             throw new IllegalArgumentException("displayToken must not be null");
   1054         }
   1055         nativeSetDisplayPowerMode(displayToken, mode);
   1056     }
   1057 
   1058     public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
   1059         if (displayToken == null) {
   1060             throw new IllegalArgumentException("displayToken must not be null");
   1061         }
   1062         return nativeGetDisplayConfigs(displayToken);
   1063     }
   1064 
   1065     public static int getActiveConfig(IBinder displayToken) {
   1066         if (displayToken == null) {
   1067             throw new IllegalArgumentException("displayToken must not be null");
   1068         }
   1069         return nativeGetActiveConfig(displayToken);
   1070     }
   1071 
   1072     public static boolean setActiveConfig(IBinder displayToken, int id) {
   1073         if (displayToken == null) {
   1074             throw new IllegalArgumentException("displayToken must not be null");
   1075         }
   1076         return nativeSetActiveConfig(displayToken, id);
   1077     }
   1078 
   1079     public static int[] getDisplayColorModes(IBinder displayToken) {
   1080         if (displayToken == null) {
   1081             throw new IllegalArgumentException("displayToken must not be null");
   1082         }
   1083         return nativeGetDisplayColorModes(displayToken);
   1084     }
   1085 
   1086     public static int getActiveColorMode(IBinder displayToken) {
   1087         if (displayToken == null) {
   1088             throw new IllegalArgumentException("displayToken must not be null");
   1089         }
   1090         return nativeGetActiveColorMode(displayToken);
   1091     }
   1092 
   1093     public static boolean setActiveColorMode(IBinder displayToken, int colorMode) {
   1094         if (displayToken == null) {
   1095             throw new IllegalArgumentException("displayToken must not be null");
   1096         }
   1097         return nativeSetActiveColorMode(displayToken, colorMode);
   1098     }
   1099 
   1100     public static void setDisplayProjection(IBinder displayToken,
   1101             int orientation, Rect layerStackRect, Rect displayRect) {
   1102         synchronized (SurfaceControl.class) {
   1103             sGlobalTransaction.setDisplayProjection(displayToken, orientation,
   1104                     layerStackRect, displayRect);
   1105         }
   1106     }
   1107 
   1108     public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
   1109         synchronized (SurfaceControl.class) {
   1110             sGlobalTransaction.setDisplayLayerStack(displayToken, layerStack);
   1111         }
   1112     }
   1113 
   1114     public static void setDisplaySurface(IBinder displayToken, Surface surface) {
   1115         synchronized (SurfaceControl.class) {
   1116             sGlobalTransaction.setDisplaySurface(displayToken, surface);
   1117         }
   1118     }
   1119 
   1120     public static void setDisplaySize(IBinder displayToken, int width, int height) {
   1121         synchronized (SurfaceControl.class) {
   1122             sGlobalTransaction.setDisplaySize(displayToken, width, height);
   1123         }
   1124     }
   1125 
   1126     public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) {
   1127         if (displayToken == null) {
   1128             throw new IllegalArgumentException("displayToken must not be null");
   1129         }
   1130         return nativeGetHdrCapabilities(displayToken);
   1131     }
   1132 
   1133     public static IBinder createDisplay(String name, boolean secure) {
   1134         if (name == null) {
   1135             throw new IllegalArgumentException("name must not be null");
   1136         }
   1137         return nativeCreateDisplay(name, secure);
   1138     }
   1139 
   1140     public static void destroyDisplay(IBinder displayToken) {
   1141         if (displayToken == null) {
   1142             throw new IllegalArgumentException("displayToken must not be null");
   1143         }
   1144         nativeDestroyDisplay(displayToken);
   1145     }
   1146 
   1147     public static IBinder getBuiltInDisplay(int builtInDisplayId) {
   1148         return nativeGetBuiltInDisplay(builtInDisplayId);
   1149     }
   1150 
   1151     /**
   1152      * Copy the current screen contents into the provided {@link Surface}
   1153      *
   1154      * @param display The display to take the screenshot of.
   1155      * @param consumer The {@link Surface} to take the screenshot into.
   1156      * @param width The desired width of the returned bitmap; the raw
   1157      * screen will be scaled down to this size.
   1158      * @param height The desired height of the returned bitmap; the raw
   1159      * screen will be scaled down to this size.
   1160      * @param minLayer The lowest (bottom-most Z order) surface layer to
   1161      * include in the screenshot.
   1162      * @param maxLayer The highest (top-most Z order) surface layer to
   1163      * include in the screenshot.
   1164      * @param useIdentityTransform Replace whatever transformation (rotation,
   1165      * scaling, translation) the surface layers are currently using with the
   1166      * identity transformation while taking the screenshot.
   1167      */
   1168     public static void screenshot(IBinder display, Surface consumer,
   1169             int width, int height, int minLayer, int maxLayer,
   1170             boolean useIdentityTransform) {
   1171         screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
   1172                 false, useIdentityTransform);
   1173     }
   1174 
   1175     /**
   1176      * Copy the current screen contents into the provided {@link Surface}
   1177      *
   1178      * @param display The display to take the screenshot of.
   1179      * @param consumer The {@link Surface} to take the screenshot into.
   1180      * @param width The desired width of the returned bitmap; the raw
   1181      * screen will be scaled down to this size.
   1182      * @param height The desired height of the returned bitmap; the raw
   1183      * screen will be scaled down to this size.
   1184      */
   1185     public static void screenshot(IBinder display, Surface consumer,
   1186             int width, int height) {
   1187         screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
   1188     }
   1189 
   1190     /**
   1191      * Copy the current screen contents into the provided {@link Surface}
   1192      *
   1193      * @param display The display to take the screenshot of.
   1194      * @param consumer The {@link Surface} to take the screenshot into.
   1195      */
   1196     public static void screenshot(IBinder display, Surface consumer) {
   1197         screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
   1198     }
   1199 
   1200     /**
   1201      * Copy the current screen contents into a hardware bitmap and return it.
   1202      * Note: If you want to modify the Bitmap in software, you will need to copy the Bitmap into
   1203      * a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)}
   1204      *
   1205      * CAVEAT: Versions of screenshot that return a {@link Bitmap} can
   1206      * be extremely slow; avoid use unless absolutely necessary; prefer
   1207      * the versions that use a {@link Surface} instead, such as
   1208      * {@link SurfaceControl#screenshot(IBinder, Surface)}.
   1209      *
   1210      * @param sourceCrop The portion of the screen to capture into the Bitmap;
   1211      * caller may pass in 'new Rect()' if no cropping is desired.
   1212      * @param width The desired width of the returned bitmap; the raw
   1213      * screen will be scaled down to this size.
   1214      * @param height The desired height of the returned bitmap; the raw
   1215      * screen will be scaled down to this size.
   1216      * @param minLayer The lowest (bottom-most Z order) surface layer to
   1217      * include in the screenshot.
   1218      * @param maxLayer The highest (top-most Z order) surface layer to
   1219      * include in the screenshot.
   1220      * @param useIdentityTransform Replace whatever transformation (rotation,
   1221      * scaling, translation) the surface layers are currently using with the
   1222      * identity transformation while taking the screenshot.
   1223      * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
   1224      * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
   1225      * screenshots in its native portrait orientation by default, so this is
   1226      * useful for returning screenshots that are independent of device
   1227      * orientation.
   1228      * @return Returns a hardware Bitmap containing the screen contents, or null
   1229      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
   1230      * possible, once its content is not needed anymore.
   1231      */
   1232     public static Bitmap screenshot(Rect sourceCrop, int width, int height,
   1233             int minLayer, int maxLayer, boolean useIdentityTransform,
   1234             int rotation) {
   1235         // TODO: should take the display as a parameter
   1236         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
   1237                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
   1238         return nativeScreenshot(displayToken, sourceCrop, width, height,
   1239                 minLayer, maxLayer, false, useIdentityTransform, rotation);
   1240     }
   1241 
   1242     /**
   1243      * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)}
   1244      * but returns a GraphicBuffer.
   1245      */
   1246     public static GraphicBuffer screenshotToBuffer(Rect sourceCrop, int width, int height,
   1247             int minLayer, int maxLayer, boolean useIdentityTransform,
   1248             int rotation) {
   1249         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
   1250                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
   1251         return nativeScreenshotToBuffer(displayToken, sourceCrop, width, height,
   1252                 minLayer, maxLayer, false, useIdentityTransform, rotation);
   1253     }
   1254 
   1255     /**
   1256      * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)} but
   1257      * includes all Surfaces in the screenshot. This will also update the orientation so it
   1258      * sends the correct coordinates to SF based on the rotation value.
   1259      *
   1260      * @param sourceCrop The portion of the screen to capture into the Bitmap;
   1261      * caller may pass in 'new Rect()' if no cropping is desired.
   1262      * @param width The desired width of the returned bitmap; the raw
   1263      * screen will be scaled down to this size.
   1264      * @param height The desired height of the returned bitmap; the raw
   1265      * screen will be scaled down to this size.
   1266      * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
   1267      * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
   1268      * screenshots in its native portrait orientation by default, so this is
   1269      * useful for returning screenshots that are independent of device
   1270      * orientation.
   1271      * @return Returns a Bitmap containing the screen contents, or null
   1272      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
   1273      * possible, once its content is not needed anymore.
   1274      */
   1275     public static Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) {
   1276         // TODO: should take the display as a parameter
   1277         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
   1278                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
   1279         if (rotation == ROTATION_90 || rotation == ROTATION_270) {
   1280             rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90;
   1281         }
   1282 
   1283         SurfaceControl.rotateCropForSF(sourceCrop, rotation);
   1284         return nativeScreenshot(displayToken, sourceCrop, width, height, 0, 0, true,
   1285                 false, rotation);
   1286     }
   1287 
   1288     private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
   1289             int width, int height, int minLayer, int maxLayer, boolean allLayers,
   1290             boolean useIdentityTransform) {
   1291         if (display == null) {
   1292             throw new IllegalArgumentException("displayToken must not be null");
   1293         }
   1294         if (consumer == null) {
   1295             throw new IllegalArgumentException("consumer must not be null");
   1296         }
   1297         nativeScreenshot(display, consumer, sourceCrop, width, height,
   1298                 minLayer, maxLayer, allLayers, useIdentityTransform);
   1299     }
   1300 
   1301     private static void rotateCropForSF(Rect crop, int rot) {
   1302         if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
   1303             int tmp = crop.top;
   1304             crop.top = crop.left;
   1305             crop.left = tmp;
   1306             tmp = crop.right;
   1307             crop.right = crop.bottom;
   1308             crop.bottom = tmp;
   1309         }
   1310     }
   1311 
   1312     /**
   1313      * Captures a layer and its children and returns a {@link GraphicBuffer} with the content.
   1314      *
   1315      * @param layerHandleToken The root layer to capture.
   1316      * @param sourceCrop       The portion of the root surface to capture; caller may pass in 'new
   1317      *                         Rect()' or null if no cropping is desired.
   1318      * @param frameScale       The desired scale of the returned buffer; the raw
   1319      *                         screen will be scaled up/down.
   1320      *
   1321      * @return Returns a GraphicBuffer that contains the layer capture.
   1322      */
   1323     public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
   1324             float frameScale) {
   1325         return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale);
   1326     }
   1327 
   1328     public static class Transaction implements Closeable {
   1329         public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
   1330                 Transaction.class.getClassLoader(),
   1331                 nativeGetNativeTransactionFinalizer(), 512);
   1332         private long mNativeObject;
   1333 
   1334         private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>();
   1335         Runnable mFreeNativeResources;
   1336 
   1337         public Transaction() {
   1338             mNativeObject = nativeCreateTransaction();
   1339             mFreeNativeResources
   1340                 = sRegistry.registerNativeAllocation(this, mNativeObject);
   1341         }
   1342 
   1343         /**
   1344          * Apply the transaction, clearing it's state, and making it usable
   1345          * as a new transaction.
   1346          */
   1347         public void apply() {
   1348             apply(false);
   1349         }
   1350 
   1351         /**
   1352          * Close the transaction, if the transaction was not already applied this will cancel the
   1353          * transaction.
   1354          */
   1355         @Override
   1356         public void close() {
   1357             mFreeNativeResources.run();
   1358             mNativeObject = 0;
   1359         }
   1360 
   1361         /**
   1362          * Jankier version of apply. Avoid use (b/28068298).
   1363          */
   1364         public void apply(boolean sync) {
   1365             applyResizedSurfaces();
   1366             nativeApplyTransaction(mNativeObject, sync);
   1367         }
   1368 
   1369         private void applyResizedSurfaces() {
   1370             for (int i = mResizedSurfaces.size() - 1; i >= 0; i--) {
   1371                 final Point size = mResizedSurfaces.valueAt(i);
   1372                 final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i);
   1373                 synchronized (surfaceControl.mSizeLock) {
   1374                     surfaceControl.mWidth = size.x;
   1375                     surfaceControl.mHeight = size.y;
   1376                 }
   1377             }
   1378             mResizedSurfaces.clear();
   1379         }
   1380 
   1381         public Transaction show(SurfaceControl sc) {
   1382             sc.checkNotReleased();
   1383             nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN);
   1384             return this;
   1385         }
   1386 
   1387         public Transaction hide(SurfaceControl sc) {
   1388             sc.checkNotReleased();
   1389             nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
   1390             return this;
   1391         }
   1392 
   1393         public Transaction setPosition(SurfaceControl sc, float x, float y) {
   1394             sc.checkNotReleased();
   1395             nativeSetPosition(mNativeObject, sc.mNativeObject, x, y);
   1396             return this;
   1397         }
   1398 
   1399         public Transaction setSize(SurfaceControl sc, int w, int h) {
   1400             sc.checkNotReleased();
   1401             mResizedSurfaces.put(sc, new Point(w, h));
   1402             nativeSetSize(mNativeObject, sc.mNativeObject, w, h);
   1403             return this;
   1404         }
   1405 
   1406         public Transaction setLayer(SurfaceControl sc, int z) {
   1407             sc.checkNotReleased();
   1408             nativeSetLayer(mNativeObject, sc.mNativeObject, z);
   1409             return this;
   1410         }
   1411 
   1412         public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) {
   1413             sc.checkNotReleased();
   1414             nativeSetRelativeLayer(mNativeObject, sc.mNativeObject,
   1415                     relativeTo.getHandle(), z);
   1416             return this;
   1417         }
   1418 
   1419         public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) {
   1420             sc.checkNotReleased();
   1421             nativeSetTransparentRegionHint(mNativeObject,
   1422                     sc.mNativeObject, transparentRegion);
   1423             return this;
   1424         }
   1425 
   1426         public Transaction setAlpha(SurfaceControl sc, float alpha) {
   1427             sc.checkNotReleased();
   1428             nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha);
   1429             return this;
   1430         }
   1431 
   1432         public Transaction setMatrix(SurfaceControl sc,
   1433                 float dsdx, float dtdx, float dtdy, float dsdy) {
   1434             sc.checkNotReleased();
   1435             nativeSetMatrix(mNativeObject, sc.mNativeObject,
   1436                     dsdx, dtdx, dtdy, dsdy);
   1437             return this;
   1438         }
   1439 
   1440         public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) {
   1441             matrix.getValues(float9);
   1442             setMatrix(sc, float9[MSCALE_X], float9[MSKEW_Y],
   1443                     float9[MSKEW_X], float9[MSCALE_Y]);
   1444             setPosition(sc, float9[MTRANS_X], float9[MTRANS_Y]);
   1445             return this;
   1446         }
   1447 
   1448         public Transaction setWindowCrop(SurfaceControl sc, Rect crop) {
   1449             sc.checkNotReleased();
   1450             if (crop != null) {
   1451                 nativeSetWindowCrop(mNativeObject, sc.mNativeObject,
   1452                         crop.left, crop.top, crop.right, crop.bottom);
   1453             } else {
   1454                 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
   1455             }
   1456 
   1457             return this;
   1458         }
   1459 
   1460         public Transaction setFinalCrop(SurfaceControl sc, Rect crop) {
   1461             sc.checkNotReleased();
   1462             if (crop != null) {
   1463                 nativeSetFinalCrop(mNativeObject, sc.mNativeObject,
   1464                         crop.left, crop.top, crop.right, crop.bottom);
   1465             } else {
   1466                 nativeSetFinalCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
   1467             }
   1468 
   1469             return this;
   1470         }
   1471 
   1472         public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
   1473             sc.checkNotReleased();
   1474             nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
   1475             return this;
   1476         }
   1477 
   1478         public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle,
   1479                 long frameNumber) {
   1480             if (frameNumber < 0) {
   1481                 return this;
   1482             }
   1483             sc.checkNotReleased();
   1484             nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, handle, frameNumber);
   1485             return this;
   1486         }
   1487 
   1488         public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface,
   1489                 long frameNumber) {
   1490             if (frameNumber < 0) {
   1491                 return this;
   1492             }
   1493             sc.checkNotReleased();
   1494             nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject,
   1495                     barrierSurface.mNativeObject, frameNumber);
   1496             return this;
   1497         }
   1498 
   1499         public Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) {
   1500             sc.checkNotReleased();
   1501             nativeReparentChildren(mNativeObject, sc.mNativeObject, newParentHandle);
   1502             return this;
   1503         }
   1504 
   1505         /** Re-parents a specific child layer to a new parent */
   1506         public Transaction reparent(SurfaceControl sc, IBinder newParentHandle) {
   1507             sc.checkNotReleased();
   1508             nativeReparent(mNativeObject, sc.mNativeObject,
   1509                     newParentHandle);
   1510             return this;
   1511         }
   1512 
   1513         public Transaction detachChildren(SurfaceControl sc) {
   1514             sc.checkNotReleased();
   1515             nativeSeverChildren(mNativeObject, sc.mNativeObject);
   1516             return this;
   1517         }
   1518 
   1519         public Transaction setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode) {
   1520             sc.checkNotReleased();
   1521             nativeSetOverrideScalingMode(mNativeObject, sc.mNativeObject,
   1522                     overrideScalingMode);
   1523             return this;
   1524         }
   1525 
   1526         /**
   1527          * Sets a color for the Surface.
   1528          * @param color A float array with three values to represent r, g, b in range [0..1]
   1529          */
   1530         public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) {
   1531             sc.checkNotReleased();
   1532             nativeSetColor(mNativeObject, sc.mNativeObject, color);
   1533             return this;
   1534         }
   1535 
   1536         /**
   1537          * If the buffer size changes in this transaction, position and crop updates specified
   1538          * in this transaction will not complete until a buffer of the new size
   1539          * arrives. As transform matrix and size are already frozen in this fashion,
   1540          * this enables totally freezing the surface until the resize has completed
   1541          * (at which point the geometry influencing aspects of this transaction will then occur)
   1542          */
   1543         public Transaction setGeometryAppliesWithResize(SurfaceControl sc) {
   1544             sc.checkNotReleased();
   1545             nativeSetGeometryAppliesWithResize(mNativeObject, sc.mNativeObject);
   1546             return this;
   1547         }
   1548 
   1549         /**
   1550          * Sets the security of the surface.  Setting the flag is equivalent to creating the
   1551          * Surface with the {@link #SECURE} flag.
   1552          */
   1553         public Transaction setSecure(SurfaceControl sc, boolean isSecure) {
   1554             sc.checkNotReleased();
   1555             if (isSecure) {
   1556                 nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE);
   1557             } else {
   1558                 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE);
   1559             }
   1560             return this;
   1561         }
   1562 
   1563         /**
   1564          * Sets the opacity of the surface.  Setting the flag is equivalent to creating the
   1565          * Surface with the {@link #OPAQUE} flag.
   1566          */
   1567         public Transaction setOpaque(SurfaceControl sc, boolean isOpaque) {
   1568             sc.checkNotReleased();
   1569             if (isOpaque) {
   1570                 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE);
   1571             } else {
   1572                 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_OPAQUE);
   1573             }
   1574             return this;
   1575         }
   1576 
   1577         /**
   1578          * Same as {@link #destroy()} except this is invoked in a transaction instead of
   1579          * immediately.
   1580          */
   1581         public Transaction destroy(SurfaceControl sc) {
   1582             sc.checkNotReleased();
   1583 
   1584             /**
   1585              * Perhaps it's safer to transfer the close guard to the Transaction
   1586              * but then we have a whole wonky scenario regarding merging, multiple
   1587              * close-guards per transaction etc...the whole scenario is kind of wonky
   1588              * and it seems really we'd like to just be able to call release here
   1589              * but the WindowManager has some code that looks like
   1590              * --- destroyInTransaction(a)
   1591              * --- reparentChildrenInTransaction(a)
   1592              * so we need to ensure the SC remains valid until the transaction
   1593              * is applied.
   1594              */
   1595             sc.mCloseGuard.close();
   1596 
   1597             nativeDestroy(mNativeObject, sc.mNativeObject);
   1598             return this;
   1599         }
   1600 
   1601         public Transaction setDisplaySurface(IBinder displayToken, Surface surface) {
   1602             if (displayToken == null) {
   1603                 throw new IllegalArgumentException("displayToken must not be null");
   1604             }
   1605 
   1606             if (surface != null) {
   1607                 synchronized (surface.mLock) {
   1608                     nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject);
   1609                 }
   1610             } else {
   1611                 nativeSetDisplaySurface(mNativeObject, displayToken, 0);
   1612             }
   1613             return this;
   1614         }
   1615 
   1616         public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) {
   1617             if (displayToken == null) {
   1618                 throw new IllegalArgumentException("displayToken must not be null");
   1619             }
   1620             nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack);
   1621             return this;
   1622         }
   1623 
   1624         public Transaction setDisplayProjection(IBinder displayToken,
   1625                 int orientation, Rect layerStackRect, Rect displayRect) {
   1626             if (displayToken == null) {
   1627                 throw new IllegalArgumentException("displayToken must not be null");
   1628             }
   1629             if (layerStackRect == null) {
   1630                 throw new IllegalArgumentException("layerStackRect must not be null");
   1631             }
   1632             if (displayRect == null) {
   1633                 throw new IllegalArgumentException("displayRect must not be null");
   1634             }
   1635             nativeSetDisplayProjection(mNativeObject, displayToken, orientation,
   1636                     layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
   1637                     displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
   1638             return this;
   1639         }
   1640 
   1641         public Transaction setDisplaySize(IBinder displayToken, int width, int height) {
   1642             if (displayToken == null) {
   1643                 throw new IllegalArgumentException("displayToken must not be null");
   1644             }
   1645             if (width <= 0 || height <= 0) {
   1646                 throw new IllegalArgumentException("width and height must be positive");
   1647             }
   1648 
   1649             nativeSetDisplaySize(mNativeObject, displayToken, width, height);
   1650             return this;
   1651         }
   1652 
   1653         /** flag the transaction as an animation */
   1654         public Transaction setAnimationTransaction() {
   1655             nativeSetAnimationTransaction(mNativeObject);
   1656             return this;
   1657         }
   1658 
   1659         /**
   1660          * Indicate that SurfaceFlinger should wake up earlier than usual as a result of this
   1661          * transaction. This should be used when the caller thinks that the scene is complex enough
   1662          * that it's likely to hit GL composition, and thus, SurfaceFlinger needs to more time in
   1663          * order not to miss frame deadlines.
   1664          * <p>
   1665          * Corresponds to setting ISurfaceComposer::eEarlyWakeup
   1666          */
   1667         public Transaction setEarlyWakeup() {
   1668             nativeSetEarlyWakeup(mNativeObject);
   1669             return this;
   1670         }
   1671 
   1672         /**
   1673          * Merge the other transaction into this transaction, clearing the
   1674          * other transaction as if it had been applied.
   1675          */
   1676         public Transaction merge(Transaction other) {
   1677             mResizedSurfaces.putAll(other.mResizedSurfaces);
   1678             other.mResizedSurfaces.clear();
   1679             nativeMergeTransaction(mNativeObject, other.mNativeObject);
   1680             return this;
   1681         }
   1682     }
   1683 }
   1684