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

Commit effd896b authored by Chong Zhang's avatar Chong Zhang
Browse files

transcoding: pass client and session id to resource lost callback

If the resource lost is reported by a session that's already paused
or cancelled, the resource lost signal should be ignored.

bug: 168307955
bug: 154733526
test: TranscodingSessionController_tests and transcoding service
unit tests.

Change-Id: Ifc820cf8a24f98787d20e3f649a0c2359cf9527c
parent 5e883d13
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -192,7 +192,7 @@ void TranscoderWrapper::reportError(ClientIdType clientId, SessionIdType session
                                        new ndk::ScopedAParcel());
                                        new ndk::ScopedAParcel());
            }
            }


            callback->onResourceLost();
            callback->onResourceLost(clientId, sessionId);
        } else {
        } else {
            callback->onError(clientId, sessionId, toTranscodingError(err));
            callback->onError(clientId, sessionId, toTranscodingError(err));
        }
        }
+21 −17
Original line number Original line Diff line number Diff line
@@ -485,30 +485,34 @@ void TranscodingSessionController::onProgressUpdate(ClientIdType clientId, Sessi
    });
    });
}
}


void TranscodingSessionController::onResourceLost() {
void TranscodingSessionController::onResourceLost(ClientIdType clientId, SessionIdType sessionId) {
    ALOGI("%s", __FUNCTION__);
    ALOGI("%s", __FUNCTION__);


    std::scoped_lock lock{mLock};
    notifyClient(clientId, sessionId, "resource_lost", [=](const SessionKeyType& sessionKey) {

        if (mResourceLost) {
        if (mResourceLost) {
            return;
            return;
        }
        }


    // If we receive a resource loss event, the TranscoderLibrary already paused
        Session* resourceLostSession = &mSessionMap[sessionKey];
    // the transcoding, so we don't need to call onPaused to notify it to pause.
        if (resourceLostSession->state != Session::RUNNING) {
    // Only need to update the session state here.
            ALOGW("session %s lost resource but is no longer running",
    if (mCurrentSession != nullptr && mCurrentSession->state == Session::RUNNING) {
                    sessionToString(sessionKey).c_str());
        mCurrentSession->state = Session::PAUSED;
            return;
        }
        // If we receive a resource loss event, the transcoder already paused the transcoding,
        // so we don't need to call onPaused() to pause it. However, we still need to notify
        // the client and update the session state here.
        resourceLostSession->state = Session::PAUSED;
        // Notify the client as a paused event.
        // Notify the client as a paused event.
        auto clientCallback = mCurrentSession->callback.lock();
        auto clientCallback = resourceLostSession->callback.lock();
        if (clientCallback != nullptr) {
        if (clientCallback != nullptr) {
            clientCallback->onTranscodingPaused(mCurrentSession->key.second);
            clientCallback->onTranscodingPaused(sessionKey.second);
        }
        mResourcePolicy->setPidResourceLost(mCurrentSession->request.clientPid);
        }
        }
        mResourcePolicy->setPidResourceLost(resourceLostSession->request.clientPid);
        mResourceLost = true;
        mResourceLost = true;


        validateState_l();
        validateState_l();
    });
}
}


