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 setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory)263 void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) { 264 mSurfaceControl.setGeometryAppliesWithResize(); 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 getTransformToDisplayInverse()461 boolean getTransformToDisplayInverse() { 462 return mSurfaceControl.getTransformToDisplayInverse(); 463 } 464 getSurface(Surface outSurface)465 void getSurface(Surface outSurface) { 466 outSurface.copyFrom(mSurfaceControl); 467 } 468 getLayer()469 int getLayer() { 470 return mSurfaceLayer; 471 } 472 getShown()473 boolean getShown() { 474 return mSurfaceShown; 475 } 476 setShown(boolean surfaceShown)477 void setShown(boolean surfaceShown) { 478 mSurfaceShown = surfaceShown; 479 } 480 getX()481 float getX() { 482 return mSurfaceX; 483 } 484 getY()485 float getY() { 486 return mSurfaceY; 487 } 488 getWidth()489 float getWidth() { 490 return mSurfaceW; 491 } 492 getHeight()493 float getHeight() { 494 return mSurfaceH; 495 } 496 497 dump(PrintWriter pw, String prefix, boolean dumpAll)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 toString()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 SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags)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 setAlpha(float alpha)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 setLayer(int zorder)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 setPosition(float x, float y)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 setGeometryAppliesWithResize()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 setSize(int w, int h)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 setWindowCrop(Rect crop)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 setFinalCrop(Rect crop)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 setLayerStack(int layerStack)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 setOpaque(boolean isOpaque)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 setSecure(boolean isSecure)652 public void setSecure(boolean isSecure) { 653 super.setSecure(isSecure); 654 } 655 656 @Override setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)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 hide()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 show()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 destroy()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 release()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 setTransparentRegionHint(Region region)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 dumpAllSurfaces(PrintWriter pw, String header)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 toString()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 SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format, int flags, AppWindowToken token)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 setAlpha(float alpha)784 public void setAlpha(float alpha) { 785 super.setAlpha(alpha); 786 mBackgroundControl.setAlpha(alpha); 787 } 788 789 @Override setLayer(int zorder)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 setPosition(float x, float y)800 public void setPosition(float x, float y) { 801 super.setPosition(x, y); 802 mBackgroundControl.setPosition(x, y); 803 } 804 805 @Override setSize(int w, int h)806 public void setSize(int w, int h) { 807 super.setSize(w, h); 808 mBackgroundControl.setSize(w, h); 809 } 810 811 @Override setWindowCrop(Rect crop)812 public void setWindowCrop(Rect crop) { 813 super.setWindowCrop(crop); 814 mBackgroundControl.setWindowCrop(crop); 815 } 816 817 @Override setFinalCrop(Rect crop)818 public void setFinalCrop(Rect crop) { 819 super.setFinalCrop(crop); 820 mBackgroundControl.setFinalCrop(crop); 821 } 822 823 @Override setLayerStack(int layerStack)824 public void setLayerStack(int layerStack) { 825 super.setLayerStack(layerStack); 826 mBackgroundControl.setLayerStack(layerStack); 827 } 828 829 @Override setOpaque(boolean isOpaque)830 public void setOpaque(boolean isOpaque) { 831 super.setOpaque(isOpaque); 832 mOpaque = isOpaque; 833 updateBackgroundVisibility(mAppForcedInvisible); 834 } 835 836 @Override setSecure(boolean isSecure)837 public void setSecure(boolean isSecure) { 838 super.setSecure(isSecure); 839 } 840 841 @Override setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)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 hide()848 public void hide() { 849 super.hide(); 850 if (mVisible) { 851 mVisible = false; 852 mAppToken.updateSurfaceViewBackgroundVisibilities(); 853 } 854 } 855 856 @Override show()857 public void show() { 858 super.show(); 859 if (!mVisible) { 860 mVisible = true; 861 mAppToken.updateSurfaceViewBackgroundVisibilities(); 862 } 863 } 864 865 @Override destroy()866 public void destroy() { 867 super.destroy(); 868 mBackgroundControl.destroy(); 869 mAppToken.removeSurfaceViewBackground(this); 870 } 871 872 @Override release()873 public void release() { 874 super.release(); 875 mBackgroundControl.release(); 876 } 877 878 @Override setTransparentRegionHint(Region region)879 public void setTransparentRegionHint(Region region) { 880 super.setTransparentRegionHint(region); 881 mBackgroundControl.setTransparentRegionHint(region); 882 } 883 884 @Override deferTransactionUntil(IBinder handle, long frame)885 public void deferTransactionUntil(IBinder handle, long frame) { 886 super.deferTransactionUntil(handle, frame); 887 mBackgroundControl.deferTransactionUntil(handle, frame); 888 } 889 updateBackgroundVisibility(boolean forcedInvisible)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