Merge "Fix another animation leak" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8d23a78b40
@@ -37,6 +37,8 @@ class AnimatingAppWindowTokenRegistry {
|
||||
|
||||
private ArrayList<Runnable> mTmpRunnableList = new ArrayList<>();
|
||||
|
||||
private boolean mEndingDeferredFinish;
|
||||
|
||||
/**
|
||||
* Notifies that an {@link AppWindowToken} has started animating.
|
||||
*/
|
||||
@@ -50,6 +52,11 @@ class AnimatingAppWindowTokenRegistry {
|
||||
void notifyFinished(AppWindowToken token) {
|
||||
mAnimatingTokens.remove(token);
|
||||
mFinishedTokens.remove(token);
|
||||
|
||||
// If we were the last token, make sure the end all deferred finishes.
|
||||
if (mAnimatingTokens.isEmpty()) {
|
||||
endDeferringFinished();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,16 +85,28 @@ class AnimatingAppWindowTokenRegistry {
|
||||
}
|
||||
|
||||
private void endDeferringFinished() {
|
||||
// Copy it into a separate temp list to avoid modifying the collection while iterating as
|
||||
// calling the callback may call back into notifyFinished.
|
||||
for (int i = mFinishedTokens.size() - 1; i >= 0; i--) {
|
||||
mTmpRunnableList.add(mFinishedTokens.valueAt(i));
|
||||
|
||||
// Don't start recursing. Running the finished listener invokes notifyFinished, which may
|
||||
// invoked us again.
|
||||
if (mEndingDeferredFinish) {
|
||||
return;
|
||||
}
|
||||
mFinishedTokens.clear();
|
||||
for (int i = mTmpRunnableList.size() - 1; i >= 0; i--) {
|
||||
mTmpRunnableList.get(i).run();
|
||||
try {
|
||||
mEndingDeferredFinish = true;
|
||||
|
||||
// Copy it into a separate temp list to avoid modifying the collection while iterating
|
||||
// as calling the callback may call back into notifyFinished.
|
||||
for (int i = mFinishedTokens.size() - 1; i >= 0; i--) {
|
||||
mTmpRunnableList.add(mFinishedTokens.valueAt(i));
|
||||
}
|
||||
mFinishedTokens.clear();
|
||||
for (int i = mTmpRunnableList.size() - 1; i >= 0; i--) {
|
||||
mTmpRunnableList.get(i).run();
|
||||
}
|
||||
mTmpRunnableList.clear();
|
||||
} finally {
|
||||
mEndingDeferredFinish = false;
|
||||
}
|
||||
mTmpRunnableList.clear();
|
||||
}
|
||||
|
||||
void dump(PrintWriter pw, String header, String prefix) {
|
||||
|
||||
@@ -88,4 +88,25 @@ public class AnimatingAppWindowTokenRegistryTest extends WindowTestsBase {
|
||||
verify(mMockEndDeferFinishCallback1).run();
|
||||
verifyZeroInteractions(mMockEndDeferFinishCallback2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainerRemoved() throws Exception {
|
||||
final AppWindowToken window1 = createAppWindowToken(mDisplayContent,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
final AppWindowToken window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
|
||||
"window2").mAppToken;
|
||||
final AnimatingAppWindowTokenRegistry registry =
|
||||
window1.getStack().getAnimatingAppWindowTokenRegistry();
|
||||
|
||||
window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
|
||||
window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
|
||||
assertTrue(window1.isSelfAnimating());
|
||||
assertTrue(window2.isSelfAnimating());
|
||||
|
||||
// Make sure that first animation finish is deferred, and removing the second window stops
|
||||
// finishes all pending deferred finishings.
|
||||
registry.notifyAboutToFinish(window1, mMockEndDeferFinishCallback1);
|
||||
window2.setParent(null);
|
||||
verify(mMockEndDeferFinishCallback1).run();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user