void TranscodingSessionController::onTopUidsChanged(const std::unordered_set<uid_t>& uids) {
void TranscodingSessionController::onTopUidsChanged(const std::unordered_set<uid_t>& uids) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -64,7 +64,7 @@ public:
    // If there is any session currently running, it will be paused. When resource contention
    // If there is any session currently running, it will be paused. When resource contention
    // is solved, the controller should call TranscoderInterface's to either start a new session,
    // is solved, the controller should call TranscoderInterface's to either start a new session,
    // or resume a paused session.
    // or resume a paused session.
    virtual void onResourceLost() = 0;
    virtual void onResourceLost(ClientIdType clientId, SessionIdType sessionId) = 0;


protected:
protected:
    virtual ~TranscoderCallbackInterface() = default;
    virtual ~TranscoderCallbackInterface() = default;
+1 −1
Original line number Original line Diff line number Diff line
@@ -58,7 +58,7 @@ public:
    void onError(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) override;
    void onError(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) override;
    void onProgressUpdate(ClientIdType clientId, SessionIdType sessionId,
    void onProgressUpdate(ClientIdType clientId, SessionIdType sessionId,
                          int32_t progress) override;
                          int32_t progress) override;
    void onResourceLost() override;
    void onResourceLost(ClientIdType clientId, SessionIdType sessionId) override;
    // ~TranscoderCallbackInterface
    // ~TranscoderCallbackInterface


    // UidPolicyCallbackInterface
    // UidPolicyCallbackInterface
+38 −5
Original line number Original line Diff line number Diff line
@@ -44,11 +44,14 @@ using aidl::android::media::TranscodingRequestParcel;
constexpr ClientIdType kClientId = 1000;
constexpr ClientIdType kClientId = 1000;
constexpr SessionIdType kClientSessionId = 0;
constexpr SessionIdType kClientSessionId = 0;
constexpr uid_t kClientUid = 5000;
constexpr uid_t kClientUid = 5000;
constexpr pid_t kClientPid = 10000;
constexpr uid_t kInvalidUid = (uid_t)-1;
constexpr uid_t kInvalidUid = (uid_t)-1;
constexpr pid_t kInvalidPid = (pid_t)-1;


#define CLIENT(n) (kClientId + (n))
#define CLIENT(n) (kClientId + (n))
#define SESSION(n) (kClientSessionId + (n))
#define SESSION(n) (kClientSessionId + (n))
#define UID(n) (kClientUid + (n))
#define UID(n) (kClientUid + (n))
#define PID(n) (kClientPid + (n))


class TestUidPolicy : public UidPolicyInterface {
class TestUidPolicy : public UidPolicyInterface {
public:
public:
@@ -81,11 +84,27 @@ public:


class TestResourcePolicy : public ResourcePolicyInterface {
class TestResourcePolicy : public ResourcePolicyInterface {
public:
public:
    TestResourcePolicy() = default;
    TestResourcePolicy() { reset(); }
    virtual ~TestResourcePolicy() = default;
    virtual ~TestResourcePolicy() = default;


    // ResourcePolicyInterface
    void setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface>& /*cb*/) override {}
    void setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface>& /*cb*/) override {}
    void setPidResourceLost(pid_t /*pid*/) override {}
    void setPidResourceLost(pid_t pid) override {
        mResourceLostPid = pid;
    }
    // ~ResourcePolicyInterface

    pid_t getPid() {
        pid_t result = mResourceLostPid;
        reset();
        return result;
    }

private:
    void reset() {
        mResourceLostPid = kInvalidPid;
    }
    pid_t mResourceLostPid;
};
};


class TestTranscoder : public TranscoderInterface {
class TestTranscoder : public TranscoderInterface {
@@ -563,10 +582,12 @@ TEST_F(TranscodingSessionControllerTest, TestResourceLost) {


    // Start with unspecified top UID.
    // Start with unspecified top UID.
    // Submit real-time session to CLIENT(0), session should start immediately.
    // Submit real-time session to CLIENT(0), session should start immediately.
    mRealtimeRequest.clientPid = PID(0);
    mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
    mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));


    // Submit offline session to CLIENT(0), should not start.
    // Submit offline session to CLIENT(0), should not start.
    mOfflineRequest.clientPid = PID(0);
    mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
    mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);


@@ -576,13 +597,22 @@ TEST_F(TranscodingSessionControllerTest, TestResourceLost) {


    // Submit real-time session to CLIENT(2) in different uid UID(1).
    // Submit real-time session to CLIENT(2) in different uid UID(1).
    // Should pause previous session and start new session.
    // Should pause previous session and start new session.
    mRealtimeRequest.clientPid = PID(1);
    mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
    mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));


    // Test 0: No call into ResourcePolicy if resource lost is from a non-running
    // or non-existent session.
    mController->onResourceLost(CLIENT(0), SESSION(0));
    EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
    mController->onResourceLost(CLIENT(3), SESSION(0));
    EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);

    // Test 1: No queue change during resource loss.
    // Test 1: No queue change during resource loss.
    // Signal resource lost.
    // Signal resource lost.
    mController->onResourceLost();
    mController->onResourceLost(CLIENT(2), SESSION(0));
    EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);


    // Signal resource available, CLIENT(2) should resume.
    // Signal resource available, CLIENT(2) should resume.
@@ -591,7 +621,8 @@ TEST_F(TranscodingSessionControllerTest, TestResourceLost) {


    // Test 2: Change of queue order during resource loss.
    // Test 2: Change of queue order during resource loss.
    // Signal resource lost.
    // Signal resource lost.
    mController->onResourceLost();
    mController->onResourceLost(CLIENT(2), SESSION(0));
    EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);


    // Move UID(0) back to top, should have no resume due to no resource.
    // Move UID(0) back to top, should have no resume due to no resource.
@@ -604,13 +635,15 @@ TEST_F(TranscodingSessionControllerTest, TestResourceLost) {


    // Test 3: Adding new queue during resource loss.
    // Test 3: Adding new queue during resource loss.
    // Signal resource lost.
    // Signal resource lost.
    mController->onResourceLost();
    mController->onResourceLost(CLIENT(0), SESSION(0));
    EXPECT_EQ(mResourcePolicy->getPid(), PID(0));
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);


    // Move UID(2) to top.
    // Move UID(2) to top.
    mUidPolicy->setTop(UID(2));
    mUidPolicy->setTop(UID(2));


    // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
    // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
    mRealtimeRequest.clientPid = PID(2);
    mController->submit(CLIENT(3), SESSION(0), UID(2), mRealtimeRequest, mClientCallback3);
    mController->submit(CLIENT(3), SESSION(0), UID(2), mRealtimeRequest, mClientCallback3);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);