Merge "Fixed deadlock between AM and WM when animating pinned stack." into nyc-dev

This commit is contained in:
TreeHugger Robot
2016-05-06 01:43:28 +00:00
committed by Android (Google) Code Review
2 changed files with 36 additions and 19 deletions

View File

@@ -24,6 +24,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.animation.Animator; import android.animation.Animator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Debug; import android.os.Debug;
import android.util.ArrayMap; import android.util.ArrayMap;
@@ -40,6 +41,8 @@ import android.view.WindowManagerInternal;
* the bounds of the resized object. * the bounds of the resized object.
* *
* The object that is resized needs to implement {@link AnimateBoundsUser} interface. * The object that is resized needs to implement {@link AnimateBoundsUser} interface.
*
* NOTE: All calls to methods in this class should be done on the UI thread
*/ */
public class BoundsAnimationController { public class BoundsAnimationController {
private static final boolean DEBUG_LOCAL = false; private static final boolean DEBUG_LOCAL = false;
@@ -51,8 +54,9 @@ public class BoundsAnimationController {
// Only accessed on UI thread. // Only accessed on UI thread.
private ArrayMap<AnimateBoundsUser, BoundsAnimator> mRunningAnimations = new ArrayMap<>(); private ArrayMap<AnimateBoundsUser, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
private final WindowManagerInternal.AppTransitionListener mAppTransitionNotifier private final class AppTransitionNotifier
= new WindowManagerInternal.AppTransitionListener() { extends WindowManagerInternal.AppTransitionListener implements Runnable {
public void onAppTransitionCancelledLocked() { public void onAppTransitionCancelledLocked() {
animationFinished(); animationFinished();
} }
@@ -61,18 +65,30 @@ public class BoundsAnimationController {
} }
private void animationFinished() { private void animationFinished() {
if (mFinishAnimationAfterTransition) { if (mFinishAnimationAfterTransition) {
mHandler.removeCallbacks(this);
// This might end up calling into activity manager which will be bad since we have the
// window manager lock held at this point. Post a message to take care of the processing
// so we don't deadlock.
mHandler.post(this);
}
}
@Override
public void run() {
for (int i = 0; i < mRunningAnimations.size(); i++) { for (int i = 0; i < mRunningAnimations.size(); i++) {
BoundsAnimator b = mRunningAnimations.valueAt(i); final BoundsAnimator b = mRunningAnimations.valueAt(i);
b.onAnimationEnd(null); b.onAnimationEnd(null);
} }
} }
} }
};
private final Handler mHandler;
private final AppTransition mAppTransition; private final AppTransition mAppTransition;
private final AppTransitionNotifier mAppTransitionNotifier = new AppTransitionNotifier();
private boolean mFinishAnimationAfterTransition = false; private boolean mFinishAnimationAfterTransition = false;
BoundsAnimationController(AppTransition transition) { BoundsAnimationController(AppTransition transition, Handler handler) {
mHandler = handler;
mAppTransition = transition; mAppTransition = transition;
mAppTransition.registerListenerLocked(mAppTransitionNotifier); mAppTransition.registerListenerLocked(mAppTransitionNotifier);
} }

View File

@@ -979,7 +979,8 @@ public class WindowManagerService extends IWindowManager.Stub
mAppTransition = new AppTransition(context, this); mAppTransition = new AppTransition(context, this);
mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier); mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
mBoundsAnimationController = new BoundsAnimationController(mAppTransition); mBoundsAnimationController =
new BoundsAnimationController(mAppTransition, UiThread.getHandler());
mActivityManager = ActivityManagerNative.getDefault(); mActivityManager = ActivityManagerNative.getDefault();
mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mAmInternal = LocalServices.getService(ActivityManagerInternal.class);