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