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 dalvik.system.CloseGuard;
     20 import android.graphics.Bitmap;
     21 import android.graphics.Rect;
     22 import android.graphics.Region;
     23 import android.os.IBinder;
     24 import android.util.Log;
     25 import android.view.Surface.OutOfResourcesException;
     26 
     27 /**
     28  * SurfaceControl
     29  *  @hide
     30  */
     31 public class SurfaceControl {
     32     private static final String TAG = "SurfaceControl";
     33 
     34     private static native long nativeCreate(SurfaceSession session, String name,
     35             int w, int h, int format, int flags)
     36             throws OutOfResourcesException;
     37     private static native void nativeRelease(long nativeObject);
     38     private static native void nativeDestroy(long nativeObject);
     39 
     40     private static native Bitmap nativeScreenshot(IBinder displayToken,
     41             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
     42             boolean allLayers, boolean useIdentityTransform, int rotation);
     43     private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
     44             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
     45             boolean allLayers, boolean useIdentityTransform);
     46 
     47     private static native void nativeOpenTransaction();
     48     private static native void nativeCloseTransaction();
     49     private static native void nativeSetAnimationTransaction();
     50 
     51     private static native void nativeSetLayer(long nativeObject, int zorder);
     52     private static native void nativeSetPosition(long nativeObject, float x, float y);
     53     private static native void nativeSetSize(long nativeObject, int w, int h);
     54     private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
     55     private static native void nativeSetAlpha(long nativeObject, float alpha);
     56     private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
     57     private static native void nativeSetFlags(long nativeObject, int flags, int mask);
     58     private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
     59     private static native void nativeSetLayerStack(long nativeObject, int layerStack);
     60 
     61     private static native boolean nativeClearContentFrameStats(long nativeObject);
     62     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
     63     private static native boolean nativeClearAnimationFrameStats();
     64     private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
     65 
     66     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
     67     private static native IBinder nativeCreateDisplay(String name, boolean secure);
     68     private static native void nativeDestroyDisplay(IBinder displayToken);
     69     private static native void nativeSetDisplaySurface(
     70             IBinder displayToken, long nativeSurfaceObject);
     71     private static native void nativeSetDisplayLayerStack(
     72             IBinder displayToken, int layerStack);
     73     private static native void nativeSetDisplayProjection(
     74             IBinder displayToken, int orientation,
     75             int l, int t, int r, int b,
     76             int L, int T, int R, int B);
     77     private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
     78     private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
     79             IBinder displayToken);
     80     private static native int nativeGetActiveConfig(IBinder displayToken);
     81     private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
     82     private static native void nativeSetDisplayPowerMode(
     83             IBinder displayToken, int mode);
     84 
     85 
     86     private final CloseGuard mCloseGuard = CloseGuard.get();
     87     private final String mName;
     88     long mNativeObject; // package visibility only for Surface.java access
     89 
     90     /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
     91 
     92     /**
     93      * Surface creation flag: Surface is created hidden
     94      */
     95     public static final int HIDDEN = 0x00000004;
     96 
     97     /**
     98      * Surface creation flag: The surface contains secure content, special
     99      * measures will be taken to disallow the surface's content to be copied
    100      * from another process. In particular, screenshots and VNC servers will
    101      * be disabled, but other measures can take place, for instance the
    102      * surface might not be hardware accelerated.
    103      *
    104      */
    105     public static final int SECURE = 0x00000080;
    106 
    107     /**
    108      * Surface creation flag: Creates a surface where color components are interpreted
    109      * as "non pre-multiplied" by their alpha channel. Of course this flag is
    110      * meaningless for surfaces without an alpha channel. By default
    111      * surfaces are pre-multiplied, which means that each color component is
    112      * already multiplied by its alpha value. In this case the blending
    113      * equation used is:
    114      * <p>
    115      *    <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code>
    116      * <p>
    117      * By contrast, non pre-multiplied surfaces use the following equation:
    118      * <p>
    119      *    <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code>
    120      * <p>
    121      * pre-multiplied surfaces must always be used if transparent pixels are
    122      * composited on top of each-other into the surface. A pre-multiplied
    123      * surface can never lower the value of the alpha component of a given
    124      * pixel.
    125      * <p>
    126      * In some rare situations, a non pre-multiplied surface is preferable.
    127      *
    128      */
    129     public static final int NON_PREMULTIPLIED = 0x00000100;
    130 
    131     /**
    132      * Surface creation flag: Indicates that the surface must be considered opaque,
    133      * even if its pixel format is set to translucent. This can be useful if an
    134      * application needs full RGBA 8888 support for instance but will
    135      * still draw every pixel opaque.
    136      * <p>
    137      * This flag is ignored if setAlpha() is used to make the surface non-opaque.
    138      * Combined effects are (assuming a buffer format with an alpha channel):
    139      * <ul>
    140      * <li>OPAQUE + alpha(1.0) == opaque composition
    141      * <li>OPAQUE + alpha(0.x) == blended composition
    142      * <li>!OPAQUE + alpha(1.0) == blended composition
    143      * <li>!OPAQUE + alpha(0.x) == blended composition
    144      * </ul>
    145      * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively
    146      * set automatically.
    147      */
    148     public static final int OPAQUE = 0x00000400;
    149 
    150     /**
    151      * Surface creation flag: Application requires a hardware-protected path to an
    152      * external display sink. If a hardware-protected path is not available,
    153      * then this surface will not be displayed on the external sink.
    154      *
    155      */
    156     public static final int PROTECTED_APP = 0x00000800;
    157 
    158     // 0x1000 is reserved for an independent DRM protected flag in framework
    159 
    160     /**
    161      * Surface creation flag: Window represents a cursor glyph.
    162      */
    163     public static final int CURSOR_WINDOW = 0x00002000;
    164 
    165     /**
    166      * Surface creation flag: Creates a normal surface.
    167      * This is the default.
    168      *
    169      */
    170     public static final int FX_SURFACE_NORMAL   = 0x00000000;
    171 
    172     /**
    173      * Surface creation flag: Creates a Dim surface.
    174      * Everything behind this surface is dimmed by the amount specified
    175      * in {@link #setAlpha}.  It is an error to lock a Dim surface, since it
    176      * doesn't have a backing store.
    177      *
    178      */
    179     public static final int FX_SURFACE_DIM = 0x00020000;
    180 
    181     /**
    182      * Mask used for FX values above.
    183      *
    184      */
    185     public static final int FX_SURFACE_MASK = 0x000F0000;
    186 
    187     /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
    188 
    189     /**
    190      * Surface flag: Hide the surface.
    191      * Equivalent to calling hide().
    192      * Updates the value set during Surface creation (see {@link #HIDDEN}).
    193      */
    194     private static final int SURFACE_HIDDEN = 0x01;
    195 
    196     /**
    197      * Surface flag: composite without blending when possible.
    198      * Updates the value set during Surface creation (see {@link #OPAQUE}).
    199      */
    200     private static final int SURFACE_OPAQUE = 0x02;
    201 
    202 
    203     /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
    204      * these are different from the logical display ids used elsewhere in the framework */
    205 
    206     /**
    207      * Built-in physical display id: Main display.
    208      * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
    209      */
    210     public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
    211 
    212     /**
    213      * Built-in physical display id: Attached HDMI display.
    214      * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
    215      */
    216     public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
    217 
    218     /* Display power modes * /
    219 
    220     /**
    221      * Display power mode off: used while blanking the screen.
    222      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
    223      */
    224     public static final int POWER_MODE_OFF = 0;
    225 
    226     /**
    227      * Display power mode doze: used while putting the screen into low power mode.
    228      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
    229      */
    230     public static final int POWER_MODE_DOZE = 1;
    231 
    232     /**
    233      * Display power mode normal: used while unblanking the screen.
    234      * Use only with {@link SurfaceControl#setDisplayPowerMode}.
    235      */
    236     public static final int POWER_MODE_NORMAL = 2;
    237 
    238     /**
    239      * Display power mode doze: used while putting the screen into a suspended
    240      * low power mode.  Use only with {@link SurfaceControl#setDisplayPowerMode}.
    241      */
    242     public static final int POWER_MODE_DOZE_SUSPEND = 3;
    243 
    244     /**
    245      * Create a surface with a name.
    246      * <p>
    247      * The surface creation flags specify what kind of surface to create and
    248      * certain options such as whether the surface can be assumed to be opaque
    249      * and whether it should be initially hidden.  Surfaces should always be
    250      * created with the {@link #HIDDEN} flag set to ensure that they are not
    251      * made visible prematurely before all of the surface's properties have been
    252      * configured.
    253      * <p>
    254      * Good practice is to first create the surface with the {@link #HIDDEN} flag
    255      * specified, open a transaction, set the surface layer, layer stack, alpha,
    256      * and position, call {@link #show} if appropriate, and close the transaction.
    257      *
    258      * @param session The surface session, must not be null.
    259      * @param name The surface name, must not be null.
    260      * @param w The surface initial width.
    261      * @param h The surface initial height.
    262      * @param flags The surface creation flags.  Should always include {@link #HIDDEN}
    263      * in the creation flags.
    264      *
    265      * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
    266      */
    267     public SurfaceControl(SurfaceSession session,
    268             String name, int w, int h, int format, int flags)
    269                     throws OutOfResourcesException {
    270         if (session == null) {
    271             throw new IllegalArgumentException("session must not be null");
    272         }
    273         if (name == null) {
    274             throw new IllegalArgumentException("name must not be null");
    275         }
    276 
    277         if ((flags & SurfaceControl.HIDDEN) == 0) {
    278             Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
    279                     + "to ensure that they are not made visible prematurely before "
    280                     + "all of the surface's properties have been configured.  "
    281                     + "Set the other properties and make the surface visible within "
    282                     + "a transaction.  New surface name: " + name,
    283                     new Throwable());
    284         }
    285 
    286         mName = name;
    287         mNativeObject = nativeCreate(session, name, w, h, format, flags);
    288         if (mNativeObject == 0) {
    289             throw new OutOfResourcesException(
    290                     "Couldn't allocate SurfaceControl native object");
    291         }
    292 
    293         mCloseGuard.open("release");
    294     }
    295 
    296     @Override
    297     protected void finalize() throws Throwable {
    298         try {
    299             if (mCloseGuard != null) {
    300                 mCloseGuard.warnIfOpen();
    301             }
    302             if (mNativeObject != 0) {
    303                 nativeRelease(mNativeObject);
    304             }
    305         } finally {
    306             super.finalize();
    307         }
    308     }
    309 
    310     @Override
    311     public String toString() {
    312         return "Surface(name=" + mName + ")";
    313     }
    314 
    315     /**
    316      * Release the local reference to the server-side surface.
    317      * Always call release() when you're done with a Surface.
    318      * This will make the surface invalid.
    319      */
    320     public void release() {
    321         if (mNativeObject != 0) {
    322             nativeRelease(mNativeObject);
    323             mNativeObject = 0;
    324         }
    325         mCloseGuard.close();
    326     }
    327 
    328     /**
    329      * Free all server-side state associated with this surface and
    330      * release this object's reference.  This method can only be
    331      * called from the process that created the service.
    332      */
    333     public void destroy() {
    334         if (mNativeObject != 0) {
    335             nativeDestroy(mNativeObject);
    336             mNativeObject = 0;
    337         }
    338         mCloseGuard.close();
    339     }
    340 
    341     private void checkNotReleased() {
    342         if (mNativeObject == 0) throw new NullPointerException(
    343                 "mNativeObject is null. Have you called release() already?");
    344     }
    345 
    346     /*
    347      * set surface parameters.
    348      * needs to be inside open/closeTransaction block
    349      */
    350 
    351     /** start a transaction */
    352     public static void openTransaction() {
    353         nativeOpenTransaction();
    354     }
    355 
    356     /** end a transaction */
    357     public static void closeTransaction() {
    358         nativeCloseTransaction();
    359     }
    360 
    361     /** flag the transaction as an animation */
    362     public static void setAnimationTransaction() {
    363         nativeSetAnimationTransaction();
    364     }
    365 
    366     public void setLayer(int zorder) {
    367         checkNotReleased();
    368         nativeSetLayer(mNativeObject, zorder);
    369     }
    370 
    371     public void setPosition(float x, float y) {
    372         checkNotReleased();
    373         nativeSetPosition(mNativeObject, x, y);
    374     }
    375 
    376     public void setSize(int w, int h) {
    377         checkNotReleased();
    378         nativeSetSize(mNativeObject, w, h);
    379     }
    380 
    381     public void hide() {
    382         checkNotReleased();
    383         nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
    384     }
    385 
    386     public void show() {
    387         checkNotReleased();
    388         nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
    389     }
    390 
    391     public void setTransparentRegionHint(Region region) {
    392         checkNotReleased();
    393         nativeSetTransparentRegionHint(mNativeObject, region);
    394     }
    395 
    396     public boolean clearContentFrameStats() {
    397         checkNotReleased();
    398         return nativeClearContentFrameStats(mNativeObject);
    399     }
    400 
    401     public boolean getContentFrameStats(WindowContentFrameStats outStats) {
    402         checkNotReleased();
    403         return nativeGetContentFrameStats(mNativeObject, outStats);
    404     }
    405 
    406     public static boolean clearAnimationFrameStats() {
    407         return nativeClearAnimationFrameStats();
    408     }
    409 
    410     public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) {
    411         return nativeGetAnimationFrameStats(outStats);
    412     }
    413 
    414     /**
    415      * Sets an alpha value for the entire Surface.  This value is combined with the
    416      * per-pixel alpha.  It may be used with opaque Surfaces.
    417      */
    418     public void setAlpha(float alpha) {
    419         checkNotReleased();
    420         nativeSetAlpha(mNativeObject, alpha);
    421     }
    422 
    423     public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
    424         checkNotReleased();
    425         nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
    426     }
    427 
    428     public void setWindowCrop(Rect crop) {
    429         checkNotReleased();
    430         if (crop != null) {
    431             nativeSetWindowCrop(mNativeObject,
    432                 crop.left, crop.top, crop.right, crop.bottom);
    433         } else {
    434             nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
    435         }
    436     }
    437 
    438     public void setLayerStack(int layerStack) {
    439         checkNotReleased();
    440         nativeSetLayerStack(mNativeObject, layerStack);
    441     }
    442 
    443     /**
    444      * Sets the opacity of the surface.  Setting the flag is equivalent to creating the
    445      * Surface with the {@link #OPAQUE} flag.
    446      */
    447     public void setOpaque(boolean isOpaque) {
    448         checkNotReleased();
    449         if (isOpaque) {
    450             nativeSetFlags(mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE);
    451         } else {
    452             nativeSetFlags(mNativeObject, 0, SURFACE_OPAQUE);
    453         }
    454     }
    455 
    456     /*
    457      * set display parameters.
    458      * needs to be inside open/closeTransaction block
    459      */
    460 
    461     /**
    462      * Describes the properties of a physical display known to surface flinger.
    463      */
    464     public static final class PhysicalDisplayInfo {
    465         public int width;
    466         public int height;
    467         public float refreshRate;
    468         public float density;
    469         public float xDpi;
    470         public float yDpi;
    471         public boolean secure;
    472         public long appVsyncOffsetNanos;
    473         public long presentationDeadlineNanos;
    474 
    475         public PhysicalDisplayInfo() {
    476         }
    477 
    478         public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
    479             copyFrom(other);
    480         }
    481 
    482         @Override
    483         public boolean equals(Object o) {
    484             return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
    485         }
    486 
    487         public boolean equals(PhysicalDisplayInfo other) {
    488             return other != null
    489                     && width == other.width
    490                     && height == other.height
    491                     && refreshRate == other.refreshRate
    492                     && density == other.density
    493                     && xDpi == other.xDpi
    494                     && yDpi == other.yDpi
    495                     && secure == other.secure
    496                     && appVsyncOffsetNanos == other.appVsyncOffsetNanos
    497                     && presentationDeadlineNanos == other.presentationDeadlineNanos;
    498         }
    499 
    500         @Override
    501         public int hashCode() {
    502             return 0; // don't care
    503         }
    504 
    505         public void copyFrom(PhysicalDisplayInfo other) {
    506             width = other.width;
    507             height = other.height;
    508             refreshRate = other.refreshRate;
    509             density = other.density;
    510             xDpi = other.xDpi;
    511             yDpi = other.yDpi;
    512             secure = other.secure;
    513             appVsyncOffsetNanos = other.appVsyncOffsetNanos;
    514             presentationDeadlineNanos = other.presentationDeadlineNanos;
    515         }
    516 
    517         // For debugging purposes
    518         @Override
    519         public String toString() {
    520             return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
    521                     + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
    522                     + ", appVsyncOffset " + appVsyncOffsetNanos
    523                     + ", bufferDeadline " + presentationDeadlineNanos + "}";
    524         }
    525     }
    526 
    527     public static void setDisplayPowerMode(IBinder displayToken, int mode) {
    528         if (displayToken == null) {
    529             throw new IllegalArgumentException("displayToken must not be null");
    530         }
    531         nativeSetDisplayPowerMode(displayToken, mode);
    532     }
    533 
    534     public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
    535         if (displayToken == null) {
    536             throw new IllegalArgumentException("displayToken must not be null");
    537         }
    538         return nativeGetDisplayConfigs(displayToken);
    539     }
    540 
    541     public static int getActiveConfig(IBinder displayToken) {
    542         if (displayToken == null) {
    543             throw new IllegalArgumentException("displayToken must not be null");
    544         }
    545         return nativeGetActiveConfig(displayToken);
    546     }
    547 
    548     public static boolean setActiveConfig(IBinder displayToken, int id) {
    549         if (displayToken == null) {
    550             throw new IllegalArgumentException("displayToken must not be null");
    551         }
    552         return nativeSetActiveConfig(displayToken, id);
    553     }
    554 
    555     public static void setDisplayProjection(IBinder displayToken,
    556             int orientation, Rect layerStackRect, Rect displayRect) {
    557         if (displayToken == null) {
    558             throw new IllegalArgumentException("displayToken must not be null");
    559         }
    560         if (layerStackRect == null) {
    561             throw new IllegalArgumentException("layerStackRect must not be null");
    562         }
    563         if (displayRect == null) {
    564             throw new IllegalArgumentException("displayRect must not be null");
    565         }
    566         nativeSetDisplayProjection(displayToken, orientation,
    567                 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
    568                 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
    569     }
    570 
    571     public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
    572         if (displayToken == null) {
    573             throw new IllegalArgumentException("displayToken must not be null");
    574         }
    575         nativeSetDisplayLayerStack(displayToken, layerStack);
    576     }
    577 
    578     public static void setDisplaySurface(IBinder displayToken, Surface surface) {
    579         if (displayToken == null) {
    580             throw new IllegalArgumentException("displayToken must not be null");
    581         }
    582 
    583         if (surface != null) {
    584             synchronized (surface.mLock) {
    585                 nativeSetDisplaySurface(displayToken, surface.mNativeObject);
    586             }
    587         } else {
    588             nativeSetDisplaySurface(displayToken, 0);
    589         }
    590     }
    591 
    592     public static void setDisplaySize(IBinder displayToken, int width, int height) {
    593         if (displayToken == null) {
    594             throw new IllegalArgumentException("displayToken must not be null");
    595         }
    596         if (width <= 0 || height <= 0) {
    597             throw new IllegalArgumentException("width and height must be positive");
    598         }
    599 
    600         nativeSetDisplaySize(displayToken, width, height);
    601     }
    602 
    603     public static IBinder createDisplay(String name, boolean secure) {
    604         if (name == null) {
    605             throw new IllegalArgumentException("name must not be null");
    606         }
    607         return nativeCreateDisplay(name, secure);
    608     }
    609 
    610     public static void destroyDisplay(IBinder displayToken) {
    611         if (displayToken == null) {
    612             throw new IllegalArgumentException("displayToken must not be null");
    613         }
    614         nativeDestroyDisplay(displayToken);
    615     }
    616 
    617     public static IBinder getBuiltInDisplay(int builtInDisplayId) {
    618         return nativeGetBuiltInDisplay(builtInDisplayId);
    619     }
    620 
    621     /**
    622      * Copy the current screen contents into the provided {@link Surface}
    623      *
    624      * @param display The display to take the screenshot of.
    625      * @param consumer The {@link Surface} to take the screenshot into.
    626      * @param width The desired width of the returned bitmap; the raw
    627      * screen will be scaled down to this size.
    628      * @param height The desired height of the returned bitmap; the raw
    629      * screen will be scaled down to this size.
    630      * @param minLayer The lowest (bottom-most Z order) surface layer to
    631      * include in the screenshot.
    632      * @param maxLayer The highest (top-most Z order) surface layer to
    633      * include in the screenshot.
    634      * @param useIdentityTransform Replace whatever transformation (rotation,
    635      * scaling, translation) the surface layers are currently using with the
    636      * identity transformation while taking the screenshot.
    637      */
    638     public static void screenshot(IBinder display, Surface consumer,
    639             int width, int height, int minLayer, int maxLayer,
    640             boolean useIdentityTransform) {
    641         screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
    642                 false, useIdentityTransform);
    643     }
    644 
    645     /**
    646      * Copy the current screen contents into the provided {@link Surface}
    647      *
    648      * @param display The display to take the screenshot of.
    649      * @param consumer The {@link Surface} to take the screenshot into.
    650      * @param width The desired width of the returned bitmap; the raw
    651      * screen will be scaled down to this size.
    652      * @param height The desired height of the returned bitmap; the raw
    653      * screen will be scaled down to this size.
    654      */
    655     public static void screenshot(IBinder display, Surface consumer,
    656             int width, int height) {
    657         screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
    658     }
    659 
    660     /**
    661      * Copy the current screen contents into the provided {@link Surface}
    662      *
    663      * @param display The display to take the screenshot of.
    664      * @param consumer The {@link Surface} to take the screenshot into.
    665      */
    666     public static void screenshot(IBinder display, Surface consumer) {
    667         screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
    668     }
    669 
    670     /**
    671      * Copy the current screen contents into a bitmap and return it.
    672      *
    673      * CAVEAT: Versions of screenshot that return a {@link Bitmap} can
    674      * be extremely slow; avoid use unless absolutely necessary; prefer
    675      * the versions that use a {@link Surface} instead, such as
    676      * {@link SurfaceControl#screenshot(IBinder, Surface)}.
    677      *
    678      * @param sourceCrop The portion of the screen to capture into the Bitmap;
    679      * caller may pass in 'new Rect()' if no cropping is desired.
    680      * @param width The desired width of the returned bitmap; the raw
    681      * screen will be scaled down to this size.
    682      * @param height The desired height of the returned bitmap; the raw
    683      * screen will be scaled down to this size.
    684      * @param minLayer The lowest (bottom-most Z order) surface layer to
    685      * include in the screenshot.
    686      * @param maxLayer The highest (top-most Z order) surface layer to
    687      * include in the screenshot.
    688      * @param useIdentityTransform Replace whatever transformation (rotation,
    689      * scaling, translation) the surface layers are currently using with the
    690      * identity transformation while taking the screenshot.
    691      * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
    692      * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
    693      * screenshots in its native portrait orientation by default, so this is
    694      * useful for returning screenshots that are independent of device
    695      * orientation.
    696      * @return Returns a Bitmap containing the screen contents, or null
    697      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
    698      * possible, once its content is not needed anymore.
    699      */
    700     public static Bitmap screenshot(Rect sourceCrop, int width, int height,
    701             int minLayer, int maxLayer, boolean useIdentityTransform,
    702             int rotation) {
    703         // TODO: should take the display as a parameter
    704         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
    705                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
    706         return nativeScreenshot(displayToken, sourceCrop, width, height,
    707                 minLayer, maxLayer, false, useIdentityTransform, rotation);
    708     }
    709 
    710     /**
    711      * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but
    712      * includes all Surfaces in the screenshot.
    713      *
    714      * @param width The desired width of the returned bitmap; the raw
    715      * screen will be scaled down to this size.
    716      * @param height The desired height of the returned bitmap; the raw
    717      * screen will be scaled down to this size.
    718      * @return Returns a Bitmap containing the screen contents, or null
    719      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
    720      * possible, once its content is not needed anymore.
    721      */
    722     public static Bitmap screenshot(int width, int height) {
    723         // TODO: should take the display as a parameter
    724         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
    725                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
    726         return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
    727                 false, Surface.ROTATION_0);
    728     }
    729 
    730     private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
    731             int width, int height, int minLayer, int maxLayer, boolean allLayers,
    732             boolean useIdentityTransform) {
    733         if (display == null) {
    734             throw new IllegalArgumentException("displayToken must not be null");
    735         }
    736         if (consumer == null) {
    737             throw new IllegalArgumentException("consumer must not be null");
    738         }
    739         nativeScreenshot(display, consumer, sourceCrop, width, height,
    740                 minLayer, maxLayer, allLayers, useIdentityTransform);
    741     }
    742 }
    743