diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java index cdcd65910974e..a8fcf865bcebb 100644 --- a/core/java/android/service/autofill/InlineSuggestionRenderService.java +++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java @@ -166,7 +166,7 @@ public abstract class InlineSuggestionRenderService extends Service { PixelFormat.TRANSPARENT); final SurfaceControlViewHost host = new SurfaceControlViewHost(this, getDisplay(), - hostInputToken); + hostInputToken, "InlineSuggestionRenderService"); host.setView(suggestionRoot, lp); // Set the suggestion view to be non-focusable so that if its background is set to a diff --git a/core/java/android/service/games/GameSessionService.java b/core/java/android/service/games/GameSessionService.java index 52c8ec3d40184..f844423445675 100644 --- a/core/java/android/service/games/GameSessionService.java +++ b/core/java/android/service/games/GameSessionService.java @@ -125,7 +125,7 @@ public abstract class GameSessionService extends Service { final Context windowContext = createWindowContext(display, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, /*options=*/ null); SurfaceControlViewHost surfaceControlViewHost = - new SurfaceControlViewHost(windowContext, display, hostToken); + new SurfaceControlViewHost(windowContext, display, hostToken, "GameSessionService"); gameSession.attach( gameSessionController, diff --git a/core/java/android/service/selectiontoolbar/RemoteSelectionToolbar.java b/core/java/android/service/selectiontoolbar/RemoteSelectionToolbar.java index 9292e9608261e..59e3a5e703764 100644 --- a/core/java/android/service/selectiontoolbar/RemoteSelectionToolbar.java +++ b/core/java/android/service/selectiontoolbar/RemoteSelectionToolbar.java @@ -275,7 +275,7 @@ final class RemoteSelectionToolbar { mHostInputToken, mTransferTouchListener); contentHolder.addView(mContentContainer); mSurfaceControlViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), - mHostInputToken); + mHostInputToken, "RemoteSelectionToolbar"); mSurfaceControlViewHost.setView(contentHolder, mPopupWidth, mPopupHeight); } if (mSurfacePackage == null) { diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 52b96de0ba5ba..ac50d09cc091c 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -32,6 +32,8 @@ import android.view.accessibility.IAccessibilityEmbeddedConnection; import android.window.ISurfaceSyncGroup; import android.window.WindowTokenClient; +import dalvik.system.CloseGuard; + import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -51,6 +53,7 @@ import java.util.concurrent.TimeoutException; public class SurfaceControlViewHost { private final static String TAG = "SurfaceControlViewHost"; private final ViewRootImpl mViewRoot; + private final CloseGuard mCloseGuard = CloseGuard.get(); private WindowlessWindowManager mWm; private SurfaceControl mSurfaceControl; @@ -292,9 +295,10 @@ public class SurfaceControlViewHost { /** @hide */ public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, - @NonNull WindowlessWindowManager wwm) { + @NonNull WindowlessWindowManager wwm, @NonNull String callsite) { mWm = wwm; mViewRoot = new ViewRootImpl(c, d, mWm, new WindowlessWindowLayout()); + mCloseGuard.openWithCallSite("release", callsite); addConfigCallback(c, d); WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot); @@ -316,15 +320,35 @@ public class SurfaceControlViewHost { */ public SurfaceControlViewHost(@NonNull Context context, @NonNull Display display, @Nullable IBinder hostToken) { + this(context, display, hostToken, "untracked"); + } + + /** + * Construct a new SurfaceControlViewHost. The root Surface will be + * allocated internally and is accessible via getSurfacePackage(). + * + * The {@param hostToken} parameter, primarily used for ANR reporting, + * must be obtained from whomever will be hosting the embedded hierarchy. + * It's accessible from {@link SurfaceView#getHostToken}. + * + * @param context The Context object for your activity or application. + * @param display The Display the hierarchy will be placed on. + * @param hostToken The host token, as discussed above. + * @param callsite The call site, used for tracking leakage of the host + * @hide + */ + public SurfaceControlViewHost(@NonNull Context context, @NonNull Display display, + @Nullable IBinder hostToken, @NonNull String callsite) { mSurfaceControl = new SurfaceControl.Builder() .setContainerLayer() .setName("SurfaceControlViewHost") - .setCallsite("SurfaceControlViewHost") + .setCallsite("SurfaceControlViewHost[" + callsite + "]") .build(); mWm = new WindowlessWindowManager(context.getResources().getConfiguration(), mSurfaceControl, hostToken); mViewRoot = new ViewRootImpl(context, display, mWm, new WindowlessWindowLayout()); + mCloseGuard.openWithCallSite("release", callsite); addConfigCallback(context, display); WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot); @@ -350,7 +374,9 @@ public class SurfaceControlViewHost { if (mReleased) { return; } - Log.e(TAG, "SurfaceControlViewHost finalized without being released: " + this); + if (mCloseGuard != null) { + mCloseGuard.warnIfOpen(); + } // We aren't on the UI thread here so we need to pass false to doDie mViewRoot.die(false /* immediate */); WindowManagerGlobal.getInstance().removeWindowlessRoot(mViewRoot); @@ -466,6 +492,7 @@ public class SurfaceControlViewHost { mViewRoot.die(true /* immediate */); WindowManagerGlobal.getInstance().removeWindowlessRoot(mViewRoot); mReleased = true; + mCloseGuard.close(); } /** diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java index bc9f74ecec997..bdaad2b68fc25 100644 --- a/core/java/android/window/SplashScreenView.java +++ b/core/java/android/window/SplashScreenView.java @@ -333,7 +333,8 @@ public final class SplashScreenView extends FrameLayout { SurfaceControlViewHost viewHost = new SurfaceControlViewHost(viewContext, viewContext.getDisplay(), - surfaceView.getHostToken()); + surfaceView.getHostToken(), + "SplashScreenView"); ImageView imageView = new ImageView(viewContext); imageView.setBackground(mIconDrawable); viewHost.setView(imageView, mIconSize, mIconSize); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java index 5e46023cd84f1..5e42782431fd3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java @@ -223,7 +223,7 @@ public class SystemWindows { } final Display display = mDisplayController.getDisplay(mDisplayId); SurfaceControlViewHost viewRoot = - new SurfaceControlViewHost(view.getContext(), display, wwm); + new SurfaceControlViewHost(view.getContext(), display, wwm, "SystemWindows"); attrs.flags |= FLAG_HARDWARE_ACCELERATED; viewRoot.setView(view, attrs); mViewRoots.put(view, viewRoot); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index fa3a6ad016b0d..e44257ebef5c8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -114,7 +114,8 @@ public class SplitDecorManager extends WindowlessWindowManager { context = context.createWindowContext(context.getDisplay(), TYPE_APPLICATION_OVERLAY, null /* options */); mHostLeash = rootLeash; - mViewHost = new SurfaceControlViewHost(context, context.getDisplay(), this); + mViewHost = new SurfaceControlViewHost(context, context.getDisplay(), this, + "SplitDecorManager"); mIconSize = context.getResources().getDimensionPixelSize(R.dimen.split_icon_size); final FrameLayout rootLayout = (FrameLayout) LayoutInflater.from(context) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java index 6b5ddcb7ebe3a..eb3c1df0ae73e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java @@ -113,7 +113,8 @@ public final class SplitWindowManager extends WindowlessWindowManager { "Try to inflate divider view again without release first"); } - mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this); + mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this, + "SplitWindowManager"); mDividerView = (DividerView) LayoutInflater.from(mContext) .inflate(R.layout.split_divider, null /* root */); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java index 34e650a72ced4..efd459498adb2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java @@ -363,7 +363,8 @@ public abstract class CompatUIWindowManagerAbstract extends WindowlessWindowMana /** Creates a {@link SurfaceControlViewHost} for this window manager. */ @VisibleForTesting(visibility = PRIVATE) public SurfaceControlViewHost createSurfaceViewHost() { - return new SurfaceControlViewHost(mContext, mContext.getDisplay(), this); + return new SurfaceControlViewHost(mContext, mContext.getDisplay(), this, + getClass().getSimpleName()); } /** Gets the layout params. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java index 8ebcd815cf12f..71cc8df80cadb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java @@ -122,7 +122,8 @@ public final class BackgroundWindowManager extends WindowlessWindowManager { return false; } - mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this); + mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this, + "BackgroundWindowManager"); mBackgroundView = (View) LayoutInflater.from(mContext) .inflate(R.layout.background_panel, null /* root */); WindowManager.LayoutParams lp = new WindowManager.LayoutParams( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index 62b72f377cdbf..9ac15983ea752 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -481,7 +481,7 @@ public abstract class WindowDecoration interface SurfaceControlViewHostFactory { default SurfaceControlViewHost create(Context c, Display d, WindowlessWindowManager wmm) { - return new SurfaceControlViewHost(c, d, wmm); + return new SurfaceControlViewHost(c, d, wmm, "WindowDecoration"); } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java index 30156a0cd6f1f..5e71bbecf55cf 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java @@ -75,7 +75,7 @@ public class SurfaceViewRequestReceiver { DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); mSurfaceControlViewHost = new SurfaceControlViewHost(context, dm.getDisplay(SurfaceViewRequestUtils.getDisplayId(bundle)), - windowlessWindowManager); + windowlessWindowManager, "SurfaceViewRequestReceiver"); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( viewSize.getWidth(), diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index adde595247f81..ef9e83aae0c15 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -94,6 +94,7 @@ constructor( context, displayManager.getDisplay(bundle.getInt(KEY_DISPLAY_ID)), hostToken, + "KeyguardPreviewRenderer" ) disposables.add(DisposableHandle { host.release() }) } diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt index 19a0866cd0a8a..6ef828fbdfdbb 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt @@ -166,7 +166,8 @@ constructor( overlayAddReason = reason - val newRoot = SurfaceControlViewHost(context, context.display!!, wwm) + val newRoot = SurfaceControlViewHost(context, context.display!!, wwm, + "UnfoldLightRevealOverlayAnimation") val params = getLayoutParams() val newView = LightRevealScrim(