blob: 961f742f3e27feb3b9226a6b76dd6d4cd05ee657 [file] [log] [blame]
Robert Carre6a83512015-11-03 16:09:21 -08001/*
2 * Copyright (C) 2015 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 com.android.server.wm;
18
Wale Ogunwale722ff892016-02-18 13:37:55 -080019import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080020import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
21import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080022import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080023import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
24import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
25import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Robert Carr1ca6a332016-04-11 18:00:43 -070026import static android.view.Surface.SCALING_MODE_FREEZE;
27import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW;
Robert Carre6a83512015-11-03 16:09:21 -080028
Robert Carr086d2922016-06-09 10:22:38 -070029import android.graphics.PixelFormat;
Robert Carre6a83512015-11-03 16:09:21 -080030import android.graphics.Point;
31import android.graphics.PointF;
32import android.graphics.Rect;
33import android.graphics.Region;
34import android.os.IBinder;
35import android.os.Debug;
36import android.view.Surface;
37import android.view.SurfaceControl;
38import android.view.SurfaceSession;
39import android.view.WindowContentFrameStats;
40import android.view.Surface.OutOfResourcesException;
41
42import android.util.Slog;
43
44import java.io.PrintWriter;
45import java.util.ArrayList;
46
47class WindowSurfaceController {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080048 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM;
Robert Carre6a83512015-11-03 16:09:21 -080049
50 final WindowStateAnimator mAnimator;
51
52 private SurfaceControl mSurfaceControl;
53
54 private boolean mSurfaceShown = false;
55 private float mSurfaceX = 0;
56 private float mSurfaceY = 0;
57 private float mSurfaceW = 0;
58 private float mSurfaceH = 0;
59
Matthew Bouyack8dd88f62016-10-24 14:01:26 -070060 // Initialize to the identity matrix.
61 private float mLastDsdx = 1;
62 private float mLastDtdx = 0;
63 private float mLastDsdy = 0;
64 private float mLastDtdy = 1;
65
Robert Carre6a83512015-11-03 16:09:21 -080066 private float mSurfaceAlpha = 0;
67
68 private int mSurfaceLayer = 0;
Robert Carre6a83512015-11-03 16:09:21 -080069
70 // Surface flinger doesn't support crop rectangles where width or height is non-positive.
71 // However, we need to somehow handle the situation where the cropping would completely hide
72 // the window. We achieve this by explicitly hiding the surface and not letting it be shown.
73 private boolean mHiddenForCrop = false;
Jorim Jaggi1eb39b02016-02-25 13:36:14 -050074
75 // Initially a surface is hidden after just being created.
76 private boolean mHiddenForOtherReasons = true;
Robert Carre6a83512015-11-03 16:09:21 -080077 private final String title;
78
79 public WindowSurfaceController(SurfaceSession s,
80 String name, int w, int h, int format, int flags, WindowStateAnimator animator) {
81 mAnimator = animator;
82
83 mSurfaceW = w;
84 mSurfaceH = h;
Robert Carre6a83512015-11-03 16:09:21 -080085
86 title = name;
87
Robert Carr086d2922016-06-09 10:22:38 -070088 // For opaque child windows placed under parent windows,
89 // we use a special SurfaceControl which mirrors commands
90 // to a black-out layer placed one Z-layer below the surface.
91 // This prevents holes to whatever app/wallpaper is underneath.
92 if (animator.mWin.isChildWindow() &&
Robert Carr91b228092016-06-28 17:32:37 -070093 animator.mWin.mSubLayer < 0 &&
94 animator.mWin.mAppToken != null) {
Robert Carr086d2922016-06-09 10:22:38 -070095 mSurfaceControl = new SurfaceControlWithBackground(s,
Robert Carr91b228092016-06-28 17:32:37 -070096 name, w, h, format, flags, animator.mWin.mAppToken);
Robert Carr086d2922016-06-09 10:22:38 -070097 } else if (DEBUG_SURFACE_TRACE) {
Robert Carre6a83512015-11-03 16:09:21 -080098 mSurfaceControl = new SurfaceTrace(
99 s, name, w, h, format, flags);
100 } else {
101 mSurfaceControl = new SurfaceControl(
102 s, name, w, h, format, flags);
103 }
104 }
105
106
107 void logSurface(String msg, RuntimeException where) {
108 String str = " SURFACE " + msg + ": " + title;
109 if (where != null) {
110 Slog.i(TAG, str, where);
111 } else {
112 Slog.i(TAG, str);
113 }
114 }
115
Filip Gruszczynski63a35e22015-11-05 15:38:59 -0800116 void hideInTransaction(String reason) {
117 if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800118 mHiddenForOtherReasons = true;
Chong Zhang3cc58dd2016-04-20 17:45:24 -0700119
120 mAnimator.destroyPreservedSurfaceLocked();
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800121 updateVisibility();
122 }
123
124 private void hideSurface() {
Robert Carre6a83512015-11-03 16:09:21 -0800125 if (mSurfaceControl != null) {
126 mSurfaceShown = false;
127 try {
128 mSurfaceControl.hide();
129 } catch (RuntimeException e) {
130 Slog.w(TAG, "Exception hiding surface in " + this);
131 }
132 }
133 }
134
135 void setPositionAndLayer(float left, float top, int layerStack, int layer) {
136 SurfaceControl.openTransaction();
137 try {
138 mSurfaceX = left;
139 mSurfaceY = top;
140
141 try {
Chong Zhangae35fef2016-03-16 15:56:55 -0700142 if (SHOW_TRANSACTIONS) logSurface(
143 "POS (setPositionAndLayer) @ (" + left + "," + top + ")", null);
Robert Carre6a83512015-11-03 16:09:21 -0800144 mSurfaceControl.setPosition(left, top);
145 mSurfaceControl.setLayerStack(layerStack);
146
147 mSurfaceControl.setLayer(layer);
148 mSurfaceControl.setAlpha(0);
149 mSurfaceShown = false;
150 } catch (RuntimeException e) {
151 Slog.w(TAG, "Error creating surface in " + this, e);
152 mAnimator.reclaimSomeSurfaceMemory("create-init", true);
153 }
154 } finally {
155 SurfaceControl.closeTransaction();
156 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
157 "<<< CLOSE TRANSACTION setPositionAndLayer");
158 }
159 }
160
161 void destroyInTransaction() {
Chong Zhangad23b3f2016-08-31 16:05:27 -0700162 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
163 Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8));
164 }
Robert Carre6a83512015-11-03 16:09:21 -0800165 try {
Wale Ogunwale722ff892016-02-18 13:37:55 -0800166 if (mSurfaceControl != null) {
167 mSurfaceControl.destroy();
168 }
Robert Carre6a83512015-11-03 16:09:21 -0800169 } catch (RuntimeException e) {
170 Slog.w(TAG, "Error destroying surface in: " + this, e);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800171 } finally {
172 mSurfaceShown = false;
173 mSurfaceControl = null;
Robert Carre6a83512015-11-03 16:09:21 -0800174 }
175 }
176
Chong Zhang47e36a32016-02-29 16:44:33 -0800177 void disconnectInTransaction() {
178 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
179 Slog.i(TAG, "Disconnecting client: " + this);
180 }
181
182 try {
183 if (mSurfaceControl != null) {
184 mSurfaceControl.disconnect();
185 }
186 } catch (RuntimeException e) {
187 Slog.w(TAG, "Error disconnecting surface in: " + this, e);
188 }
189 }
190
Robert Carre6a83512015-11-03 16:09:21 -0800191 void setCropInTransaction(Rect clipRect, boolean recoveringMemory) {
192 if (SHOW_TRANSACTIONS) logSurface(
193 "CROP " + clipRect.toShortString(), null);
194 try {
Robert Carr4320d332016-06-10 15:13:32 -0700195 if (clipRect.width() > 0 && clipRect.height() > 0) {
Robert Carre6a83512015-11-03 16:09:21 -0800196 mSurfaceControl.setWindowCrop(clipRect);
197 mHiddenForCrop = false;
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800198 updateVisibility();
Robert Carre6a83512015-11-03 16:09:21 -0800199 } else {
Robert Carre6a83512015-11-03 16:09:21 -0800200 mHiddenForCrop = true;
Chong Zhang3cc58dd2016-04-20 17:45:24 -0700201 mAnimator.destroyPreservedSurfaceLocked();
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800202 updateVisibility();
Robert Carre6a83512015-11-03 16:09:21 -0800203 }
204 } catch (RuntimeException e) {
205 Slog.w(TAG, "Error setting crop surface of " + this
206 + " crop=" + clipRect.toShortString(), e);
207 if (!recoveringMemory) {
208 mAnimator.reclaimSomeSurfaceMemory("crop", true);
209 }
210 }
211 }
212
Robert Carr4320d332016-06-10 15:13:32 -0700213 void clearCropInTransaction(boolean recoveringMemory) {
214 if (SHOW_TRANSACTIONS) logSurface(
215 "CLEAR CROP", null);
216 try {
217 Rect clipRect = new Rect(0, 0, -1, -1);
218 mSurfaceControl.setWindowCrop(clipRect);
219 } catch (RuntimeException e) {
220 Slog.w(TAG, "Error setting clearing crop of " + this, e);
221 if (!recoveringMemory) {
222 mAnimator.reclaimSomeSurfaceMemory("crop", true);
223 }
224 }
225 }
226
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100227 void setFinalCropInTransaction(Rect clipRect) {
228 if (SHOW_TRANSACTIONS) logSurface(
229 "FINAL CROP " + clipRect.toShortString(), null);
230 try {
231 mSurfaceControl.setFinalCrop(clipRect);
232 } catch (RuntimeException e) {
233 Slog.w(TAG, "Error disconnecting surface in: " + this, e);
234 }
235 }
236
Robert Carre6a83512015-11-03 16:09:21 -0800237 void setLayer(int layer) {
238 if (mSurfaceControl != null) {
239 SurfaceControl.openTransaction();
240 try {
241 mSurfaceControl.setLayer(layer);
242 } finally {
243 SurfaceControl.closeTransaction();
244 }
245 }
246 }
247
248 void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
249 final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
250 if (surfaceMoved) {
251 mSurfaceX = left;
252 mSurfaceY = top;
253
254 try {
Chong Zhangae35fef2016-03-16 15:56:55 -0700255 if (SHOW_TRANSACTIONS) logSurface(
256 "POS (setPositionInTransaction) @ (" + left + "," + top + ")", null);
257
Robert Carre6a83512015-11-03 16:09:21 -0800258 mSurfaceControl.setPosition(left, top);
259 } catch (RuntimeException e) {
260 Slog.w(TAG, "Error positioning surface of " + this
261 + " pos=(" + left + "," + top + ")", e);
262 if (!recoveringMemory) {
263 mAnimator.reclaimSomeSurfaceMemory("position", true);
264 }
265 }
266 }
267 }
268
Robert Carr6da3cc02016-06-16 15:17:07 -0700269 void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) {
270 mSurfaceControl.setGeometryAppliesWithResize();
Robert Carra9408d42016-06-03 13:28:48 -0700271 }
272
Robert Carre1034cc32016-02-01 13:08:15 -0800273 void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
Robert Carre6a83512015-11-03 16:09:21 -0800274 boolean recoveringMemory) {
Matthew Bouyack8dd88f62016-10-24 14:01:26 -0700275 final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
276 mLastDsdy != dsdy || mLastDtdy != dtdy;
277 if (!matrixChanged) {
278 return;
279 }
280
281 mLastDsdx = dsdx;
282 mLastDtdx = dtdx;
283 mLastDsdy = dsdy;
284 mLastDtdy = dtdy;
285
Robert Carre1034cc32016-02-01 13:08:15 -0800286 try {
287 if (SHOW_TRANSACTIONS) logSurface(
288 "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
289 mSurfaceControl.setMatrix(
290 dsdx, dtdx, dsdy, dtdy);
291 } catch (RuntimeException e) {
292 // If something goes wrong with the surface (such
293 // as running out of memory), don't take down the
294 // entire system.
295 Slog.e(TAG, "Error setting matrix on surface surface" + title
296 + " MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
297 if (!recoveringMemory) {
298 mAnimator.reclaimSomeSurfaceMemory("matrix", true);
299 }
300 }
Robert Carre1034cc32016-02-01 13:08:15 -0800301 }
302
303 boolean setSizeInTransaction(int width, int height, boolean recoveringMemory) {
Robert Carre6a83512015-11-03 16:09:21 -0800304 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
305 if (surfaceResized) {
306 mSurfaceW = width;
307 mSurfaceH = height;
308
309 try {
310 if (SHOW_TRANSACTIONS) logSurface(
311 "SIZE " + width + "x" + height, null);
312 mSurfaceControl.setSize(width, height);
Robert Carre6a83512015-11-03 16:09:21 -0800313 } catch (RuntimeException e) {
314 // If something goes wrong with the surface (such
315 // as running out of memory), don't take down the
316 // entire system.
317 Slog.e(TAG, "Error resizing surface of " + title
318 + " size=(" + width + "x" + height + ")", e);
319 if (!recoveringMemory) {
320 mAnimator.reclaimSomeSurfaceMemory("size", true);
321 }
322 return false;
323 }
324 return true;
325 }
326 return false;
327 }
328
329 boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy,
330 float dtdy, boolean recoveringMemory) {
331 if (mSurfaceControl != null) {
332 try {
333 mSurfaceAlpha = alpha;
334 mSurfaceControl.setAlpha(alpha);
335 mSurfaceLayer = layer;
336 mSurfaceControl.setLayer(layer);
Matthew Bouyack8dd88f62016-10-24 14:01:26 -0700337 mLastDsdx = dsdx;
338 mLastDtdx = dtdx;
339 mLastDsdy = dsdy;
340 mLastDtdy = dtdy;
Robert Carre6a83512015-11-03 16:09:21 -0800341 mSurfaceControl.setMatrix(
342 dsdx, dtdx, dsdy, dtdy);
343
344 } catch (RuntimeException e) {
345 Slog.w(TAG, "Error updating surface in " + title, e);
346 if (!recoveringMemory) {
347 mAnimator.reclaimSomeSurfaceMemory("update", true);
348 }
349 return false;
350 }
351 }
352 return true;
353 }
354
355 void setTransparentRegionHint(final Region region) {
356 if (mSurfaceControl == null) {
357 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
358 return;
359 }
360 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
361 SurfaceControl.openTransaction();
362 try {
363 mSurfaceControl.setTransparentRegionHint(region);
364 } finally {
365 SurfaceControl.closeTransaction();
366 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
367 "<<< CLOSE TRANSACTION setTransparentRegion");
368 }
369 }
370
371 void setOpaque(boolean isOpaque) {
372 if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque,
373 null);
374
375 if (mSurfaceControl == null) {
376 return;
377 }
378 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
379 SurfaceControl.openTransaction();
380 try {
381 mSurfaceControl.setOpaque(isOpaque);
382 } finally {
383 SurfaceControl.closeTransaction();
384 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
385 }
386 }
387
388 void setSecure(boolean isSecure) {
389 if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure,
390 null);
391
392 if (mSurfaceControl == null) {
393 return;
394 }
395 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
396 SurfaceControl.openTransaction();
397 try {
398 mSurfaceControl.setSecure(isSecure);
399 } finally {
400 SurfaceControl.closeTransaction();
401 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
402 }
403 }
404
405 boolean showRobustlyInTransaction() {
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800406 if (SHOW_TRANSACTIONS) logSurface(
407 "SHOW (performLayout)", null);
408 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
409 + " during relayout");
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800410 mHiddenForOtherReasons = false;
411 return updateVisibility();
412 }
Robert Carre6a83512015-11-03 16:09:21 -0800413
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800414 private boolean updateVisibility() {
415 if (mHiddenForCrop || mHiddenForOtherReasons) {
416 if (mSurfaceShown) {
417 hideSurface();
418 }
Robert Carre6a83512015-11-03 16:09:21 -0800419 return false;
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800420 } else {
421 if (!mSurfaceShown) {
422 return showSurface();
423 } else {
424 return true;
425 }
Robert Carre6a83512015-11-03 16:09:21 -0800426 }
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800427 }
Robert Carre6a83512015-11-03 16:09:21 -0800428
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800429 private boolean showSurface() {
Robert Carre6a83512015-11-03 16:09:21 -0800430 try {
431 mSurfaceShown = true;
432 mSurfaceControl.show();
433 return true;
434 } catch (RuntimeException e) {
435 Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + this, e);
436 }
437
438 mAnimator.reclaimSomeSurfaceMemory("show", true);
439
440 return false;
441 }
442
443 void deferTransactionUntil(IBinder handle, long frame) {
444 // TODO: Logging
445 mSurfaceControl.deferTransactionUntil(handle, frame);
446 }
447
Robert Carr1ca6a332016-04-11 18:00:43 -0700448 void forceScaleableInTransaction(boolean force) {
449 // -1 means we don't override the default or client specified
450 // scaling mode.
451 int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1;
452 mSurfaceControl.setOverrideScalingMode(scalingMode);
453 }
454
Robert Carre6a83512015-11-03 16:09:21 -0800455 boolean clearWindowContentFrameStats() {
456 if (mSurfaceControl == null) {
457 return false;
458 }
459 return mSurfaceControl.clearContentFrameStats();
460 }
461
462 boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
463 if (mSurfaceControl == null) {
464 return false;
465 }
466 return mSurfaceControl.getContentFrameStats(outStats);
467 }
468
469
470 boolean hasSurface() {
471 return mSurfaceControl != null;
472 }
473
474 IBinder getHandle() {
475 if (mSurfaceControl == null) {
476 return null;
477 }
478 return mSurfaceControl.getHandle();
479 }
480
Robert Carr6da3cc02016-06-16 15:17:07 -0700481 boolean getTransformToDisplayInverse() {
482 return mSurfaceControl.getTransformToDisplayInverse();
483 }
484
Robert Carre6a83512015-11-03 16:09:21 -0800485 void getSurface(Surface outSurface) {
486 outSurface.copyFrom(mSurfaceControl);
487 }
488
489 int getLayer() {
490 return mSurfaceLayer;
491 }
492
493 boolean getShown() {
494 return mSurfaceShown;
495 }
496
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800497 void setShown(boolean surfaceShown) {
498 mSurfaceShown = surfaceShown;
499 }
500
Robert Carre6a83512015-11-03 16:09:21 -0800501 float getX() {
502 return mSurfaceX;
503 }
504
505 float getY() {
506 return mSurfaceY;
507 }
508
Robert Carrfed10072016-05-26 11:48:49 -0700509 float getWidth() {
510 return mSurfaceW;
511 }
512
513 float getHeight() {
514 return mSurfaceH;
515 }
516
517
Robert Carre6a83512015-11-03 16:09:21 -0800518 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
519 if (dumpAll) {
520 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
521 }
522 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
523 pw.print(" layer="); pw.print(mSurfaceLayer);
524 pw.print(" alpha="); pw.print(mSurfaceAlpha);
525 pw.print(" rect=("); pw.print(mSurfaceX);
526 pw.print(","); pw.print(mSurfaceY);
527 pw.print(") "); pw.print(mSurfaceW);
528 pw.print(" x "); pw.println(mSurfaceH);
529 }
530
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -0800531 @Override
532 public String toString() {
533 return mSurfaceControl.toString();
534 }
535
Robert Carre6a83512015-11-03 16:09:21 -0800536 static class SurfaceTrace extends SurfaceControl {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800537 private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM;
Robert Carre6a83512015-11-03 16:09:21 -0800538 private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE;
539 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
540
541 private float mSurfaceTraceAlpha = 0;
542 private int mLayer;
543 private final PointF mPosition = new PointF();
544 private final Point mSize = new Point();
545 private final Rect mWindowCrop = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100546 private final Rect mFinalCrop = new Rect();
Robert Carre6a83512015-11-03 16:09:21 -0800547 private boolean mShown = false;
548 private int mLayerStack;
549 private boolean mIsOpaque;
550 private float mDsdx, mDtdx, mDsdy, mDtdy;
551 private final String mName;
552
553 public SurfaceTrace(SurfaceSession s,
554 String name, int w, int h, int format, int flags)
555 throws OutOfResourcesException {
556 super(s, name, w, h, format, flags);
557 mName = name != null ? name : "Not named";
558 mSize.set(w, h);
559 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
560 + Debug.getCallers(3));
561 synchronized (sSurfaces) {
562 sSurfaces.add(0, this);
563 }
564 }
565
566 @Override
567 public void setAlpha(float alpha) {
568 if (mSurfaceTraceAlpha != alpha) {
569 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
570 ". Called by " + Debug.getCallers(3));
571 mSurfaceTraceAlpha = alpha;
572 }
573 super.setAlpha(alpha);
574 }
575
576 @Override
577 public void setLayer(int zorder) {
578 if (zorder != mLayer) {
579 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
580 + ". Called by " + Debug.getCallers(3));
581 mLayer = zorder;
582 }
583 super.setLayer(zorder);
584
585 synchronized (sSurfaces) {
586 sSurfaces.remove(this);
587 int i;
588 for (i = sSurfaces.size() - 1; i >= 0; i--) {
589 SurfaceTrace s = sSurfaces.get(i);
590 if (s.mLayer < zorder) {
591 break;
592 }
593 }
594 sSurfaces.add(i + 1, this);
595 }
596 }
597
598 @Override
599 public void setPosition(float x, float y) {
600 if (x != mPosition.x || y != mPosition.y) {
601 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
602 + this + ". Called by " + Debug.getCallers(3));
603 mPosition.set(x, y);
604 }
605 super.setPosition(x, y);
606 }
607
608 @Override
Robert Carr6da3cc02016-06-16 15:17:07 -0700609 public void setGeometryAppliesWithResize() {
610 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setGeometryAppliesWithResize(): OLD: "
611 + this + ". Called by" + Debug.getCallers(3));
612 super.setGeometryAppliesWithResize();
Robert Carra9408d42016-06-03 13:28:48 -0700613 }
614
615 @Override
Robert Carre6a83512015-11-03 16:09:21 -0800616 public void setSize(int w, int h) {
617 if (w != mSize.x || h != mSize.y) {
618 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
619 + this + ". Called by " + Debug.getCallers(3));
620 mSize.set(w, h);
621 }
622 super.setSize(w, h);
623 }
624
625 @Override
626 public void setWindowCrop(Rect crop) {
627 if (crop != null) {
628 if (!crop.equals(mWindowCrop)) {
629 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop("
630 + crop.toShortString() + "): OLD:" + this + ". Called by "
631 + Debug.getCallers(3));
632 mWindowCrop.set(crop);
633 }
634 }
635 super.setWindowCrop(crop);
636 }
637
638 @Override
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100639 public void setFinalCrop(Rect crop) {
640 if (crop != null) {
641 if (!crop.equals(mFinalCrop)) {
642 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop("
643 + crop.toShortString() + "): OLD:" + this + ". Called by "
644 + Debug.getCallers(3));
645 mFinalCrop.set(crop);
646 }
647 }
648 super.setFinalCrop(crop);
649 }
650
651 @Override
Robert Carre6a83512015-11-03 16:09:21 -0800652 public void setLayerStack(int layerStack) {
653 if (layerStack != mLayerStack) {
654 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
655 + this + ". Called by " + Debug.getCallers(3));
656 mLayerStack = layerStack;
657 }
658 super.setLayerStack(layerStack);
659 }
660
661 @Override
662 public void setOpaque(boolean isOpaque) {
663 if (isOpaque != mIsOpaque) {
664 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
665 + this + ". Called by " + Debug.getCallers(3));
666 mIsOpaque = isOpaque;
667 }
668 super.setOpaque(isOpaque);
669 }
670
671 @Override
672 public void setSecure(boolean isSecure) {
673 super.setSecure(isSecure);
674 }
675
676 @Override
677 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
678 if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
679 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
680 + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
681 + Debug.getCallers(3));
682 mDsdx = dsdx;
683 mDtdx = dtdx;
684 mDsdy = dsdy;
685 mDtdy = dtdy;
686 }
687 super.setMatrix(dsdx, dtdx, dsdy, dtdy);
688 }
689
690 @Override
691 public void hide() {
692 if (mShown) {
693 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
694 + Debug.getCallers(3));
695 mShown = false;
696 }
697 super.hide();
698 }
699
700 @Override
701 public void show() {
702 if (!mShown) {
703 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
704 + Debug.getCallers(3));
705 mShown = true;
706 }
707 super.show();
708 }
709
710 @Override
711 public void destroy() {
712 super.destroy();
713 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
714 + Debug.getCallers(3));
715 synchronized (sSurfaces) {
716 sSurfaces.remove(this);
717 }
718 }
719
720 @Override
721 public void release() {
722 super.release();
723 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
724 + Debug.getCallers(3));
725 synchronized (sSurfaces) {
726 sSurfaces.remove(this);
727 }
728 }
729
Robert Carr6a19b4f2016-03-14 19:17:20 -0700730 @Override
731 public void setTransparentRegionHint(Region region) {
732 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region
733 + "): OLD: " + this + " . Called by " + Debug.getCallers(3));
734 super.setTransparentRegionHint(region);
735 }
736
Robert Carre6a83512015-11-03 16:09:21 -0800737 static void dumpAllSurfaces(PrintWriter pw, String header) {
738 synchronized (sSurfaces) {
739 final int N = sSurfaces.size();
740 if (N <= 0) {
741 return;
742 }
743 if (header != null) {
744 pw.println(header);
745 }
746 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
747 for (int i = 0; i < N; i++) {
748 SurfaceTrace s = sSurfaces.get(i);
749 pw.print(" Surface #"); pw.print(i); pw.print(": #");
750 pw.print(Integer.toHexString(System.identityHashCode(s)));
751 pw.print(" "); pw.println(s.mName);
752 pw.print(" mLayerStack="); pw.print(s.mLayerStack);
753 pw.print(" mLayer="); pw.println(s.mLayer);
754 pw.print(" mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
755 pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
756 pw.println(s.mIsOpaque);
757 pw.print(" mPosition="); pw.print(s.mPosition.x); pw.print(",");
758 pw.print(s.mPosition.y);
759 pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
760 pw.println(s.mSize.y);
761 pw.print(" mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100762 pw.print(" mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println();
Robert Carre6a83512015-11-03 16:09:21 -0800763 pw.print(" Transform: ("); pw.print(s.mDsdx); pw.print(", ");
764 pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
765 pw.print(", "); pw.print(s.mDtdy); pw.println(")");
766 }
767 }
768 }
769
770 @Override
771 public String toString() {
772 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
773 + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
774 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
775 + " " + mSize.x + "x" + mSize.y
776 + " crop=" + mWindowCrop.toShortString()
777 + " opaque=" + mIsOpaque
778 + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
779 }
780 }
Robert Carr086d2922016-06-09 10:22:38 -0700781
Robert Carr91b228092016-06-28 17:32:37 -0700782 class SurfaceControlWithBackground extends SurfaceControl {
Robert Carr086d2922016-06-09 10:22:38 -0700783 private SurfaceControl mBackgroundControl;
784 private boolean mOpaque = true;
Robert Carr91b228092016-06-28 17:32:37 -0700785 private boolean mAppForcedInvisible = false;
786 private AppWindowToken mAppToken;
787 public boolean mVisible = false;
788 public int mLayer = -1;
Robert Carr086d2922016-06-09 10:22:38 -0700789
790 public SurfaceControlWithBackground(SurfaceSession s,
Robert Carr91b228092016-06-28 17:32:37 -0700791 String name, int w, int h, int format, int flags,
792 AppWindowToken token)
Robert Carr086d2922016-06-09 10:22:38 -0700793 throws OutOfResourcesException {
794 super(s, name, w, h, format, flags);
795 mBackgroundControl = new SurfaceControl(s, name, w, h,
796 PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM);
797 mOpaque = (flags & SurfaceControl.OPAQUE) != 0;
Robert Carr91b228092016-06-28 17:32:37 -0700798 mAppToken = token;
799
800 mAppToken.addSurfaceViewBackground(this);
Robert Carr086d2922016-06-09 10:22:38 -0700801 }
802
803 @Override
804 public void setAlpha(float alpha) {
805 super.setAlpha(alpha);
806 mBackgroundControl.setAlpha(alpha);
807 }
808
809 @Override
810 public void setLayer(int zorder) {
811 super.setLayer(zorder);
812 mBackgroundControl.setLayer(zorder - 1);
Robert Carr91b228092016-06-28 17:32:37 -0700813 if (mLayer != zorder) {
814 mLayer = zorder;
815 mAppToken.updateSurfaceViewBackgroundVisibilities();
816 }
Robert Carr086d2922016-06-09 10:22:38 -0700817 }
818
819 @Override
820 public void setPosition(float x, float y) {
821 super.setPosition(x, y);
822 mBackgroundControl.setPosition(x, y);
823 }
824
825 @Override
826 public void setSize(int w, int h) {
827 super.setSize(w, h);
828 mBackgroundControl.setSize(w, h);
829 }
830
831 @Override
832 public void setWindowCrop(Rect crop) {
833 super.setWindowCrop(crop);
834 mBackgroundControl.setWindowCrop(crop);
835 }
836
837 @Override
838 public void setFinalCrop(Rect crop) {
839 super.setFinalCrop(crop);
840 mBackgroundControl.setFinalCrop(crop);
841 }
842
843 @Override
844 public void setLayerStack(int layerStack) {
845 super.setLayerStack(layerStack);
846 mBackgroundControl.setLayerStack(layerStack);
847 }
848
849 @Override
850 public void setOpaque(boolean isOpaque) {
851 super.setOpaque(isOpaque);
852 mOpaque = isOpaque;
Robert Carr91b228092016-06-28 17:32:37 -0700853 updateBackgroundVisibility(mAppForcedInvisible);
Robert Carr086d2922016-06-09 10:22:38 -0700854 }
855
856 @Override
857 public void setSecure(boolean isSecure) {
858 super.setSecure(isSecure);
859 }
860
861 @Override
862 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
863 super.setMatrix(dsdx, dtdx, dsdy, dtdy);
864 mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy);
865 }
866
867 @Override
868 public void hide() {
Robert Carr086d2922016-06-09 10:22:38 -0700869 super.hide();
Robert Carr91b228092016-06-28 17:32:37 -0700870 if (mVisible) {
871 mVisible = false;
872 mAppToken.updateSurfaceViewBackgroundVisibilities();
873 }
Robert Carr086d2922016-06-09 10:22:38 -0700874 }
875
876 @Override
877 public void show() {
Robert Carr086d2922016-06-09 10:22:38 -0700878 super.show();
Robert Carr91b228092016-06-28 17:32:37 -0700879 if (!mVisible) {
880 mVisible = true;
881 mAppToken.updateSurfaceViewBackgroundVisibilities();
882 }
Robert Carr086d2922016-06-09 10:22:38 -0700883 }
884
885 @Override
886 public void destroy() {
887 super.destroy();
888 mBackgroundControl.destroy();
Robert Carr91b228092016-06-28 17:32:37 -0700889 mAppToken.removeSurfaceViewBackground(this);
890 }
Robert Carr086d2922016-06-09 10:22:38 -0700891
892 @Override
893 public void release() {
894 super.release();
895 mBackgroundControl.release();
896 }
897
898 @Override
899 public void setTransparentRegionHint(Region region) {
900 super.setTransparentRegionHint(region);
901 mBackgroundControl.setTransparentRegionHint(region);
902 }
903
904 @Override
905 public void deferTransactionUntil(IBinder handle, long frame) {
906 super.deferTransactionUntil(handle, frame);
907 mBackgroundControl.deferTransactionUntil(handle, frame);
908 }
909
Robert Carr91b228092016-06-28 17:32:37 -0700910 void updateBackgroundVisibility(boolean forcedInvisible) {
911 mAppForcedInvisible = forcedInvisible;
912 if (mOpaque && mVisible && !mAppForcedInvisible) {
Robert Carr086d2922016-06-09 10:22:38 -0700913 mBackgroundControl.show();
914 } else {
915 mBackgroundControl.hide();
916 }
917 }
918 }
Robert Carre6a83512015-11-03 16:09:21 -0800919}