From fca784712a5a8bc6aca725c890861ff95336d6b6 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Mon, 9 Mar 2020 15:34:47 -0700 Subject: [PATCH] Consider processes embedding content to be "interesting" If a process is embedding content in another process, give an indication that it shows visible UI to the user. This means if the process does not respond to input, we can show an ANR dialog to the user instead of just killing the process. Bug: 134365580 Test: atest CtsWindowManagerDeviceTestCases:AnrTests#embeddedWindowTriggersAnr Change-Id: I980f51a26342a3223347210b7ab1522015753262 --- .../com/android/server/wm/ActivityRecord.java | 2 +- .../server/wm/EmbeddedWindowController.java | 59 ++++++++++++++++--- .../server/wm/WindowManagerService.java | 4 +- .../server/wm/WindowProcessController.java | 38 ++++++++++++ 4 files changed, 91 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 7a302110b13b7..05e70c1120857 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3150,7 +3150,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Reset the last saved PiP snap fraction on removal. mDisplayContent.mPinnedStackControllerLocked.resetReentryBounds(mActivityComponent); - + mWmService.mEmbeddedWindowController.onActivityRemoved(this); mRemovingFromDisplay = false; } diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index 884f7694d6486..484a5a8b53b8f 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -17,11 +17,15 @@ package com.android.server.wm; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; + import android.annotation.Nullable; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArrayMap; +import android.util.Slog; import android.view.IWindow; import android.view.InputApplicationHandle; @@ -33,12 +37,15 @@ import android.view.InputApplicationHandle; * the host window to send pointerDownOutsideFocus. */ class EmbeddedWindowController { + private static final String TAG = TAG_WITH_CLASS_NAME ? "EmbeddedWindowController" : TAG_WM; /* maps input token to an embedded window */ private ArrayMap mWindows = new ArrayMap<>(); - private final Object mWmLock; + private final Object mGlobalLock; + private final ActivityTaskManagerService mAtmService; - EmbeddedWindowController(Object wmLock) { - mWmLock = wmLock; + EmbeddedWindowController(ActivityTaskManagerService atmService) { + mAtmService = atmService; + mGlobalLock = atmService.getGlobalLock(); } /** @@ -46,13 +53,14 @@ class EmbeddedWindowController { * * @param inputToken input channel token passed in by the embedding process when it requests * the server to add an input channel to the embedded surface. - * @param embeddedWindow An {@link EmbeddedWindow} object to add to this controller. + * @param window An {@link EmbeddedWindow} object to add to this controller. */ - void add(IBinder inputToken, EmbeddedWindow embeddedWindow) { + void add(IBinder inputToken, EmbeddedWindow window) { try { - mWindows.put(inputToken, embeddedWindow); - embeddedWindow.mClient.asBinder().linkToDeath(()-> { - synchronized (mWmLock) { + mWindows.put(inputToken, window); + updateProcessController(window); + window.mClient.asBinder().linkToDeath(()-> { + synchronized (mGlobalLock) { mWindows.remove(inputToken); } }, 0); @@ -62,6 +70,23 @@ class EmbeddedWindowController { } } + /** + * Track the host activity in the embedding process so we can determine if the + * process is currently showing any UI to the user. + */ + private void updateProcessController(EmbeddedWindow window) { + if (window.mHostActivityRecord == null) { + return; + } + final WindowProcessController processController = + mAtmService.getProcessController(window.mOwnerPid, window.mOwnerUid); + if (processController == null) { + Slog.w(TAG, "Could not find the embedding process."); + } else { + processController.addHostActivity(window.mHostActivityRecord); + } + } + WindowState getHostWindow(IBinder inputToken) { EmbeddedWindow embeddedWindow = mWindows.get(inputToken); return embeddedWindow != null ? embeddedWindow.mHostWindowState : null; @@ -76,7 +101,7 @@ class EmbeddedWindowController { } } - void removeWindowsWithHost(WindowState host) { + void onWindowRemoved(WindowState host) { for (int i = mWindows.size() - 1; i >= 0; i--) { if (mWindows.valueAt(i).mHostWindowState == host) { mWindows.removeAt(i); @@ -88,9 +113,23 @@ class EmbeddedWindowController { return mWindows.get(inputToken); } + void onActivityRemoved(ActivityRecord activityRecord) { + for (int i = mWindows.size() - 1; i >= 0; i--) { + final EmbeddedWindow window = mWindows.valueAt(i); + if (window.mHostActivityRecord == activityRecord) { + final WindowProcessController processController = + mAtmService.getProcessController(window.mOwnerPid, window.mOwnerUid); + if (processController != null) { + processController.removeHostActivity(activityRecord); + } + } + } + } + static class EmbeddedWindow { final IWindow mClient; @Nullable final WindowState mHostWindowState; + @Nullable final ActivityRecord mHostActivityRecord; final int mOwnerUid; final int mOwnerPid; @@ -107,6 +146,8 @@ class EmbeddedWindowController { int ownerPid) { mClient = clientToken; mHostWindowState = hostWindowState; + mHostActivityRecord = (mHostWindowState != null) ? mHostWindowState.mActivityRecord + : null; mOwnerUid = ownerUid; mOwnerPid = ownerPid; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 3f4f629b52924..2894787f6c206 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1287,7 +1287,7 @@ public class WindowManagerService extends IWindowManager.Stub mConstants.start(new HandlerExecutor(mH)); LocalServices.addService(WindowManagerInternal.class, new LocalService()); - mEmbeddedWindowController = new EmbeddedWindowController(mGlobalLock); + mEmbeddedWindowController = new EmbeddedWindowController(mAtmService); mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources( mContext.getResources()); @@ -1900,7 +1900,7 @@ public class WindowManagerService extends IWindowManager.Stub if (dc.mCurrentFocus == null) { dc.mWinRemovedSinceNullFocus.add(win); } - mEmbeddedWindowController.removeWindowsWithHost(win); + mEmbeddedWindowController.onWindowRemoved(win); mPendingRemove.remove(win); mResizingWindows.remove(win); updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */); diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 03dc4c9fd1d23..833bb83acb309 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -41,6 +41,7 @@ import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_T import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityThread; import android.app.IApplicationThread; import android.app.ProfilerInfo; @@ -185,6 +186,13 @@ public class WindowProcessController extends ConfigurationContainer mHostActivities = new ArrayList<>(); /** Whether our process is currently running a {@link RecentsAnimation} */ private boolean mRunningRecentsAnimation; @@ -672,6 +680,23 @@ public class WindowProcessController extends ConfigurationContainer= 0; --i) { + final ActivityRecord r = mHostActivities.get(i); + if (r.isInterestingToUserLocked()) { + return true; + } } return false; } @@ -814,6 +839,19 @@ public class WindowProcessController extends ConfigurationContainer