OSDN Git Service

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