Merge changes I7261cf87,Icabfcf47,I09e6b032,I252cf139,If85ade73, ... into nyc-dev
* changes:
Revert "Death to synchronous transactions (2/2)"
Fix a few weird state issues from race-conditions
Fix lifecycle bug in when calling positionTask
Animation fixes when task is not resumed
Keep stack from mReuseTask
Final fixes for growing recents transition
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 6115aa8..2ec180d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -202,8 +202,8 @@
* Handles dragging touch events
*/
private void handleTouchEvent(MotionEvent ev) {
- int action = ev.getAction();
- switch (action & MotionEvent.ACTION_MASK) {
+ int action = ev.getActionMasked();
+ switch (action) {
case MotionEvent.ACTION_DOWN:
mDownPos.set((int) ev.getX(), (int) ev.getY());
break;
@@ -258,7 +258,7 @@
case MotionEvent.ACTION_CANCEL: {
if (mDragRequested) {
EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView,
- mLastDropTarget));
+ action == MotionEvent.ACTION_UP ? mLastDropTarget : null));
break;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b043311..06d6430 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -116,6 +116,7 @@
import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
import android.util.EventLog;
+import android.util.Log;
import android.util.Slog;
import android.view.Display;
@@ -3431,8 +3432,10 @@
mWindowManager.prepareAppTransition(transit, false);
mWindowManager.setAppVisibility(r.appToken, false);
mWindowManager.executeAppTransition();
+ mStackSupervisor.mWaitingVisibleActivities.add(r);
}
- return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
+ return finishCurrentActivityLocked(r,
+ r.visible ? FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
}
@@ -5023,10 +5026,20 @@
}
void positionTask(final TaskRecord task, int position) {
+ final ActivityRecord topRunningActivity = task.topRunningActivityLocked();
+ final boolean wasResumed = topRunningActivity == task.stack.mResumedActivity;
final ActivityStack prevStack = preAddTask(task, "positionTask");
task.stack = this;
insertTaskAtPosition(task, position);
postAddTask(task, prevStack);
+ if (wasResumed) {
+ if (mResumedActivity != null) {
+ Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from"
+ + " other stack to this stack mResumedActivity=" + mResumedActivity
+ + " other mResumedActivity=" + topRunningActivity);
+ }
+ mResumedActivity = topRunningActivity;
+ }
}
private ActivityStack preAddTask(TaskRecord task, String reason) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 4da6976..6622b34 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -527,8 +527,13 @@
doPendingActivityLaunchesLocked(false);
- err = startActivityUnchecked(
- r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);
+ try {
+ mService.mWindowManager.deferSurfaceLayout();
+ err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
+ true, options, inTask);
+ } finally {
+ mService.mWindowManager.continueSurfaceLayout();
+ }
postStartActivityUncheckedProcessing(r, err, stack.mStackId);
return err;
}
@@ -1853,6 +1858,12 @@
private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
ActivityOptions aOptions) {
+
+ // We are reusing a task, keep the stack!
+ if (mReuseTask != null) {
+ return mReuseTask.stack;
+ }
+
final int launchStackId =
(aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 11b01cc..9199d10 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -1914,6 +1914,14 @@
setAppTransition(transit);
}
}
+ if (transit != TRANSIT_DOCK_TASK_FROM_RECENTS
+ && mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+
+ // Somebody is trying to start another transition while we are waiting for the docking
+ // window to be drawn. Because TRANSIT_DOCK_TASK_FROM_RECENTS starts prolonged
+ // animations, we need to override it or our prolonged animations will never be ended.
+ setAppTransition(transit);
+ }
boolean prepared = prepare();
if (isTransitionSet()) {
mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index aae52e8..abb1bb1 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -433,7 +433,7 @@
WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + winAnimator);
winAnimator.performShowLocked();
- isAnimating |= winAnimator.isAnimating();
+ isAnimating |= winAnimator.isAnimationSet();
}
return isAnimating;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 545b9db..9f54b53 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -204,7 +204,7 @@
if (DEBUG_VISIBILITY) {
Slog.v(TAG, "Win " + win + ": isDrawn="
+ win.isDrawnLw()
- + ", isAnimating=" + win.mWinAnimator.isAnimating());
+ + ", isAnimationSet=" + win.mWinAnimator.isAnimationSet());
if (!win.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s=" +
win.mWinAnimator.mSurfaceController
@@ -220,11 +220,11 @@
numInteresting++;
if (win.isDrawnLw()) {
numDrawn++;
- if (!win.mWinAnimator.isAnimating()) {
+ if (!win.mWinAnimator.isAnimationSet()) {
numVisible++;
}
nowGone = false;
- } else if (win.mWinAnimator.isAnimating()) {
+ } else if (win.mWinAnimator.isAnimationSet()) {
nowGone = false;
}
}
@@ -297,7 +297,7 @@
// Return true so that the alpha doesn't get cleared.
if (!win.mAppFreezing
&& (win.mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface
- || (win.mWinAnimator.isAnimating()
+ || (win.mWinAnimator.isAnimationSet()
&& !service.mAppTransition.isTransitionSet()))
&& !win.mDestroying
&& win.isDrawnLw()) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4f49eed..6925fa5 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -601,7 +601,7 @@
// Anyway we don't need to synchronize position and content updates for these
// windows since they aren't at the base layer and could be moved around anyway.
if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
- !mStack.getBoundsAnimating()) {
+ !mStack.getBoundsAnimating() && !win.isGoneForLayoutLw()) {
win.mResizedWhileNotDragResizing = true;
}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index af8875c..00de7e4 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -41,7 +41,6 @@
import android.util.SparseArray;
import android.view.DisplayInfo;
import android.view.Surface;
-import android.view.animation.PathInterpolator;
import android.view.SurfaceControl;
import com.android.internal.policy.DividerSnapAlgorithm;
@@ -502,7 +501,7 @@
final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
- if (winAnimator.isAnimating() || winAnimator.mWin.mAnimatingExit) {
+ if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
return true;
}
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index e44b0f3..88028be 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -146,7 +146,7 @@
}
boolean isWallpaperTargetAnimating() {
- return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+ return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimationSet()
&& !mWallpaperTarget.mWinAnimator.isDummyAnimation();
}
@@ -516,7 +516,7 @@
if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
result.setWallpaperTarget(w, i);
- if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
+ if (w == mWallpaperTarget && w.mWinAnimator.isAnimationSet()) {
// The current wallpaper target is animating, so we'll look behind it for
// another possible target and figure out what is going on later.
if (DEBUG_WALLPAPER) Slog.v(TAG,
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 6bc633f..eae7838 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -670,6 +670,7 @@
if (SHOW_TRANSACTIONS) Slog.i(
TAG, ">>> OPEN TRANSACTION animateLocked");
SurfaceControl.openTransaction();
+ SurfaceControl.setAnimationTransaction();
try {
final int numDisplays = mDisplayContentsAnimators.size();
for (int i = 0; i < numDisplays; i++) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 59b0a00..ff63632 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -120,7 +120,6 @@
import android.view.WindowManagerPolicy.PointerEventListener;
import android.view.animation.Animation;
import android.view.inputmethod.InputMethodManagerInternal;
-import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.app.IAssistScreenshotReceiver;
@@ -1526,7 +1525,7 @@
if (highestTarget != null) {
if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, mAppTransition + " " + highestTarget
- + " animating=" + highestTarget.mWinAnimator.isAnimating()
+ + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
+ " layer=" + highestTarget.mWinAnimator.mAnimLayer
+ " new layer=" + w.mWinAnimator.mAnimLayer);
@@ -1536,7 +1535,7 @@
mInputMethodTargetWaitingAnim = true;
mInputMethodTarget = highestTarget;
return highestPos + 1;
- } else if (highestTarget.mWinAnimator.isAnimating() &&
+ } else if (highestTarget.mWinAnimator.isAnimationSet() &&
highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
// If the window we are currently targeting is involved
// with an animation, and it is on top of the next target
@@ -2276,7 +2275,7 @@
+ " mRemoveOnExit=" + win.mRemoveOnExit
+ " mHasSurface=" + win.mHasSurface
+ " surfaceShowing=" + win.mWinAnimator.getShown()
- + " isAnimating=" + win.mWinAnimator.isAnimating()
+ + " isAnimationSet=" + win.mWinAnimator.isAnimationSet()
+ " app-animation="
+ (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
+ " mWillReplaceWindow=" + win.mWillReplaceWindow
@@ -2340,7 +2339,7 @@
}
}
final boolean isAnimating =
- winAnimator.isAnimating() && !winAnimator.isDummyAnimation();
+ winAnimator.isAnimationSet() && !winAnimator.isDummyAnimation();
final boolean lastWindowIsStartingWindow = startingWindow && appToken != null
&& appToken.allAppWindows.size() == 1;
// We delay the removal of a window if it has a showing surface that can be used to run
@@ -2925,7 +2924,7 @@
focusMayChange = isDefaultDisplay;
win.mAnimatingExit = true;
win.mWinAnimator.mAnimating = true;
- } else if (win.mWinAnimator.isAnimating()) {
+ } else if (win.mWinAnimator.isAnimationSet()) {
// Currently in a hide animation... turn this into
// an exit.
win.mAnimatingExit = true;
@@ -3282,7 +3281,7 @@
WindowState win = wtoken.windows.get(i);
displayContent = win.getDisplayContent();
- if (win.mWinAnimator.isAnimating()) {
+ if (win.mWinAnimator.isAnimationSet()) {
delayed = true;
}
@@ -4298,7 +4297,7 @@
}
for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
- if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
+ if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimationSet()) {
delayed = true;
}
}
@@ -9105,7 +9104,7 @@
void updateResizingWindows(final WindowState w) {
final WindowStateAnimator winAnimator = w.mWinAnimator;
- if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
+ if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq && !w.isGoneForLayoutLw()) {
w.setInsetsChanged();
boolean configChanged = w.isConfigChanged();
if (DEBUG_CONFIGURATION && configChanged) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8c29c9b..f603995 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -291,21 +291,33 @@
}
}
- /** Is the window or its container currently animating? */
- boolean isAnimating() {
+ /**
+ * Is the window or its container currently set to animate or currently animating?
+ */
+ boolean isAnimationSet() {
return mAnimation != null
|| (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
|| (mAppAnimator != null && mAppAnimator.isAnimating());
}
+ /**
+ * @return whether an animation is about to start, i.e. the animation is set already but we
+ * haven't processed the first frame yet.
+ */
+ boolean isAnimationStarting() {
+ return isAnimationSet() && !mAnimating;
+ }
+
/** Is the window animating the DummyAnimation? */
boolean isDummyAnimation() {
return mAppAnimator != null
&& mAppAnimator.animation == sDummyAnimation;
}
- /** Is this window currently set to animate or currently animating? */
- boolean isWindowAnimating() {
+ /**
+ * Is this window currently set to animate or currently animating?
+ */
+ boolean isWindowAnimationSet() {
return mAnimation != null;
}
@@ -340,7 +352,7 @@
// there is more animation to run.
boolean stepAnimationLocked(long currentTime) {
// Save the animation state as it was before this step so WindowManagerService can tell if
- // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
+ // we just started or just stopped animating by comparing mWasAnimating with isAnimationSet().
mWasAnimating = mAnimating;
final DisplayContent displayContent = mWin.getDisplayContent();
if (displayContent != null && mService.okToDisplay()) {
@@ -402,7 +414,7 @@
// Little trick to get through the path below to act like
// we have finished an animation.
mAnimating = true;
- } else if (isAnimating()) {
+ } else if (isAnimationSet()) {
mAnimating = true;
}
} else if (mAnimation != null) {
@@ -476,7 +488,7 @@
TAG, "finishExit in " + this
+ ": exiting=" + mWin.mAnimatingExit
+ " remove=" + mWin.mRemoveOnExit
- + " windowAnimating=" + isWindowAnimating());
+ + " windowAnimating=" + isWindowAnimationSet());
if (!mWin.mChildWindows.isEmpty()) {
// Copying to a different list as multiple children can be removed.
@@ -499,7 +511,7 @@
}
}
- if (!isWindowAnimating()) {
+ if (!isWindowAnimationSet()) {
//TODO (multidisplay): Accessibility is supported only for the default display.
if (mService.mAccessibilityController != null
&& mWin.getDisplayId() == DEFAULT_DISPLAY) {
@@ -511,7 +523,7 @@
return;
}
- if (isWindowAnimating()) {
+ if (isWindowAnimationSet()) {
return;
}
@@ -1310,7 +1322,7 @@
final int stackClip = resolveStackClip();
// It's animating and we don't want to clip it to stack bounds during animation - abort.
- if (isAnimating() && stackClip == STACK_CLIP_NONE) {
+ if (isAnimationSet() && stackClip == STACK_CLIP_NONE) {
return;
}
@@ -1332,7 +1344,7 @@
// If we are animating, we either apply the clip before applying all the animation
// transformation or after all the transformation.
- final boolean useFinalClipRect = isAnimating() && stackClip == STACK_CLIP_AFTER_ANIM;
+ final boolean useFinalClipRect = isAnimationSet() && stackClip == STACK_CLIP_AFTER_ANIM;
// We need to do some acrobatics with surface position, because their clip region is
// relative to the inside of the surface, but the stack bounds aren't.
@@ -1507,7 +1519,7 @@
w.mToken.hasVisible = true;
}
} else {
- if (DEBUG_ANIM && isAnimating()) {
+ if (DEBUG_ANIM && isAnimationSet()) {
Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
}
displayed = true;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 928fcc0..8937f09 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -10,7 +10,6 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
@@ -762,13 +761,15 @@
}
}
}
- if (!winAnimator.isAnimating()) {
+ if (!winAnimator.isAnimationStarting()) {
// Updates the shown frame before we set up the surface. This is needed
// because the resizing could change the top-left position (in addition to
// size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
- // position the surface. We only apply it to windows that aren't animating,
- // because we depend on the animation to calculate the correct shown frame
- // on the next animation step.
+ // position the surface.
+ //
+ // If an animation is being started, we can't call this method because the
+ // animation hasn't processed its initial transformation yet, but in general
+ // we do want to update the position if the window is animating.
winAnimator.computeShownFrameLocked();
}
winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
@@ -792,7 +793,7 @@
if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Slog.v(TAG, "Eval win " + w + ": isDrawn="
+ w.isDrawnLw()
- + ", isAnimating=" + winAnimator.isAnimating());
+ + ", isAnimationSet=" + winAnimator.isAnimationSet());
if (!w.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s="
+ winAnimator.mSurfaceController
@@ -943,7 +944,8 @@
// windows, since that means "perform layout as normal,
// just don't display").
if (!gone || !win.mHaveFrame || win.mLayoutNeeded
- || ((win.isConfigChanged() || win.setInsetsChanged()) &&
+ || ((win.isConfigChanged() || win.setInsetsChanged())
+ && !win.isGoneForLayoutLw() &&
((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
(win.mHasSurface && win.mAppToken != null &&
win.mAppToken.layoutConfigChanges)))) {