Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2478d45 authored by John Reck's avatar John Reck
Browse files

Fix some wrong-thread issues around animator management

 Bug: 17372309

 Fixes a case where UI thread and RT thread both used the same method
 which wasn't safe for either of them.

 Adds additional assertions & logging in unusual circumstances to
 try and track down where the issue is occuring from.

Change-Id: I93d31a6fd0c5927259b67bdf96a475944226eee6
parent 3215da25
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -458,7 +458,7 @@ static void android_view_RenderNode_addAnimator(JNIEnv* env, jobject clazz,
static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz,
        jlong renderNodePtr) {
    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    renderNode->animators().endAllAnimators();
    renderNode->animators().endAllStagingAnimators();
}

#endif // USE_OPENGL_RENDERER
+14 −6
Original line number Diff line number Diff line
@@ -166,12 +166,7 @@ public:
    // Runs any animations still left in mCurrentFrameAnimations
    virtual void runRemainingAnimations(TreeInfo& info) {
        AnimationContext::runRemainingAnimations(info);
        // post all the finished stuff
        if (mOnFinishedEvents.size()) {
            sp<InvokeAnimationListeners> message
                    = new InvokeAnimationListeners(mOnFinishedEvents);
            mRootNode->sendMessage(message);
        }
        postOnFinishedEvents();
    }

    virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) {
@@ -179,9 +174,22 @@ public:
        mOnFinishedEvents.push_back(event);
    }

    virtual void destroy() {
        AnimationContext::destroy();
        postOnFinishedEvents();
    }

private:
    sp<RootRenderNode> mRootNode;
    std::vector<OnFinishedEvent> mOnFinishedEvents;

    void postOnFinishedEvents() {
        if (mOnFinishedEvents.size()) {
            sp<InvokeAnimationListeners> message
                    = new InvokeAnimationListeners(mOnFinishedEvents);
            mRootNode->sendMessage(message);
        }
    }
};

class ContextFactoryImpl : public IContextFactory {
+4 −1
Original line number Diff line number Diff line
@@ -31,11 +31,14 @@ AnimationContext::AnimationContext(renderthread::TimeLord& clock)
}

AnimationContext::~AnimationContext() {
}

void AnimationContext::destroy() {
    startFrame();
    while (mCurrentFrameAnimations.mNextHandle) {
        AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
        AnimatorManager& animators = current->mRenderNode->animators();
        animators.endAllAnimators();
        animators.endAllActiveAnimators();
        LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
                "endAllAnimators failed to remove from current frame list!");
    }
+2 −0
Original line number Diff line number Diff line
@@ -98,6 +98,8 @@ public:

    ANDROID_API virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener);

    ANDROID_API virtual void destroy();

private:
    friend class AnimationHandle;
    void addAnimationHandle(AnimationHandle* handle);
+7 −0
Original line number Diff line number Diff line
@@ -161,6 +161,13 @@ bool BaseRenderNodeAnimator::animate(AnimationContext& context) {
    return false;
}

void BaseRenderNodeAnimator::forceEndNow(AnimationContext& context) {
    if (mPlayState < FINISHED) {
        mPlayState = FINISHED;
        callOnFinishedListener(context);
    }
}

void BaseRenderNodeAnimator::callOnFinishedListener(AnimationContext& context) {
    if (mListener.get()) {
        context.callOnFinished(this, mListener.get());
Loading