From 350e65206cfbd86484fcfda77bb988e270606dda Mon Sep 17 00:00:00 2001 From: Doris Liu Date: Fri, 19 Feb 2016 14:20:37 -0800 Subject: [PATCH] End staging animators when destroy RootRenderNode When animation happens in a dialog, it is possible for the dialog to be dismissed and RootRenderNode to be destroyed before we create animation handle for the staged animators. In that case, we need to remove the staged animators so they will not run without a animation handle. Bug: 26975079 Change-Id: I0c2c6c1b530beaec3984c0b1c410df4fd8f25c95 --- core/java/android/view/ThreadedRenderer.java | 4 ++-- core/jni/android_view_ThreadedRenderer.cpp | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index ca41d7867febc..c972476565404 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -380,7 +380,7 @@ public final class ThreadedRenderer { void destroy() { mInitialized = false; updateEnabledState(null); - nDestroy(mNativeProxy); + nDestroy(mNativeProxy, mRootNode.mNativeRenderNode); } /** @@ -994,7 +994,7 @@ public final class ThreadedRenderer { float lightX, float lightY, float lightZ); private static native void nSetOpaque(long nativeProxy, boolean opaque); private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size); - private static native void nDestroy(long nativeProxy); + private static native void nDestroy(long nativeProxy, long rootRenderNode); private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode); private static native void nInvokeFunctor(long functor, boolean waitForCompletion); diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index cd2c0d6643a10..07868c54cf52f 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -164,6 +164,13 @@ public: mPendingAnimatingRenderNodes.clear(); } + void destroy() { + for (auto& renderNode : mPendingAnimatingRenderNodes) { + renderNode->animators().endAllStagingAnimators(); + } + mPendingAnimatingRenderNodes.clear(); + } + private: sp mLooper; JavaVM* mVm; @@ -476,7 +483,9 @@ static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject c } static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz, - jlong proxyPtr) { + jlong proxyPtr, jlong rootNodePtr) { + RootRenderNode* rootRenderNode = reinterpret_cast(rootNodePtr); + rootRenderNode->destroy(); RenderProxy* proxy = reinterpret_cast(proxyPtr); proxy->destroy(); } @@ -698,7 +707,7 @@ static const JNINativeMethod gMethods[] = { { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter }, { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque }, { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, - { "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy }, + { "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy }, { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode }, { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor }, { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },