Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb02c57b authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Reuse death recipient of window session for its windows

The process of WindowState is impossible to be different from
the Session. Since Session has registered death recipient, it
is unnecessary to register for the windows belonging to the
same process.

This simplifies the code structure and reduces overhead to binder.

Additional note:
 WMS#addWindow has checked valid display at the beginning.

Bug: 163976519
Test: WindowManagerServiceTests

Change-Id: Id249c9b4d3f347383939ee70e0b0deb54be7172a
parent c7f210a6
Loading
Loading
Loading
Loading
+6 −12
Original line number Original line Diff line number Diff line
@@ -367,12 +367,6 @@
      "group": "WM_DEBUG_IME",
      "group": "WM_DEBUG_IME",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
      "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": {
    "-1768557332": {
      "message": "removeWallpaperAnimation()",
      "message": "removeWallpaperAnimation()",
      "level": "DEBUG",
      "level": "DEBUG",
@@ -3229,6 +3223,12 @@
      "group": "WM_DEBUG_LOCKTASK",
      "group": "WM_DEBUG_LOCKTASK",
      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
      "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": {
    "726205185": {
      "message": "Moving to DESTROYED: %s (destroy skipped)",
      "message": "Moving to DESTROYED: %s (destroy skipped)",
      "level": "VERBOSE",
      "level": "VERBOSE",
@@ -4213,12 +4213,6 @@
      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
      "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": {
    "1730300180": {
      "message": "PendingStartTransaction found",
      "message": "PendingStartTransaction found",
      "level": "VERBOSE",
      "level": "VERBOSE",
+29 −15
Original line number Original line Diff line number Diff line
@@ -89,6 +89,7 @@ import com.android.server.wm.WindowManagerService.H;
import com.android.window.flags.Flags;
import com.android.window.flags.Flags;


import java.io.PrintWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Collections;
import java.util.List;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiConsumer;
@@ -106,7 +107,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
    final WindowProcessController mProcess;
    final WindowProcessController mProcess;
    private final String mStringName;
    private final String mStringName;
    SurfaceSession mSurfaceSession;
    SurfaceSession mSurfaceSession;
    private int mNumWindow = 0;
    private final ArrayList<WindowState> mAddedWindows = new ArrayList<>();
    // Set of visible application overlay window surfaces connected to this session.
    // Set of visible application overlay window surfaces connected to this session.
    private final ArraySet<WindowSurfaceController> mAppOverlaySurfaces = new ArraySet<>();
    private final ArraySet<WindowSurfaceController> mAppOverlaySurfaces = new ArraySet<>();
    // Set of visible alert window surfaces connected to this session.
    // Set of visible alert window surfaces connected to this session.
@@ -192,8 +193,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
        try {
        try {
            mCallback.asBinder().linkToDeath(this, 0);
            mCallback.asBinder().linkToDeath(this, 0);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            // The caller has died, so we can just forget about this.
            mClientDead = true;
            // Hmmm, should we call killSessionLocked()??
        }
        }
    }
    }


@@ -211,14 +211,29 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
        }
        }
    }
    }


    boolean isClientDead() {
        return mClientDead;
    }

    @Override
    @Override
    public void binderDied() {
    public void binderDied() {
        synchronized (mService.mGlobalLock) {
        synchronized (mService.mGlobalLock) {
            mCallback.asBinder().unlinkToDeath(this, 0);
            mCallback.asBinder().unlinkToDeath(this, 0);
            mClientDead = true;
            mClientDead = true;
            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();
                killSessionLocked();
            }
            }
        }
        }
    }


    @Override
    @Override
    public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
    public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
