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
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/libmediatranscoding/TranscoderWrapper.cpp
index 8cc8dd2..da86187 100644
--- a/media/libmediatranscoding/TranscoderWrapper.cpp
+++ b/media/libmediatranscoding/TranscoderWrapper.cpp
@@ -192,7 +192,7 @@
new ndk::ScopedAParcel());
}
- callback->onResourceLost();
+ callback->onResourceLost(clientId, sessionId);
} else {
callback->onError(clientId, sessionId, toTranscodingError(err));
}
diff --git a/media/libmediatranscoding/TranscodingSessionController.cpp b/media/libmediatranscoding/TranscodingSessionController.cpp
index bab25c6..49a7083 100644
--- a/media/libmediatranscoding/TranscodingSessionController.cpp
+++ b/media/libmediatranscoding/TranscodingSessionController.cpp
@@ -485,30 +485,34 @@
});
}
-void TranscodingSessionController::onResourceLost() {
+void TranscodingSessionController::onResourceLost(ClientIdType clientId, SessionIdType sessionId) {
ALOGI("%s", __FUNCTION__);
- std::scoped_lock lock{mLock};
-
- if (mResourceLost) {
- return;
- }
-
- // If we receive a resource loss event, the TranscoderLibrary already paused
- // the transcoding, so we don't need to call onPaused to notify it to pause.
- // Only need to update the session state here.
- if (mCurrentSession != nullptr && mCurrentSession->state == Session::RUNNING) {
- mCurrentSession->state = Session::PAUSED;
- // Notify the client as a paused event.
- auto clientCallback = mCurrentSession->callback.lock();
- if (clientCallback != nullptr) {
- clientCallback->onTranscodingPaused(mCurrentSession->key.second);
+ notifyClient(clientId, sessionId, "resource_lost", [=](const SessionKeyType& sessionKey) {
+ if (mResourceLost) {
+ return;
}
- mResourcePolicy->setPidResourceLost(mCurrentSession->request.clientPid);
- }
- mResourceLost = true;
- validateState_l();
+ Session* resourceLostSession = &mSessionMap[sessionKey];
+ if (resourceLostSession->state != Session::RUNNING) {
+ ALOGW("session %s lost resource but is no longer running",
+ sessionToString(sessionKey).c_str());
+ 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.
+ auto clientCallback = resourceLostSession->callback.lock();
+ if (clientCallback != nullptr) {
+ clientCallback->onTranscodingPaused(sessionKey.second);
+ }
+ mResourcePolicy->setPidResourceLost(resourceLostSession->request.clientPid);
+ mResourceLost = true;
+
+ validateState_l();
+ });
}
void TranscodingSessionController::onTopUidsChanged(const std::unordered_set<uid_t>& uids) {
diff --git a/media/libmediatranscoding/include/media/TranscoderInterface.h b/media/libmediatranscoding/include/media/TranscoderInterface.h
index e17cd5a..6268aa5 100644
--- a/media/libmediatranscoding/include/media/TranscoderInterface.h
+++ b/media/libmediatranscoding/include/media/TranscoderInterface.h
@@ -64,7 +64,7 @@
// 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,
// or resume a paused session.
- virtual void onResourceLost() = 0;
+ virtual void onResourceLost(ClientIdType clientId, SessionIdType sessionId) = 0;
protected:
virtual ~TranscoderCallbackInterface() = default;
diff --git a/media/libmediatranscoding/include/media/TranscodingSessionController.h b/media/libmediatranscoding/include/media/TranscodingSessionController.h
index c082074..4215e06 100644
--- a/media/libmediatranscoding/include/media/TranscodingSessionController.h
+++ b/media/libmediatranscoding/include/media/TranscodingSessionController.h
@@ -58,7 +58,7 @@
void onError(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) override;
void onProgressUpdate(ClientIdType clientId, SessionIdType sessionId,
int32_t progress) override;
- void onResourceLost() override;
+ void onResourceLost(ClientIdType clientId, SessionIdType sessionId) override;
// ~TranscoderCallbackInterface
// UidPolicyCallbackInterface
diff --git a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp b/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
index c8b38fb..fa52f63 100644
--- a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
+++ b/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
@@ -44,11 +44,14 @@
constexpr ClientIdType kClientId = 1000;
constexpr SessionIdType kClientSessionId = 0;
constexpr uid_t kClientUid = 5000;
+constexpr pid_t kClientPid = 10000;
constexpr uid_t kInvalidUid = (uid_t)-1;
+constexpr pid_t kInvalidPid = (pid_t)-1;
#define CLIENT(n) (kClientId + (n))
#define SESSION(n) (kClientSessionId + (n))
#define UID(n) (kClientUid + (n))
+#define PID(n) (kClientPid + (n))
class TestUidPolicy : public UidPolicyInterface {
public:
@@ -81,11 +84,27 @@
class TestResourcePolicy : public ResourcePolicyInterface {
public:
- TestResourcePolicy() = default;
+ TestResourcePolicy() { reset(); }
virtual ~TestResourcePolicy() = default;
+ // ResourcePolicyInterface
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 {
@@ -563,10 +582,12 @@
// Start with unspecified top UID.
// 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);
EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
// Submit offline session to CLIENT(0), should not start.
+ mOfflineRequest.clientPid = PID(0);
mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
@@ -576,13 +597,22 @@
// Submit real-time session to CLIENT(2) in different uid UID(1).
// Should pause previous session and start new session.
+ mRealtimeRequest.clientPid = PID(1);
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::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.
// Signal resource lost.
- mController->onResourceLost();
+ mController->onResourceLost(CLIENT(2), SESSION(0));
+ EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Signal resource available, CLIENT(2) should resume.
@@ -591,7 +621,8 @@
// Test 2: Change of queue order during resource loss.
// Signal resource lost.
- mController->onResourceLost();
+ mController->onResourceLost(CLIENT(2), SESSION(0));
+ EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Move UID(0) back to top, should have no resume due to no resource.
@@ -604,13 +635,15 @@
// Test 3: Adding new queue during resource loss.
// Signal resource lost.
- mController->onResourceLost();
+ mController->onResourceLost(CLIENT(0), SESSION(0));
+ EXPECT_EQ(mResourcePolicy->getPid(), PID(0));
EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Move UID(2) to top.
mUidPolicy->setTop(UID(2));
// 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);
EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);