• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         public int colorTransform;
488 
PhysicalDisplayInfo()489         public PhysicalDisplayInfo() {
490         }
491 
PhysicalDisplayInfo(PhysicalDisplayInfo other)492         public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
493             copyFrom(other);
494         }
495 
496         @Override
equals(Object o)497         public boolean equals(Object o) {
498             return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
499         }
500 
equals(PhysicalDisplayInfo other)501         public boolean equals(PhysicalDisplayInfo other) {
502             return other != null
503                     && width == other.width
504                     && height == other.height
505                     && refreshRate == other.refreshRate
506                     && density == other.density
507                     && xDpi == other.xDpi
508                     && yDpi == other.yDpi
509                     && secure == other.secure
510                     && appVsyncOffsetNanos == other.appVsyncOffsetNanos
511                     && presentationDeadlineNanos == other.presentationDeadlineNanos
512                     && colorTransform == other.colorTransform;
513         }
514 
515         @Override
hashCode()516         public int hashCode() {
517             return 0; // don't care
518         }
519 
copyFrom(PhysicalDisplayInfo other)520         public void copyFrom(PhysicalDisplayInfo other) {
521             width = other.width;
522             height = other.height;
523             refreshRate = other.refreshRate;
524             density = other.density;
525             xDpi = other.xDpi;
526             yDpi = other.yDpi;
527             secure = other.secure;
528             appVsyncOffsetNanos = other.appVsyncOffsetNanos;
529             presentationDeadlineNanos = other.presentationDeadlineNanos;
530             colorTransform = other.colorTransform;
531         }
532 
533         // For debugging purposes
534         @Override
toString()535         public String toString() {
536             return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
537                     + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
538                     + ", appVsyncOffset " + appVsyncOffsetNanos
539                     + ", bufferDeadline " + presentationDeadlineNanos
540                     + ", colorTransform " + colorTransform + "}";
541         }
542     }
543 
setDisplayPowerMode(IBinder displayToken, int mode)544     public static void setDisplayPowerMode(IBinder displayToken, int mode) {
545         if (displayToken == null) {
546             throw new IllegalArgumentException("displayToken must not be null");
547         }
548         nativeSetDisplayPowerMode(displayToken, mode);
549     }
550 
getDisplayConfigs(IBinder displayToken)551     public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
552         if (displayToken == null) {
553             throw new IllegalArgumentException("displayToken must not be null");
554         }
555         return nativeGetDisplayConfigs(displayToken);
556     }
557 
getActiveConfig(IBinder displayToken)558     public static int getActiveConfig(IBinder displayToken) {
559         if (displayToken == null) {
560             throw new IllegalArgumentException("displayToken must not be null");
561         }
562         return nativeGetActiveConfig(displayToken);
563     }
564 
setActiveConfig(IBinder displayToken, int id)565     public static boolean setActiveConfig(IBinder displayToken, int id) {
566         if (displayToken == null) {
567             throw new IllegalArgumentException("displayToken must not be null");
568         }
569         return nativeSetActiveConfig(displayToken, id);
570     }
571 
setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)572     public static void setDisplayProjection(IBinder displayToken,
573             int orientation, Rect layerStackRect, Rect displayRect) {
574         if (displayToken == null) {
575             throw new IllegalArgumentException("displayToken must not be null");
576         }
577         if (layerStackRect == null) {
578             throw new IllegalArgumentException("layerStackRect must not be null");
579         }
580         if (displayRect == null) {
581             throw new IllegalArgumentException("displayRect must not be null");
582         }
583         nativeSetDisplayProjection(displayToken, orientation,
584                 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
585                 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
586     }
587 
setDisplayLayerStack(IBinder displayToken, int layerStack)588     public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
589         if (displayToken == null) {
590             throw new IllegalArgumentException("displayToken must not be null");
591         }
592         nativeSetDisplayLayerStack(displayToken, layerStack);
593     }
594 
setDisplaySurface(IBinder displayToken, Surface surface)595     public static void setDisplaySurface(IBinder displayToken, Surface surface) {
596         if (displayToken == null) {
597             throw new IllegalArgumentException("displayToken must not be null");
598         }
599 
600         if (surface != null) {
601             synchronized (surface.mLock) {
602                 nativeSetDisplaySurface(displayToken, surface.mNativeObject);
603             }
604         } else {
605             nativeSetDisplaySurface(displayToken, 0);
606         }
607     }
608 
setDisplaySize(IBinder displayToken, int width, int height)609     public static void setDisplaySize(IBinder displayToken, int width, int height) {
610         if (displayToken == null) {
611             throw new IllegalArgumentException("displayToken must not be null");
612         }
613         if (width <= 0 || height <= 0) {
614             throw new IllegalArgumentException("width and height must be positive");
615         }
616 
617         nativeSetDisplaySize(displayToken, width, height);
618     }
619 
createDisplay(String name, boolean secure)620     public static IBinder createDisplay(String name, boolean secure) {
621         if (name == null) {
622             throw new IllegalArgumentException("name must not be null");
623         }
624         return nativeCreateDisplay(name, secure);
625     }
626 
destroyDisplay(IBinder displayToken)627     public static void destroyDisplay(IBinder displayToken) {
628         if (displayToken == null) {
629             throw new IllegalArgumentException("displayToken must not be null");
630         }
631         nativeDestroyDisplay(displayToken);
632     }
633 
getBuiltInDisplay(int builtInDisplayId)634     public static IBinder getBuiltInDisplay(int builtInDisplayId) {
635         return nativeGetBuiltInDisplay(builtInDisplayId);
636     }
637 
638     /**
639      * Copy the current screen contents into the provided {@link Surface}
640      *
641      * @param display The display to take the screenshot of.
642      * @param consumer The {@link Surface} to take the screenshot into.
643      * @param width The desired width of the returned bitmap; the raw
644      * screen will be scaled down to this size.
645      * @param height The desired height of the returned bitmap; the raw
646      * screen will be scaled down to this size.
647      * @param minLayer The lowest (bottom-most Z order) surface layer to
648      * include in the screenshot.
649      * @param maxLayer The highest (top-most Z order) surface layer to
650      * include in the screenshot.
651      * @param useIdentityTransform Replace whatever transformation (rotation,
652      * scaling, translation) the surface layers are currently using with the
653      * identity transformation while taking the screenshot.
654      */
screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform)655     public static void screenshot(IBinder display, Surface consumer,
656             int width, int height, int minLayer, int maxLayer,
657             boolean useIdentityTransform) {
658         screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
659                 false, useIdentityTransform);
660     }
661 
662     /**
663      * Copy the current screen contents into the provided {@link Surface}
664      *
665      * @param display The display to take the screenshot of.
666      * @param consumer The {@link Surface} to take the screenshot into.
667      * @param width The desired width of the returned bitmap; the raw
668      * screen will be scaled down to this size.
669      * @param height The desired height of the returned bitmap; the raw
670      * screen will be scaled down to this size.
671      */
screenshot(IBinder display, Surface consumer, int width, int height)672     public static void screenshot(IBinder display, Surface consumer,
673             int width, int height) {
674         screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
675     }
676 
677     /**
678      * Copy the current screen contents into the provided {@link Surface}
679      *
680      * @param display The display to take the screenshot of.
681      * @param consumer The {@link Surface} to take the screenshot into.
682      */
screenshot(IBinder display, Surface consumer)683     public static void screenshot(IBinder display, Surface consumer) {
684         screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
685     }
686 
687     /**
688      * Copy the current screen contents into a bitmap and return it.
689      *
690      * CAVEAT: Versions of screenshot that return a {@link Bitmap} can
691      * be extremely slow; avoid use unless absolutely necessary; prefer
692      * the versions that use a {@link Surface} instead, such as
693      * {@link SurfaceControl#screenshot(IBinder, Surface)}.
694      *
695      * @param sourceCrop The portion of the screen to capture into the Bitmap;
696      * caller may pass in 'new Rect()' if no cropping is desired.
697      * @param width The desired width of the returned bitmap; the raw
698      * screen will be scaled down to this size.
699      * @param height The desired height of the returned bitmap; the raw
700      * screen will be scaled down to this size.
701      * @param minLayer The lowest (bottom-most Z order) surface layer to
702      * include in the screenshot.
703      * @param maxLayer The highest (top-most Z order) surface layer to
704      * include in the screenshot.
705      * @param useIdentityTransform Replace whatever transformation (rotation,
706      * scaling, translation) the surface layers are currently using with the
707      * identity transformation while taking the screenshot.
708      * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
709      * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
710      * screenshots in its native portrait orientation by default, so this is
711      * useful for returning screenshots that are independent of device
712      * orientation.
713      * @return Returns a Bitmap containing the screen contents, or null
714      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
715      * possible, once its content is not needed anymore.
716      */
screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)717     public static Bitmap screenshot(Rect sourceCrop, int width, int height,
718             int minLayer, int maxLayer, boolean useIdentityTransform,
719             int rotation) {
720         // TODO: should take the display as a parameter
721         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
722                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
723         return nativeScreenshot(displayToken, sourceCrop, width, height,
724                 minLayer, maxLayer, false, useIdentityTransform, rotation);
725     }
726 
727     /**
728      * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but
729      * includes all Surfaces in the screenshot.
730      *
731      * @param width The desired width of the returned bitmap; the raw
732      * screen will be scaled down to this size.
733      * @param height The desired height of the returned bitmap; the raw
734      * screen will be scaled down to this size.
735      * @return Returns a Bitmap containing the screen contents, or null
736      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
737      * possible, once its content is not needed anymore.
738      */
screenshot(int width, int height)739     public static Bitmap screenshot(int width, int height) {
740         // TODO: should take the display as a parameter
741         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
742                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
743         return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
744                 false, Surface.ROTATION_0);
745     }
746 
screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)747     private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
748             int width, int height, int minLayer, int maxLayer, boolean allLayers,
749             boolean useIdentityTransform) {
750         if (display == null) {
751             throw new IllegalArgumentException("displayToken must not be null");
752         }
753         if (consumer == null) {
754             throw new IllegalArgumentException("consumer must not be null");
755         }
756         nativeScreenshot(display, consumer, sourceCrop, width, height,
757                 minLayer, maxLayer, allLayers, useIdentityTransform);
758     }
759 }
760