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 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 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 110 void hideInTransaction(String reason) { 111 if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null); 112 mHiddenForOtherReasons = true; 113 114 mAnimator.destroyPreservedSurfaceLocked(); 115 updateVisibility(); 116 } 117 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 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 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 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 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 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 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 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 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 263 void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) { 264 mSurfaceControl.setGeometryAppliesWithResize(); 265 } 266 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 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 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 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 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 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 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 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 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 423 void deferTransactionUntil(IBinder handle, long frame) { 424 // TODO: Logging 425 mSurfaceControl.deferTransactionUntil(handle, frame); 426 } 427 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 435 boolean clearWindowContentFrameStats() { 436 if (mSurfaceControl == null) { 437 return false; 438 } 439 return mSurfaceControl.clearContentFrameStats(); 440 } 441 442 boolean getWindowContentFrameStats(WindowContentFrameStats outStats) { 443 if (mSurfaceControl == null) { 444 return false; 445 } 446 return mSurfaceControl.getContentFrameStats(outStats); 447 } 448 449 450 boolean hasSurface() { 451 return mSurfaceControl != null; 452 } 453 454 IBinder getHandle() { 455 if (mSurfaceControl == null) { 456 return null; 457 } 458 return mSurfaceControl.getHandle(); 459 } 460 461 boolean getTransformToDisplayInverse() { 462 return mSurfaceControl.getTransformToDisplayInverse(); 463 } 464 465 void getSurface(Surface outSurface) { 466 outSurface.copyFrom(mSurfaceControl); 467 } 468 469 int getLayer() { 470 return mSurfaceLayer; 471 } 472 473 boolean getShown() { 474 return mSurfaceShown; 475 } 476 477 void setShown(boolean surfaceShown) { 478 mSurfaceShown = surfaceShown; 479 } 480 481 float getX() { 482 return mSurfaceX; 483 } 484 485 float getY() { 486 return mSurfaceY; 487 } 488 489 float getWidth() { 490 return mSurfaceW; 491 } 492 493 float getHeight() { 494 return mSurfaceH; 495 } 496 497 498 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 499 if (dumpAll) { 500 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl); 501 } 502 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown); 503 pw.print(" layer="); pw.print(mSurfaceLayer); 504 pw.print(" alpha="); pw.print(mSurfaceAlpha); 505 pw.print(" rect=("); pw.print(mSurfaceX); 506 pw.print(","); pw.print(mSurfaceY); 507 pw.print(") "); pw.print(mSurfaceW); 508 pw.print(" x "); pw.println(mSurfaceH); 509 } 510 511 @Override 512 public String toString() { 513 return mSurfaceControl.toString(); 514 } 515 516 static class SurfaceTrace extends SurfaceControl { 517 private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM; 518 private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE; 519 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>(); 520 521 private float mSurfaceTraceAlpha = 0; 522 private int mLayer; 523 private final PointF mPosition = new PointF(); 524 private final Point mSize = new Point(); 525 private final Rect mWindowCrop = new Rect(); 526 private final Rect mFinalCrop = new Rect(); 527 private boolean mShown = false; 528 private int mLayerStack; 529 private boolean mIsOpaque; 530 private float mDsdx, mDtdx, mDsdy, mDtdy; 531 private final String mName; 532 533 public SurfaceTrace(SurfaceSession s, 534 String name, int w, int h, int format, int flags) 535 throws OutOfResourcesException { 536 super(s, name, w, h, format, flags); 537 mName = name != null ? name : "Not named"; 538 mSize.set(w, h); 539 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " 540 + Debug.getCallers(3)); 541 synchronized (sSurfaces) { 542 sSurfaces.add(0, this); 543 } 544 } 545 546 @Override 547 public void setAlpha(float alpha) { 548 if (mSurfaceTraceAlpha != alpha) { 549 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this + 550 ". Called by " + Debug.getCallers(3)); 551 mSurfaceTraceAlpha = alpha; 552 } 553 super.setAlpha(alpha); 554 } 555 556 @Override 557 public void setLayer(int zorder) { 558 if (zorder != mLayer) { 559 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this 560 + ". Called by " + Debug.getCallers(3)); 561 mLayer = zorder; 562 } 563 super.setLayer(zorder); 564 565 synchronized (sSurfaces) { 566 sSurfaces.remove(this); 567 int i; 568 for (i = sSurfaces.size() - 1; i >= 0; i--) { 569 SurfaceTrace s = sSurfaces.get(i); 570 if (s.mLayer < zorder) { 571 break; 572 } 573 } 574 sSurfaces.add(i + 1, this); 575 } 576 } 577 578 @Override 579 public void setPosition(float x, float y) { 580 if (x != mPosition.x || y != mPosition.y) { 581 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:" 582 + this + ". Called by " + Debug.getCallers(3)); 583 mPosition.set(x, y); 584 } 585 super.setPosition(x, y); 586 } 587 588 @Override 589 public void setGeometryAppliesWithResize() { 590 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setGeometryAppliesWithResize(): OLD: " 591 + this + ". Called by" + Debug.getCallers(3)); 592 super.setGeometryAppliesWithResize(); 593 } 594 595 @Override 596 public void setSize(int w, int h) { 597 if (w != mSize.x || h != mSize.y) { 598 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" 599 + this + ". Called by " + Debug.getCallers(3)); 600 mSize.set(w, h); 601 } 602 super.setSize(w, h); 603 } 604 605 @Override 606 public void setWindowCrop(Rect crop) { 607 if (crop != null) { 608 if (!crop.equals(mWindowCrop)) { 609 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop(" 610 + crop.toShortString() + "): OLD:" + this + ". Called by " 611 + Debug.getCallers(3)); 612 mWindowCrop.set(crop); 613 } 614 } 615 super.setWindowCrop(crop); 616 } 617 618 @Override 619 public void setFinalCrop(Rect crop) { 620 if (crop != null) { 621 if (!crop.equals(mFinalCrop)) { 622 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop(" 623 + crop.toShortString() + "): OLD:" + this + ". Called by " 624 + Debug.getCallers(3)); 625 mFinalCrop.set(crop); 626 } 627 } 628 super.setFinalCrop(crop); 629 } 630 631 @Override 632 public void setLayerStack(int layerStack) { 633 if (layerStack != mLayerStack) { 634 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:" 635 + this + ". Called by " + Debug.getCallers(3)); 636 mLayerStack = layerStack; 637 } 638 super.setLayerStack(layerStack); 639 } 640 641 @Override 642 public void setOpaque(boolean isOpaque) { 643 if (isOpaque != mIsOpaque) { 644 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:" 645 + this + ". Called by " + Debug.getCallers(3)); 646 mIsOpaque = isOpaque; 647 } 648 super.setOpaque(isOpaque); 649 } 650 651 @Override 652 public void setSecure(boolean isSecure) { 653 super.setSecure(isSecure); 654 } 655 656 @Override 657 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 658 if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) { 659 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," 660 + dsdy + "," + dtdy + "): OLD:" + this + ". Called by " 661 + Debug.getCallers(3)); 662 mDsdx = dsdx; 663 mDtdx = dtdx; 664 mDsdy = dsdy; 665 mDtdy = dtdy; 666 } 667 super.setMatrix(dsdx, dtdx, dsdy, dtdy); 668 } 669 670 @Override 671 public void hide() { 672 if (mShown) { 673 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " 674 + Debug.getCallers(3)); 675 mShown = false; 676 } 677 super.hide(); 678 } 679 680 @Override 681 public void show() { 682 if (!mShown) { 683 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by " 684 + Debug.getCallers(3)); 685 mShown = true; 686 } 687 super.show(); 688 } 689 690 @Override 691 public void destroy() { 692 super.destroy(); 693 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " 694 + Debug.getCallers(3)); 695 synchronized (sSurfaces) { 696 sSurfaces.remove(this); 697 } 698 } 699 700 @Override 701 public void release() { 702 super.release(); 703 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by " 704 + Debug.getCallers(3)); 705 synchronized (sSurfaces) { 706 sSurfaces.remove(this); 707 } 708 } 709 710 @Override 711 public void setTransparentRegionHint(Region region) { 712 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region 713 + "): OLD: " + this + " . Called by " + Debug.getCallers(3)); 714 super.setTransparentRegionHint(region); 715 } 716 717 static void dumpAllSurfaces(PrintWriter pw, String header) { 718 synchronized (sSurfaces) { 719 final int N = sSurfaces.size(); 720 if (N <= 0) { 721 return; 722 } 723 if (header != null) { 724 pw.println(header); 725 } 726 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)"); 727 for (int i = 0; i < N; i++) { 728 SurfaceTrace s = sSurfaces.get(i); 729 pw.print(" Surface #"); pw.print(i); pw.print(": #"); 730 pw.print(Integer.toHexString(System.identityHashCode(s))); 731 pw.print(" "); pw.println(s.mName); 732 pw.print(" mLayerStack="); pw.print(s.mLayerStack); 733 pw.print(" mLayer="); pw.println(s.mLayer); 734 pw.print(" mShown="); pw.print(s.mShown); pw.print(" mAlpha="); 735 pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque="); 736 pw.println(s.mIsOpaque); 737 pw.print(" mPosition="); pw.print(s.mPosition.x); pw.print(","); 738 pw.print(s.mPosition.y); 739 pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x"); 740 pw.println(s.mSize.y); 741 pw.print(" mCrop="); s.mWindowCrop.printShortString(pw); pw.println(); 742 pw.print(" mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println(); 743 pw.print(" Transform: ("); pw.print(s.mDsdx); pw.print(", "); 744 pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy); 745 pw.print(", "); pw.print(s.mDtdy); pw.println(")"); 746 } 747 } 748 } 749 750 @Override 751 public String toString() { 752 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " " 753 + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer 754 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y 755 + " " + mSize.x + "x" + mSize.y 756 + " crop=" + mWindowCrop.toShortString() 757 + " opaque=" + mIsOpaque 758 + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")"; 759 } 760 } 761 762 class SurfaceControlWithBackground extends SurfaceControl { 763 private SurfaceControl mBackgroundControl; 764 private boolean mOpaque = true; 765 private boolean mAppForcedInvisible = false; 766 private AppWindowToken mAppToken; 767 public boolean mVisible = false; 768 public int mLayer = -1; 769 770 public SurfaceControlWithBackground(SurfaceSession s, 771 String name, int w, int h, int format, int flags, 772 AppWindowToken token) 773 throws OutOfResourcesException { 774 super(s, name, w, h, format, flags); 775 mBackgroundControl = new SurfaceControl(s, name, w, h, 776 PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM); 777 mOpaque = (flags & SurfaceControl.OPAQUE) != 0; 778 mAppToken = token; 779 780 mAppToken.addSurfaceViewBackground(this); 781 } 782 783 @Override 784 public void setAlpha(float alpha) { 785 super.setAlpha(alpha); 786 mBackgroundControl.setAlpha(alpha); 787 } 788 789 @Override 790 public void setLayer(int zorder) { 791 super.setLayer(zorder); 792 mBackgroundControl.setLayer(zorder - 1); 793 if (mLayer != zorder) { 794 mLayer = zorder; 795 mAppToken.updateSurfaceViewBackgroundVisibilities(); 796 } 797 } 798 799 @Override 800 public void setPosition(float x, float y) { 801 super.setPosition(x, y); 802 mBackgroundControl.setPosition(x, y); 803 } 804 805 @Override 806 public void setSize(int w, int h) { 807 super.setSize(w, h); 808 mBackgroundControl.setSize(w, h); 809 } 810 811 @Override 812 public void setWindowCrop(Rect crop) { 813 super.setWindowCrop(crop); 814 mBackgroundControl.setWindowCrop(crop); 815 } 816 817 @Override 818 public void setFinalCrop(Rect crop) { 819 super.setFinalCrop(crop); 820 mBackgroundControl.setFinalCrop(crop); 821 } 822 823 @Override 824 public void setLayerStack(int layerStack) { 825 super.setLayerStack(layerStack); 826 mBackgroundControl.setLayerStack(layerStack); 827 } 828 829 @Override 830 public void setOpaque(boolean isOpaque) { 831 super.setOpaque(isOpaque); 832 mOpaque = isOpaque; 833 updateBackgroundVisibility(mAppForcedInvisible); 834 } 835 836 @Override 837 public void setSecure(boolean isSecure) { 838 super.setSecure(isSecure); 839 } 840 841 @Override 842 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 843 super.setMatrix(dsdx, dtdx, dsdy, dtdy); 844 mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy); 845 } 846 847 @Override 848 public void hide() { 849 super.hide(); 850 if (mVisible) { 851 mVisible = false; 852 mAppToken.updateSurfaceViewBackgroundVisibilities(); 853 } 854 } 855 856 @Override 857 public void show() { 858 super.show(); 859 if (!mVisible) { 860 mVisible = true; 861 mAppToken.updateSurfaceViewBackgroundVisibilities(); 862 } 863 } 864 865 @Override 866 public void destroy() { 867 super.destroy(); 868 mBackgroundControl.destroy(); 869 mAppToken.removeSurfaceViewBackground(this); 870 } 871 872 @Override 873 public void release() { 874 super.release(); 875 mBackgroundControl.release(); 876 } 877 878 @Override 879 public void setTransparentRegionHint(Region region) { 880 super.setTransparentRegionHint(region); 881 mBackgroundControl.setTransparentRegionHint(region); 882 } 883 884 @Override 885 public void deferTransactionUntil(IBinder handle, long frame) { 886 super.deferTransactionUntil(handle, frame); 887 mBackgroundControl.deferTransactionUntil(handle, frame); 888 } 889 890 void updateBackgroundVisibility(boolean forcedInvisible) { 891 mAppForcedInvisible = forcedInvisible; 892 if (mOpaque && mVisible && !mAppForcedInvisible) { 893 mBackgroundControl.show(); 894 } else { 895 mBackgroundControl.hide(); 896 } 897 } 898 } 899 } 900