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

Commit 480b056d authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "MediaCodec: fix crash when stop-error-death"

parents 00732464 40c674e8
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -3061,10 +3061,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                        case STOPPING:
                        {
                            if (mFlags & kFlagSawMediaServerDie) {
                                bool postPendingReplies = true;
                                if (mState == RELEASING && !mReplyID) {
                                    ALOGD("Releasing asynchronously, so nothing to reply here.");
                                    postPendingReplies = false;
                                }
                                // MediaServer died, there definitely won't
                                // be a shutdown complete notification after
@@ -3077,8 +3075,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                                if (mState == RELEASING) {
                                    mComponentName.clear();
                                }
                                if (postPendingReplies) {
                                if (mReplyID) {
                                    postPendingRepliesAndDeferredMessages(origin + ":dead");
                                } else {
                                    ALOGD("no pending replies: %s:dead following %s",
                                          origin.c_str(), mLastReplyOrigin.c_str());
                                }
                                sendErrorResponse = false;
                            } else if (!mReplyID) {
+48 −0
Original line number Diff line number Diff line
@@ -393,3 +393,51 @@ TEST(MediaCodecTest, DeadWhileAsyncReleasing) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    looper->stop();
}

TEST(MediaCodecTest, DeadWhileStoppingError) {
    // Test scenario:
    //
    // 1) Client thread calls stop(); MediaCodec looper thread calls
    //    initiateShutdown(); shutdown is being handled at the component thread.
    // 2) An error occurs while handling initiateShutdown().
    // 3) MediaCodec looper thread handles the error.
    // 4) Codec service dies after the error is handled
    // 5) MediaCodec looper thread handles the death.

    static const AString kCodecName{"test.codec"};
    static const AString kCodecOwner{"nobody"};
    static const AString kMediaType{"video/x-test"};

    sp<MockCodec> mockCodec;
    std::function<sp<CodecBase>(const AString &name, const char *owner)> getCodecBase =
        [&mockCodec](const AString &, const char *) {
            mockCodec = new MockCodec([](const std::shared_ptr<MockBufferChannel> &) {
                // No mock setup, as we don't expect any buffer operations
                // in this scenario.
            });
            ON_CALL(*mockCodec, initiateAllocateComponent(_))
                .WillByDefault([mockCodec](const sp<AMessage> &) {
                    mockCodec->callback()->onComponentAllocated(kCodecName.c_str());
                });
            ON_CALL(*mockCodec, initiateShutdown(_))
                .WillByDefault([mockCodec](bool) {
                    // 2)
                    mockCodec->callback()->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
                    // 4)
                    mockCodec->callback()->onError(DEAD_OBJECT, ACTION_CODE_FATAL);
                    // Codec service has died, no callback.
                });
            return mockCodec;
        };

    sp<ALooper> looper{new ALooper};
    sp<MediaCodec> codec = SetupMediaCodec(
            kCodecOwner, kCodecName, kMediaType, looper, getCodecBase);
    ASSERT_NE(nullptr, codec) << "Codec must not be null";
    ASSERT_NE(nullptr, mockCodec) << "MockCodec must not be null";

    codec->stop();
    // sleep here so that the looper thread can handle the error
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    looper->stop();
}