blob: 1a2968f6345f49deab0a9ddd7d877deeb508d1f6 [file] [log] [blame]
Mathias Agopian3866f0d2013-02-11 22:08:48 -08001/*
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
17package android.view;
18
Albert Chaulke4338f82017-04-19 15:54:08 -040019import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
20
Mathias Agopian3866f0d2013-02-11 22:08:48 -080021import android.graphics.Bitmap;
Robert Carr6486d312017-01-09 19:48:29 -080022import android.graphics.GraphicBuffer;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080023import android.graphics.Rect;
24import android.graphics.Region;
Albert Chaulke4338f82017-04-19 15:54:08 -040025import android.os.Binder;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080026import android.os.IBinder;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080027import android.util.Log;
Igor Murashkina86ab6402013-08-30 12:58:36 -070028import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080029
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070030import dalvik.system.CloseGuard;
31
Mathias Agopian3866f0d2013-02-11 22:08:48 -080032/**
33 * SurfaceControl
34 * @hide
35 */
36public class SurfaceControl {
37 private static final String TAG = "SurfaceControl";
Mathias Agopian29479eb2013-02-14 14:36:04 -080038
Ashok Bhat36bef0b2014-01-20 20:08:01 +000039 private static native long nativeCreate(SurfaceSession session, String name,
Albert Chaulk3bf2e572016-11-22 13:59:19 -050040 int w, int h, int format, int flags, long parentObject, int windowType, int ownerUid)
Mathias Agopian29479eb2013-02-14 14:36:04 -080041 throws OutOfResourcesException;
Ashok Bhat36bef0b2014-01-20 20:08:01 +000042 private static native void nativeRelease(long nativeObject);
43 private static native void nativeDestroy(long nativeObject);
Chong Zhang47e36a32016-02-29 16:44:33 -080044 private static native void nativeDisconnect(long nativeObject);
Mathias Agopian29479eb2013-02-14 14:36:04 -080045
46 private static native Bitmap nativeScreenshot(IBinder displayToken,
Dan Stoza9890e3412014-05-22 16:12:54 -070047 Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
Riley Andrews1d134062014-08-21 15:47:07 -070048 boolean allLayers, boolean useIdentityTransform, int rotation);
Robert Carr6486d312017-01-09 19:48:29 -080049 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);
Mathias Agopian0449a402013-03-01 23:01:51 -080052 private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
Dan Stoza9890e3412014-05-22 16:12:54 -070053 Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
54 boolean allLayers, boolean useIdentityTransform);
Mathias Agopian29479eb2013-02-14 14:36:04 -080055
56 private static native void nativeOpenTransaction();
Robert Carre9953b12016-05-23 20:52:04 -070057 private static native void nativeCloseTransaction(boolean sync);
Mathias Agopian29479eb2013-02-14 14:36:04 -080058 private static native void nativeSetAnimationTransaction();
59
Ashok Bhat36bef0b2014-01-20 20:08:01 +000060 private static native void nativeSetLayer(long nativeObject, int zorder);
Robert Carraf422a82017-04-10 18:34:33 -070061 private static native void nativeSetRelativeLayer(long nativeObject, IBinder relativeTo,
62 int zorder);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000063 private static native void nativeSetPosition(long nativeObject, float x, float y);
Robert Carr6da3cc02016-06-16 15:17:07 -070064 private static native void nativeSetGeometryAppliesWithResize(long nativeObject);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000065 private static native void nativeSetSize(long nativeObject, int w, int h);
66 private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
67 private static native void nativeSetAlpha(long nativeObject, float alpha);
Andrii Kulian283acd22017-08-03 04:03:51 -070068 private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx,
69 float dtdy, float dsdy);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000070 private static native void nativeSetFlags(long nativeObject, int flags, int mask);
71 private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
Pablo Ceballos27982e62016-03-09 10:50:45 -080072 private static native void nativeSetFinalCrop(long nativeObject, int l, int t, int r, int b);
Ashok Bhat36bef0b2014-01-20 20:08:01 +000073 private static native void nativeSetLayerStack(long nativeObject, int layerStack);
Mathias Agopian29479eb2013-02-14 14:36:04 -080074
Svetoslav1376d602014-03-13 11:17:26 -070075 private static native boolean nativeClearContentFrameStats(long nativeObject);
76 private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
77 private static native boolean nativeClearAnimationFrameStats();
78 private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
79
Mathias Agopian29479eb2013-02-14 14:36:04 -080080 private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
81 private static native IBinder nativeCreateDisplay(String name, boolean secure);
Jesse Hall6a6bc212013-08-08 12:15:03 -070082 private static native void nativeDestroyDisplay(IBinder displayToken);
Mathias Agopian29479eb2013-02-14 14:36:04 -080083 private static native void nativeSetDisplaySurface(
Ashok Bhat36bef0b2014-01-20 20:08:01 +000084 IBinder displayToken, long nativeSurfaceObject);
Mathias Agopian29479eb2013-02-14 14:36:04 -080085 private static native void nativeSetDisplayLayerStack(
86 IBinder displayToken, int layerStack);
87 private static native void nativeSetDisplayProjection(
88 IBinder displayToken, int orientation,
Jesse Hall6a6bc212013-08-08 12:15:03 -070089 int l, int t, int r, int b,
Mathias Agopian29479eb2013-02-14 14:36:04 -080090 int L, int T, int R, int B);
Michael Wright01e840f2014-06-26 16:03:25 -070091 private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
Dan Stoza00101052014-05-02 15:23:40 -070092 private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
93 IBinder displayToken);
94 private static native int nativeGetActiveConfig(IBinder displayToken);
95 private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
Michael Wright1c9977b2016-07-12 13:30:10 -070096 private static native int[] nativeGetDisplayColorModes(IBinder displayToken);
97 private static native int nativeGetActiveColorMode(IBinder displayToken);
98 private static native boolean nativeSetActiveColorMode(IBinder displayToken,
99 int colorMode);
Prashant Malanic55929a2014-05-25 01:59:21 -0700100 private static native void nativeSetDisplayPowerMode(
101 IBinder displayToken, int mode);
Rob Carr64e516f2015-10-29 00:20:45 +0000102 private static native void nativeDeferTransactionUntil(long nativeObject,
103 IBinder handle, long frame);
Robert Carrd5c7dd62017-03-08 10:39:30 -0800104 private static native void nativeDeferTransactionUntilSurface(long nativeObject,
105 long surfaceObject, long frame);
106 private static native void nativeReparentChildren(long nativeObject,
107 IBinder handle);
108 private static native void nativeSeverChildren(long nativeObject);
Robert Carr1ca6a332016-04-11 18:00:43 -0700109 private static native void nativeSetOverrideScalingMode(long nativeObject,
110 int scalingMode);
Rob Carr64e516f2015-10-29 00:20:45 +0000111 private static native IBinder nativeGetHandle(long nativeObject);
Robert Carr6da3cc02016-06-16 15:17:07 -0700112 private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);
113
Michael Wright9ff94c02016-03-30 18:05:40 -0700114 private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800115
116
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800117 private final CloseGuard mCloseGuard = CloseGuard.get();
Igor Murashkina86ab6402013-08-30 12:58:36 -0700118 private final String mName;
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000119 long mNativeObject; // package visibility only for Surface.java access
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800120
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800121 /* 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
Jesse Hall6a6bc212013-08-08 12:15:03 -0700133 * surface might not be hardware accelerated.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800134 *
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:
Andy McFadden314405b2014-01-29 17:18:05 -0800145 * <p>
146 * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code>
147 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800148 * By contrast, non pre-multiplied surfaces use the following equation:
Andy McFadden314405b2014-01-29 17:18:05 -0800149 * <p>
150 * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code>
151 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800152 * 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.
Andy McFadden314405b2014-01-29 17:18:05 -0800156 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800157 * 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.
Andy McFadden314405b2014-01-29 17:18:05 -0800167 * <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.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800178 */
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 /**
Riley Andrews68eccda2014-07-07 11:47:35 -0700192 * Surface creation flag: Window represents a cursor glyph.
193 */
194 public static final int CURSOR_WINDOW = 0x00002000;
195
196 /**
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800197 * 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 /**
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800204 * 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 /**
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800213 * 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().
Andy McFadden314405b2014-01-29 17:18:05 -0800223 * Updates the value set during Surface creation (see {@link #HIDDEN}).
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800224 */
Andy McFadden40b9ef12014-01-30 13:44:47 -0800225 private static final int SURFACE_HIDDEN = 0x01;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800226
Andy McFadden314405b2014-01-29 17:18:05 -0800227 /**
228 * Surface flag: composite without blending when possible.
229 * Updates the value set during Surface creation (see {@link #OPAQUE}).
230 */
Andy McFadden40b9ef12014-01-30 13:44:47 -0800231 private static final int SURFACE_OPAQUE = 0x02;
Andy McFadden314405b2014-01-29 17:18:05 -0800232
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800233
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.
Andy McFadden40b9ef12014-01-30 13:44:47 -0800239 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800240 */
241 public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
242
243 /**
244 * Built-in physical display id: Attached HDMI display.
Andy McFadden40b9ef12014-01-30 13:44:47 -0800245 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800246 */
247 public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
248
Prashant Malanic55929a2014-05-25 01:59:21 -0700249 /* Display power modes * /
250
251 /**
252 * Display power mode off: used while blanking the screen.
Jeff Brown5dc21912014-07-17 18:50:18 -0700253 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
Prashant Malanic55929a2014-05-25 01:59:21 -0700254 */
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.
Jeff Brown5dc21912014-07-17 18:50:18 -0700259 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
Prashant Malanic55929a2014-05-25 01:59:21 -0700260 */
261 public static final int POWER_MODE_DOZE = 1;
262
263 /**
264 * Display power mode normal: used while unblanking the screen.
Jeff Brown5dc21912014-07-17 18:50:18 -0700265 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
Prashant Malanic55929a2014-05-25 01:59:21 -0700266 */
267 public static final int POWER_MODE_NORMAL = 2;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800268
Jeff Brown5dc21912014-07-17 18:50:18 -0700269 /**
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;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800274
275 /**
Robert Carr132c9f52017-07-31 17:02:30 -0700276 * 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 /**
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800285 * Create a surface with a name.
Andy McFadden314405b2014-01-29 17:18:05 -0800286 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800287 * 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.
Andy McFadden314405b2014-01-29 17:18:05 -0800293 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800294 * 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.
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500304 * @param windowType The type of the window as specified in WindowManager.java.
305 * @param ownerUid A unique per-app ID.
Igor Murashkina86ab6402013-08-30 12:58:36 -0700306 *
307 * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800308 */
309 public SurfaceControl(SurfaceSession session,
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500310 String name, int w, int h, int format, int flags, int windowType, int ownerUid)
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800311 throws OutOfResourcesException {
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500312 this(session, name, w, h, format, flags, null, windowType, ownerUid);
Robert Carr838120c2016-11-01 18:31:12 -0700313 }
314
315 public SurfaceControl(SurfaceSession session,
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500316 String name, int w, int h, int format, int flags)
317 throws OutOfResourcesException {
Albert Chaulke4338f82017-04-19 15:54:08 -0400318 this(session, name, w, h, format, flags, null, INVALID_WINDOW_TYPE, Binder.getCallingUid());
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500319 }
320
321 public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
322 SurfaceControl parent, int windowType, int ownerUid)
Robert Carr838120c2016-11-01 18:31:12 -0700323 throws OutOfResourcesException {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800324 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
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800340 mName = name;
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500341 mNativeObject = nativeCreate(session, name, w, h, format, flags,
342 parent != null ? parent.mNativeObject : 0, windowType, ownerUid);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800343 if (mNativeObject == 0) {
344 throw new OutOfResourcesException(
345 "Couldn't allocate SurfaceControl native object");
346 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700347
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800348 mCloseGuard.open("release");
349 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700350
Robert Carr3b716242016-08-16 16:02:21 -0700351 // 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.
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
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800362 @Override
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
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 */
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 */
399 public void destroy() {
400 if (mNativeObject != 0) {
401 nativeDestroy(mNativeObject);
402 mNativeObject = 0;
403 }
404 mCloseGuard.close();
405 }
406
Chong Zhang47e36a32016-02-29 16:44:33 -0800407 /**
408 * Disconnect any client still connected to the surface.
409 */
410 public void disconnect() {
411 if (mNativeObject != 0) {
412 nativeDisconnect(mNativeObject);
413 }
414 }
415
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800416 private void checkNotReleased() {
417 if (mNativeObject == 0) throw new NullPointerException(
418 "mNativeObject is null. Have you called release() already?");
419 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700420
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800421 /*
422 * set surface parameters.
423 * needs to be inside open/closeTransaction block
424 */
425
426 /** start a transaction */
427 public static void openTransaction() {
428 nativeOpenTransaction();
429 }
430
431 /** end a transaction */
432 public static void closeTransaction() {
Robert Carre9953b12016-05-23 20:52:04 -0700433 nativeCloseTransaction(false);
434 }
435
436 public static void closeTransactionSync() {
437 nativeCloseTransaction(true);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800438 }
439
Rob Carr64e516f2015-10-29 00:20:45 +0000440 public void deferTransactionUntil(IBinder handle, long frame) {
Robert Carrd5c7dd62017-03-08 10:39:30 -0800441 if (frame > 0) {
442 nativeDeferTransactionUntil(mNativeObject, handle, frame);
443 }
444 }
445
446 public void deferTransactionUntil(Surface barrier, long frame) {
447 if (frame > 0) {
448 nativeDeferTransactionUntilSurface(mNativeObject, barrier.mNativeObject, frame);
449 }
450 }
451
452 public void reparentChildren(IBinder newParentHandle) {
453 nativeReparentChildren(mNativeObject, newParentHandle);
454 }
455
456 public void detachChildren() {
457 nativeSeverChildren(mNativeObject);
Rob Carr64e516f2015-10-29 00:20:45 +0000458 }
459
Robert Carr1ca6a332016-04-11 18:00:43 -0700460 public void setOverrideScalingMode(int scalingMode) {
461 checkNotReleased();
462 nativeSetOverrideScalingMode(mNativeObject, scalingMode);
463 }
464
Rob Carr64e516f2015-10-29 00:20:45 +0000465 public IBinder getHandle() {
466 return nativeGetHandle(mNativeObject);
467 }
468
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800469 /** flag the transaction as an animation */
470 public static void setAnimationTransaction() {
471 nativeSetAnimationTransaction();
472 }
473
474 public void setLayer(int zorder) {
475 checkNotReleased();
476 nativeSetLayer(mNativeObject, zorder);
477 }
478
Robert Carraf422a82017-04-10 18:34:33 -0700479 public void setRelativeLayer(IBinder relativeTo, int zorder) {
480 checkNotReleased();
481 nativeSetRelativeLayer(mNativeObject, relativeTo, zorder);
482 }
483
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800484 public void setPosition(float x, float y) {
485 checkNotReleased();
486 nativeSetPosition(mNativeObject, x, y);
487 }
488
Robert Carra9408d42016-06-03 13:28:48 -0700489 /**
Robert Carr6da3cc02016-06-16 15:17:07 -0700490 * If the buffer size changes in this transaction, position and crop updates specified
Robert Carra9408d42016-06-03 13:28:48 -0700491 * in this transaction will not complete until a buffer of the new size
Robert Carr6da3cc02016-06-16 15:17:07 -0700492 * 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)
Robert Carra9408d42016-06-03 13:28:48 -0700495 */
Robert Carr6da3cc02016-06-16 15:17:07 -0700496 public void setGeometryAppliesWithResize() {
Robert Carra9408d42016-06-03 13:28:48 -0700497 checkNotReleased();
Robert Carr6da3cc02016-06-16 15:17:07 -0700498 nativeSetGeometryAppliesWithResize(mNativeObject);
Robert Carra9408d42016-06-03 13:28:48 -0700499 }
500
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800501 public void setSize(int w, int h) {
502 checkNotReleased();
503 nativeSetSize(mNativeObject, w, h);
504 }
505
506 public void hide() {
507 checkNotReleased();
508 nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
509 }
510
511 public void show() {
512 checkNotReleased();
513 nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
514 }
515
516 public void setTransparentRegionHint(Region region) {
517 checkNotReleased();
518 nativeSetTransparentRegionHint(mNativeObject, region);
519 }
520
Svetoslav1376d602014-03-13 11:17:26 -0700521 public boolean clearContentFrameStats() {
522 checkNotReleased();
523 return nativeClearContentFrameStats(mNativeObject);
524 }
525
526 public boolean getContentFrameStats(WindowContentFrameStats outStats) {
527 checkNotReleased();
528 return nativeGetContentFrameStats(mNativeObject, outStats);
529 }
530
531 public static boolean clearAnimationFrameStats() {
532 return nativeClearAnimationFrameStats();
533 }
534
535 public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) {
536 return nativeGetAnimationFrameStats(outStats);
537 }
538
Andy McFadden314405b2014-01-29 17:18:05 -0800539 /**
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 */
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800543 public void setAlpha(float alpha) {
544 checkNotReleased();
545 nativeSetAlpha(mNativeObject, alpha);
546 }
547
Robert Carr0edf18f2017-02-21 20:01:47 -0800548 public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800549 checkNotReleased();
Robert Carr0edf18f2017-02-21 20:01:47 -0800550 nativeSetMatrix(mNativeObject, dsdx, dtdx, dtdy, dsdy);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800551 }
552
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800553 public void setWindowCrop(Rect crop) {
554 checkNotReleased();
555 if (crop != null) {
Jesse Hall6a6bc212013-08-08 12:15:03 -0700556 nativeSetWindowCrop(mNativeObject,
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800557 crop.left, crop.top, crop.right, crop.bottom);
558 } else {
559 nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
560 }
561 }
562
Pablo Ceballos27982e62016-03-09 10:50:45 -0800563 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
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800573 public void setLayerStack(int layerStack) {
574 checkNotReleased();
575 nativeSetLayerStack(mNativeObject, layerStack);
576 }
577
Andy McFadden314405b2014-01-29 17:18:05 -0800578 /**
579 * Sets the opacity of the surface. Setting the flag is equivalent to creating the
580 * Surface with the {@link #OPAQUE} flag.
581 */
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
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -0700591 /**
592 * Sets the security of the surface. Setting the flag is equivalent to creating the
593 * Surface with the {@link #SECURE} flag.
594 */
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
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800604 /*
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;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700620 public long appVsyncOffsetNanos;
621 public long presentationDeadlineNanos;
Jesse Hall6a6bc212013-08-08 12:15:03 -0700622
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800623 public PhysicalDisplayInfo() {
624 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700625
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800626 public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
627 copyFrom(other);
628 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700629
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800630 @Override
631 public boolean equals(Object o) {
632 return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
633 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700634
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800635 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
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700643 && secure == other.secure
644 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
Michael Wright1c9977b2016-07-12 13:30:10 -0700645 && presentationDeadlineNanos == other.presentationDeadlineNanos;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800646 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700647
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800648 @Override
649 public int hashCode() {
650 return 0; // don't care
651 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700652
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800653 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;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700661 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
662 presentationDeadlineNanos = other.presentationDeadlineNanos;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800663 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700664
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800665 // For debugging purposes
666 @Override
667 public String toString() {
668 return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
669 + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700670 + ", appVsyncOffset " + appVsyncOffsetNanos
Michael Wright1c9977b2016-07-12 13:30:10 -0700671 + ", bufferDeadline " + presentationDeadlineNanos + "}";
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800672 }
673 }
674
Prashant Malanic55929a2014-05-25 01:59:21 -0700675 public static void setDisplayPowerMode(IBinder displayToken, int mode) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800676 if (displayToken == null) {
677 throw new IllegalArgumentException("displayToken must not be null");
678 }
Prashant Malanic55929a2014-05-25 01:59:21 -0700679 nativeSetDisplayPowerMode(displayToken, mode);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800680 }
681
Dan Stoza00101052014-05-02 15:23:40 -0700682 public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800683 if (displayToken == null) {
684 throw new IllegalArgumentException("displayToken must not be null");
685 }
Dan Stoza00101052014-05-02 15:23:40 -0700686 return nativeGetDisplayConfigs(displayToken);
687 }
688
689 public static int getActiveConfig(IBinder displayToken) {
690 if (displayToken == null) {
691 throw new IllegalArgumentException("displayToken must not be null");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800692 }
Dan Stoza00101052014-05-02 15:23:40 -0700693 return nativeGetActiveConfig(displayToken);
694 }
695
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);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800701 }
702
Michael Wright1c9977b2016-07-12 13:30:10 -0700703 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
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
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
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800724 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,
Jesse Hall6a6bc212013-08-08 12:15:03 -0700736 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800737 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
738 }
739
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
747 public static void setDisplaySurface(IBinder displayToken, Surface surface) {
748 if (displayToken == null) {
749 throw new IllegalArgumentException("displayToken must not be null");
750 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700751
752 if (surface != null) {
753 synchronized (surface.mLock) {
754 nativeSetDisplaySurface(displayToken, surface.mNativeObject);
755 }
756 } else {
757 nativeSetDisplaySurface(displayToken, 0);
758 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800759 }
760
Michael Wright01e840f2014-06-26 16:03:25 -0700761 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
Michael Wright9ff94c02016-03-30 18:05:40 -0700772 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
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800779 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
Jesse Hall6a6bc212013-08-08 12:15:03 -0700786 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
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800793 public static IBinder getBuiltInDisplay(int builtInDisplayId) {
794 return nativeGetBuiltInDisplay(builtInDisplayId);
795 }
796
Mathias Agopian0449a402013-03-01 23:01:51 -0800797 /**
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.
Dan Stoza16ec12a2014-02-14 15:06:55 -0800810 * @param useIdentityTransform Replace whatever transformation (rotation,
811 * scaling, translation) the surface layers are currently using with the
812 * identity transformation while taking the screenshot.
Mathias Agopian0449a402013-03-01 23:01:51 -0800813 */
814 public static void screenshot(IBinder display, Surface consumer,
Dan Stoza16ec12a2014-02-14 15:06:55 -0800815 int width, int height, int minLayer, int maxLayer,
816 boolean useIdentityTransform) {
Dan Stoza9890e3412014-05-22 16:12:54 -0700817 screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
818 false, useIdentityTransform);
Mathias Agopian0449a402013-03-01 23:01:51 -0800819 }
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 */
831 public static void screenshot(IBinder display, Surface consumer,
832 int width, int height) {
Dan Stoza9890e3412014-05-22 16:12:54 -0700833 screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
Mathias Agopian0449a402013-03-01 23:01:51 -0800834 }
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 */
842 public static void screenshot(IBinder display, Surface consumer) {
Dan Stoza9890e3412014-05-22 16:12:54 -0700843 screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
Mathias Agopian0449a402013-03-01 23:01:51 -0800844 }
845
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800846 /**
847 * Copy the current screen contents into a bitmap and return it.
848 *
Mathias Agopian0449a402013-03-01 23:01:51 -0800849 * 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 *
Dan Stoza9890e3412014-05-22 16:12:54 -0700854 * @param sourceCrop The portion of the screen to capture into the Bitmap;
855 * caller may pass in 'new Rect()' if no cropping is desired.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800856 * @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.
Dan Stoza16ec12a2014-02-14 15:06:55 -0800864 * @param useIdentityTransform Replace whatever transformation (rotation,
865 * scaling, translation) the surface layers are currently using with the
866 * identity transformation while taking the screenshot.
Riley Andrews1d134062014-08-21 15:47:07 -0700867 * @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.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800872 * @return Returns a Bitmap containing the screen contents, or null
Mathias Agopian49ff2c62013-03-17 01:05:21 -0700873 * if an error occurs. Make sure to call Bitmap.recycle() as soon as
874 * possible, once its content is not needed anymore.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800875 */
Dan Stoza9890e3412014-05-22 16:12:54 -0700876 public static Bitmap screenshot(Rect sourceCrop, int width, int height,
Riley Andrews1d134062014-08-21 15:47:07 -0700877 int minLayer, int maxLayer, boolean useIdentityTransform,
878 int rotation) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800879 // TODO: should take the display as a parameter
Mathias Agopian0449a402013-03-01 23:01:51 -0800880 IBinder displayToken = SurfaceControl.getBuiltInDisplay(
881 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
Dan Stoza9890e3412014-05-22 16:12:54 -0700882 return nativeScreenshot(displayToken, sourceCrop, width, height,
Riley Andrews1d134062014-08-21 15:47:07 -0700883 minLayer, maxLayer, false, useIdentityTransform, rotation);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800884 }
885
886 /**
Robert Carr6486d312017-01-09 19:48:29 -0800887 * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)}
888 * but returns a GraphicBuffer.
889 */
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 /**
Svetoslav1376d602014-03-13 11:17:26 -0700900 * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but
901 * includes all Surfaces in the screenshot.
Mathias Agopian49ff2c62013-03-17 01:05:21 -0700902 *
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.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800910 */
911 public static Bitmap screenshot(int width, int height) {
912 // TODO: should take the display as a parameter
Mathias Agopian0449a402013-03-01 23:01:51 -0800913 IBinder displayToken = SurfaceControl.getBuiltInDisplay(
914 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
Riley Andrews1d134062014-08-21 15:47:07 -0700915 return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
916 false, Surface.ROTATION_0);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800917 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700918
Dan Stoza9890e3412014-05-22 16:12:54 -0700919 private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
Dan Stoza16ec12a2014-02-14 15:06:55 -0800920 int width, int height, int minLayer, int maxLayer, boolean allLayers,
921 boolean useIdentityTransform) {
Mathias Agopian0449a402013-03-01 23:01:51 -0800922 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 }
Dan Stoza9890e3412014-05-22 16:12:54 -0700928 nativeScreenshot(display, consumer, sourceCrop, width, height,
929 minLayer, maxLayer, allLayers, useIdentityTransform);
Mathias Agopian0449a402013-03-01 23:01:51 -0800930 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800931}