Switched DisplayContent to use WindowContainer
Bug: 30060889
Test: Manual testing and existing tests still pass.
Change-Id: I99f2e38da417f62e8aa65bb6582aba53fd528c1b
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4fc3ab0..1c83a9b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -20,9 +20,11 @@
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_TOP;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
@@ -32,6 +34,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
@@ -53,7 +56,6 @@
import android.view.DisplayInfo;
import android.view.IWindow;
import android.view.Surface;
-import android.view.animation.Animation;
import com.android.internal.util.FastPrintWriter;
import java.io.FileDescriptor;
@@ -73,7 +75,7 @@
* IMPORTANT: No method from this class should ever be used without holding
* WindowManagerService.mWindowMap.
*/
-class DisplayContent {
+class DisplayContent extends WindowContainer<TaskStack> {
/** Unique identifier of this stack. */
private final int mDisplayId;
@@ -104,10 +106,6 @@
/** Window tokens that are in the process of exiting, but still on screen for animations. */
final ArrayList<WindowToken> mExitingTokens = new ArrayList<>();
- /** Array containing all TaskStacks on this display. Array
- * is stored in display order with the current bottom stack at 0. */
- private final ArrayList<TaskStack> mStacks = new ArrayList<>();
-
/** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack
* (except a future lockscreen TaskStack) moves to the top. */
private TaskStack mHomeStack = null;
@@ -193,10 +191,6 @@
return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0;
}
- ArrayList<TaskStack> getStacks() {
- return mStacks;
- }
-
TaskStack getHomeStack() {
if (mHomeStack == null && mDisplayId == Display.DEFAULT_DISPLAY) {
Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
@@ -205,8 +199,8 @@
}
TaskStack getStackById(int stackId) {
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
if (stack.mStackId == stackId) {
return stack;
}
@@ -223,8 +217,8 @@
getDockedDividerController().onConfigurationChanged();
- for (int i = 0; i < mStacks.size(); i++) {
- final TaskStack stack = mStacks.get(i);
+ for (int i = 0; i < mChildren.size(); i++) {
+ final TaskStack stack = mChildren.get(i);
if (stack.onConfigurationChanged()) {
changedStackList.add(stack.mStackId);
}
@@ -232,39 +226,23 @@
}
void checkAppWindowsReadyToShow() {
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
- stack.checkAppWindowsReadyToShow(mDisplayId);
- }
+ super.checkAppWindowsReadyToShow(mDisplayId);
}
void updateAllDrawn() {
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
- stack.updateAllDrawn(mDisplayId);
- }
+ super.updateAllDrawn(mDisplayId);
}
void stepAppWindowsAnimation(long currentTime) {
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
- stack.stepAppWindowsAnimation(currentTime, mDisplayId);
- }
+ super.stepAppWindowsAnimation(currentTime, mDisplayId);
}
void onAppTransitionDone() {
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
- stack.onAppTransitionDone();
- }
-
+ super.onAppTransitionDone();
rebuildAppWindowList();
}
int getOrientation() {
- // TODO: Most of the logic here can be removed once this class is converted to use
- // WindowContainer which has an abstract implementation of getOrientation that
- // should cover this.
if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
|| mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
// Apps and their containers are not allowed to specify an orientation while the docked
@@ -280,23 +258,11 @@
return SCREEN_ORIENTATION_UNSPECIFIED;
}
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
- if (!stack.isVisible()) {
- continue;
- }
-
- final int orientation = stack.getOrientation();
-
- if (orientation == SCREEN_ORIENTATION_BEHIND) {
- continue;
- }
-
- if (orientation != SCREEN_ORIENTATION_UNSET) {
- if (stack.fillsParent() || orientation != SCREEN_ORIENTATION_UNSPECIFIED) {
- return orientation;
- }
- }
+ final int orientation = super.getOrientation();
+ if (orientation != SCREEN_ORIENTATION_UNSET) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+ "App is requesting an orientation, return " + orientation);
+ return orientation;
}
if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
@@ -309,8 +275,8 @@
void updateDisplayInfo() {
mDisplay.getDisplayInfo(mDisplayInfo);
mDisplay.getMetrics(mDisplayMetrics);
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- mStacks.get(i).updateDisplayInfo(null);
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ mChildren.get(i).updateDisplayInfo(null);
}
}
@@ -356,11 +322,7 @@
}
mHomeStack = stack;
}
- if (onTop) {
- mStacks.add(stack);
- } else {
- mStacks.add(0, stack);
- }
+ addChild(stack, onTop ? mChildren.size() : 0);
layoutNeeded = true;
}
@@ -371,11 +333,12 @@
return;
}
- if (!mStacks.remove(stack)) {
+ if (!mChildren.contains(stack)) {
Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable());
}
+ removeChild(stack);
- int addIndex = toTop ? mStacks.size() : 0;
+ int addIndex = toTop ? mChildren.size() : 0;
if (toTop
&& mService.isStackVisibleLocked(PINNED_STACK_ID)
@@ -383,30 +346,12 @@
// The pinned stack is always the top most stack (always-on-top) when it is visible.
// So, stack is moved just below the pinned stack.
addIndex--;
- TaskStack topStack = mStacks.get(addIndex);
+ TaskStack topStack = mChildren.get(addIndex);
if (topStack.mStackId != PINNED_STACK_ID) {
- throw new IllegalStateException("Pinned stack isn't top stack??? " + mStacks);
+ throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren);
}
}
- mStacks.add(addIndex, stack);
- }
-
- // TODO: Don't forget to switch to WC.removeChild
- void detachChild(TaskStack stack) {
- detachStack(stack);
- if (stack.detachFromDisplay()) {
- mService.mWindowPlacerLocked.requestTraversal();
- }
- if (stack.mStackId == DOCKED_STACK_ID) {
- mService.getDefaultDisplayContentLocked().mDividerControllerLocked
- .notifyDockedStackExistsChanged(false);
- }
- }
-
- // TODO: See about removing this by untangling the use case in WMS.attachStack()
- void detachStack(TaskStack stack) {
- mDimLayerController.removeDimLayerUser(stack);
- mStacks.remove(stack);
+ addChild(stack, addIndex);
}
/**
@@ -418,8 +363,8 @@
}
int taskIdFromPoint(int x, int y) {
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = mStacks.get(stackNdx);
+ for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) {
+ final TaskStack stack = mChildren.get(stackNdx);
final int taskId = stack.taskIdFromPoint(x, y);
if (taskId != -1) {
return taskId;
@@ -435,8 +380,8 @@
Task findTaskForResizePoint(int x, int y) {
final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
mTmpTaskForResizePointSearchResult.reset();
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- TaskStack stack = mStacks.get(stackNdx);
+ for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) {
+ TaskStack stack = mChildren.get(stackNdx);
if (!StackId.isTaskResizeAllowed(stack.mStackId)) {
return null;
}
@@ -453,8 +398,8 @@
mTouchExcludeRegion.set(mBaseDisplayRect);
final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
mTmpRect2.setEmpty();
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = mStacks.get(stackNdx);
+ for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) {
+ final TaskStack stack = mChildren.get(stackNdx);
stack.setTouchExcludeRegion(
focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2);
}
@@ -498,16 +443,16 @@
}
}
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).switchUser();
+ for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) {
+ mChildren.get(stackNdx).switchUser();
}
rebuildAppWindowList();
}
void resetAnimationBackgroundAnimator() {
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).resetAnimationBackgroundAnimator();
+ for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) {
+ mChildren.get(stackNdx).resetAnimationBackgroundAnimator();
}
}
@@ -527,37 +472,142 @@
mDimLayerController.stopDimmingIfNeeded();
}
- void close() {
- mDimLayerController.close();
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).close();
+ @Override
+ void removeIfPossible() {
+ if (isAnimating()) {
+ mDeferredRemoval = true;
+ return;
}
+ removeImmediately();
}
- boolean isAnimating() {
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = mStacks.get(stackNdx);
- if (stack.isAnimating()) {
- return true;
- }
+ @Override
+ void removeImmediately() {
+ super.removeImmediately();
+ if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
+ mService.mDisplayContents.delete(mDisplayId);
+ mDimLayerController.close();
+ if (mDisplayId == Display.DEFAULT_DISPLAY) {
+ mService.unregisterPointerEventListener(mTapDetector);
+ mService.unregisterPointerEventListener(mService.mMousePositionTracker);
}
- return false;
}
/** Returns true if a removal action is still being deferred. */
+ @Override
boolean checkCompleteDeferredRemoval() {
- boolean stillDeferringRemoval = false;
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = mStacks.get(stackNdx);
- stillDeferringRemoval |= stack.checkCompleteDeferredRemoval();
- }
+ final boolean stillDeferringRemoval = super.checkCompleteDeferredRemoval();
+
if (!stillDeferringRemoval && mDeferredRemoval) {
+ removeImmediately();
mService.onDisplayRemoved(mDisplayId);
return false;
}
return true;
}
+ boolean animateForIme(float interpolatedValue, float animationTarget,
+ float dividerAnimationTarget) {
+ boolean updated = false;
+
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
+ if (stack == null || !stack.isAdjustedForIme()) {
+ continue;
+ }
+
+ if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
+ stack.resetAdjustedForIme(true /* adjustBoundsNow */);
+ updated = true;
+ } else {
+ mDividerControllerLocked.mLastAnimationProgress =
+ mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
+ mDividerControllerLocked.mLastDividerProgress =
+ mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
+ updated |= stack.updateAdjustForIme(
+ mDividerControllerLocked.mLastAnimationProgress,
+ mDividerControllerLocked.mLastDividerProgress,
+ false /* force */);
+ }
+ if (interpolatedValue >= 1f) {
+ stack.endImeAdjustAnimation();
+ }
+ }
+
+ return updated;
+ }
+
+ boolean clearImeAdjustAnimation() {
+ boolean changed = false;
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
+ if (stack != null && stack.isAdjustedForIme()) {
+ stack.resetAdjustedForIme(true /* adjustBoundsNow */);
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ void beginImeAdjustAnimation() {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
+ if (stack.isVisible() && stack.isAdjustedForIme()) {
+ stack.beginImeAdjustAnimation();
+ }
+ }
+ }
+
+ void adjustForImeIfNeeded() {
+ final WindowState imeWin = mService.mInputMethodWindow;
+ final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
+ && !mDividerControllerLocked.isImeHideRequested();
+ final boolean dockVisible = mService.isStackVisibleLocked(DOCKED_STACK_ID);
+ final TaskStack imeTargetStack = mService.getImeFocusStackLocked();
+ final int imeDockSide = (dockVisible && imeTargetStack != null) ?
+ imeTargetStack.getDockSide() : DOCKED_INVALID;
+ final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
+ final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
+ final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock();
+ final int imeHeight = mService.mPolicy.getInputMethodWindowVisibleHeightLw();
+ final boolean imeHeightChanged = imeVisible &&
+ imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
+
+ // The divider could be adjusted for IME position, or be thinner than usual,
+ // or both. There are three possible cases:
+ // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
+ // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
+ // - If IME is not visible, divider is not moved and is normal width.
+
+ if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
+ final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
+ if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
+ stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
+ } else {
+ stack.resetAdjustedForIme(false);
+ }
+ }
+ mDividerControllerLocked.setAdjustedForIme(
+ imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
+ } else {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
+ stack.resetAdjustedForIme(!dockVisible);
+ }
+ mDividerControllerLocked.setAdjustedForIme(
+ false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
+ }
+ }
+
+ void prepareFreezingTaskBounds() {
+ for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) {
+ final TaskStack stack = mChildren.get(stackNdx);
+ stack.prepareFreezingTaskBounds();
+ }
+ }
+
void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
final int rotationDelta = DisplayContent.deltaRotation(oldRotation, newRotation);
getLogicalDisplayRect(mTmpRect);
@@ -624,8 +674,8 @@
pw.println();
pw.println(" Application tokens in top down Z order:");
- for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = mStacks.get(stackNdx);
+ for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) {
+ final TaskStack stack = mChildren.get(stackNdx);
stack.dump(prefix + " ", pw);
}
@@ -649,7 +699,7 @@
@Override
public String toString() {
- return getName() + " stacks=" + mStacks;
+ return getName() + " stacks=" + mChildren;
}
String getName() {
@@ -706,15 +756,6 @@
return touchedWin;
}
- /**
- * See {@link WindowManagerService#overridePlayingAppAnimationsLw}.
- */
- void overridePlayingAppAnimationsLw(Animation a) {
- for (int i = mStacks.size() - 1; i >= 0; i--) {
- mStacks.get(i).overridePlayingAppAnimations(a);
- }
- }
-
boolean canAddToastWindowForUid(int uid) {
// We allow one toast window per UID being shown at a time.
WindowList windows = getWindowList();
@@ -788,12 +829,7 @@
// Descend through all of the app tokens and find the first that either matches
// win.mAppToken (return win) or mFocusedApp (return null).
if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
- final TaskStack focusedAppStack = focusedApp.mTask.mStack;
- final TaskStack appStack = wtoken.mTask.mStack;
-
- // TODO: Use WindowContainer.compareTo() once everything is using WindowContainer
- if ((focusedAppStack == appStack && focusedApp.compareTo(wtoken) > 0)
- || mStacks.indexOf(focusedAppStack) > mStacks.indexOf(appStack)) {
+ if (focusedApp.compareTo(wtoken) > 0) {
// App stack below focused app stack. No focus for you!!!
if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
"findFocusedWindow: Reached focused app=" + focusedApp);
@@ -826,8 +862,8 @@
// Figure out where the window should go, based on the order of applications.
mTmpGetWindowOnDisplaySearchResult.reset();
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
if (mTmpGetWindowOnDisplaySearchResult.reachedToken) {
// We have reach the token we are interested in. End search.
@@ -858,8 +894,8 @@
// Continue looking down until we find the first token that has windows on this display.
mTmpGetWindowOnDisplaySearchResult.reset();
- for (int i = mStacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = mStacks.get(i);
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mChildren.get(i);
stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) {
// We have found a window after the token. End search.
@@ -1023,9 +1059,9 @@
// First add all of the exiting app tokens... these are no longer in the main app list,
// but still have windows shown. We put them in the back because now that the animation is
// over we no longer will care about them.
- final int numStacks = mStacks.size();
+ final int numStacks = mChildren.size();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
- AppTokenList exitingAppTokens = mStacks.get(stackNdx).mExitingAppTokens;
+ AppTokenList exitingAppTokens = mChildren.get(stackNdx).mExitingAppTokens;
int NT = exitingAppTokens.size();
for (int j = 0; j < NT; j++) {
i = exitingAppTokens.get(j).rebuildWindowList(this, i);
@@ -1034,7 +1070,7 @@
// And add in the still active app tokens in Z order.
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
- i = mStacks.get(stackNdx).rebuildWindowList(this, i);
+ i = mChildren.get(stackNdx).rebuildWindowList(this, i);
}
i -= lastBelow;
@@ -1158,24 +1194,11 @@
dumpChildrenNames(pw, " ");
}
- private void dumpChildrenNames(PrintWriter pw, String prefix) {
- final String childPrefix = prefix + prefix;
- for (int j = mStacks.size() - 1; j >= 0; j--) {
- final TaskStack stack = mStacks.get(j);
- pw.println("#" + j + " " + getName());
- stack.dumpChildrenNames(pw, childPrefix);
- }
- }
-
private void dumpWindows() {
- final int numDisplays = mService.mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
- Slog.v(TAG_WM, " Display #" + displayContent.getDisplayId());
- final WindowList windows = displayContent.getWindowList();
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
- Slog.v(TAG_WM, " #" + winNdx + ": " + windows.get(winNdx));
- }
+ Slog.v(TAG_WM, " Display #" + mDisplayId);
+ final WindowList windows = getWindowList();
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ Slog.v(TAG_WM, " #" + winNdx + ": " + windows.get(winNdx));
}
}
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index ff676e9..ef8f492 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -131,8 +131,8 @@
private boolean mAdjustedForDivider;
private float mDividerAnimationStart;
private float mDividerAnimationTarget;
- private float mLastAnimationProgress;
- private float mLastDividerProgress;
+ float mLastAnimationProgress;
+ float mLastDividerProgress;
private final DividerSnapAlgorithm[] mSnapAlgorithmForRotation = new DividerSnapAlgorithm[4];
private boolean mImeHideRequested;
@@ -594,15 +594,7 @@
}
private boolean clearImeAdjustAnimation() {
- boolean changed = false;
- final ArrayList<TaskStack> stacks = mDisplayContent.getStacks();
- for (int i = stacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = stacks.get(i);
- if (stack != null && stack.isAdjustedForIme()) {
- stack.resetAdjustedForIme(true /* adjustBoundsNow */);
- changed = true;
- }
- }
+ final boolean changed = mDisplayContent.clearImeAdjustAnimation();
mAnimatingForIme = false;
return changed;
}
@@ -634,13 +626,7 @@
mAnimationTarget = adjustedForIme ? 1 : 0;
mDividerAnimationTarget = adjustedForDivider ? 1 : 0;
- final ArrayList<TaskStack> stacks = mDisplayContent.getStacks();
- for (int i = stacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = stacks.get(i);
- if (stack.isVisible() && stack.isAdjustedForIme()) {
- stack.beginImeAdjustAnimation();
- }
- }
+ mDisplayContent.beginImeAdjustAnimation();
// We put all tasks into drag resizing mode - wait until all of them have completed the
// drag resizing switch.
@@ -721,27 +707,8 @@
float t = Math.min(1f, (float) (now - mAnimationStartTime) / mAnimationDuration);
t = (mAnimationTarget == 1f ? IME_ADJUST_ENTRY_INTERPOLATOR : TOUCH_RESPONSE_INTERPOLATOR)
.getInterpolation(t);
- final ArrayList<TaskStack> stacks = mDisplayContent.getStacks();
- boolean updated = false;
- for (int i = stacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = stacks.get(i);
- if (stack != null && stack.isAdjustedForIme()) {
- if (t >= 1f && mAnimationTarget == 0f && mDividerAnimationTarget == 0f) {
- stack.resetAdjustedForIme(true /* adjustBoundsNow */);
- updated = true;
- } else {
- mLastAnimationProgress = getInterpolatedAnimationValue(t);
- mLastDividerProgress = getInterpolatedDividerValue(t);
- updated |= stack.updateAdjustForIme(
- mLastAnimationProgress,
- mLastDividerProgress,
- false /* force */);
- }
- if (t >= 1f) {
- stack.endImeAdjustAnimation();
- }
- }
- }
+ final boolean updated =
+ mDisplayContent.animateForIme(t, mAnimationTarget, mDividerAnimationTarget);
if (updated) {
mService.mWindowPlacerLocked.performSurfacePlacement();
}
@@ -785,11 +752,11 @@
}
}
- private float getInterpolatedAnimationValue(float t) {
+ float getInterpolatedAnimationValue(float t) {
return t * mAnimationTarget + (1 - t) * mAnimationStart;
}
- private float getInterpolatedDividerValue(float t) {
+ float getInterpolatedDividerValue(float t) {
return t * mDividerAnimationTarget + (1 - t) * mDividerAnimationStart;
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index b24a06a..d6a1fae 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -110,7 +110,7 @@
/** Detach this stack from its display when animation completes. */
// TODO: maybe tie this to WindowContainer#removeChild some how...
- boolean mDeferDetach;
+ boolean mDeferRemoval;
private final Rect mTmpAdjustedBounds = new Rect();
private boolean mAdjustedForIme;
@@ -764,12 +764,34 @@
1 /*allowResizeInDockedMode*/, bounds).sendToTarget();
}
- // TODO: Should this really be removeImmidiately or removeChild?
- boolean detachFromDisplay() {
+ @Override
+ void removeIfPossible() {
+ if (isAnimating()) {
+ mDeferRemoval = true;
+ return;
+ }
+ removeImmediately();
+ }
+
+ @Override
+ void removeImmediately() {
+ super.removeImmediately();
+
+ mDisplayContent.mDimLayerController.removeDimLayerUser(this);
EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
- boolean didSomething = super.detachFromDisplay();
- close();
- return didSomething;
+
+ if (mAnimationBackgroundSurface != null) {
+ mAnimationBackgroundSurface.destroySurface();
+ mAnimationBackgroundSurface = null;
+ }
+ mDisplayContent = null;
+
+ mService.mWindowPlacerLocked.requestTraversal();
+
+ if (mStackId == DOCKED_STACK_ID) {
+ mService.getDefaultDisplayContentLocked().mDividerControllerLocked
+ .notifyDockedStackExistsChanged(false);
+ }
}
void resetAnimationBackgroundAnimator() {
@@ -801,14 +823,6 @@
}
}
- void close() {
- if (mAnimationBackgroundSurface != null) {
- mAnimationBackgroundSurface.destroySurface();
- mAnimationBackgroundSurface = null;
- }
- mDisplayContent = null;
- }
-
/**
* Adjusts the stack bounds if the IME is visible.
*
@@ -1077,7 +1091,7 @@
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "mStackId=" + mStackId);
- pw.println(prefix + "mDeferDetach=" + mDeferDetach);
+ pw.println(prefix + "mDeferRemoval=" + mDeferRemoval);
pw.println(prefix + "mFillsParent=" + mFillsParent);
pw.println(prefix + "mBounds=" + mBounds.toShortString());
if (mMinimizeAmount != 0f) {
@@ -1411,8 +1425,8 @@
if (isAnimating()) {
return true;
}
- if (mDeferDetach) {
- mDisplayContent.detachChild(this);
+ if (mDeferRemoval) {
+ removeImmediately();
}
return super.checkCompleteDeferredRemoval();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 106284a..4862265 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -187,15 +187,6 @@
}
}
- boolean detachFromDisplay() {
- boolean didSomething = false;
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final WindowContainer wc = mChildren.get(i);
- didSomething |= wc.detachFromDisplay();
- }
- return didSomething;
- }
-
void forceWindowsScaleableInTransaction(boolean force) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer wc = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a3c830a..e4f6c27 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -173,9 +173,7 @@
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_TOP;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -3153,13 +3151,8 @@
private void prepareFreezingAllTaskBounds() {
for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
- ArrayList<TaskStack> stacks = mDisplayContents.valueAt(i).getStacks();
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = stacks.get(stackNdx);
- stack.prepareFreezingTaskBounds();
- }
+ mDisplayContents.valueAt(i).prepareFreezingTaskBounds();
}
-
}
private int[] onConfigurationChanged() {
@@ -3986,10 +3979,8 @@
stack = displayContent.getStackById(stackId);
if (stack != null) {
- // It's already attached to the display. Detach and re-attach
- // because onTop might change, and be sure to clear mDeferDetach!
- displayContent.detachStack(stack);
- stack.mDeferDetach = false;
+ // It's already attached to the display...clear mDeferRemoval!
+ stack.mDeferRemoval = false;
attachedToDisplay = true;
} else {
stack = new TaskStack(this, stackId);
@@ -4023,14 +4014,7 @@
synchronized (mWindowMap) {
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack != null) {
- final DisplayContent displayContent = stack.getDisplayContent();
- if (displayContent != null) {
- if (stack.isAnimating()) {
- stack.mDeferDetach = true;
- return;
- }
- displayContent.detachChild(stack);
- }
+ stack.removeIfPossible();
}
}
}
@@ -4135,7 +4119,7 @@
@Override
public void overridePlayingAppAnimationsLw(Animation a) {
- getDefaultDisplayContentLocked().overridePlayingAppAnimationsLw(a);
+ getDefaultDisplayContentLocked().overridePlayingAppAnimations(a);
}
/**
@@ -4751,7 +4735,7 @@
hideBootMessagesLocked();
// If the screen still doesn't come up after 30 seconds, give
// up and turn it on.
- mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
+ mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000);
}
mPolicy.systemBooted();
@@ -6689,51 +6673,6 @@
}
}
- void adjustForImeIfNeeded(final DisplayContent displayContent) {
- final WindowState imeWin = mInputMethodWindow;
- final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
- && !displayContent.mDividerControllerLocked.isImeHideRequested();
- final boolean dockVisible = isStackVisibleLocked(DOCKED_STACK_ID);
- final TaskStack imeTargetStack = getImeFocusStackLocked();
- final int imeDockSide = (dockVisible && imeTargetStack != null) ?
- imeTargetStack.getDockSide() : DOCKED_INVALID;
- final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
- final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
- final boolean dockMinimized = displayContent.mDividerControllerLocked.isMinimizedDock();
- final int imeHeight = mPolicy.getInputMethodWindowVisibleHeightLw();
- final boolean imeHeightChanged = imeVisible &&
- imeHeight != displayContent.mDividerControllerLocked.getImeHeightAdjustedFor();
-
- // The divider could be adjusted for IME position, or be thinner than usual,
- // or both. There are three possible cases:
- // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
- // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
- // - If IME is not visible, divider is not moved and is normal width.
-
- if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
- final ArrayList<TaskStack> stacks = displayContent.getStacks();
- for (int i = stacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = stacks.get(i);
- final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
- if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
- stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
- } else {
- stack.resetAdjustedForIme(false);
- }
- }
- displayContent.mDividerControllerLocked.setAdjustedForIme(
- imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
- } else {
- final ArrayList<TaskStack> stacks = displayContent.getStacks();
- for (int i = stacks.size() - 1; i >= 0; --i) {
- final TaskStack stack = stacks.get(i);
- stack.resetAdjustedForIme(!dockVisible);
- }
- displayContent.mDividerControllerLocked.setAdjustedForIme(
- false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
- }
- }
-
// -------------------------------------------------------------
// Drag and drop
// -------------------------------------------------------------
@@ -7636,7 +7575,7 @@
synchronized (mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
displayContent.getDockedDividerController().reevaluateVisibility(false);
- adjustForImeIfNeeded(displayContent);
+ displayContent.adjustForImeIfNeeded();
}
}
break;
@@ -8619,7 +8558,7 @@
mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
}
- adjustForImeIfNeeded(displayContent);
+ displayContent.adjustForImeIfNeeded();
// We may need to schedule some toast windows to be removed. The
// toasts for an app that does not have input focus are removed
@@ -9753,17 +9692,7 @@
private void handleDisplayRemovedLocked(int displayId) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
- if (displayContent.isAnimating()) {
- displayContent.mDeferredRemoval = true;
- return;
- }
- if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + displayContent);
- mDisplayContents.delete(displayId);
- displayContent.close();
- if (displayId == Display.DEFAULT_DISPLAY) {
- unregisterPointerEventListener(displayContent.mTapDetector);
- unregisterPointerEventListener(mMousePositionTracker);
- }
+ displayContent.removeIfPossible();
}
mAnimator.removeDisplayLocked(displayId);
mWindowPlacerLocked.requestTraversal();
@@ -10030,7 +9959,7 @@
}
}
- private MousePositionTracker mMousePositionTracker = new MousePositionTracker();
+ MousePositionTracker mMousePositionTracker = new MousePositionTracker();
private static class MousePositionTracker implements PointerEventListener {
private boolean mLatestEventWasMouse;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 60b0d03..1c0d830 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1816,15 +1816,6 @@
Binder.restoreCallingIdentity(origId);
}
- @Override
- boolean detachFromDisplay() {
- // We are in the middle of changing the state of displays/stacks/tasks. We need
- // to finish that, before we let layout interfere with it.
- // Also removes child windows.
- removeIfPossible();
- return true;
- }
-
private void setupWindowForRemoveOnExit() {
mRemoveOnExit = true;
setDisplayLayoutNeeded();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 125368c..ce101e7 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1750,7 +1750,7 @@
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
if (mWin.mAttrs.type == TYPE_INPUT_METHOD) {
- mService.adjustForImeIfNeeded(mWin.mDisplayContent);
+ mWin.mDisplayContent.adjustForImeIfNeeded();
if (isEntrance) {
mWin.setDisplayLayoutNeeded();
mService.mWindowPlacerLocked.requestTraversal();
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 973f1b9..eb2372a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -178,25 +178,6 @@
}
@Test
- public void testDetachFromDisplay() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
- final TestWindowContainer root = builder.setLayer(0).build();
-
- final TestWindowContainer child1 = root.addChildWindow(builder.setCanDetach(true));
- final TestWindowContainer child2 = root.addChildWindow();
- final TestWindowContainer child11 = child1.addChildWindow();
- final TestWindowContainer child12 = child1.addChildWindow(builder.setCanDetach(true));
- final TestWindowContainer child21 = child2.addChildWindow();
-
- assertTrue(root.detachFromDisplay());
- assertTrue(child1.detachFromDisplay());
- assertFalse(child11.detachFromDisplay());
- assertTrue(child12.detachFromDisplay());
- assertFalse(child2.detachFromDisplay());
- assertFalse(child21.detachFromDisplay());
- }
-
- @Test
public void testIsAnimating() throws Exception {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
final TestWindowContainer root = builder.setLayer(0).build();
@@ -399,7 +380,6 @@
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
private final int mLayer;
- private final boolean mCanDetach;
private boolean mIsAnimating;
private boolean mIsVisible;
private boolean mFillsParent;
@@ -419,9 +399,8 @@
return 1;
};
- TestWindowContainer(int layer, boolean canDetach, boolean isAnimating, boolean isVisible) {
+ TestWindowContainer(int layer, boolean isAnimating, boolean isVisible) {
mLayer = layer;
- mCanDetach = canDetach;
mIsAnimating = isAnimating;
mIsVisible = isVisible;
mFillsParent = true;
@@ -455,11 +434,6 @@
}
@Override
- boolean detachFromDisplay() {
- return super.detachFromDisplay() || mCanDetach;
- }
-
- @Override
boolean isAnimating() {
return mIsAnimating || super.isAnimating();
}
@@ -481,7 +455,6 @@
private class TestWindowContainerBuilder {
private int mLayer;
- private boolean mCanDetach;
private boolean mIsAnimating;
private boolean mIsVisible;
@@ -494,11 +467,6 @@
return this;
}
- TestWindowContainerBuilder setCanDetach(boolean canDetach) {
- mCanDetach = canDetach;
- return this;
- }
-
TestWindowContainerBuilder setIsAnimating(boolean isAnimating) {
mIsAnimating = isAnimating;
return this;
@@ -511,14 +479,13 @@
TestWindowContainerBuilder reset() {
mLayer = 0;
- mCanDetach = false;
mIsAnimating = false;
mIsVisible = false;
return this;
}
TestWindowContainer build() {
- return new TestWindowContainer(mLayer, mCanDetach, mIsAnimating, mIsVisible);
+ return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible);
}
}
}