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
This commit is contained in:
@@ -25,6 +25,12 @@
|
||||
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
|
||||
"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": {
|
||||
"message": "Attempted to add window with token that is a sub-window: %s. Aborting.",
|
||||
"level": "WARN",
|
||||
@@ -301,12 +307,6 @@
|
||||
"group": "WM_DEBUG_ADD_REMOVE",
|
||||
"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": {
|
||||
"message": "SAFE MODE ENABLED (menu=%d s=%d dpad=%d trackball=%d)",
|
||||
"level": "INFO",
|
||||
@@ -385,12 +385,6 @@
|
||||
"group": "WM_DEBUG_RESIZE",
|
||||
"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": {
|
||||
"message": "Computed rotation=%s (%d) for display id=%d based on lastOrientation=%s (%d) and oldRotation=%s (%d)",
|
||||
"level": "VERBOSE",
|
||||
@@ -673,12 +667,6 @@
|
||||
"group": "WM_DEBUG_SCREEN_ON",
|
||||
"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": {
|
||||
"message": "Losing delayed focus: %s",
|
||||
"level": "INFO",
|
||||
|
||||
@@ -5321,7 +5321,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
throw new IllegalArgumentException(
|
||||
"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;
|
||||
}
|
||||
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 "
|
||||
+ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -3440,13 +3440,23 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
getMergedConfiguration(mLastReportedConfiguration);
|
||||
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 contentInsets = mWindowFrames.mLastContentInsets;
|
||||
final Rect visibleInsets = mWindowFrames.mLastVisibleInsets;
|
||||
final Rect stableInsets = mWindowFrames.mLastStableInsets;
|
||||
final MergedConfiguration mergedConfiguration = mLastReportedConfiguration;
|
||||
final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING;
|
||||
final boolean forceRelayout = mReportOrientationChanged || isDragResizeChanged();
|
||||
final boolean forceRelayout = reportOrientation || isDragResizeChanged();
|
||||
final int displayId = getDisplayId();
|
||||
final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout();
|
||||
|
||||
@@ -3455,25 +3465,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
mergedConfiguration, getBackdropFrame(frame), forceRelayout,
|
||||
getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this),
|
||||
displayId, new DisplayCutout.ParcelableWrapper(displayCutout));
|
||||
mDragResizingChangeReported = true;
|
||||
|
||||
if (mWmService.mAccessibilityController != null) {
|
||||
mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId);
|
||||
}
|
||||
updateLocationInParentDisplayIfNeeded();
|
||||
|
||||
mWindowFrames.resetInsetsChanged();
|
||||
mWinAnimator.mSurfaceResized = false;
|
||||
mReportOrientationChanged = false;
|
||||
} catch (RemoteException e) {
|
||||
// Cancel orientation change of this window to avoid blocking unfreeze display.
|
||||
setOrientationChanging(false);
|
||||
mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
|
||||
- mWmService.mDisplayFreezeTime);
|
||||
// We are assuming the hosting process is dead or in a zombie state.
|
||||
Slog.w(TAG, "Failed to report 'resized' to the client of " + this
|
||||
+ ", removing this window.");
|
||||
mWmService.mPendingRemove.add(this);
|
||||
mWmService.mWindowPlacerLocked.requestTraversal();
|
||||
Slog.w(TAG, "Failed to report 'resized' to " + this + " due to " + e);
|
||||
}
|
||||
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
|
||||
}
|
||||
|
||||
@@ -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.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.never;
|
||||
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.verify;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
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.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
@@ -65,6 +69,7 @@ import android.graphics.Insets;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.Size;
|
||||
import android.view.DisplayCutout;
|
||||
@@ -569,6 +574,36 @@ public class WindowStateTests extends WindowTestsBase {
|
||||
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
|
||||
public void testGetTransformationMatrix() {
|
||||
final int PARENT_WINDOW_OFFSET = 1;
|
||||
|
||||
Reference in New Issue
Block a user