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