Loading services/java/com/android/server/wm/WindowAnimator.java +62 −6 Original line number Original line Diff line number Diff line Loading @@ -14,6 +14,7 @@ import android.content.Context; import android.os.SystemClock; import android.os.SystemClock; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; import android.view.Choreographer; import android.view.Surface; import android.view.Surface; import android.view.WindowManager; import android.view.WindowManager; import android.view.WindowManagerPolicy; import android.view.WindowManagerPolicy; Loading @@ -35,6 +36,8 @@ public class WindowAnimator { final Context mContext; final Context mContext; final WindowManagerPolicy mPolicy; final WindowManagerPolicy mPolicy; final Choreographer mChoreographer = Choreographer.getInstance(); ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>(); ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>(); boolean mAnimating; boolean mAnimating; Loading @@ -50,6 +53,18 @@ public class WindowAnimator { } } InnerLoopParams mInner = new InnerLoopParams(); 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 mAdjResult; int mPendingLayoutChanges; int mPendingLayoutChanges; Loading Loading @@ -86,11 +101,48 @@ public class WindowAnimator { static final int WALLPAPER_ACTION_PENDING = 1; static final int WALLPAPER_ACTION_PENDING = 1; int mPendingActions; int mPendingActions; WindowState mWallpaperTarget = null; WindowAnimator(final WindowManagerService service, final Context context, WindowAnimator(final WindowManagerService service, final Context context, final WindowManagerPolicy policy) { final WindowManagerPolicy policy) { mService = service; mService = service; mContext = context; mContext = context; mPolicy = policy; 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) { void hideWallpapersLocked(final WindowState w) { Loading Loading @@ -128,11 +180,11 @@ public class WindowAnimator { if (mService.mWallpaperTarget == target if (mService.mWallpaperTarget == target || mService.mLowerWallpaperTarget == target || mService.mLowerWallpaperTarget == target || mService.mUpperWallpaperTarget == target) { || mService.mUpperWallpaperTarget == target) { final int N = mService.mWindows.size(); final int N = mWinAnimators.size(); for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) { WindowState w = mService.mWindows.get(i); WindowStateAnimator winAnimator = mWinAnimators.get(i); if (w.mIsWallpaper) { if (winAnimator.mWin.mIsWallpaper) { target = w; target = winAnimator.mWin; break; break; } } } } Loading Loading @@ -479,7 +531,9 @@ public class WindowAnimator { } } } } 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; mPendingLayoutChanges = 0; mCurrentTime = SystemClock.uptimeMillis(); mCurrentTime = SystemClock.uptimeMillis(); mBulkUpdateParams = 0; mBulkUpdateParams = 0; Loading Loading @@ -546,7 +600,9 @@ public class WindowAnimator { } } if (mAnimating) { if (mAnimating) { mService.scheduleAnimationLocked(); synchronized (mLayoutToAnim) { scheduleAnimationLocked(); } } else if (wasAnimating) { } else if (wasAnimating) { mService.requestTraversalLocked(); mService.requestTraversalLocked(); } } Loading services/java/com/android/server/wm/WindowManagerService.java +31 −42 Original line number Original line Diff line number Diff line Loading @@ -655,33 +655,6 @@ public class WindowManagerService extends IWindowManager.Stub /** Only do a maximum of 6 repeated layouts. After that quit */ /** Only do a maximum of 6 repeated layouts. After that quit */ private int mLayoutRepeatCount; 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 WindowAnimator mAnimator; final class DragInputEventReceiver extends InputEventReceiver { final class DragInputEventReceiver extends InputEventReceiver { Loading Loading @@ -7156,7 +7129,11 @@ public class WindowManagerService extends IWindowManager.Stub case FORCE_GC: { case FORCE_GC: { synchronized (mWindowMap) { synchronized (mWindowMap) { if (mAnimationScheduled) { 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 // If we are animating, don't do the gc now but // delay a bit so we don't interrupt the animation. // delay a bit so we don't interrupt the animation. mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC), mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC), Loading @@ -7169,6 +7146,7 @@ public class WindowManagerService extends IWindowManager.Stub return; return; } } } } } Runtime.getRuntime().gc(); Runtime.getRuntime().gc(); break; break; } } Loading Loading @@ -8960,9 +8938,20 @@ public class WindowManagerService extends IWindowManager.Stub } } void scheduleAnimationLocked() { void scheduleAnimationLocked() { if (!mAnimationScheduled) { final WindowAnimator.LayoutToAnimatorParams layoutToAnim = mAnimator.mLayoutToAnim; mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationRunnable, null); synchronized (layoutToAnim) { mAnimationScheduled = true; // 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(); } } } } Loading Loading
services/java/com/android/server/wm/WindowAnimator.java +62 −6 Original line number Original line Diff line number Diff line Loading @@ -14,6 +14,7 @@ import android.content.Context; import android.os.SystemClock; import android.os.SystemClock; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; import android.view.Choreographer; import android.view.Surface; import android.view.Surface; import android.view.WindowManager; import android.view.WindowManager; import android.view.WindowManagerPolicy; import android.view.WindowManagerPolicy; Loading @@ -35,6 +36,8 @@ public class WindowAnimator { final Context mContext; final Context mContext; final WindowManagerPolicy mPolicy; final WindowManagerPolicy mPolicy; final Choreographer mChoreographer = Choreographer.getInstance(); ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>(); ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>(); boolean mAnimating; boolean mAnimating; Loading @@ -50,6 +53,18 @@ public class WindowAnimator { } } InnerLoopParams mInner = new InnerLoopParams(); 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 mAdjResult; int mPendingLayoutChanges; int mPendingLayoutChanges; Loading Loading @@ -86,11 +101,48 @@ public class WindowAnimator { static final int WALLPAPER_ACTION_PENDING = 1; static final int WALLPAPER_ACTION_PENDING = 1; int mPendingActions; int mPendingActions; WindowState mWallpaperTarget = null; WindowAnimator(final WindowManagerService service, final Context context, WindowAnimator(final WindowManagerService service, final Context context, final WindowManagerPolicy policy) { final WindowManagerPolicy policy) { mService = service; mService = service; mContext = context; mContext = context; mPolicy = policy; 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) { void hideWallpapersLocked(final WindowState w) { Loading Loading @@ -128,11 +180,11 @@ public class WindowAnimator { if (mService.mWallpaperTarget == target if (mService.mWallpaperTarget == target || mService.mLowerWallpaperTarget == target || mService.mLowerWallpaperTarget == target || mService.mUpperWallpaperTarget == target) { || mService.mUpperWallpaperTarget == target) { final int N = mService.mWindows.size(); final int N = mWinAnimators.size(); for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) { WindowState w = mService.mWindows.get(i); WindowStateAnimator winAnimator = mWinAnimators.get(i); if (w.mIsWallpaper) { if (winAnimator.mWin.mIsWallpaper) { target = w; target = winAnimator.mWin; break; break; } } } } Loading Loading @@ -479,7 +531,9 @@ public class WindowAnimator { } } } } 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; mPendingLayoutChanges = 0; mCurrentTime = SystemClock.uptimeMillis(); mCurrentTime = SystemClock.uptimeMillis(); mBulkUpdateParams = 0; mBulkUpdateParams = 0; Loading Loading @@ -546,7 +600,9 @@ public class WindowAnimator { } } if (mAnimating) { if (mAnimating) { mService.scheduleAnimationLocked(); synchronized (mLayoutToAnim) { scheduleAnimationLocked(); } } else if (wasAnimating) { } else if (wasAnimating) { mService.requestTraversalLocked(); mService.requestTraversalLocked(); } } Loading
services/java/com/android/server/wm/WindowManagerService.java +31 −42 Original line number Original line Diff line number Diff line Loading @@ -655,33 +655,6 @@ public class WindowManagerService extends IWindowManager.Stub /** Only do a maximum of 6 repeated layouts. After that quit */ /** Only do a maximum of 6 repeated layouts. After that quit */ private int mLayoutRepeatCount; 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 WindowAnimator mAnimator; final class DragInputEventReceiver extends InputEventReceiver { final class DragInputEventReceiver extends InputEventReceiver { Loading Loading @@ -7156,7 +7129,11 @@ public class WindowManagerService extends IWindowManager.Stub case FORCE_GC: { case FORCE_GC: { synchronized (mWindowMap) { synchronized (mWindowMap) { if (mAnimationScheduled) { 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 // If we are animating, don't do the gc now but // delay a bit so we don't interrupt the animation. // delay a bit so we don't interrupt the animation. mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC), mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC), Loading @@ -7169,6 +7146,7 @@ public class WindowManagerService extends IWindowManager.Stub return; return; } } } } } Runtime.getRuntime().gc(); Runtime.getRuntime().gc(); break; break; } } Loading Loading @@ -8960,9 +8938,20 @@ public class WindowManagerService extends IWindowManager.Stub } } void scheduleAnimationLocked() { void scheduleAnimationLocked() { if (!mAnimationScheduled) { final WindowAnimator.LayoutToAnimatorParams layoutToAnim = mAnimator.mLayoutToAnim; mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationRunnable, null); synchronized (layoutToAnim) { mAnimationScheduled = true; // 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(); } } } } Loading