Optimize window relayouts when dragging divider
- Communicate the resize mode to ViewRootImpl. If it is a docked
divider resize, do not call relayout for every traversal.
- Do not call Task.resizeWindows() unconditionally when changing
Stack bounds. It might be just a move.
- However, not calling relayout breaks layout bounds while
relaunching. To fix that, do the following:
-- Inform ViewRootImpl that the activity just relaunched, and force
a relayout call in the next traversal so the client can pick up
the unfrozen bounds.
-- When unfreezing the bounds, cause a traversal in window manager.
Bug: 25015474
Change-Id: Iab9a445dabce4f6ec1e25957038fe40a4be65246
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 751f871..46240783 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -67,6 +67,7 @@
// Whether we're performing an entering animation with a saved surface.
boolean mAnimatingWithSavedSurface;
+
Task mTask;
boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -477,6 +478,15 @@
*/
void unfreezeBounds() {
mFrozenBounds.remove();
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState win = windows.get(i);
+ win.mLayoutNeeded = true;
+ win.setDisplayLayoutNeeded();
+ if (!service.mResizingWindows.contains(win)) {
+ service.mResizingWindows.add(win);
+ }
+ }
+ service.mWindowPlacerLocked.performSurfacePlacement();
}
@Override
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 632c033..7748c6a 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -105,12 +105,6 @@
return mTasks;
}
- void resizeWindows() {
- for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
- mTasks.get(taskNdx).resizeWindows();
- }
- }
-
/**
* Set the bounds of the stack and its containing tasks.
* @param stackBounds New stack bounds. Passing in null sets the bounds to fullscreen.
@@ -137,11 +131,11 @@
// it might no longer fully cover the stack area.
// Save the old bounds and re-apply the scroll. This adjusts the bounds to
// fit the new stack bounds.
- task.setBounds(bounds, config);
+ task.resizeLocked(bounds, config, false /* forced */);
task.getBounds(mTmpRect);
task.scrollLocked(mTmpRect);
} else {
- task.setBounds(bounds, config);
+ task.resizeLocked(bounds, config, false /* forced */);
task.setTempInsetBounds(
taskTempInsetBounds != null ? taskTempInsetBounds.get(task.mTaskId)
: null);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7d142ec..bdaa05b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2869,7 +2869,12 @@
result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
}
}
- result |= win.isDragResizing() ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0;
+ final boolean freeformResizing = win.isDragResizing()
+ && win.getResizeMode() == WindowState.DRAG_RESIZE_MODE_FREEFORM;
+ final boolean dockedResizing = win.isDragResizing()
+ && win.getResizeMode() == WindowState.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+ result |= freeformResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM : 0;
+ result |= dockedResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED : 0;
if (win.isAnimatingWithSavedSurface()) {
// If we're animating with a saved surface now, request client to report draw.
// We still need to know when the real thing is drawn.
@@ -4858,7 +4863,6 @@
}
if (stack.setBounds(bounds, configs, taskBounds, taskTempInsetBounds)
&& stack.isVisibleLocked()) {
- stack.resizeWindows();
stack.getDisplayContent().layoutNeeded = true;
mWindowPlacerLocked.performSurfacePlacement();
}