blob: aa86c03c53c7168c919ffbf2c3a56d46665530b7 [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
19import dalvik.system.CloseGuard;
20import android.graphics.Bitmap;
21import android.graphics.Rect;
22import android.graphics.Region;
23import android.os.IBinder;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080024import android.util.Log;
Igor Murashkina86ab6402013-08-30 12:58:36 -070025import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080026
27/**
28 * SurfaceControl
29 * @hide
30 */
31public class SurfaceControl {
32 private static final String TAG = "SurfaceControl";
Mathias Agopian29479eb2013-02-14 14:36:04 -080033
Ashok Bhat36bef0b2014-01-20 20:08:01 +000034 private static native long nativeCreate(SurfaceSession session, String name,
Mathias Agopian29479eb2013-02-14 14:36:04 -080035 int w, int h, int format, int flags)
36 throws OutOfResourcesException;
Ashok Bhat36bef0b2014-01-20 20:08:01 +000037 private static native void nativeRelease(long nativeObject);
38 private static native void nativeDestroy(long nativeObject);
Chong Zhang47e36a32016-02-29 16:44:33 -080039 private static native void nativeDisconnect(long nativeObject);
Mathias Agopian29479eb2013-02-14 14:36:04 -080040
41 private static native Bitmap nativeScreenshot(IBinder displayToken,
Dan Stoza9890e3412014-05-22 16:12:54 -070042 Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
Riley Andrews1d134062014-08-21 15:47:07 -070043 boolean allLayers, boolean useIdentityTransform, int rotation);
Mathias Agopian0449a402013-03-01 23:01:51 -080044 private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
Dan Stoza9890e3412014-05-22 16:12:54 -070045 Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
46 boolean allLayers, boolean useIdentityTransform);
Mathias Agopian29479eb2013-02-14 14:36:04 -080047
48 private static native void nativeOpenTransaction();
49 private static native void nativeCloseTransaction();
50 private static native void nativeSetAnimationTransaction();
51
Ashok Bhat36bef0b2014-01-20 20:08:01 +000052 private static native void nativeSetLayer(long nativeObject, int zorder);
53 private static native void nativeSetPosition(long nativeObject, float x, float y);
54 private static native void nativeSetSize(long nativeObject, int w, int h);
55 private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
56 private static native void nativeSetAlpha(long nativeObject, float alpha);
57 private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
58 private static native void nativeSetFlags(long nativeObject, int flags, int mask);
59 private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
60 private static native void nativeSetLayerStack(long nativeObject, int layerStack);
Mathias Agopian29479eb2013-02-14 14:36:04 -080061
Svetoslav1376d602014-03-13 11:17:26 -070062 private static native boolean nativeClearContentFrameStats(long nativeObject);
63 private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
64 private static native boolean nativeClearAnimationFrameStats();
65 private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
66
Mathias Agopian29479eb2013-02-14 14:36:04 -080067 private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
68 private static native IBinder nativeCreateDisplay(String name, boolean secure);
Jesse Hall6a6bc212013-08-08 12:15:03 -070069 private static native void nativeDestroyDisplay(IBinder displayToken);
Mathias Agopian29479eb2013-02-14 14:36:04 -080070 private static native void nativeSetDisplaySurface(
Ashok Bhat36bef0b2014-01-20 20:08:01 +000071 IBinder displayToken, long nativeSurfaceObject);
Mathias Agopian29479eb2013-02-14 14:36:04 -080072 private static native void nativeSetDisplayLayerStack(
73 IBinder displayToken, int layerStack);
74 private static native void nativeSetDisplayProjection(
75 IBinder displayToken, int orientation,
Jesse Hall6a6bc212013-08-08 12:15:03 -070076 int l, int t, int r, int b,
Mathias Agopian29479eb2013-02-14 14:36:04 -080077 int L, int T, int R, int B);
Michael Wright01e840f2014-06-26 16:03:25 -070078 private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
Dan Stoza00101052014-05-02 15:23:40 -070079 private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
80 IBinder displayToken);
81 private static native int nativeGetActiveConfig(IBinder displayToken);
82 private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
Prashant Malanic55929a2014-05-25 01:59:21 -070083 private static native void nativeSetDisplayPowerMode(
84 IBinder displayToken, int mode);
Rob Carr64e516f2015-10-29 00:20:45 +000085 private static native void nativeDeferTransactionUntil(long nativeObject,
86 IBinder handle, long frame);
87 private static native IBinder nativeGetHandle(long nativeObject);
Mathias Agopian29479eb2013-02-14 14:36:04 -080088
89
Mathias Agopian3866f0d2013-02-11 22:08:48 -080090 private final CloseGuard mCloseGuard = CloseGuard.get();
Igor Murashkina86ab6402013-08-30 12:58:36 -070091 private final String mName;
Ashok Bhat36bef0b2014-01-20 20:08:01 +000092 long mNativeObject; // package visibility only for Surface.java access
Mathias Agopian3866f0d2013-02-11 22:08:48 -080093
Mathias Agopian3866f0d2013-02-11 22:08:48 -080094 /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
95
96 /**
97 * Surface creation flag: Surface is created hidden
98 */
99 public static final int HIDDEN = 0x00000004;
100
101 /**
102 * Surface creation flag: The surface contains secure content, special
103 * measures will be taken to disallow the surface's content to be copied
104 * from another process. In particular, screenshots and VNC servers will
105 * be disabled, but other measures can take place, for instance the
Jesse Hall6a6bc212013-08-08 12:15:03 -0700106 * surface might not be hardware accelerated.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800107 *
108 */
109 public static final int SECURE = 0x00000080;
110
111 /**
112 * Surface creation flag: Creates a surface where color components are interpreted
113 * as "non pre-multiplied" by their alpha channel. Of course this flag is
114 * meaningless for surfaces without an alpha channel. By default
115 * surfaces are pre-multiplied, which means that each color component is
116 * already multiplied by its alpha value. In this case the blending
117 * equation used is:
Andy McFadden314405b2014-01-29 17:18:05 -0800118 * <p>
119 * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code>
120 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800121 * By contrast, non pre-multiplied surfaces use the following equation:
Andy McFadden314405b2014-01-29 17:18:05 -0800122 * <p>
123 * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code>
124 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800125 * pre-multiplied surfaces must always be used if transparent pixels are
126 * composited on top of each-other into the surface. A pre-multiplied
127 * surface can never lower the value of the alpha component of a given
128 * pixel.
Andy McFadden314405b2014-01-29 17:18:05 -0800129 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800130 * In some rare situations, a non pre-multiplied surface is preferable.
131 *
132 */
133 public static final int NON_PREMULTIPLIED = 0x00000100;
134
135 /**
136 * Surface creation flag: Indicates that the surface must be considered opaque,
137 * even if its pixel format is set to translucent. This can be useful if an
138 * application needs full RGBA 8888 support for instance but will
139 * still draw every pixel opaque.
Andy McFadden314405b2014-01-29 17:18:05 -0800140 * <p>
141 * This flag is ignored if setAlpha() is used to make the surface non-opaque.
142 * Combined effects are (assuming a buffer format with an alpha channel):
143 * <ul>
144 * <li>OPAQUE + alpha(1.0) == opaque composition
145 * <li>OPAQUE + alpha(0.x) == blended composition
146 * <li>!OPAQUE + alpha(1.0) == blended composition
147 * <li>!OPAQUE + alpha(0.x) == blended composition
148 * </ul>
149 * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively
150 * set automatically.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800151 */
152 public static final int OPAQUE = 0x00000400;
153
154 /**
155 * Surface creation flag: Application requires a hardware-protected path to an
156 * external display sink. If a hardware-protected path is not available,
157 * then this surface will not be displayed on the external sink.
158 *
159 */
160 public static final int PROTECTED_APP = 0x00000800;
161
162 // 0x1000 is reserved for an independent DRM protected flag in framework
163
164 /**
Riley Andrews68eccda2014-07-07 11:47:35 -0700165 * Surface creation flag: Window represents a cursor glyph.
166 */
167 public static final int CURSOR_WINDOW = 0x00002000;
168
169 /**
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800170 * Surface creation flag: Creates a normal surface.
171 * This is the default.
172 *
173 */
174 public static final int FX_SURFACE_NORMAL = 0x00000000;
175
176 /**
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800177 * Surface creation flag: Creates a Dim surface.
178 * Everything behind this surface is dimmed by the amount specified
179 * in {@link #setAlpha}. It is an error to lock a Dim surface, since it
180 * doesn't have a backing store.
181 *
182 */
183 public static final int FX_SURFACE_DIM = 0x00020000;
184
185 /**
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800186 * Mask used for FX values above.
187 *
188 */
189 public static final int FX_SURFACE_MASK = 0x000F0000;
190
191 /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
192
193 /**
194 * Surface flag: Hide the surface.
195 * Equivalent to calling hide().
Andy McFadden314405b2014-01-29 17:18:05 -0800196 * Updates the value set during Surface creation (see {@link #HIDDEN}).
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800197 */
Andy McFadden40b9ef12014-01-30 13:44:47 -0800198 private static final int SURFACE_HIDDEN = 0x01;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800199
Andy McFadden314405b2014-01-29 17:18:05 -0800200 /**
201 * Surface flag: composite without blending when possible.
202 * Updates the value set during Surface creation (see {@link #OPAQUE}).
203 */
Andy McFadden40b9ef12014-01-30 13:44:47 -0800204 private static final int SURFACE_OPAQUE = 0x02;
Andy McFadden314405b2014-01-29 17:18:05 -0800205
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800206
207 /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
208 * these are different from the logical display ids used elsewhere in the framework */
209
210 /**
211 * Built-in physical display id: Main display.
Andy McFadden40b9ef12014-01-30 13:44:47 -0800212 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800213 */
214 public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
215
216 /**
217 * Built-in physical display id: Attached HDMI display.
Andy McFadden40b9ef12014-01-30 13:44:47 -0800218 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800219 */
220 public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
221
Prashant Malanic55929a2014-05-25 01:59:21 -0700222 /* Display power modes * /
223
224 /**
225 * Display power mode off: used while blanking the screen.
Jeff Brown5dc21912014-07-17 18:50:18 -0700226 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
Prashant Malanic55929a2014-05-25 01:59:21 -0700227 */
228 public static final int POWER_MODE_OFF = 0;
229
230 /**
231 * Display power mode doze: used while putting the screen into low power mode.
Jeff Brown5dc21912014-07-17 18:50:18 -0700232 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
Prashant Malanic55929a2014-05-25 01:59:21 -0700233 */
234 public static final int POWER_MODE_DOZE = 1;
235
236 /**
237 * Display power mode normal: used while unblanking the screen.
Jeff Brown5dc21912014-07-17 18:50:18 -0700238 * Use only with {@link SurfaceControl#setDisplayPowerMode}.
Prashant Malanic55929a2014-05-25 01:59:21 -0700239 */
240 public static final int POWER_MODE_NORMAL = 2;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800241
Jeff Brown5dc21912014-07-17 18:50:18 -0700242 /**
243 * Display power mode doze: used while putting the screen into a suspended
244 * low power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}.
245 */
246 public static final int POWER_MODE_DOZE_SUSPEND = 3;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800247
248 /**
249 * Create a surface with a name.
Andy McFadden314405b2014-01-29 17:18:05 -0800250 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800251 * The surface creation flags specify what kind of surface to create and
252 * certain options such as whether the surface can be assumed to be opaque
253 * and whether it should be initially hidden. Surfaces should always be
254 * created with the {@link #HIDDEN} flag set to ensure that they are not
255 * made visible prematurely before all of the surface's properties have been
256 * configured.
Andy McFadden314405b2014-01-29 17:18:05 -0800257 * <p>
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800258 * Good practice is to first create the surface with the {@link #HIDDEN} flag
259 * specified, open a transaction, set the surface layer, layer stack, alpha,
260 * and position, call {@link #show} if appropriate, and close the transaction.
261 *
262 * @param session The surface session, must not be null.
263 * @param name The surface name, must not be null.
264 * @param w The surface initial width.
265 * @param h The surface initial height.
266 * @param flags The surface creation flags. Should always include {@link #HIDDEN}
267 * in the creation flags.
Igor Murashkina86ab6402013-08-30 12:58:36 -0700268 *
269 * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800270 */
271 public SurfaceControl(SurfaceSession session,
272 String name, int w, int h, int format, int flags)
273 throws OutOfResourcesException {
274 if (session == null) {
275 throw new IllegalArgumentException("session must not be null");
276 }
277 if (name == null) {
278 throw new IllegalArgumentException("name must not be null");
279 }
280
281 if ((flags & SurfaceControl.HIDDEN) == 0) {
282 Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
283 + "to ensure that they are not made visible prematurely before "
284 + "all of the surface's properties have been configured. "
285 + "Set the other properties and make the surface visible within "
286 + "a transaction. New surface name: " + name,
287 new Throwable());
288 }
289
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800290 mName = name;
291 mNativeObject = nativeCreate(session, name, w, h, format, flags);
292 if (mNativeObject == 0) {
293 throw new OutOfResourcesException(
294 "Couldn't allocate SurfaceControl native object");
295 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700296
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800297 mCloseGuard.open("release");
298 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700299
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800300 @Override
301 protected void finalize() throws Throwable {
302 try {
303 if (mCloseGuard != null) {
304 mCloseGuard.warnIfOpen();
305 }
306 if (mNativeObject != 0) {
307 nativeRelease(mNativeObject);
308 }
309 } finally {
310 super.finalize();
311 }
312 }
313
314 @Override
315 public String toString() {
316 return "Surface(name=" + mName + ")";
317 }
318
319 /**
320 * Release the local reference to the server-side surface.
321 * Always call release() when you're done with a Surface.
322 * This will make the surface invalid.
323 */
324 public void release() {
325 if (mNativeObject != 0) {
326 nativeRelease(mNativeObject);
327 mNativeObject = 0;
328 }
329 mCloseGuard.close();
330 }
331
332 /**
333 * Free all server-side state associated with this surface and
334 * release this object's reference. This method can only be
335 * called from the process that created the service.
336 */
337 public void destroy() {
338 if (mNativeObject != 0) {
339 nativeDestroy(mNativeObject);
340 mNativeObject = 0;
341 }
342 mCloseGuard.close();
343 }
344
Chong Zhang47e36a32016-02-29 16:44:33 -0800345 /**
346 * Disconnect any client still connected to the surface.
347 */
348 public void disconnect() {
349 if (mNativeObject != 0) {
350 nativeDisconnect(mNativeObject);
351 }
352 }
353
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800354 private void checkNotReleased() {
355 if (mNativeObject == 0) throw new NullPointerException(
356 "mNativeObject is null. Have you called release() already?");
357 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700358
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800359 /*
360 * set surface parameters.
361 * needs to be inside open/closeTransaction block
362 */
363
364 /** start a transaction */
365 public static void openTransaction() {
366 nativeOpenTransaction();
367 }
368
369 /** end a transaction */
370 public static void closeTransaction() {
371 nativeCloseTransaction();
372 }
373
Rob Carr64e516f2015-10-29 00:20:45 +0000374 public void deferTransactionUntil(IBinder handle, long frame) {
375 nativeDeferTransactionUntil(mNativeObject, handle, frame);
376 }
377
378 public IBinder getHandle() {
379 return nativeGetHandle(mNativeObject);
380 }
381
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800382 /** flag the transaction as an animation */
383 public static void setAnimationTransaction() {
384 nativeSetAnimationTransaction();
385 }
386
387 public void setLayer(int zorder) {
388 checkNotReleased();
389 nativeSetLayer(mNativeObject, zorder);
390 }
391
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800392 public void setPosition(float x, float y) {
393 checkNotReleased();
394 nativeSetPosition(mNativeObject, x, y);
395 }
396
397 public void setSize(int w, int h) {
398 checkNotReleased();
399 nativeSetSize(mNativeObject, w, h);
400 }
401
402 public void hide() {
403 checkNotReleased();
404 nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
405 }
406
407 public void show() {
408 checkNotReleased();
409 nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
410 }
411
412 public void setTransparentRegionHint(Region region) {
413 checkNotReleased();
414 nativeSetTransparentRegionHint(mNativeObject, region);
415 }
416
Svetoslav1376d602014-03-13 11:17:26 -0700417 public boolean clearContentFrameStats() {
418 checkNotReleased();
419 return nativeClearContentFrameStats(mNativeObject);
420 }
421
422 public boolean getContentFrameStats(WindowContentFrameStats outStats) {
423 checkNotReleased();
424 return nativeGetContentFrameStats(mNativeObject, outStats);
425 }
426
427 public static boolean clearAnimationFrameStats() {
428 return nativeClearAnimationFrameStats();
429 }
430
431 public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) {
432 return nativeGetAnimationFrameStats(outStats);
433 }
434
Andy McFadden314405b2014-01-29 17:18:05 -0800435 /**
436 * Sets an alpha value for the entire Surface. This value is combined with the
437 * per-pixel alpha. It may be used with opaque Surfaces.
438 */
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800439 public void setAlpha(float alpha) {
440 checkNotReleased();
441 nativeSetAlpha(mNativeObject, alpha);
442 }
443
444 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
445 checkNotReleased();
446 nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
447 }
448
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800449 public void setWindowCrop(Rect crop) {
450 checkNotReleased();
451 if (crop != null) {
Jesse Hall6a6bc212013-08-08 12:15:03 -0700452 nativeSetWindowCrop(mNativeObject,
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800453 crop.left, crop.top, crop.right, crop.bottom);
454 } else {
455 nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
456 }
457 }
458
459 public void setLayerStack(int layerStack) {
460 checkNotReleased();
461 nativeSetLayerStack(mNativeObject, layerStack);
462 }
463
Andy McFadden314405b2014-01-29 17:18:05 -0800464 /**
465 * Sets the opacity of the surface. Setting the flag is equivalent to creating the
466 * Surface with the {@link #OPAQUE} flag.
467 */
468 public void setOpaque(boolean isOpaque) {
469 checkNotReleased();
470 if (isOpaque) {
471 nativeSetFlags(mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE);
472 } else {
473 nativeSetFlags(mNativeObject, 0, SURFACE_OPAQUE);
474 }
475 }
476
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -0700477 /**
478 * Sets the security of the surface. Setting the flag is equivalent to creating the
479 * Surface with the {@link #SECURE} flag.
480 */
481 public void setSecure(boolean isSecure) {
482 checkNotReleased();
483 if (isSecure) {
484 nativeSetFlags(mNativeObject, SECURE, SECURE);
485 } else {
486 nativeSetFlags(mNativeObject, 0, SECURE);
487 }
488 }
489
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800490 /*
491 * set display parameters.
492 * needs to be inside open/closeTransaction block
493 */
494
495 /**
496 * Describes the properties of a physical display known to surface flinger.
497 */
498 public static final class PhysicalDisplayInfo {
499 public int width;
500 public int height;
501 public float refreshRate;
502 public float density;
503 public float xDpi;
504 public float yDpi;
505 public boolean secure;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700506 public long appVsyncOffsetNanos;
507 public long presentationDeadlineNanos;
Dan Stoza904f4852015-08-31 12:01:48 -0700508 public int colorTransform;
Jesse Hall6a6bc212013-08-08 12:15:03 -0700509
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800510 public PhysicalDisplayInfo() {
511 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700512
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800513 public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
514 copyFrom(other);
515 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700516
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800517 @Override
518 public boolean equals(Object o) {
519 return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
520 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700521
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800522 public boolean equals(PhysicalDisplayInfo other) {
523 return other != null
524 && width == other.width
525 && height == other.height
526 && refreshRate == other.refreshRate
527 && density == other.density
528 && xDpi == other.xDpi
529 && yDpi == other.yDpi
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700530 && secure == other.secure
531 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
Dan Stoza904f4852015-08-31 12:01:48 -0700532 && presentationDeadlineNanos == other.presentationDeadlineNanos
533 && colorTransform == other.colorTransform;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800534 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700535
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800536 @Override
537 public int hashCode() {
538 return 0; // don't care
539 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700540
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800541 public void copyFrom(PhysicalDisplayInfo other) {
542 width = other.width;
543 height = other.height;
544 refreshRate = other.refreshRate;
545 density = other.density;
546 xDpi = other.xDpi;
547 yDpi = other.yDpi;
548 secure = other.secure;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700549 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
550 presentationDeadlineNanos = other.presentationDeadlineNanos;
Dan Stoza904f4852015-08-31 12:01:48 -0700551 colorTransform = other.colorTransform;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800552 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700553
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800554 // For debugging purposes
555 @Override
556 public String toString() {
557 return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
558 + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700559 + ", appVsyncOffset " + appVsyncOffsetNanos
Dan Stoza904f4852015-08-31 12:01:48 -0700560 + ", bufferDeadline " + presentationDeadlineNanos
561 + ", colorTransform " + colorTransform + "}";
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800562 }
563 }
564
Prashant Malanic55929a2014-05-25 01:59:21 -0700565 public static void setDisplayPowerMode(IBinder displayToken, int mode) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800566 if (displayToken == null) {
567 throw new IllegalArgumentException("displayToken must not be null");
568 }
Prashant Malanic55929a2014-05-25 01:59:21 -0700569 nativeSetDisplayPowerMode(displayToken, mode);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800570 }
571
Dan Stoza00101052014-05-02 15:23:40 -0700572 public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800573 if (displayToken == null) {
574 throw new IllegalArgumentException("displayToken must not be null");
575 }
Dan Stoza00101052014-05-02 15:23:40 -0700576 return nativeGetDisplayConfigs(displayToken);
577 }
578
579 public static int getActiveConfig(IBinder displayToken) {
580 if (displayToken == null) {
581 throw new IllegalArgumentException("displayToken must not be null");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800582 }
Dan Stoza00101052014-05-02 15:23:40 -0700583 return nativeGetActiveConfig(displayToken);
584 }
585
586 public static boolean setActiveConfig(IBinder displayToken, int id) {
587 if (displayToken == null) {
588 throw new IllegalArgumentException("displayToken must not be null");
589 }
590 return nativeSetActiveConfig(displayToken, id);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800591 }
592
593 public static void setDisplayProjection(IBinder displayToken,
594 int orientation, Rect layerStackRect, Rect displayRect) {
595 if (displayToken == null) {
596 throw new IllegalArgumentException("displayToken must not be null");
597 }
598 if (layerStackRect == null) {
599 throw new IllegalArgumentException("layerStackRect must not be null");
600 }
601 if (displayRect == null) {
602 throw new IllegalArgumentException("displayRect must not be null");
603 }
604 nativeSetDisplayProjection(displayToken, orientation,
Jesse Hall6a6bc212013-08-08 12:15:03 -0700605 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800606 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
607 }
608
609 public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
610 if (displayToken == null) {
611 throw new IllegalArgumentException("displayToken must not be null");
612 }
613 nativeSetDisplayLayerStack(displayToken, layerStack);
614 }
615
616 public static void setDisplaySurface(IBinder displayToken, Surface surface) {
617 if (displayToken == null) {
618 throw new IllegalArgumentException("displayToken must not be null");
619 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700620
621 if (surface != null) {
622 synchronized (surface.mLock) {
623 nativeSetDisplaySurface(displayToken, surface.mNativeObject);
624 }
625 } else {
626 nativeSetDisplaySurface(displayToken, 0);
627 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800628 }
629
Michael Wright01e840f2014-06-26 16:03:25 -0700630 public static void setDisplaySize(IBinder displayToken, int width, int height) {
631 if (displayToken == null) {
632 throw new IllegalArgumentException("displayToken must not be null");
633 }
634 if (width <= 0 || height <= 0) {
635 throw new IllegalArgumentException("width and height must be positive");
636 }
637
638 nativeSetDisplaySize(displayToken, width, height);
639 }
640
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800641 public static IBinder createDisplay(String name, boolean secure) {
642 if (name == null) {
643 throw new IllegalArgumentException("name must not be null");
644 }
645 return nativeCreateDisplay(name, secure);
646 }
647
Jesse Hall6a6bc212013-08-08 12:15:03 -0700648 public static void destroyDisplay(IBinder displayToken) {
649 if (displayToken == null) {
650 throw new IllegalArgumentException("displayToken must not be null");
651 }
652 nativeDestroyDisplay(displayToken);
653 }
654
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800655 public static IBinder getBuiltInDisplay(int builtInDisplayId) {
656 return nativeGetBuiltInDisplay(builtInDisplayId);
657 }
658
Mathias Agopian0449a402013-03-01 23:01:51 -0800659 /**
660 * Copy the current screen contents into the provided {@link Surface}
661 *
662 * @param display The display to take the screenshot of.
663 * @param consumer The {@link Surface} to take the screenshot into.
664 * @param width The desired width of the returned bitmap; the raw
665 * screen will be scaled down to this size.
666 * @param height The desired height of the returned bitmap; the raw
667 * screen will be scaled down to this size.
668 * @param minLayer The lowest (bottom-most Z order) surface layer to
669 * include in the screenshot.
670 * @param maxLayer The highest (top-most Z order) surface layer to
671 * include in the screenshot.
Dan Stoza16ec12a2014-02-14 15:06:55 -0800672 * @param useIdentityTransform Replace whatever transformation (rotation,
673 * scaling, translation) the surface layers are currently using with the
674 * identity transformation while taking the screenshot.
Mathias Agopian0449a402013-03-01 23:01:51 -0800675 */
676 public static void screenshot(IBinder display, Surface consumer,
Dan Stoza16ec12a2014-02-14 15:06:55 -0800677 int width, int height, int minLayer, int maxLayer,
678 boolean useIdentityTransform) {
Dan Stoza9890e3412014-05-22 16:12:54 -0700679 screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer,
680 false, useIdentityTransform);
Mathias Agopian0449a402013-03-01 23:01:51 -0800681 }
682
683 /**
684 * Copy the current screen contents into the provided {@link Surface}
685 *
686 * @param display The display to take the screenshot of.
687 * @param consumer The {@link Surface} to take the screenshot into.
688 * @param width The desired width of the returned bitmap; the raw
689 * screen will be scaled down to this size.
690 * @param height The desired height of the returned bitmap; the raw
691 * screen will be scaled down to this size.
692 */
693 public static void screenshot(IBinder display, Surface consumer,
694 int width, int height) {
Dan Stoza9890e3412014-05-22 16:12:54 -0700695 screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
Mathias Agopian0449a402013-03-01 23:01:51 -0800696 }
697
698 /**
699 * Copy the current screen contents into the provided {@link Surface}
700 *
701 * @param display The display to take the screenshot of.
702 * @param consumer The {@link Surface} to take the screenshot into.
703 */
704 public static void screenshot(IBinder display, Surface consumer) {
Dan Stoza9890e3412014-05-22 16:12:54 -0700705 screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false);
Mathias Agopian0449a402013-03-01 23:01:51 -0800706 }
707
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800708 /**
709 * Copy the current screen contents into a bitmap and return it.
710 *
Mathias Agopian0449a402013-03-01 23:01:51 -0800711 * CAVEAT: Versions of screenshot that return a {@link Bitmap} can
712 * be extremely slow; avoid use unless absolutely necessary; prefer
713 * the versions that use a {@link Surface} instead, such as
714 * {@link SurfaceControl#screenshot(IBinder, Surface)}.
715 *
Dan Stoza9890e3412014-05-22 16:12:54 -0700716 * @param sourceCrop The portion of the screen to capture into the Bitmap;
717 * caller may pass in 'new Rect()' if no cropping is desired.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800718 * @param width The desired width of the returned bitmap; the raw
719 * screen will be scaled down to this size.
720 * @param height The desired height of the returned bitmap; the raw
721 * screen will be scaled down to this size.
722 * @param minLayer The lowest (bottom-most Z order) surface layer to
723 * include in the screenshot.
724 * @param maxLayer The highest (top-most Z order) surface layer to
725 * include in the screenshot.
Dan Stoza16ec12a2014-02-14 15:06:55 -0800726 * @param useIdentityTransform Replace whatever transformation (rotation,
727 * scaling, translation) the surface layers are currently using with the
728 * identity transformation while taking the screenshot.
Riley Andrews1d134062014-08-21 15:47:07 -0700729 * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
730 * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
731 * screenshots in its native portrait orientation by default, so this is
732 * useful for returning screenshots that are independent of device
733 * orientation.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800734 * @return Returns a Bitmap containing the screen contents, or null
Mathias Agopian49ff2c62013-03-17 01:05:21 -0700735 * if an error occurs. Make sure to call Bitmap.recycle() as soon as
736 * possible, once its content is not needed anymore.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800737 */
Dan Stoza9890e3412014-05-22 16:12:54 -0700738 public static Bitmap screenshot(Rect sourceCrop, int width, int height,
Riley Andrews1d134062014-08-21 15:47:07 -0700739 int minLayer, int maxLayer, boolean useIdentityTransform,
740 int rotation) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800741 // TODO: should take the display as a parameter
Mathias Agopian0449a402013-03-01 23:01:51 -0800742 IBinder displayToken = SurfaceControl.getBuiltInDisplay(
743 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
Dan Stoza9890e3412014-05-22 16:12:54 -0700744 return nativeScreenshot(displayToken, sourceCrop, width, height,
Riley Andrews1d134062014-08-21 15:47:07 -0700745 minLayer, maxLayer, false, useIdentityTransform, rotation);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800746 }
747
748 /**
Svetoslav1376d602014-03-13 11:17:26 -0700749 * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but
750 * includes all Surfaces in the screenshot.
Mathias Agopian49ff2c62013-03-17 01:05:21 -0700751 *
752 * @param width The desired width of the returned bitmap; the raw
753 * screen will be scaled down to this size.
754 * @param height The desired height of the returned bitmap; the raw
755 * screen will be scaled down to this size.
756 * @return Returns a Bitmap containing the screen contents, or null
757 * if an error occurs. Make sure to call Bitmap.recycle() as soon as
758 * possible, once its content is not needed anymore.
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800759 */
760 public static Bitmap screenshot(int width, int height) {
761 // TODO: should take the display as a parameter
Mathias Agopian0449a402013-03-01 23:01:51 -0800762 IBinder displayToken = SurfaceControl.getBuiltInDisplay(
763 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
Riley Andrews1d134062014-08-21 15:47:07 -0700764 return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
765 false, Surface.ROTATION_0);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800766 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700767
Dan Stoza9890e3412014-05-22 16:12:54 -0700768 private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
Dan Stoza16ec12a2014-02-14 15:06:55 -0800769 int width, int height, int minLayer, int maxLayer, boolean allLayers,
770 boolean useIdentityTransform) {
Mathias Agopian0449a402013-03-01 23:01:51 -0800771 if (display == null) {
772 throw new IllegalArgumentException("displayToken must not be null");
773 }
774 if (consumer == null) {
775 throw new IllegalArgumentException("consumer must not be null");
776 }
Dan Stoza9890e3412014-05-22 16:12:54 -0700777 nativeScreenshot(display, consumer, sourceCrop, width, height,
778 minLayer, maxLayer, allLayers, useIdentityTransform);
Mathias Agopian0449a402013-03-01 23:01:51 -0800779 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800780}