@@ -739,7 +754,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
        }
        }
    }
    }


    void windowAddedLocked() {
    void onWindowAdded(WindowState w) {
        if (mPackageName == null) {
        if (mPackageName == null) {
            mPackageName = mProcess.mInfo.packageName;
            mPackageName = mProcess.mInfo.packageName;
            mRelayoutTag = "relayoutWindow: " + mPackageName;
            mRelayoutTag = "relayoutWindow: " + mPackageName;
@@ -755,13 +770,15 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
                mService.dispatchNewAnimatorScaleLocked(this);
                mService.dispatchNewAnimatorScaleLocked(this);
            }
            }
        }
        }
        mNumWindow++;
        mAddedWindows.add(w);
    }
    }


    void windowRemovedLocked() {
    void onWindowRemoved(WindowState w) {
        mNumWindow--;
        mAddedWindows.remove(w);
        if (mAddedWindows.isEmpty()) {
            killSessionLocked();
            killSessionLocked();
        }
        }
    }




    void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController,
    void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController,
@@ -827,7 +844,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
    }
    }


    private void killSessionLocked() {
    private void killSessionLocked() {
        if (mNumWindow > 0 || !mClientDead) {
        if (!mClientDead) {
            return;
            return;
        }
        }


@@ -836,10 +853,6 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
            return;
            return;
        }
        }


        if (DEBUG) {
            Slog.v(TAG_WM, "Last window removed from " + this
                    + ", destroying " + mSurfaceSession);
        }
        ProtoLog.i(WM_SHOW_TRANSACTIONS, "  KILL SURFACE SESSION %s", mSurfaceSession);
        ProtoLog.i(WM_SHOW_TRANSACTIONS, "  KILL SURFACE SESSION %s", mSurfaceSession);
        try {
        try {
            mSurfaceSession.kill();
            mSurfaceSession.kill();
@@ -848,6 +861,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
                    + " in session " + this + ": " + e.toString());
                    + " in session " + this + ": " + e.toString());
        }
        }
        mSurfaceSession = null;
        mSurfaceSession = null;
        mAddedWindows.clear();
        mAlertWindowSurfaces.clear();
        mAlertWindowSurfaces.clear();
        mAppOverlaySurfaces.clear();
        mAppOverlaySurfaces.clear();
        setHasOverlayUi(false);
        setHasOverlayUi(false);
@@ -867,7 +881,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
    }
    }


    void dump(PrintWriter pw, String prefix) {
    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(" mCanAddInternalSystemWindow="); pw.print(mCanAddInternalSystemWindow);
                pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces);
                pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces);
                pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
                pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
+6 −14
Original line number Original line Diff line number Diff line
@@ -1445,6 +1445,11 @@ public class WindowManagerService extends IWindowManager.Stub
            if (!mDisplayReady) {
            if (!mDisplayReady) {
                throw new IllegalStateException("Display has not been initialialized");
                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);
            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,
            final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], attrs, viewVisibility, session.mUid, userId,
                    appOp[0], attrs, viewVisibility, session.mUid, userId,
                    session.mCanAddInternalSystemWindow);
                    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();
            final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
            displayPolicy.adjustWindowParamsLw(win, win.mAttrs);
            displayPolicy.adjustWindowParamsLw(win, win.mAttrs);
            attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), callingUid, callingPid);
            attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), callingUid, callingPid);
@@ -1725,7 +1717,7 @@ public class WindowManagerService extends IWindowManager.Stub
                displayContent.mTapExcludedWindows.add(win);
                displayContent.mTapExcludedWindows.add(win);
            }
            }


            win.attach();
            win.mSession.onWindowAdded(win);
            mWindowMap.put(client.asBinder(), win);
            mWindowMap.put(client.asBinder(), win);
            win.initAppOpsState();
            win.initAppOpsState();


+1 −56
Original line number Original line Diff line number Diff line
@@ -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
    // mAttrs.flags is tested in animation without being locked. If the bits tested are ever
    // modified they will need to be locked.
    // modified they will need to be locked.
    final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
    final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
    final DeathRecipient mDeathRecipient;
    private boolean mIsChildWindow;
    private boolean mIsChildWindow;
    final int mBaseLayer;
    final int mBaseLayer;
    final int mSubLayer;
    final int mSubLayer;
