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

Commit 839b5f55 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Do not remove window if IWindow#resized is failed

Even DeadObjectException is thrown, it is not equivalent to the
window is died (transaction failed by small size data will be
DeadObjectException). Sometimes it may be caused by the binder
buffer of process is temporarily full. If the window is removed
directly but the process is still alive, the application client
and window manager are out of sync. Especially if the window is
important system window, e.g. status bar, notification shade,
navigation bar, which might need to reboot to recover. Ideally,
if the process is really dead, there should be a binderDied
callback that also removes the window.

The original purpose of the removal is to avoid display frozen
(e.g. rotation) always timeout which is caused by resetting
WindowState#mOrientationChanging in each layout traversal. Now
the window states are still updated as "resized" has reported,
so it won't block unfreeze display.

Bug: 151814107
Bug: 147448299
Test: atest WindowStateTests#testReportResizedWithRemoteException
Test: Hard code to throw RemoteException for a specified window
      and rotate the display.

Change-Id: Id295456cc99ab9af30aa5fad2eedada6afb862a2
parent 07217a0d
Loading
Loading
Loading
Loading
+6 −18
Original line number Original line Diff line number Diff line
@@ -25,6 +25,12 @@
      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
    },
    },
    "-2101985723": {
      "message": "Failed looking up window session=%s callers=%s",
      "level": "WARN",
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-2072089308": {
    "-2072089308": {
      "message": "Attempted to add window with token that is a sub-window: %s.  Aborting.",
      "message": "Attempted to add window with token that is a sub-window: %s.  Aborting.",
      "level": "WARN",
      "level": "WARN",
@@ -301,12 +307,6 @@
      "group": "WM_DEBUG_ADD_REMOVE",
      "group": "WM_DEBUG_ADD_REMOVE",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    },
    "-1455600136": {
      "message": "Attempted to add Dream window with unknown token %s.  Aborting.",
      "level": "WARN",
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-1443029505": {
    "-1443029505": {
      "message": "SAFE MODE ENABLED (menu=%d s=%d dpad=%d trackball=%d)",
      "message": "SAFE MODE ENABLED (menu=%d s=%d dpad=%d trackball=%d)",
      "level": "INFO",
      "level": "INFO",
@@ -385,12 +385,6 @@
      "group": "WM_DEBUG_RESIZE",
      "group": "WM_DEBUG_RESIZE",
      "at": "com\/android\/server\/wm\/WindowState.java"
      "at": "com\/android\/server\/wm\/WindowState.java"
    },
    },
    "-1263554915": {
      "message": "Attempted to add Dream window with bad token %s.  Aborting.",
      "level": "WARN",
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-1263316010": {
    "-1263316010": {
      "message": "Computed rotation=%s (%d) for display id=%d based on lastOrientation=%s (%d) and oldRotation=%s (%d)",
      "message": "Computed rotation=%s (%d) for display id=%d based on lastOrientation=%s (%d) and oldRotation=%s (%d)",
      "level": "VERBOSE",
      "level": "VERBOSE",
@@ -673,12 +667,6 @@
      "group": "WM_DEBUG_SCREEN_ON",
      "group": "WM_DEBUG_SCREEN_ON",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    },
    "-747671114": {
      "message": "Failed looking up window callers=%s",
      "level": "WARN",
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-714291355": {
    "-714291355": {
      "message": "Losing delayed focus: %s",
      "message": "Losing delayed focus: %s",
      "level": "INFO",
      "level": "INFO",
+4 −2
Original line number Original line Diff line number Diff line
@@ -5321,7 +5321,8 @@ public class WindowManagerService extends IWindowManager.Stub
                throw new IllegalArgumentException(
                throw new IllegalArgumentException(
                        "Requested window " + client + " does not exist");
                        "Requested window " + client + " does not exist");
            }
            }
            ProtoLog.w(WM_ERROR, "Failed looking up window callers=%s", Debug.getCallers(3));
            ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
                    Debug.getCallers(3));
            return null;
            return null;
        }
        }
        if (session != null && win.mSession != session) {
        if (session != null && win.mSession != session) {
@@ -5329,7 +5330,8 @@ public class WindowManagerService extends IWindowManager.Stub
                throw new IllegalArgumentException("Requested window " + client + " is in session "
                throw new IllegalArgumentException("Requested window " + client + " is in session "
                        + win.mSession + ", not " + session);
                        + win.mSession + ", not " + session);
            }
            }
            ProtoLog.w(WM_ERROR, "Failed looking up window callers=%s", Debug.getCallers(3));
            ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
                    Debug.getCallers(3));
            return null;
            return null;
        }
        }


+13 −11
Original line number Original line Diff line number Diff line
@@ -3440,13 +3440,23 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        getMergedConfiguration(mLastReportedConfiguration);
        getMergedConfiguration(mLastReportedConfiguration);
        mLastConfigReportedToClient = true;
        mLastConfigReportedToClient = true;


        final boolean reportOrientation = mReportOrientationChanged;
        // Always reset these states first, so if {@link IWindow#resized} fails, this
        // window won't be added to {@link WindowManagerService#mResizingWindows} and set
        // {@link #mOrientationChanging} to true again by {@link #updateResizingWindowIfNeeded}
        // that may cause WINDOW_FREEZE_TIMEOUT because resizing the client keeps failing.
        mReportOrientationChanged = false;
        mDragResizingChangeReported = true;
        mWinAnimator.mSurfaceResized = false;
        mWindowFrames.resetInsetsChanged();

        final Rect frame = mWindowFrames.mCompatFrame;
        final Rect frame = mWindowFrames.mCompatFrame;
        final Rect contentInsets = mWindowFrames.mLastContentInsets;
        final Rect contentInsets = mWindowFrames.mLastContentInsets;
        final Rect visibleInsets = mWindowFrames.mLastVisibleInsets;
        final Rect visibleInsets = mWindowFrames.mLastVisibleInsets;
        final Rect stableInsets = mWindowFrames.mLastStableInsets;
        final Rect stableInsets = mWindowFrames.mLastStableInsets;
        final MergedConfiguration mergedConfiguration = mLastReportedConfiguration;
        final MergedConfiguration mergedConfiguration = mLastReportedConfiguration;
        final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING;
        final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING;
        final boolean forceRelayout = mReportOrientationChanged || isDragResizeChanged();
        final boolean forceRelayout = reportOrientation || isDragResizeChanged();
        final int displayId = getDisplayId();
        final int displayId = getDisplayId();
        final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout();
        final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout();


@@ -3455,25 +3465,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                    mergedConfiguration, getBackdropFrame(frame), forceRelayout,
                    mergedConfiguration, getBackdropFrame(frame), forceRelayout,
                    getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this),
                    getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this),
                    displayId, new DisplayCutout.ParcelableWrapper(displayCutout));
                    displayId, new DisplayCutout.ParcelableWrapper(displayCutout));
            mDragResizingChangeReported = true;


            if (mWmService.mAccessibilityController != null) {
            if (mWmService.mAccessibilityController != null) {
                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId);
                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId);
            }
            }
            updateLocationInParentDisplayIfNeeded();
            updateLocationInParentDisplayIfNeeded();

            mWindowFrames.resetInsetsChanged();
            mWinAnimator.mSurfaceResized = false;
            mReportOrientationChanged = false;
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            // Cancel orientation change of this window to avoid blocking unfreeze display.
            setOrientationChanging(false);
            setOrientationChanging(false);
            mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
            mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                    - mWmService.mDisplayFreezeTime);
                    - mWmService.mDisplayFreezeTime);
            // We are assuming the hosting process is dead or in a zombie state.
            Slog.w(TAG, "Failed to report 'resized' to " + this + " due to " + e);
            Slog.w(TAG, "Failed to report 'resized' to the client of " + this
                    + ", removing this window.");
            mWmService.mPendingRemove.add(this);
            mWmService.mWindowPlacerLocked.requestTraversal();
        }
        }
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
    }
+35 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;


import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
@@ -47,6 +48,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;


import static com.google.common.truth.Truth.assertThat;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
@@ -55,6 +58,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.anyString;
@@ -65,6 +69,7 @@ import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.Presubmit;
import android.util.Size;
import android.util.Size;
import android.view.DisplayCutout;
import android.view.DisplayCutout;
@@ -569,6 +574,36 @@ public class WindowStateTests extends WindowTestsBase {
        assertEquals(Arrays.asList(keyguardHostWindow, startingWindow), outWaitingForDrawn);
        assertEquals(Arrays.asList(keyguardHostWindow, startingWindow), outWaitingForDrawn);
    }
    }


    @Test
    public void testReportResizedWithRemoteException() {
        final WindowState win = mChildAppWindowAbove;
        makeWindowVisible(win, win.getParentWindow());
        win.mLayoutSeq = win.getDisplayContent().mLayoutSeq;
        win.updateResizingWindowIfNeeded();

        assertThat(mWm.mResizingWindows).contains(win);
        assertTrue(win.getOrientationChanging());

        mWm.mResizingWindows.remove(win);
        spyOn(win.mClient);
        try {
            doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frame */,
                    any() /* contentInsets */, any() /* visibleInsets */, any() /* stableInsets */,
                    anyBoolean() /* reportDraw */, any() /* mergedConfig */,
                    any() /* backDropFrame */, anyBoolean() /* forceLayout */,
                    anyBoolean() /* alwaysConsumeSystemBars */, anyInt() /* displayId */,
                    any() /* displayCutout */);
        } catch (RemoteException ignored) {
        }
        win.reportResized();
        win.updateResizingWindowIfNeeded();

        // Even "resized" throws remote exception, it is still considered as reported. So the window
        // shouldn't be resized again (which may block unfreeze in real case).
        assertThat(mWm.mResizingWindows).doesNotContain(win);
        assertFalse(win.getOrientationChanging());
    }

    @Test
    @Test
    public void testGetTransformationMatrix() {
    public void testGetTransformationMatrix() {
        final int PARENT_WINDOW_OFFSET = 1;
        final int PARENT_WINDOW_OFFSET = 1;