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 
nativeCreate(SurfaceSession session, String name, int w, int h, int format, int flags)34     private static native long nativeCreate(SurfaceSession session, String name,
35             int w, int h, int format, int flags)
36             throws OutOfResourcesException;
nativeRelease(long nativeObject)37     private static native void nativeRelease(long nativeObject);
nativeDestroy(long nativeObject)38     private static native void nativeDestroy(long nativeObject);
39 
nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform, int rotation)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);
nativeScreenshot(IBinder displayToken, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)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 
nativeOpenTransaction()47     private static native void nativeOpenTransaction();
nativeCloseTransaction()48     private static native void nativeCloseTransaction();
nativeSetAnimationTransaction()49     private static native void nativeSetAnimationTransaction();
50 
nativeSetLayer(long nativeObject, int zorder)51     private static native void nativeSetLayer(long nativeObject, int zorder);
nativeSetPosition(long nativeObject, float x, float y)52     private static native void nativeSetPosition(long nativeObject, float x, float y);
nativeSetSize(long nativeObject, int w, int h)53     private static native void nativeSetSize(long nativeObject, int w, int h);
nativeSetTransparentRegionHint(long nativeObject, Region region)54     private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
nativeSetAlpha(long nativeObject, float alpha)55     private static native void nativeSetAlpha(long nativeObject, float alpha);
nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy)56     private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
nativeSetFlags(long nativeObject, int flags, int mask)57     private static native void nativeSetFlags(long nativeObject, int flags, int mask);
nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b)58     private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
nativeSetLayerStack(long nativeObject, int layerStack)59     private static native void nativeSetLayerStack(long nativeObject, int layerStack);
60 
nativeClearContentFrameStats(long nativeObject)61     private static native boolean nativeClearContentFrameStats(long nativeObject);
nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats)62     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
nativeClearAnimationFrameStats()63     private static native boolean nativeClearAnimationFrameStats();
nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats)64     private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
65 
nativeGetBuiltInDisplay(int physicalDisplayId)66     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
nativeCreateDisplay(String name, boolean secure)67     private static native IBinder nativeCreateDisplay(String name, boolean secure);
nativeDestroyDisplay(IBinder displayToken)68     private static native void nativeDestroyDisplay(IBinder displayToken);
nativeSetDisplaySurface( IBinder displayToken, long nativeSurfaceObject)69     private static native void nativeSetDisplaySurface(
70             IBinder displayToken, long nativeSurfaceObject);
nativeSetDisplayLayerStack( IBinder displayToken, int layerStack)71     private static native void nativeSetDisplayLayerStack(
72             IBinder displayToken, int layerStack);
nativeSetDisplayProjection( IBinder displayToken, int orientation, int l, int t, int r, int b, int L, int T, int R, int B)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);
nativeSetDisplaySize(IBinder displayToken, int width, int height)77     private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
nativeGetDisplayConfigs( IBinder displayToken)78     private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
79             IBinder displayToken);
nativeGetActiveConfig(IBinder displayToken)80     private static native int nativeGetActiveConfig(IBinder displayToken);
nativeSetActiveConfig(IBinder displayToken, int id)81     private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
nativeSetDisplayPowerMode( IBinder displayToken, int mode)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      */
SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags)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
finalize()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
toString()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      */
release()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      */
destroy()333     public void destroy() {
334         if (mNativeObject != 0) {
335             nativeDestroy(mNativeObject);
336             mNativeObject = 0;
337         }
338         mCloseGuard.close();
339     }
340 
checkNotReleased()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 */
openTransaction()352     public static void openTransaction() {
353         nativeOpenTransaction();
354     }
355 
356     /** end a transaction */
closeTransaction()357     public static void closeTransaction() {
358         nativeCloseTransaction();
359     }
360 
361     /** flag the transaction as an animation */
setAnimationTransaction()362     public static void setAnimationTransaction() {
363         nativeSetAnimationTransaction();
364     }
365 
setLayer(int zorder)366     public void setLayer(int zorder) {
367         checkNotReleased();
368         nativeSetLayer(mNativeObject, zorder);
369     }
370 
setPosition(float x, float y)371     public void setPosition(float x, float y) {
372         checkNotReleased();
373         nativeSetPosition(mNativeObject, x, y);
374     }
375 
setSize(int w, int h)376     public void setSize(int w, int h) {
377         checkNotReleased();
378         nativeSetSize(mNativeObject, w, h);
379     }
380 
hide()381     public void hide() {
382         checkNotReleased();
383         nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
384     }
385 
show()386     public void show() {
387         checkNotReleased();
388         nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
389     }
390 
setTransparentRegionHint(Region region)391     public void setTransparentRegionHint(Region region) {
392         checkNotReleased();
393         nativeSetTransparentRegionHint(mNativeObject, region);
394     }
395 
clearContentFrameStats()396     public boolean clearContentFrameStats() {
397         checkNotReleased();
398         return nativeClearContentFrameStats(mNativeObject);
399     }
400 
getContentFrameStats(WindowContentFrameStats outStats)401     public boolean getContentFrameStats(WindowContentFrameStats outStats) {
402         checkNotReleased();
403         return nativeGetContentFrameStats(mNativeObject, outStats);
404     }
405 
clearAnimationFrameStats()406     public static boolean clearAnimationFrameStats() {
407         return nativeClearAnimationFrameStats();
408     }
409 
getAnimationFrameStats(WindowAnimationFrameStats outStats)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      */
setAlpha(float alpha)418     public void setAlpha(float alpha) {
419         checkNotReleased();
420         nativeSetAlpha(mNativeObject, alpha);
421     }
422 
setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)423     public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
424         checkNotReleased();
425         nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
426     }
427 
setWindowCrop(Rect crop)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 
setLayerStack(int layerStack)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      */
setOpaque(boolean isOpaque)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      * Sets the security of the surface.  Setting the flag is equivalent to creating the
458      * Surface with the {@link #SECURE} flag.
459      */
setSecure(boolean isSecure)460     public void setSecure(boolean isSecure) {
461         checkNotReleased();
462         if (isSecure) {
463             nativeSetFlags(mNativeObject, SECURE, SECURE);
464         } else {
465             nativeSetFlags(mNativeObject, 0, SECURE);
466         }
467     }
468 
469     /*
470      * set display parameters.
471      * needs to be inside open/closeTransaction block
472      */
473 
474     /**
475      * Describes the properties of a physical display known to surface flinger.
476      */
477     public static final class PhysicalDisplayInfo {
478         public int width;
479         public int height;
480         public float refreshRate;
481         public float density;
482         public float xDpi;
483         public float yDpi;
484         public boolean secure;
485         public long appVsyncOffsetNanos;
486         public long presentationDeadlineNanos;
487 
PhysicalDisplayInfo()488         public PhysicalDisplayInfo() {
489         }
490 
PhysicalDisplayInfo(PhysicalDisplayInfo other)491         public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
492             copyFrom(other);
493         }
494 
495         @Override
equals(Object o)496         public boolean equals(Object o) {
497             return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
498         }
499 
equals(PhysicalDisplayInfo other)500         public boolean equals(PhysicalDisplayInfo other) {
501             return other != null
502                     && width == other.width
503                     && height == other.height
504                     && refreshRate == other.refreshRate
505                     && density == other.density
506                     && xDpi == other.xDpi
507                     && yDpi == other.yDpi
508                     && secure == other.secure
509                     && appVsyncOffsetNanos == other.appVsyncOffsetNanos
510                     && presentationDeadlineNanos == other.presentationDeadlineNanos;
511         }
512 
513         @Override
hashCode()514         public int hashCode() {
515             return 0; // don't care
516         }
517 
copyFrom(PhysicalDisplayInfo other)518         public void copyFrom(PhysicalDisplayInfo other) {
519             width = other.width;
520             height = other.height;
521             refreshRate = other.refreshRate;
522             density = other.density;
523             xDpi = other.xDpi;
524             yDpi = other.yDpi;
525             secure = other.secure;
526             appVsyncOffsetNanos = other.appVsyncOffsetNanos;
527             presentationDeadlineNanos = other.presentationDeadlineNanos;
528         }
529 
530         // For debugging purposes
531         @Override
toString()532         public String toString() {
533             return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
534                     + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
535                     + ", appVsyncOffset " + appVsyncOffsetNanos
536                     + ", bufferDeadline " + presentationDeadlineNanos + "}";
537         }
538     }
539 
setDisplayPowerMode(IBinder displayToken, int mode)540     public static void setDisplayPowerMode(IBinder displayToken, int mode) {
541         if (displayToken == null) {
542             throw new IllegalArgumentException("displayToken must not be null");
543         }
544         nativeSetDisplayPowerMode(displayToken, mode);
545     }
546 
getDisplayConfigs(IBinder displayToken)547     public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
548         if (displayToken == null) {
549             throw new IllegalArgumentException("displayToken must not be null");
550         }
551         return nativeGetDisplayConfigs(displayToken);
552     }
553 
getActiveConfig(IBinder displayToken)554     public static int getActiveConfig(IBinder displayToken) {
555         if (displayToken == null) {
556             throw new IllegalArgumentException("displayToken must not be null");
557         }
558         return nativeGetActiveConfig(displayToken);
559     }
560 
setActiveConfig(IBinder displayToken, int id)561     public static boolean setActiveConfig(IBinder displayToken, int id) {
562         if (displayToken == null) {
563             throw new IllegalArgumentException("displayToken must not be null");
564         }
565         return nativeSetActiveConfig(displayToken, id);
566     }
567 
setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)568     public static void setDisplayProjection(IBinder displayToken,
569             int orientation, Rect layerStackRect, Rect displayRect) {
570         if (displayToken == null) {
571             throw new IllegalArgumentException("displayToken must not be null");
572         }
573         if (layerStackRect == null) {
574             throw new IllegalArgumentException("layerStackRect must not be null");
575         }
576         if (displayRect == null) {
577             throw new IllegalArgumentException("displayRect must not be null");
578         }
579         nativeSetDisplayProjection(displayToken, orientation,
580                 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
581                 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
582     }
583 
setDisplayLayerStack(IBinder displayToken, int layerStack)584     public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
585         if (displayToken == null) {
586             throw new IllegalArgumentException("displayToken must not be null");
587         }
588         nativeSetDisplayLayerStack(displayToken, layerStack);
589     }
590 
setDisplaySurface(IBinder displayToken, Surface surface)591     public static void setDisplaySurface(IBinder displayToken, Surface surface) {
592         if (displayToken == null) {
593             throw new IllegalArgumentException("displayToken must not be null");
594         }
595 
596         if (surface != null) {
597             synchronized (surface.mLock) {
598                 nativeSetDisplaySurface(displayToken, surface.mNativeObject);
599             }
600         } else {
601             nativeSetDisplaySurface(displayToken, 0);
602         }
603     }
604 
setDisplaySize(IBinder displayToken, int width, int height)605     public static void setDisplaySize(IBinder displayToken, int width, int height) {
606         if (displayToken == null) {
607             throw new IllegalArgumentException("displayToken must not be null");
608         }
609         if (width <= 0 || height <= 0) {
610             throw new IllegalArgumentException("width and height must be positive");
611         }
612 
613         nativeSetDisplaySize(displayToken, width, height);
614     }
615 
createDisplay(String name, boolean secure)616     public static IBinder createDisplay(String name, boolean secure) {
617         if (name == null) {
618             throw new IllegalArgumentException("name must not be null");
619         }
620         return nativeCreateDisplay(name, secure);
621     }
622 
destroyDisplay(IBinder displayToken)623     public static void destroyDisplay(IBinder displayToken) {
624         if (displayToken == null) {
625             throw new IllegalArgumentException("displayToken must not be null");
626         }
627         nativeDestroyDisplay(displayToken);
628     }
629 
getBuiltInDisplay(int builtInDisplayId)630     public static IBinder getBuiltInDisplay(int builtInDisplayId) {
631         return nativeGetBuiltInDisplay(builtInDisplayId);
632     }
633 
634     /**
635      * Copy the current screen contents into the provided {@link Surface}
636      *
637      * @param display The display to take the screenshot of.
638      * @param consumer The {@link Surface} to take the screenshot into.
639      * @param width The desired width of the returned bitmap; the raw
640      * screen will be scaled down to this size.
641      * @param height The desired height of the returned bitmap; the raw
642      * screen will be scaled down to this size.
643      * @param minLayer The lowest (bottom-most Z order) surface layer to
644      * include in the screenshot.
645      * @param maxLayer The highest (top-most Z order) surface layer to
646      * include in the screenshot.
647      * @param useIdentityTransform Replace whatever transformation (rotation,
648      * scaling, translation) the surface layers are currently using with the
649      * identity transformation while taking the screenshot.
650      */
screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform)651     public static void screenshot(IBinder display, Surface consumer,
652             int width, int height, int minLayer, int maxLayer,
653             boolean useIdentityTransform) {
654         screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
655                 false, useIdentityTransform);
656     }
657 
658     /**
659      * Copy the current screen contents into the provided {@link Surface}
660      *
661      * @param display The display to take the screenshot of.
662      * @param consumer The {@link Surface} to take the screenshot into.
663      * @param width The desired width of the returned bitmap; the raw
664      * screen will be scaled down to this size.
665      * @param height The desired height of the returned bitmap; the raw
666      * screen will be scaled down to this size.
667      */
screenshot(IBinder display, Surface consumer, int width, int height)668     public static void screenshot(IBinder display, Surface consumer,
669             int width, int height) {
670         screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
671     }
672 
673     /**
674      * Copy the current screen contents into the provided {@link Surface}
675      *
676      * @param display The display to take the screenshot of.
677      * @param consumer The {@link Surface} to take the screenshot into.
678      */
screenshot(IBinder display, Surface consumer)679     public static void screenshot(IBinder display, Surface consumer) {
680         screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
681     }
682 
683     /**
684      * Copy the current screen contents into a bitmap and return it.
685      *
686      * CAVEAT: Versions of screenshot that return a {@link Bitmap} can
687      * be extremely slow; avoid use unless absolutely necessary; prefer
688      * the versions that use a {@link Surface} instead, such as
689      * {@link SurfaceControl#screenshot(IBinder, Surface)}.
690      *
691      * @param sourceCrop The portion of the screen to capture into the Bitmap;
692      * caller may pass in 'new Rect()' if no cropping is desired.
693      * @param width The desired width of the returned bitmap; the raw
694      * screen will be scaled down to this size.
695      * @param height The desired height of the returned bitmap; the raw
696      * screen will be scaled down to this size.
697      * @param minLayer The lowest (bottom-most Z order) surface layer to
698      * include in the screenshot.
699      * @param maxLayer The highest (top-most Z order) surface layer to
700      * include in the screenshot.
701      * @param useIdentityTransform Replace whatever transformation (rotation,
702      * scaling, translation) the surface layers are currently using with the
703      * identity transformation while taking the screenshot.
704      * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
705      * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
706      * screenshots in its native portrait orientation by default, so this is
707      * useful for returning screenshots that are independent of device
708      * orientation.
709      * @return Returns a Bitmap containing the screen contents, or null
710      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
711      * possible, once its content is not needed anymore.
712      */
screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)713     public static Bitmap screenshot(Rect sourceCrop, int width, int height,
714             int minLayer, int maxLayer, boolean useIdentityTransform,
715             int rotation) {
716         // TODO: should take the display as a parameter
717         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
718                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
719         return nativeScreenshot(displayToken, sourceCrop, width, height,
720                 minLayer, maxLayer, false, useIdentityTransform, rotation);
721     }
722 
723     /**
724      * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but
725      * includes all Surfaces in the screenshot.
726      *
727      * @param width The desired width of the returned bitmap; the raw
728      * screen will be scaled down to this size.
729      * @param height The desired height of the returned bitmap; the raw
730      * screen will be scaled down to this size.
731      * @return Returns a Bitmap containing the screen contents, or null
732      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
733      * possible, once its content is not needed anymore.
734      */
screenshot(int width, int height)735     public static Bitmap screenshot(int width, int height) {
736         // TODO: should take the display as a parameter
737         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
738                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
739         return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
740                 false, Surface.ROTATION_0);
741     }
742 
screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)743     private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
744             int width, int height, int minLayer, int maxLayer, boolean allLayers,
745             boolean useIdentityTransform) {
746         if (display == null) {
747             throw new IllegalArgumentException("displayToken must not be null");
748         }
749         if (consumer == null) {
750             throw new IllegalArgumentException("consumer must not be null");
751         }
752         nativeScreenshot(display, consumer, sourceCrop, width, height,
753                 minLayer, maxLayer, allLayers, useIdentityTransform);
754     }
755 }
756