diff options
5 files changed, 56 insertions, 100 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 19128212094d..6b83a1d3021b 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -367,12 +367,6 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/DisplayContent.java" }, - "-1770075711": { - "message": "Adding window client %s that is dead, aborting.", - "level": "WARN", - "group": "WM_ERROR", - "at": "com\/android\/server\/wm\/WindowManagerService.java" - }, "-1768557332": { "message": "removeWallpaperAnimation()", "level": "DEBUG", @@ -3229,6 +3223,12 @@ "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" }, + "723575093": { + "message": "Attempted to add window with a client %s that is dead. Aborting.", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, "726205185": { "message": "Moving to DESTROYED: %s (destroy skipped)", "level": "VERBOSE", @@ -4213,12 +4213,6 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, - "1720696061": { - "message": "Adding window to Display that has been removed.", - "level": "WARN", - "group": "WM_ERROR", - "at": "com\/android\/server\/wm\/WindowManagerService.java" - }, "1730300180": { "message": "PendingStartTransaction found", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 56f9aa4c6361..f5635d96714d 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -89,6 +89,7 @@ import com.android.server.wm.WindowManagerService.H; import com.android.window.flags.Flags; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.BiConsumer; @@ -106,7 +107,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { final WindowProcessController mProcess; private final String mStringName; SurfaceSession mSurfaceSession; - private int mNumWindow = 0; + private final ArrayList<WindowState> mAddedWindows = new ArrayList<>(); // Set of visible application overlay window surfaces connected to this session. private final ArraySet<WindowSurfaceController> mAppOverlaySurfaces = new ArraySet<>(); // Set of visible alert window surfaces connected to this session. @@ -192,8 +193,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { try { mCallback.asBinder().linkToDeath(this, 0); } catch (RemoteException e) { - // The caller has died, so we can just forget about this. - // Hmmm, should we call killSessionLocked()?? + mClientDead = true; } } @@ -211,12 +211,27 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } } + boolean isClientDead() { + return mClientDead; + } + @Override public void binderDied() { synchronized (mService.mGlobalLock) { mCallback.asBinder().unlinkToDeath(this, 0); mClientDead = true; - killSessionLocked(); + try { + for (int i = mAddedWindows.size() - 1; i >= 0; i--) { + final WindowState w = mAddedWindows.get(i); + Slog.i(TAG_WM, "WIN DEATH: " + w); + if (w.mActivityRecord != null && w.mActivityRecord.findMainWindow() == w) { + mService.mSnapshotController.onAppDied(w.mActivityRecord); + } + w.removeIfPossible(); + } + } finally { + killSessionLocked(); + } } } @@ -739,7 +754,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } } - void windowAddedLocked() { + void onWindowAdded(WindowState w) { if (mPackageName == null) { mPackageName = mProcess.mInfo.packageName; mRelayoutTag = "relayoutWindow: " + mPackageName; @@ -755,12 +770,14 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { mService.dispatchNewAnimatorScaleLocked(this); } } - mNumWindow++; + mAddedWindows.add(w); } - void windowRemovedLocked() { - mNumWindow--; - killSessionLocked(); + void onWindowRemoved(WindowState w) { + mAddedWindows.remove(w); + if (mAddedWindows.isEmpty()) { + killSessionLocked(); + } } @@ -827,7 +844,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } private void killSessionLocked() { - if (mNumWindow > 0 || !mClientDead) { + if (!mClientDead) { return; } @@ -836,10 +853,6 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { return; } - if (DEBUG) { - Slog.v(TAG_WM, "Last window removed from " + this - + ", destroying " + mSurfaceSession); - } ProtoLog.i(WM_SHOW_TRANSACTIONS, " KILL SURFACE SESSION %s", mSurfaceSession); try { mSurfaceSession.kill(); @@ -848,6 +861,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { + " in session " + this + ": " + e.toString()); } mSurfaceSession = null; + mAddedWindows.clear(); mAlertWindowSurfaces.clear(); mAppOverlaySurfaces.clear(); setHasOverlayUi(false); @@ -867,7 +881,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } void dump(PrintWriter pw, String prefix) { - pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow); + pw.print(prefix); pw.print("numWindow="); pw.print(mAddedWindows.size()); pw.print(" mCanAddInternalSystemWindow="); pw.print(mCanAddInternalSystemWindow); pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces); pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0c57036a3b02..58851d5a5fc0 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1445,6 +1445,11 @@ public class WindowManagerService extends IWindowManager.Stub if (!mDisplayReady) { throw new IllegalStateException("Display has not been initialialized"); } + if (session.isClientDead()) { + ProtoLog.w(WM_ERROR, "Attempted to add window with a client %s " + + "that is dead. Aborting.", session); + return WindowManagerGlobal.ADD_APP_EXITING; + } final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token); @@ -1629,19 +1634,6 @@ public class WindowManagerService extends IWindowManager.Stub final WindowState win = new WindowState(this, session, client, token, parentWindow, appOp[0], attrs, viewVisibility, session.mUid, userId, session.mCanAddInternalSystemWindow); - if (win.mDeathRecipient == null) { - // Client has apparently died, so there is no reason to - // continue. - ProtoLog.w(WM_ERROR, "Adding window client %s" - + " that is dead, aborting.", client.asBinder()); - return WindowManagerGlobal.ADD_APP_EXITING; - } - - if (win.getDisplayContent() == null) { - ProtoLog.w(WM_ERROR, "Adding window to Display that has been removed."); - return WindowManagerGlobal.ADD_INVALID_DISPLAY; - } - final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy(); displayPolicy.adjustWindowParamsLw(win, win.mAttrs); attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), callingUid, callingPid); @@ -1725,7 +1717,7 @@ public class WindowManagerService extends IWindowManager.Stub displayContent.mTapExcludedWindows.add(win); } - win.attach(); + win.mSession.onWindowAdded(win); mWindowMap.put(client.asBinder(), win); win.initAppOpsState(); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 7bc7e2cb780b..3d510ca4160b 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -309,7 +309,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // mAttrs.flags is tested in animation without being locked. If the bits tested are ever // modified they will need to be locked. final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); - final DeathRecipient mDeathRecipient; private boolean mIsChildWindow; final int mBaseLayer; final int mSubLayer; @@ -1101,7 +1100,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mViewVisibility = viewVisibility; mPolicy = mWmService.mPolicy; mContext = mWmService.mContext; - DeathRecipient deathRecipient = new DeathRecipient(); mPowerManagerWrapper = powerManagerWrapper; mForceSeamlesslyRotate = token.mRoundedCornerOverlay; mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle( @@ -1121,22 +1119,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP Slog.v(TAG, "Window " + this + " client=" + c.asBinder() + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); } - try { - c.asBinder().linkToDeath(deathRecipient, 0); - } catch (RemoteException e) { - mDeathRecipient = null; - mIsChildWindow = false; - mLayoutAttached = false; - mIsImWindow = false; - mIsWallpaper = false; - mIsFloatingLayer = false; - mBaseLayer = 0; - mSubLayer = 0; - mWinAnimator = null; - mOverrideScale = 1f; - return; - } - mDeathRecipient = deathRecipient; if (mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW) { // The multiplier here is to reserve space for multiple @@ -1231,11 +1213,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return TouchOcclusionMode.BLOCK_UNTRUSTED; } - void attach() { - if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken); - mSession.windowAddedLocked(); - } - void updateGlobalScale() { if (hasCompatScale()) { mCompatScale = (mOverrideScale == 1f || mToken.hasSizeCompatBounds()) @@ -2389,14 +2366,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP disposeInputChannel(); mOnBackInvokedCallbackInfo = null; - mSession.windowRemovedLocked(); - try { - mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); - } catch (RuntimeException e) { - // Ignore if it has already been removed (usually because - // we are doing this as part of processing a death note.) - } - + mSession.onWindowRemoved(this); mWmService.postWindowRemoveCleanupLocked(this); mWmService.mTrustedPresentationListenerController.removeIgnoredWindowTokens( @@ -2926,31 +2896,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } - private class DeathRecipient implements IBinder.DeathRecipient { - @Override - public void binderDied() { - try { - synchronized (mWmService.mGlobalLock) { - final WindowState win = mWmService - .windowForClientLocked(mSession, mClient, false); - Slog.i(TAG, "WIN DEATH: " + win); - if (win != null) { - if (win.mActivityRecord != null - && win.mActivityRecord.findMainWindow() == win) { - mWmService.mSnapshotController.onAppDied(win.mActivityRecord); - } - win.removeIfPossible(); - } else if (mHasSurface) { - Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid."); - WindowState.this.removeIfPossible(); - } - } - } catch (IllegalArgumentException ex) { - // This will happen if the window has already been removed. - } - } - } - /** Returns {@code true} if this window desires key events. */ boolean canReceiveKeys() { return canReceiveKeys(false /* fromUserTouch */); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index f99b489720b9..8bf4833bc2ca 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -499,11 +499,16 @@ public class WindowManagerServiceTests extends WindowTestsBase { public void testAddWindowWithSubWindowTypeByWindowContext() { spyOn(mWm.mWindowContextListenerController); - final WindowToken windowToken = createTestWindowToken(TYPE_INPUT_METHOD, mDefaultDisplay); - final Session session = getTestSession(); + final WindowState parentWin = createWindow(null, TYPE_INPUT_METHOD, "ime"); + final IBinder parentToken = parentWin.mToken.token; + parentWin.mAttrs.token = parentToken; + mWm.mWindowMap.put(parentToken, parentWin); + final Session session = parentWin.mSession; + session.onWindowAdded(parentWin); final WindowManager.LayoutParams params = new WindowManager.LayoutParams( TYPE_APPLICATION_ATTACHED_DIALOG); - params.token = windowToken.token; + params.token = parentToken; + params.setTitle("attached-dialog"); final IBinder windowContextToken = new Binder(); params.setWindowContextToken(windowContextToken); doReturn(true).when(mWm.mWindowContextListenerController) @@ -517,6 +522,12 @@ public class WindowManagerServiceTests extends WindowTestsBase { verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(), any(), any(), anyInt(), any(), anyBoolean()); + + assertTrue(parentWin.hasChild()); + assertTrue(parentWin.isAttached()); + session.binderDied(); + assertFalse(parentWin.hasChild()); + assertFalse(parentWin.isAttached()); } @Test |