summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/etc/services.core.protolog.json18
-rw-r--r--services/core/java/com/android/server/wm/Session.java44
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java57
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java17
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