@@ -1101,7 +1100,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        mViewVisibility = viewVisibility;
        mViewVisibility = viewVisibility;
        mPolicy = mWmService.mPolicy;
        mPolicy = mWmService.mPolicy;
        mContext = mWmService.mContext;
        mContext = mWmService.mContext;
        DeathRecipient deathRecipient = new DeathRecipient();
        mPowerManagerWrapper = powerManagerWrapper;
        mPowerManagerWrapper = powerManagerWrapper;
        mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
        mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
        mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle(
        mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle(
@@ -1121,22 +1119,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            Slog.v(TAG, "Window " + this + " client=" + c.asBinder()
            Slog.v(TAG, "Window " + this + " client=" + c.asBinder()
                            + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
                            + " 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) {
        if (mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW) {
            // The multiplier here is to reserve space for multiple
            // The multiplier here is to reserve space for multiple
@@ -1231,11 +1213,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return TouchOcclusionMode.BLOCK_UNTRUSTED;
        return TouchOcclusionMode.BLOCK_UNTRUSTED;
    }
    }


    void attach() {
        if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
        mSession.windowAddedLocked();
    }

    void updateGlobalScale() {
    void updateGlobalScale() {
        if (hasCompatScale()) {
        if (hasCompatScale()) {
            mCompatScale = (mOverrideScale == 1f || mToken.hasSizeCompatBounds())
            mCompatScale = (mOverrideScale == 1f || mToken.hasSizeCompatBounds())
@@ -2389,14 +2366,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        disposeInputChannel();
        disposeInputChannel();
        mOnBackInvokedCallbackInfo = null;
        mOnBackInvokedCallbackInfo = null;


        mSession.windowRemovedLocked();
        mSession.onWindowRemoved(this);
        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.)
        }

        mWmService.postWindowRemoveCleanupLocked(this);
        mWmService.postWindowRemoveCleanupLocked(this);


        mWmService.mTrustedPresentationListenerController.removeIgnoredWindowTokens(
        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. */
    /** Returns {@code true} if this window desires key events. */
    boolean canReceiveKeys() {
    boolean canReceiveKeys() {
        return canReceiveKeys(false /* fromUserTouch */);
        return canReceiveKeys(false /* fromUserTouch */);
+14 −3
Original line number Original line Diff line number Diff line
@@ -499,11 +499,16 @@ public class WindowManagerServiceTests extends WindowTestsBase {
    public void testAddWindowWithSubWindowTypeByWindowContext() {
    public void testAddWindowWithSubWindowTypeByWindowContext() {
        spyOn(mWm.mWindowContextListenerController);
        spyOn(mWm.mWindowContextListenerController);


        final WindowToken windowToken = createTestWindowToken(TYPE_INPUT_METHOD, mDefaultDisplay);
        final WindowState parentWin = createWindow(null, TYPE_INPUT_METHOD, "ime");
        final Session session = getTestSession();
        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(
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                TYPE_APPLICATION_ATTACHED_DIALOG);
                TYPE_APPLICATION_ATTACHED_DIALOG);
        params.token = windowToken.token;
        params.token = parentToken;
        params.setTitle("attached-dialog");
        final IBinder windowContextToken = new Binder();
        final IBinder windowContextToken = new Binder();
        params.setWindowContextToken(windowContextToken);
        params.setWindowContextToken(windowContextToken);
        doReturn(true).when(mWm.mWindowContextListenerController)
        doReturn(true).when(mWm.mWindowContextListenerController)
@@ -517,6 +522,12 @@ public class WindowManagerServiceTests extends WindowTestsBase {


        verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(),
        verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(),
                any(), any(), anyInt(), any(), anyBoolean());
                any(), any(), anyInt(), any(), anyBoolean());

        assertTrue(parentWin.hasChild());
        assertTrue(parentWin.isAttached());
        session.binderDied();
        assertFalse(parentWin.hasChild());
        assertFalse(parentWin.isAttached());
    }
    }


    @Test
    @Test