Merge "Move animation step from layout to animator."
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index e65d5d2..0934ddb 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -14,6 +14,7 @@
import android.os.SystemClock;
import android.util.Log;
import android.util.Slog;
+import android.view.Choreographer;
import android.view.Surface;
import android.view.WindowManager;
import android.view.WindowManagerPolicy;
@@ -35,6 +36,8 @@
final Context mContext;
final WindowManagerPolicy mPolicy;
+ final Choreographer mChoreographer = Choreographer.getInstance();
+
ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
boolean mAnimating;
@@ -50,6 +53,18 @@
}
InnerLoopParams mInner = new InnerLoopParams();
+ static class LayoutToAnimatorParams {
+ boolean mAnimationScheduled;
+ ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
+ WindowState mWallpaperTarget;
+ }
+ /** Params from WindowManagerService. Do not modify or read without first locking on
+ * either WindowManagerService.mWindowMap or WindowManagerService.mAnimator.and then on
+ * mLayoutToAnim */
+ final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams();
+
+ final Runnable mAnimationRunnable;
+
int mAdjResult;
int mPendingLayoutChanges;
@@ -86,11 +101,48 @@
static final int WALLPAPER_ACTION_PENDING = 1;
int mPendingActions;
+ WindowState mWallpaperTarget = null;
+
WindowAnimator(final WindowManagerService service, final Context context,
final WindowManagerPolicy policy) {
mService = service;
mContext = context;
mPolicy = policy;
+
+ mAnimationRunnable = new Runnable() {
+ @Override
+ public void run() {
+ // TODO(cmautner): When full isolation is achieved for animation, the first lock
+ // goes away and only the WindowAnimator.this remains.
+ synchronized(mService.mWindowMap) {
+ synchronized(WindowAnimator.this) {
+ copyLayoutToAnimParamsLocked();
+ animateLocked();
+ }
+ }
+ }
+ };
+ }
+
+ /** Copy all WindowManagerService params into local params here. Locked on 'this'. */
+ private void copyLayoutToAnimParamsLocked() {
+ final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
+ synchronized(layoutToAnim) {
+ layoutToAnim.mAnimationScheduled = false;
+
+ mWinAnimators = new ArrayList<WindowStateAnimator>(layoutToAnim.mWinAnimators);
+ mWallpaperTarget = layoutToAnim.mWallpaperTarget;
+ }
+ }
+
+ /** Note that Locked in this case is on mLayoutToAnim */
+ void scheduleAnimationLocked() {
+ final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
+ if (!layoutToAnim.mAnimationScheduled) {
+ layoutToAnim.mAnimationScheduled = true;
+ mChoreographer.postCallback(
+ Choreographer.CALLBACK_ANIMATION, mAnimationRunnable, null);
+ }
}
void hideWallpapersLocked(final WindowState w) {
@@ -128,11 +180,11 @@
if (mService.mWallpaperTarget == target
|| mService.mLowerWallpaperTarget == target
|| mService.mUpperWallpaperTarget == target) {
- final int N = mService.mWindows.size();
+ final int N = mWinAnimators.size();
for (int i = 0; i < N; i++) {
- WindowState w = mService.mWindows.get(i);
- if (w.mIsWallpaper) {
- target = w;
+ WindowStateAnimator winAnimator = mWinAnimators.get(i);
+ if (winAnimator.mWin.mIsWallpaper) {
+ target = winAnimator.mWin;
break;
}
}
@@ -479,7 +531,9 @@
}
}
- synchronized void animate() {
+ // TODO(cmautner): Change the following comment when no longer locked on mWindowMap */
+ /** Locked on mService.mWindowMap and this. */
+ private void animateLocked() {
mPendingLayoutChanges = 0;
mCurrentTime = SystemClock.uptimeMillis();
mBulkUpdateParams = 0;
@@ -546,7 +600,9 @@
}
if (mAnimating) {
- mService.scheduleAnimationLocked();
+ synchronized (mLayoutToAnim) {
+ scheduleAnimationLocked();
+ }
} else if (wasAnimating) {
mService.requestTraversalLocked();
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0ffb510..60ddf05 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -655,33 +655,6 @@
/** Only do a maximum of 6 repeated layouts. After that quit */
private int mLayoutRepeatCount;
- private final class AnimationRunnable implements Runnable {
- @Override
- public void run() {
- synchronized(mWindowMap) {
- mAnimationScheduled = false;
- // Update animations of all applications, including those
- // associated with exiting/removed apps
- synchronized (mAnimator) {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmAnimate");
- final ArrayList<WindowStateAnimator> winAnimators = mAnimator.mWinAnimators;
- winAnimators.clear();
- final int N = mWindows.size();
- for (int i = 0; i < N; i++) {
- final WindowStateAnimator winAnimator = mWindows.get(i).mWinAnimator;
- if (winAnimator.mSurface != null) {
- winAnimators.add(winAnimator);
- }
- }
- mAnimator.animate();
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
- }
- }
- }
- }
- final AnimationRunnable mAnimationRunnable = new AnimationRunnable();
- boolean mAnimationScheduled;
-
final WindowAnimator mAnimator;
final class DragInputEventReceiver extends InputEventReceiver {
@@ -7155,18 +7128,23 @@
}
case FORCE_GC: {
- synchronized(mWindowMap) {
- if (mAnimationScheduled) {
- // If we are animating, don't do the gc now but
- // delay a bit so we don't interrupt the animation.
- mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
- 2000);
- return;
- }
- // If we are currently rotating the display, it will
- // schedule a new message when done.
- if (mDisplayFrozen) {
- return;
+ synchronized (mWindowMap) {
+ synchronized (mAnimator) {
+ // Since we're holding both mWindowMap and mAnimator we don't need to
+ // hold mAnimator.mLayoutToAnim.
+ if (mAnimator.mAnimating ||
+ mAnimator.mLayoutToAnim.mAnimationScheduled) {
+ // If we are animating, don't do the gc now but
+ // delay a bit so we don't interrupt the animation.
+ mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
+ 2000);
+ return;
+ }
+ // If we are currently rotating the display, it will
+ // schedule a new message when done.
+ if (mDisplayFrozen) {
+ return;
+ }
}
}
Runtime.getRuntime().gc();
@@ -8960,9 +8938,20 @@
}
void scheduleAnimationLocked() {
- if (!mAnimationScheduled) {
- mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationRunnable, null);
- mAnimationScheduled = true;
+ final WindowAnimator.LayoutToAnimatorParams layoutToAnim = mAnimator.mLayoutToAnim;
+ synchronized (layoutToAnim) {
+ // Copy local params to transfer params.
+ ArrayList<WindowStateAnimator> winAnimators = layoutToAnim.mWinAnimators;
+ winAnimators.clear();
+ final int N = mWindows.size();
+ for (int i = 0; i < N; i++) {
+ final WindowStateAnimator winAnimator = mWindows.get(i).mWinAnimator;
+ if (winAnimator.mSurface != null) {
+ winAnimators.add(winAnimator);
+ }
+ }
+ layoutToAnim.mWallpaperTarget = mWallpaperTarget;
+ mAnimator.scheduleAnimationLocked();
}
}