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