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);
nativeDisconnect(long nativeObject)39     private static native void nativeDisconnect(long nativeObject);
40 
nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform, int rotation)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);
nativeScreenshot(IBinder displayToken, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)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 
nativeOpenTransaction()48     private static native void nativeOpenTransaction();
nativeCloseTransaction(boolean sync)49     private static native void nativeCloseTransaction(boolean sync);
nativeSetAnimationTransaction()50     private static native void nativeSetAnimationTransaction();
51 
nativeSetLayer(long nativeObject, int zorder)52     private static native void nativeSetLayer(long nativeObject, int zorder);
nativeSetPosition(long nativeObject, float x, float y)53     private static native void nativeSetPosition(long nativeObject, float x, float y);
nativeSetPositionAppliesWithResize(long nativeObject)54     private static native void nativeSetPositionAppliesWithResize(long nativeObject);
nativeSetSize(long nativeObject, int w, int h)55     private static native void nativeSetSize(long nativeObject, int w, int h);
nativeSetTransparentRegionHint(long nativeObject, Region region)56     private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
nativeSetAlpha(long nativeObject, float alpha)57     private static native void nativeSetAlpha(long nativeObject, float alpha);
nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy)58     private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
nativeSetFlags(long nativeObject, int flags, int mask)59     private static native void nativeSetFlags(long nativeObject, int flags, int mask);
nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b)60     private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
nativeSetFinalCrop(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);
nativeSetLayerStack(long nativeObject, int layerStack)62     private static native void nativeSetLayerStack(long nativeObject, int layerStack);
63 
nativeClearContentFrameStats(long nativeObject)64     private static native boolean nativeClearContentFrameStats(long nativeObject);
nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats)65     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
nativeClearAnimationFrameStats()66     private static native boolean nativeClearAnimationFrameStats();
nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats)67     private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
68 
nativeGetBuiltInDisplay(int physicalDisplayId)69     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
nativeCreateDisplay(String name, boolean secure)70     private static native IBinder nativeCreateDisplay(String name, boolean secure);
nativeDestroyDisplay(IBinder displayToken)71     private static native void nativeDestroyDisplay(IBinder displayToken);
nativeSetDisplaySurface( IBinder displayToken, long nativeSurfaceObject)72     private static native void nativeSetDisplaySurface(
73             IBinder displayToken, long nativeSurfaceObject);
nativeSetDisplayLayerStack( IBinder displayToken, int layerStack)74     private static native void nativeSetDisplayLayerStack(
75             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)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);
nativeSetDisplaySize(IBinder displayToken, int width, int height)80     private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
nativeGetDisplayConfigs( IBinder displayToken)81     private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
82             IBinder displayToken);
nativeGetActiveConfig(IBinder displayToken)83     private static native int nativeGetActiveConfig(IBinder displayToken);
nativeSetActiveConfig(IBinder displayToken, int id)84     private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
nativeSetDisplayPowerMode( IBinder displayToken, int mode)85     private static native void nativeSetDisplayPowerMode(
86             IBinder displayToken, int mode);
nativeDeferTransactionUntil(long nativeObject, IBinder handle, long frame)87     private static native void nativeDeferTransactionUntil(long nativeObject,
88             IBinder handle, long frame);
nativeSetOverrideScalingMode(long nativeObject, int scalingMode)89     private static native void nativeSetOverrideScalingMode(long nativeObject,
90             int scalingMode);
nativeGetHandle(long nativeObject)91     private static native IBinder nativeGetHandle(long nativeObject);
nativeGetHdrCapabilities(IBinder displayToken)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      */
SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags)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
finalize()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
toString()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      */
release()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      */
destroy()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      */
disconnect()353     public void disconnect() {
354         if (mNativeObject != 0) {
355             nativeDisconnect(mNativeObject);
356         }
357     }
358 
checkNotReleased()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 */
openTransaction()370     public static void openTransaction() {
371         nativeOpenTransaction();
372     }
373 
374     /** end a transaction */
closeTransaction()375     public static void closeTransaction() {
376         nativeCloseTransaction(false);
377     }
378 
closeTransactionSync()379     public static void closeTransactionSync() {
380         nativeCloseTransaction(true);
381     }
382 
deferTransactionUntil(IBinder handle, long frame)383     public void deferTransactionUntil(IBinder handle, long frame) {
384         nativeDeferTransactionUntil(mNativeObject, handle, frame);
385     }
386 
setOverrideScalingMode(int scalingMode)387     public void setOverrideScalingMode(int scalingMode) {
388         checkNotReleased();
389         nativeSetOverrideScalingMode(mNativeObject, scalingMode);
390     }
391 
getHandle()392     public IBinder getHandle() {
393         return nativeGetHandle(mNativeObject);
394     }
395 
396     /** flag the transaction as an animation */
setAnimationTransaction()397     public static void setAnimationTransaction() {
398         nativeSetAnimationTransaction();
399     }
400 
setLayer(int zorder)401     public void setLayer(int zorder) {
402         checkNotReleased();
403         nativeSetLayer(mNativeObject, zorder);
404     }
405 
setPosition(float x, float y)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      */
setPositionAppliesWithResize()416     public void setPositionAppliesWithResize() {
417         checkNotReleased();
418         nativeSetPositionAppliesWithResize(mNativeObject);
419     }
420 
setSize(int w, int h)421     public void setSize(int w, int h) {
422         checkNotReleased();
423         nativeSetSize(mNativeObject, w, h);
424     }
425 
hide()426     public void hide() {
427         checkNotReleased();
428         nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
429     }
430 
show()431     public void show() {
432         checkNotReleased();
433         nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
434     }
435 
setTransparentRegionHint(Region region)436     public void setTransparentRegionHint(Region region) {
437         checkNotReleased();
438         nativeSetTransparentRegionHint(mNativeObject, region);
439     }
440 
clearContentFrameStats()441     public boolean clearContentFrameStats() {
442         checkNotReleased();
443         return nativeClearContentFrameStats(mNativeObject);
444     }
445 
getContentFrameStats(WindowContentFrameStats outStats)446     public boolean getContentFrameStats(WindowContentFrameStats outStats) {
447         checkNotReleased();
448         return nativeGetContentFrameStats(mNativeObject, outStats);
449     }
450 
clearAnimationFrameStats()451     public static boolean clearAnimationFrameStats() {
452         return nativeClearAnimationFrameStats();
453     }
454 
getAnimationFrameStats(WindowAnimationFrameStats outStats)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      */
setAlpha(float alpha)463     public void setAlpha(float alpha) {
464         checkNotReleased();
465         nativeSetAlpha(mNativeObject, alpha);
466     }
467 
setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)468     public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
469         checkNotReleased();
470         nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
471     }
472 
setWindowCrop(Rect crop)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 
setFinalCrop(Rect crop)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 
setLayerStack(int layerStack)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      */
setOpaque(boolean isOpaque)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      */
setSecure(boolean isSecure)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 
PhysicalDisplayInfo()544         public PhysicalDisplayInfo() {
545         }
546 
PhysicalDisplayInfo(PhysicalDisplayInfo other)547         public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
548             copyFrom(other);
549         }
550 
551         @Override
equals(Object o)552         public boolean equals(Object o) {
553             return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
554         }
555 
equals(PhysicalDisplayInfo other)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
hashCode()571         public int hashCode() {
572             return 0; // don't care
573         }
574 
copyFrom(PhysicalDisplayInfo other)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
toString()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 
setDisplayPowerMode(IBinder displayToken, int mode)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 
getDisplayConfigs(IBinder displayToken)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 
getActiveConfig(IBinder displayToken)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 
setActiveConfig(IBinder displayToken, int id)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 
setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)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 
setDisplayLayerStack(IBinder displayToken, int layerStack)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 
setDisplaySurface(IBinder displayToken, Surface surface)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 
setDisplaySize(IBinder displayToken, int width, int height)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 
getHdrCapabilities(IBinder displayToken)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 
createDisplay(String name, boolean secure)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 
destroyDisplay(IBinder displayToken)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 
getBuiltInDisplay(int builtInDisplayId)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      */
screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform)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      */
screenshot(IBinder display, Surface consumer, int width, int height)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      */
screenshot(IBinder display, Surface consumer)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      */
screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation)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      */
screenshot(int width, int height)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 
screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform)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 }
822