summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java34
-rw-r--r--services/core/java/com/android/server/wm/AnimatingActivityRegistry.java120
-rw-r--r--services/core/java/com/android/server/wm/AnimationAdapter.java9
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimator.java23
-rw-r--r--services/core/java/com/android/server/wm/Task.java17
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java107
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java76
7 files changed, 21 insertions, 365 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f38394e2a259..1a658902c2c5 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -659,8 +659,6 @@ final class ActivityRecord extends WindowToken {
private RemoteAnimationDefinition mRemoteAnimationDefinition;
- AnimatingActivityRegistry mAnimatingActivityRegistry;
-
// Set to the previous Task parent of the ActivityRecord when it is reparented to a new Task
// due to picture-in-picture. This gets cleared whenever this activity or the Task
// it references to gets removed. This should also be cleared when we move out of pip.
@@ -1596,9 +1594,6 @@ final class ActivityRecord extends WindowToken {
}
}
final Task rootTask = getRootTask();
-
- updateAnimatingActivityRegistry();
-
if (task == mLastParentBeforePip && task != null) {
// Notify the TaskFragmentOrganizer that the activity is reparented back from pip.
mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController
@@ -1700,20 +1695,6 @@ final class ActivityRecord extends WindowToken {
return !organizedTaskFragment.isAllowedToEmbedActivityInTrustedMode(this);
}
- void updateAnimatingActivityRegistry() {
- final Task rootTask = getRootTask();
- final AnimatingActivityRegistry registry = rootTask != null
- ? rootTask.getAnimatingActivityRegistry()
- : null;
-
- // If we reparent, make sure to remove ourselves from the old animation registry.
- if (mAnimatingActivityRegistry != null && mAnimatingActivityRegistry != registry) {
- mAnimatingActivityRegistry.notifyFinished(this);
- }
-
- mAnimatingActivityRegistry = registry;
- }
-
boolean canAutoEnterPip() {
// beforeStopping=false since the actual pip-ing will take place after startPausing()
final boolean activityCanPip = checkEnterPictureInPictureState(
@@ -7648,13 +7629,6 @@ final class ActivityRecord extends WindowToken {
}
@Override
- public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
- return mAnimatingActivityRegistry != null
- && mAnimatingActivityRegistry.notifyAboutToFinish(
- this, endDeferFinishCallback);
- }
-
- @Override
boolean isWaitingForTransitionStart() {
final DisplayContent dc = getDisplayContent();
return dc != null && dc.mAppTransition.isTransitionSet()
@@ -7675,10 +7649,6 @@ final class ActivityRecord extends WindowToken {
@Override
public void onLeashAnimationStarting(Transaction t, SurfaceControl leash) {
- if (mAnimatingActivityRegistry != null) {
- mAnimatingActivityRegistry.notifyStarting(this);
- }
-
if (mNeedsLetterboxedAnimation) {
updateLetterboxSurfaceIfNeeded(findMainWindow(), t);
mNeedsAnimationBoundsLayer = true;
@@ -7855,10 +7825,6 @@ final class ActivityRecord extends WindowToken {
mNeedsLetterboxedAnimation = false;
updateLetterboxSurfaceIfNeeded(findMainWindow(), t);
}
-
- if (mAnimatingActivityRegistry != null) {
- mAnimatingActivityRegistry.notifyFinished(this);
- }
}
@Override
diff --git a/services/core/java/com/android/server/wm/AnimatingActivityRegistry.java b/services/core/java/com/android/server/wm/AnimatingActivityRegistry.java
deleted file mode 100644
index 18ec96c38264..000000000000
--- a/services/core/java/com/android/server/wm/AnimatingActivityRegistry.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.wm;
-
-import android.util.ArrayMap;
-import android.util.ArraySet;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * Keeps track of all {@link ActivityRecord} that are animating and makes sure all animations are
- * finished at the same time such that we don't run into issues with z-ordering: An activity A
- * that has a shorter animation that is above another activity B with a longer animation in the same
- * task, the animation layer would put the B on top of A, but from the hierarchy, A needs to be on
- * top of B. Thus, we defer reparenting A to the original hierarchy such that it stays on top of B
- * until B finishes animating.
- */
-class AnimatingActivityRegistry {
-
- private ArraySet<ActivityRecord> mAnimatingActivities = new ArraySet<>();
- private ArrayMap<ActivityRecord, Runnable> mFinishedTokens = new ArrayMap<>();
-
- private ArrayList<Runnable> mTmpRunnableList = new ArrayList<>();
-
- private boolean mEndingDeferredFinish;
-
- /**
- * Notifies that an {@link ActivityRecord} has started animating.
- */
- void notifyStarting(ActivityRecord token) {
- mAnimatingActivities.add(token);
- }
-
- /**
- * Notifies that an {@link ActivityRecord} has finished animating.
- */
- void notifyFinished(ActivityRecord activity) {
- mAnimatingActivities.remove(activity);
- mFinishedTokens.remove(activity);
-
- // If we were the last activity, make sure the end all deferred finishes.
- if (mAnimatingActivities.isEmpty()) {
- endDeferringFinished();
- }
- }
-
- /**
- * Called when an {@link ActivityRecord} is about to finish animating.
- *
- * @param endDeferFinishCallback Callback to run when defer finish should be ended.
- * @return {@code true} if finishing the animation should be deferred, {@code false} otherwise.
- */
- boolean notifyAboutToFinish(ActivityRecord activity, Runnable endDeferFinishCallback) {
- final boolean removed = mAnimatingActivities.remove(activity);
- if (!removed) {
- return false;
- }
-
- if (mAnimatingActivities.isEmpty()) {
-
- // If no animations are animating anymore, finish all others.
- endDeferringFinished();
- return false;
- } else {
-
- // Otherwise let's put it into the pending list of to be finished animations.
- mFinishedTokens.put(activity, endDeferFinishCallback);
- return true;
- }
- }
-
- private void endDeferringFinished() {
-
- // Don't start recursing. Running the finished listener invokes notifyFinished, which may
- // invoked us again.
- if (mEndingDeferredFinish) {
- return;
- }
- 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;
- }
- }
-
- void dump(PrintWriter pw, String header, String prefix) {
- if (!mAnimatingActivities.isEmpty() || !mFinishedTokens.isEmpty()) {
- pw.print(prefix); pw.println(header);
- prefix = prefix + " ";
- pw.print(prefix); pw.print("mAnimatingActivities="); pw.println(mAnimatingActivities);
- pw.print(prefix); pw.print("mFinishedTokens="); pw.println(mFinishedTokens);
- }
- }
-}
diff --git a/services/core/java/com/android/server/wm/AnimationAdapter.java b/services/core/java/com/android/server/wm/AnimationAdapter.java
index 3dc377dbc14c..4458ed76dcba 100644
--- a/services/core/java/com/android/server/wm/AnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/AnimationAdapter.java
@@ -109,15 +109,6 @@ public interface AnimationAdapter {
* Gets called when the animation is about to finish and gives the client the opportunity to
* defer finishing the animation, i.e. it keeps the leash around until the client calls
* endDeferFinishCallback.
- * <p>
- * This has the same effect as
- * {@link com.android.server.wm.SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable)}
- * . The later will be evaluated first and has precedence over this method if it returns true,
- * which means that if the {@link com.android.server.wm.SurfaceAnimator.Animatable} requests to
- * defer its finish, this method won't be called so this adapter will never have access to the
- * finish callback. On the other hand, if the
- * {@link com.android.server.wm.SurfaceAnimator.Animatable}, doesn't request to defer, this
- * {@link AnimationAdapter} is responsible for ending the animation.
*
* @param endDeferFinishCallback The callback to call when defer finishing should be ended.
* @return Whether the client would like to defer the animation finish.
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 3dfff39e9b68..c5425fedf2ac 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -132,10 +132,7 @@ public class SurfaceAnimator {
animationFinishCallback.onAnimationFinished(type, anim);
}
};
- // If both the Animatable and AnimationAdapter requests to be deferred, only the
- // first one will be called.
- if (!(mAnimatable.shouldDeferAnimationFinish(resetAndInvokeFinish)
- || anim.shouldDeferAnimationFinish(resetAndInvokeFinish))) {
+ if (!anim.shouldDeferAnimationFinish(resetAndInvokeFinish)) {
resetAndInvokeFinish.run();
}
mAnimationFinished = true;
@@ -639,23 +636,5 @@ public class SurfaceAnimator {
* @return The height of the surface to be animated.
*/
int getSurfaceHeight();
-
- /**
- * Gets called when the animation is about to finish and gives the client the opportunity to
- * defer finishing the animation, i.e. it keeps the leash around until the client calls
- * {@link #cancelAnimation}.
- * <p>
- * {@link AnimationAdapter} has a similar method which is called only if this method returns
- * false. This mean that if both this {@link Animatable} and the {@link AnimationAdapter}
- * request to be deferred, this method is the sole responsible to call
- * endDeferFinishCallback. On the other hand, the animation finish might still be deferred
- * if this method return false and the one from the {@link AnimationAdapter} returns true.
- *
- * @param endDeferFinishCallback The callback to call when defer finishing should be ended.
- * @return Whether the client would like to defer the animation finish.
- */
- default boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
- return false;
- }
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index f75e7175b4d2..2edf4db1ae1a 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -508,9 +508,6 @@ class Task extends TaskFragment {
*/
boolean mAllowForceResizeOverride = true;
- private final AnimatingActivityRegistry mAnimatingActivityRegistry =
- new AnimatingActivityRegistry();
-
private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_TASK_MSG + 1;
private final Handler mHandler;
@@ -1185,9 +1182,6 @@ class Task extends TaskFragment {
}
mRootWindowContainer.updateUIDsPresentOnDisplay();
-
- // Ensure all animations are finished at same time in split-screen mode.
- forAllActivities(ActivityRecord::updateAnimatingActivityRegistry);
}
@Override
@@ -3345,13 +3339,6 @@ class Task extends TaskFragment {
mLastSurfaceShowing = show;
}
- @Override
- void dump(PrintWriter pw, String prefix, boolean dumpAll) {
- super.dump(pw, prefix, dumpAll);
- mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix);
- }
-
-
/**
* Fills in a {@link TaskInfo} with information from this task. Note that the base intent in the
* task info will not include any extras or clip data.
@@ -6313,10 +6300,6 @@ class Task extends TaskFragment {
return mDisplayContent.getDisplayInfo();
}
- AnimatingActivityRegistry getAnimatingActivityRegistry() {
- return mAnimatingActivityRegistry;
- }
-
private Rect getRawBounds() {
return super.getBounds();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
deleted file mode 100644
index 8871056988ef..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for the {@link ActivityStack} class.
- *
- * Build/Install/Run:
- * atest WmTests:AnimatingActivityRegistryTest
- */
-@SmallTest
-@Presubmit
-@RunWith(WindowTestRunner.class)
-public class AnimatingActivityRegistryTest extends WindowTestsBase {
-
- @Mock
- AnimationAdapter mAdapter;
-
- @Mock
- Runnable mMockEndDeferFinishCallback1;
- @Mock
- Runnable mMockEndDeferFinishCallback2;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testDeferring() {
- final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
- final ActivityRecord activity2 = createAppWindow(activity1.getTask(), ACTIVITY_TYPE_STANDARD,
- "activity2").mActivityRecord;
- final AnimatingActivityRegistry registry =
- activity1.getRootTask().getAnimatingActivityRegistry();
-
- activity1.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */,
- ANIMATION_TYPE_APP_TRANSITION);
- activity2.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */,
- ANIMATION_TYPE_APP_TRANSITION);
- assertTrue(activity1.isAnimating(TRANSITION));
- assertTrue(activity2.isAnimating(TRANSITION));
-
- // Make sure that first animation finish is deferred, second one is not deferred, and first
- // one gets cancelled.
- assertTrue(registry.notifyAboutToFinish(activity1, mMockEndDeferFinishCallback1));
- assertFalse(registry.notifyAboutToFinish(activity2, mMockEndDeferFinishCallback2));
- verify(mMockEndDeferFinishCallback1).run();
- verifyZeroInteractions(mMockEndDeferFinishCallback2);
- }
-
- @Test
- public void testContainerRemoved() {
- final ActivityRecord window1 = createActivityRecord(mDisplayContent);
- final ActivityRecord window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
- "window2").mActivityRecord;
- final AnimatingActivityRegistry registry =
- window1.getRootTask().getAnimatingActivityRegistry();
-
- window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */,
- ANIMATION_TYPE_APP_TRANSITION);
- window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */,
- ANIMATION_TYPE_APP_TRANSITION);
- assertTrue(window1.isAnimating(TRANSITION));
- assertTrue(window2.isAnimating(TRANSITION));
-
- // 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();
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 7dba1422d61d..2544550120d4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -22,6 +22,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -69,7 +70,6 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
private MyAnimatable mAnimatable;
private MyAnimatable mAnimatable2;
- private DeferFinishAnimatable mDeferFinishAnimatable;
@Before
public void setUp() throws Exception {
@@ -77,14 +77,12 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
mAnimatable = new MyAnimatable(mWm, mTransaction);
mAnimatable2 = new MyAnimatable(mWm, mTransaction);
- mDeferFinishAnimatable = new DeferFinishAnimatable(mWm, mTransaction);
}
@After
public void tearDown() {
mAnimatable = null;
mAnimatable2 = null;
- mDeferFinishAnimatable = null;
}
@Test
@@ -202,41 +200,33 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
}
@Test
- public void testDeferFinish() {
-
- // Start animation
- final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
-
- // Finish the animation but then make sure we are deferring.
- onFinishedCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
- assertAnimating(mDeferFinishAnimatable);
-
- // Now end defer finishing.
- mDeferFinishAnimatable.mEndDeferFinishCallback.run();
- assertNotAnimating(mAnimatable2);
- assertTrue(mDeferFinishAnimatable.mFinishedCallbackCalled);
- assertEquals(ANIMATION_TYPE_APP_TRANSITION, mDeferFinishAnimatable.mFinishedAnimationType);
- verify(mTransaction).remove(eq(mDeferFinishAnimatable.mLeash));
- }
-
- @Test
public void testDeferFinishDoNotFinishNextAnimation() {
+ final DeferredFinishAdapter deferredFinishAdapter = new DeferredFinishAdapter();
+ spyOn(deferredFinishAdapter);
// Start the first animation.
- final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
- onFinishedCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
+ mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, deferredFinishAdapter,
+ true /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION);
+ assertAnimating(mAnimatable);
+ final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
+ OnAnimationFinishedCallback.class);
+ verify(deferredFinishAdapter).startAnimation(any(), any(),
+ eq(ANIMATION_TYPE_WINDOW_ANIMATION), callbackCaptor.capture());
+ final OnAnimationFinishedCallback onFinishedCallback = callbackCaptor.getValue();
+ onFinishedCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION,
+ deferredFinishAdapter);
// The callback is the resetAndInvokeFinish in {@link SurfaceAnimator#getFinishedCallback}.
- final Runnable firstDeferFinishCallback = mDeferFinishAnimatable.mEndDeferFinishCallback;
+ final Runnable firstDeferFinishCallback = deferredFinishAdapter.mEndDeferFinishCallback;
// Start the second animation.
- mDeferFinishAnimatable.mSurfaceAnimator.cancelAnimation();
- startDeferFinishAnimatable(mSpec2);
- mDeferFinishAnimatable.mFinishedCallbackCalled = false;
+ mAnimatable.mSurfaceAnimator.cancelAnimation();
+ mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2,
+ true /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION);
+ mAnimatable.mFinishedCallbackCalled = false;
- // Simulate the first deferred callback is executed from
- // {@link AnimatingActivityRegistry#endDeferringFinished}.
+ // Simulate the first deferred callback is executed.
firstDeferFinishCallback.run();
// The second animation should not be finished.
- assertFalse(mDeferFinishAnimatable.mFinishedCallbackCalled);
+ assertFalse(mAnimatable.mFinishedCallbackCalled);
}
@Test
@@ -260,17 +250,6 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
verify(mTransaction).remove(eq(deferredFinishAdapter.mAnimationLeash));
}
- private OnAnimationFinishedCallback startDeferFinishAnimatable(AnimationAdapter anim) {
- mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, anim,
- true /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
- final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
- OnAnimationFinishedCallback.class);
- assertAnimating(mDeferFinishAnimatable);
- verify(anim).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
- callbackCaptor.capture());
- return callbackCaptor.getValue();
- }
-
private void assertAnimating(MyAnimatable animatable) {
assertTrue(animatable.mSurfaceAnimator.isAnimating());
assertNotNull(animatable.mSurfaceAnimator.getAnimation());
@@ -370,21 +349,6 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
};
}
- private static class DeferFinishAnimatable extends MyAnimatable {
-
- Runnable mEndDeferFinishCallback;
-
- DeferFinishAnimatable(WindowManagerService wm, Transaction transaction) {
- super(wm, transaction);
- }
-
- @Override
- public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
- mEndDeferFinishCallback = endDeferFinishCallback;
- return true;
- }
- }
-
private static class DeferredFinishAdapter implements AnimationAdapter {
private Runnable mEndDeferFinishCallback;