1 /* 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 17 package com.android.server.wm; 18 19 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; 20 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; 21 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; 22 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE; 23 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 24 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 25 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 26 import static android.view.Surface.SCALING_MODE_FREEZE; 27 import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW; 28 29 import android.graphics.PixelFormat; 30 import android.graphics.Point; 31 import android.graphics.PointF; 32 import android.graphics.Rect; 33 import android.graphics.Region; 34 import android.os.IBinder; 35 import android.os.Debug; 36 import android.view.Surface; 37 import android.view.SurfaceControl; 38 import android.view.SurfaceSession; 39 import android.view.WindowContentFrameStats; 40 import android.view.Surface.OutOfResourcesException; 41 42 import android.util.Slog; 43 44 import java.io.PrintWriter; 45 import java.util.ArrayList; 46 47 class WindowSurfaceController { 48 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM; 49 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 60 private float mSurfaceAlpha = 0; 61 62 private int mSurfaceLayer = 0; 63 64 // Surface flinger doesn't support crop rectangles where width or height is non-positive. 65 // However, we need to somehow handle the situation where the cropping would completely hide 66 // the window. We achieve this by explicitly hiding the surface and not letting it be shown. 67 private boolean mHiddenForCrop = false; 68 69 // Initially a surface is hidden after just being created. 70 private boolean mHiddenForOtherReasons = true; 71 private final String title; 72 WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format, int flags, WindowStateAnimator animator)73 public WindowSurfaceController(SurfaceSession s, 74 String name, int w, int h, int format, int flags, WindowStateAnimator animator) { 75 mAnimator = animator; 76 77 mSurfaceW = w; 78 mSurfaceH = h; 79 80 title = name; 81 82 // For opaque child windows placed under parent windows, 83 // we use a special SurfaceControl which mirrors commands 84 // to a black-out layer placed one Z-layer below the surface. 85 // This prevents holes to whatever app/wallpaper is underneath. 86 if (animator.mWin.isChildWindow() && 87 animator.mWin.mSubLayer < 0 && 88 animator.mWin.mAppToken != null) { 89 mSurfaceControl = new SurfaceControlWithBackground(s, 90 name, w, h, format, flags, animator.mWin.mAppToken); 91 } else if (DEBUG_SURFACE_TRACE) { 92 mSurfaceControl = new SurfaceTrace( 93 s, name, w, h, format, flags); 94 } else { 95 mSurfaceControl = new SurfaceControl( 96 s, name, w, h, format, flags); 97 } 98 } 99 100 logSurface(String msg, RuntimeException where)101 void logSurface(String msg, RuntimeException where) { 102 String str = " SURFACE " + msg + ": " + title; 103 if (where != null) { 104 Slog.i(TAG, str, where); 105 } else { 106 Slog.i(TAG, str); 107 } 108 } 109 hideInTransaction(String reason)110 void hideInTransaction(String reason) { 111 if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null); 112 mHiddenForOtherReasons = true; 113 114 mAnimator.destroyPreservedSurfaceLocked(); 115 updateVisibility(); 116 } 117 hideSurface()118 private void hideSurface() { 119 if (mSurfaceControl != null) { 120 mSurfaceShown = false; 121 try { 122 mSurfaceControl.hide(); 123 } catch (RuntimeException e) { 124 Slog.w(TAG, "Exception hiding surface in " + this); 125 } 126 } 127 } 128 setPositionAndLayer(float left, float top, int layerStack, int layer)129 void setPositionAndLayer(float left, float top, int layerStack, int layer) { 130 SurfaceControl.openTransaction(); 131 try { 132 mSurfaceX = left; 133 mSurfaceY = top; 134 135 try { 136 if (SHOW_TRANSACTIONS) logSurface( 137 "POS (setPositionAndLayer) @ (" + left + "," + top + ")", null); 138 mSurfaceControl.setPosition(left, top); 139 mSurfaceControl.setLayerStack(layerStack); 140 141 mSurfaceControl.setLayer(layer); 142 mSurfaceControl.setAlpha(0); 143 mSurfaceShown = false; 144 } catch (RuntimeException e) { 145 Slog.w(TAG, "Error creating surface in " + this, e); 146 mAnimator.reclaimSomeSurfaceMemory("create-init", true); 147 } 148 } finally { 149 SurfaceControl.closeTransaction(); 150 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 151 "<<< CLOSE TRANSACTION setPositionAndLayer"); 152 } 153 } 154 destroyInTransaction()155 void destroyInTransaction() { 156 // if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 157 Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8)); 158 // } 159 try { 160 if (mSurfaceControl != null) { 161 mSurfaceControl.destroy(); 162 } 163 } catch (RuntimeException e) { 164 Slog.w(TAG, "Error destroying surface in: " + this, e); 165 } finally { 166 mSurfaceShown = false; 167 mSurfaceControl = null; 168 } 169 } 170 disconnectInTransaction()171 void disconnectInTransaction() { 172 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 173 Slog.i(TAG, "Disconnecting client: " + this); 174 } 175 176 try { 177 if (mSurfaceControl != null) { 178 mSurfaceControl.disconnect(); 179 } 180 } catch (RuntimeException e) { 181 Slog.w(TAG, "Error disconnecting surface in: " + this, e); 182 } 183 } 184 setCropInTransaction(Rect clipRect, boolean recoveringMemory)185 void setCropInTransaction(Rect clipRect, boolean recoveringMemory) { 186 if (SHOW_TRANSACTIONS) logSurface( 187 "CROP " + clipRect.toShortString(), null); 188 try { 189 if (clipRect.width() > 0 && clipRect.height() > 0) { 190 mSurfaceControl.setWindowCrop(clipRect); 191 mHiddenForCrop = false; 192 updateVisibility(); 193 } else { 194 mHiddenForCrop = true; 195 mAnimator.destroyPreservedSurfaceLocked(); 196 updateVisibility(); 197 } 198 } catch (RuntimeException e) { 199 Slog.w(TAG, "Error setting crop surface of " + this 200 + " crop=" + clipRect.toShortString(), e); 201 if (!recoveringMemory) { 202 mAnimator.reclaimSomeSurfaceMemory("crop", true); 203 } 204 } 205 } 206 clearCropInTransaction(boolean recoveringMemory)207 void clearCropInTransaction(boolean recoveringMemory) { 208 if (SHOW_TRANSACTIONS) logSurface( 209 "CLEAR CROP", null); 210 try { 211 Rect clipRect = new Rect(0, 0, -1, -1); 212 mSurfaceControl.setWindowCrop(clipRect); 213 } catch (RuntimeException e) { 214 Slog.w(TAG, "Error setting clearing crop of " + this, e); 215 if (!recoveringMemory) { 216 mAnimator.reclaimSomeSurfaceMemory("crop", true); 217 } 218 } 219 } 220 setFinalCropInTransaction(Rect clipRect)221 void setFinalCropInTransaction(Rect clipRect) { 222 if (SHOW_TRANSACTIONS) logSurface( 223 "FINAL CROP " + clipRect.toShortString(), null); 224 try { 225 mSurfaceControl.setFinalCrop(clipRect); 226 } catch (RuntimeException e) { 227 Slog.w(TAG, "Error disconnecting surface in: " + this, e); 228 } 229 } 230 setLayer(int layer)231 void setLayer(int layer) { 232 if (mSurfaceControl != null) { 233 SurfaceControl.openTransaction(); 234 try { 235 mSurfaceControl.setLayer(layer); 236 } finally { 237 SurfaceControl.closeTransaction(); 238 } 239 } 240 } 241 setPositionInTransaction(float left, float top, boolean recoveringMemory)242 void setPositionInTransaction(float left, float top, boolean recoveringMemory) { 243 final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top; 244 if (surfaceMoved) { 245 mSurfaceX = left; 246 mSurfaceY = top; 247 248 try { 249 if (SHOW_TRANSACTIONS) logSurface( 250 "POS (setPositionInTransaction) @ (" + left + "," + top + ")", null); 251 252 mSurfaceControl.setPosition(left, top); 253 } catch (RuntimeException e) { 254 Slog.w(TAG, "Error positioning surface of " + this 255 + " pos=(" + left + "," + top + ")", e); 256 if (!recoveringMemory) { 257 mAnimator.reclaimSomeSurfaceMemory("position", true); 258 } 259 } 260 } 261 } 262 setPositionAppliesWithResizeInTransaction(boolean recoveringMemory)263 void setPositionAppliesWithResizeInTransaction(boolean recoveringMemory) { 264 mSurfaceControl.setPositionAppliesWithResize(); 265 } 266 setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy, boolean recoveringMemory)267 void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy, 268 boolean recoveringMemory) { 269 try { 270 if (SHOW_TRANSACTIONS) logSurface( 271 "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null); 272 mSurfaceControl.setMatrix( 273 dsdx, dtdx, dsdy, dtdy); 274 } catch (RuntimeException e) { 275 // If something goes wrong with the surface (such 276 // as running out of memory), don't take down the 277 // entire system. 278 Slog.e(TAG, "Error setting matrix on surface surface" + title 279 + " MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null); 280 if (!recoveringMemory) { 281 mAnimator.reclaimSomeSurfaceMemory("matrix", true); 282 } 283 } 284 return; 285 } 286 setSizeInTransaction(int width, int height, boolean recoveringMemory)287 boolean setSizeInTransaction(int width, int height, boolean recoveringMemory) { 288 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height; 289 if (surfaceResized) { 290 mSurfaceW = width; 291 mSurfaceH = height; 292 293 try { 294 if (SHOW_TRANSACTIONS) logSurface( 295 "SIZE " + width + "x" + height, null); 296 mSurfaceControl.setSize(width, height); 297 } catch (RuntimeException e) { 298 // If something goes wrong with the surface (such 299 // as running out of memory), don't take down the 300 // entire system. 301 Slog.e(TAG, "Error resizing surface of " + title 302 + " size=(" + width + "x" + height + ")", e); 303 if (!recoveringMemory) { 304 mAnimator.reclaimSomeSurfaceMemory("size", true); 305 } 306 return false; 307 } 308 return true; 309 } 310 return false; 311 } 312 prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy, float dtdy, boolean recoveringMemory)313 boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy, 314 float dtdy, boolean recoveringMemory) { 315 if (mSurfaceControl != null) { 316 try { 317 mSurfaceAlpha = alpha; 318 mSurfaceControl.setAlpha(alpha); 319 mSurfaceLayer = layer; 320 mSurfaceControl.setLayer(layer); 321 mSurfaceControl.setMatrix( 322 dsdx, dtdx, dsdy, dtdy); 323 324 } catch (RuntimeException e) { 325 Slog.w(TAG, "Error updating surface in " + title, e); 326 if (!recoveringMemory) { 327 mAnimator.reclaimSomeSurfaceMemory("update", true); 328 } 329 return false; 330 } 331 } 332 return true; 333 } 334 setTransparentRegionHint(final Region region)335 void setTransparentRegionHint(final Region region) { 336 if (mSurfaceControl == null) { 337 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true"); 338 return; 339 } 340 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion"); 341 SurfaceControl.openTransaction(); 342 try { 343 mSurfaceControl.setTransparentRegionHint(region); 344 } finally { 345 SurfaceControl.closeTransaction(); 346 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 347 "<<< CLOSE TRANSACTION setTransparentRegion"); 348 } 349 } 350 setOpaque(boolean isOpaque)351 void setOpaque(boolean isOpaque) { 352 if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque, 353 null); 354 355 if (mSurfaceControl == null) { 356 return; 357 } 358 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked"); 359 SurfaceControl.openTransaction(); 360 try { 361 mSurfaceControl.setOpaque(isOpaque); 362 } finally { 363 SurfaceControl.closeTransaction(); 364 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked"); 365 } 366 } 367 setSecure(boolean isSecure)368 void setSecure(boolean isSecure) { 369 if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure, 370 null); 371 372 if (mSurfaceControl == null) { 373 return; 374 } 375 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked"); 376 SurfaceControl.openTransaction(); 377 try { 378 mSurfaceControl.setSecure(isSecure); 379 } finally { 380 SurfaceControl.closeTransaction(); 381 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked"); 382 } 383 } 384 showRobustlyInTransaction()385 boolean showRobustlyInTransaction() { 386 if (SHOW_TRANSACTIONS) logSurface( 387 "SHOW (performLayout)", null); 388 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this 389 + " during relayout"); 390 mHiddenForOtherReasons = false; 391 return updateVisibility(); 392 } 393 updateVisibility()394 private boolean updateVisibility() { 395 if (mHiddenForCrop || mHiddenForOtherReasons) { 396 if (mSurfaceShown) { 397 hideSurface(); 398 } 399 return false; 400 } else { 401 if (!mSurfaceShown) { 402 return showSurface(); 403 } else { 404 return true; 405 } 406 } 407 } 408 showSurface()409 private boolean showSurface() { 410 try { 411 mSurfaceShown = true; 412 mSurfaceControl.show(); 413 return true; 414 } catch (RuntimeException e) { 415 Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + this, e); 416 } 417 418 mAnimator.reclaimSomeSurfaceMemory("show", true); 419 420 return false; 421 } 422 deferTransactionUntil(IBinder handle, long frame)423 void deferTransactionUntil(IBinder handle, long frame) { 424 // TODO: Logging 425 mSurfaceControl.deferTransactionUntil(handle, frame); 426 } 427 forceScaleableInTransaction(boolean force)428 void forceScaleableInTransaction(boolean force) { 429 // -1 means we don't override the default or client specified 430 // scaling mode. 431 int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1; 432 mSurfaceControl.setOverrideScalingMode(scalingMode); 433 } 434 clearWindowContentFrameStats()435 boolean clearWindowContentFrameStats() { 436 if (mSurfaceControl == null) { 437 return false; 438 } 439 return mSurfaceControl.clearContentFrameStats(); 440 } 441 getWindowContentFrameStats(WindowContentFrameStats outStats)442 boolean getWindowContentFrameStats(WindowContentFrameStats outStats) { 443 if (mSurfaceControl == null) { 444 return false; 445 } 446 return mSurfaceControl.getContentFrameStats(outStats); 447 } 448 449 hasSurface()450 boolean hasSurface() { 451 return mSurfaceControl != null; 452 } 453 getHandle()454 IBinder getHandle() { 455 if (mSurfaceControl == null) { 456 return null; 457 } 458 return mSurfaceControl.getHandle(); 459 } 460 getSurface(Surface outSurface)461 void getSurface(Surface outSurface) { 462 outSurface.copyFrom(mSurfaceControl); 463 } 464 getLayer()465 int getLayer() { 466 return mSurfaceLayer; 467 } 468 getShown()469 boolean getShown() { 470 return mSurfaceShown; 471 } 472 setShown(boolean surfaceShown)473 void setShown(boolean surfaceShown) { 474 mSurfaceShown = surfaceShown; 475 } 476 getX()477 float getX() { 478 return mSurfaceX; 479 } 480 getY()481 float getY() { 482 return mSurfaceY; 483 } 484 getWidth()485 float getWidth() { 486 return mSurfaceW; 487 } 488 getHeight()489 float getHeight() { 490 return mSurfaceH; 491 } 492 493 dump(PrintWriter pw, String prefix, boolean dumpAll)494 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 495 if (dumpAll) { 496 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl); 497 } 498 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown); 499 pw.print(" layer="); pw.print(mSurfaceLayer); 500 pw.print(" alpha="); pw.print(mSurfaceAlpha); 501 pw.print(" rect=("); pw.print(mSurfaceX); 502 pw.print(","); pw.print(mSurfaceY); 503 pw.print(") "); pw.print(mSurfaceW); 504 pw.print(" x "); pw.println(mSurfaceH); 505 } 506 507 @Override toString()508 public String toString() { 509 return mSurfaceControl.toString(); 510 } 511 512 static class SurfaceTrace extends SurfaceControl { 513 private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM; 514 private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE; 515 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>(); 516 517 private float mSurfaceTraceAlpha = 0; 518 private int mLayer; 519 private final PointF mPosition = new PointF(); 520 private final Point mSize = new Point(); 521 private final Rect mWindowCrop = new Rect(); 522 private final Rect mFinalCrop = new Rect(); 523 private boolean mShown = false; 524 private int mLayerStack; 525 private boolean mIsOpaque; 526 private float mDsdx, mDtdx, mDsdy, mDtdy; 527 private final String mName; 528 SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags)529 public SurfaceTrace(SurfaceSession s, 530 String name, int w, int h, int format, int flags) 531 throws OutOfResourcesException { 532 super(s, name, w, h, format, flags); 533 mName = name != null ? name : "Not named"; 534 mSize.set(w, h); 535 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " 536 + Debug.getCallers(3)); 537 synchronized (sSurfaces) { 538 sSurfaces.add(0, this); 539 } 540 } 541 542 @Override setAlpha(float alpha)543 public void setAlpha(float alpha) { 544 if (mSurfaceTraceAlpha != alpha) { 545 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this + 546 ". Called by " + Debug.getCallers(3)); 547 mSurfaceTraceAlpha = alpha; 548 } 549 super.setAlpha(alpha); 550 } 551 552 @Override setLayer(int zorder)553 public void setLayer(int zorder) { 554 if (zorder != mLayer) { 555 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this 556 + ". Called by " + Debug.getCallers(3)); 557 mLayer = zorder; 558 } 559 super.setLayer(zorder); 560 561 synchronized (sSurfaces) { 562 sSurfaces.remove(this); 563 int i; 564 for (i = sSurfaces.size() - 1; i >= 0; i--) { 565 SurfaceTrace s = sSurfaces.get(i); 566 if (s.mLayer < zorder) { 567 break; 568 } 569 } 570 sSurfaces.add(i + 1, this); 571 } 572 } 573 574 @Override setPosition(float x, float y)575 public void setPosition(float x, float y) { 576 if (x != mPosition.x || y != mPosition.y) { 577 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:" 578 + this + ". Called by " + Debug.getCallers(3)); 579 mPosition.set(x, y); 580 } 581 super.setPosition(x, y); 582 } 583 584 @Override setPositionAppliesWithResize()585 public void setPositionAppliesWithResize() { 586 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPositionAppliesWithResize(): OLD: " 587 + this + ". Called by" + Debug.getCallers(9)); 588 super.setPositionAppliesWithResize(); 589 } 590 591 @Override setSize(int w, int h)592 public void setSize(int w, int h) { 593 if (w != mSize.x || h != mSize.y) { 594 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" 595 + this + ". Called by " + Debug.getCallers(3)); 596 mSize.set(w, h); 597 } 598 super.setSize(w, h); 599 } 600 601 @Override setWindowCrop(Rect crop)602 public void setWindowCrop(Rect crop) { 603 if (crop != null) { 604 if (!crop.equals(mWindowCrop)) { 605 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop(" 606 + crop.toShortString() + "): OLD:" + this + ". Called by " 607 + Debug.getCallers(3)); 608 mWindowCrop.set(crop); 609 } 610 } 611 super.setWindowCrop(crop); 612 } 613 614 @Override setFinalCrop(Rect crop)615 public void setFinalCrop(Rect crop) { 616 if (crop != null) { 617 if (!crop.equals(mFinalCrop)) { 618 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop(" 619 + crop.toShortString() + "): OLD:" + this + ". Called by " 620 + Debug.getCallers(3)); 621 mFinalCrop.set(crop); 622 } 623 } 624 super.setFinalCrop(crop); 625 } 626 627 @Override setLayerStack(int layerStack)628 public void setLayerStack(int layerStack) { 629 if (layerStack != mLayerStack) { 630 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:" 631 + this + ". Called by " + Debug.getCallers(3)); 632 mLayerStack = layerStack; 633 } 634 super.setLayerStack(layerStack); 635 } 636 637 @Override setOpaque(boolean isOpaque)638 public void setOpaque(boolean isOpaque) { 639 if (isOpaque != mIsOpaque) { 640 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:" 641 + this + ". Called by " + Debug.getCallers(3)); 642 mIsOpaque = isOpaque; 643 } 644 super.setOpaque(isOpaque); 645 } 646 647 @Override setSecure(boolean isSecure)648 public void setSecure(boolean isSecure) { 649 super.setSecure(isSecure); 650 } 651 652 @Override setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)653 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 654 if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) { 655 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," 656 + dsdy + "," + dtdy + "): OLD:" + this + ". Called by " 657 + Debug.getCallers(3)); 658 mDsdx = dsdx; 659 mDtdx = dtdx; 660 mDsdy = dsdy; 661 mDtdy = dtdy; 662 } 663 super.setMatrix(dsdx, dtdx, dsdy, dtdy); 664 } 665 666 @Override hide()667 public void hide() { 668 if (mShown) { 669 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " 670 + Debug.getCallers(3)); 671 mShown = false; 672 } 673 super.hide(); 674 } 675 676 @Override show()677 public void show() { 678 if (!mShown) { 679 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by " 680 + Debug.getCallers(3)); 681 mShown = true; 682 } 683 super.show(); 684 } 685 686 @Override destroy()687 public void destroy() { 688 super.destroy(); 689 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " 690 + Debug.getCallers(3)); 691 synchronized (sSurfaces) { 692 sSurfaces.remove(this); 693 } 694 } 695 696 @Override release()697 public void release() { 698 super.release(); 699 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by " 700 + Debug.getCallers(3)); 701 synchronized (sSurfaces) { 702 sSurfaces.remove(this); 703 } 704 } 705 706 @Override setTransparentRegionHint(Region region)707 public void setTransparentRegionHint(Region region) { 708 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region 709 + "): OLD: " + this + " . Called by " + Debug.getCallers(3)); 710 super.setTransparentRegionHint(region); 711 } 712 dumpAllSurfaces(PrintWriter pw, String header)713 static void dumpAllSurfaces(PrintWriter pw, String header) { 714 synchronized (sSurfaces) { 715 final int N = sSurfaces.size(); 716 if (N <= 0) { 717 return; 718 } 719 if (header != null) { 720 pw.println(header); 721 } 722 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)"); 723 for (int i = 0; i < N; i++) { 724 SurfaceTrace s = sSurfaces.get(i); 725 pw.print(" Surface #"); pw.print(i); pw.print(": #"); 726 pw.print(Integer.toHexString(System.identityHashCode(s))); 727 pw.print(" "); pw.println(s.mName); 728 pw.print(" mLayerStack="); pw.print(s.mLayerStack); 729 pw.print(" mLayer="); pw.println(s.mLayer); 730 pw.print(" mShown="); pw.print(s.mShown); pw.print(" mAlpha="); 731 pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque="); 732 pw.println(s.mIsOpaque); 733 pw.print(" mPosition="); pw.print(s.mPosition.x); pw.print(","); 734 pw.print(s.mPosition.y); 735 pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x"); 736 pw.println(s.mSize.y); 737 pw.print(" mCrop="); s.mWindowCrop.printShortString(pw); pw.println(); 738 pw.print(" mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println(); 739 pw.print(" Transform: ("); pw.print(s.mDsdx); pw.print(", "); 740 pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy); 741 pw.print(", "); pw.print(s.mDtdy); pw.println(")"); 742 } 743 } 744 } 745 746 @Override toString()747 public String toString() { 748 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " " 749 + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer 750 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y 751 + " " + mSize.x + "x" + mSize.y 752 + " crop=" + mWindowCrop.toShortString() 753 + " opaque=" + mIsOpaque 754 + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")"; 755 } 756 } 757 758 class SurfaceControlWithBackground extends SurfaceControl { 759 private SurfaceControl mBackgroundControl; 760 private boolean mOpaque = true; 761 private boolean mAppForcedInvisible = false; 762 private AppWindowToken mAppToken; 763 public boolean mVisible = false; 764 public int mLayer = -1; 765 SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format, int flags, AppWindowToken token)766 public SurfaceControlWithBackground(SurfaceSession s, 767 String name, int w, int h, int format, int flags, 768 AppWindowToken token) 769 throws OutOfResourcesException { 770 super(s, name, w, h, format, flags); 771 mBackgroundControl = new SurfaceControl(s, name, w, h, 772 PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM); 773 mOpaque = (flags & SurfaceControl.OPAQUE) != 0; 774 mAppToken = token; 775 776 mAppToken.addSurfaceViewBackground(this); 777 } 778 779 @Override setAlpha(float alpha)780 public void setAlpha(float alpha) { 781 super.setAlpha(alpha); 782 mBackgroundControl.setAlpha(alpha); 783 } 784 785 @Override setLayer(int zorder)786 public void setLayer(int zorder) { 787 super.setLayer(zorder); 788 mBackgroundControl.setLayer(zorder - 1); 789 if (mLayer != zorder) { 790 mLayer = zorder; 791 mAppToken.updateSurfaceViewBackgroundVisibilities(); 792 } 793 } 794 795 @Override setPosition(float x, float y)796 public void setPosition(float x, float y) { 797 super.setPosition(x, y); 798 mBackgroundControl.setPosition(x, y); 799 } 800 801 @Override setSize(int w, int h)802 public void setSize(int w, int h) { 803 super.setSize(w, h); 804 mBackgroundControl.setSize(w, h); 805 } 806 807 @Override setWindowCrop(Rect crop)808 public void setWindowCrop(Rect crop) { 809 super.setWindowCrop(crop); 810 mBackgroundControl.setWindowCrop(crop); 811 } 812 813 @Override setFinalCrop(Rect crop)814 public void setFinalCrop(Rect crop) { 815 super.setFinalCrop(crop); 816 mBackgroundControl.setFinalCrop(crop); 817 } 818 819 @Override setLayerStack(int layerStack)820 public void setLayerStack(int layerStack) { 821 super.setLayerStack(layerStack); 822 mBackgroundControl.setLayerStack(layerStack); 823 } 824 825 @Override setOpaque(boolean isOpaque)826 public void setOpaque(boolean isOpaque) { 827 super.setOpaque(isOpaque); 828 mOpaque = isOpaque; 829 updateBackgroundVisibility(mAppForcedInvisible); 830 } 831 832 @Override setSecure(boolean isSecure)833 public void setSecure(boolean isSecure) { 834 super.setSecure(isSecure); 835 } 836 837 @Override setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)838 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 839 super.setMatrix(dsdx, dtdx, dsdy, dtdy); 840 mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy); 841 } 842 843 @Override hide()844 public void hide() { 845 super.hide(); 846 if (mVisible) { 847 mVisible = false; 848 mAppToken.updateSurfaceViewBackgroundVisibilities(); 849 } 850 } 851 852 @Override show()853 public void show() { 854 super.show(); 855 if (!mVisible) { 856 mVisible = true; 857 mAppToken.updateSurfaceViewBackgroundVisibilities(); 858 } 859 } 860 861 @Override destroy()862 public void destroy() { 863 super.destroy(); 864 mBackgroundControl.destroy(); 865 mAppToken.removeSurfaceViewBackground(this); 866 } 867 868 @Override release()869 public void release() { 870 super.release(); 871 mBackgroundControl.release(); 872 } 873 874 @Override setTransparentRegionHint(Region region)875 public void setTransparentRegionHint(Region region) { 876 super.setTransparentRegionHint(region); 877 mBackgroundControl.setTransparentRegionHint(region); 878 } 879 880 @Override deferTransactionUntil(IBinder handle, long frame)881 public void deferTransactionUntil(IBinder handle, long frame) { 882 super.deferTransactionUntil(handle, frame); 883 mBackgroundControl.deferTransactionUntil(handle, frame); 884 } 885 updateBackgroundVisibility(boolean forcedInvisible)886 void updateBackgroundVisibility(boolean forcedInvisible) { 887 mAppForcedInvisible = forcedInvisible; 888 if (mOpaque && mVisible && !mAppForcedInvisible) { 889 mBackgroundControl.show(); 890 } else { 891 mBackgroundControl.hide(); 892 } 893 } 894 } 895 } 896