summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2020-03-31 21:41:18 +0800
committer Riddle Hsu <riddlehsu@google.com> 2020-04-03 14:59:12 +0000
commit839b5f55f9d985b1abfac608df7928d713b51ce5 (patch)
tree0eac1da87cd290b542c472f8dd9e01dc6de294b1
parent07217a0dacee26bee0e8933d81dfee877999ced0 (diff)
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
-rw-r--r--data/etc/services.core.protolog.json24
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java35
4 files changed, 58 insertions, 31 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index a871047a0602..852af47dacea 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -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",
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b1f22f8623d6..56bb19f6e26c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -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;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 016277c0c37d..c3a740791caf 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -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);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index e95ccab38960..aac10052b894 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -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;
@@ -570,6 +575,36 @@ public class WindowStateTests extends WindowTestsBase {
}
@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;
final int DISPLAY_IN_PARENT_WINDOW_OFFSET = 2;