blob: b3ffcf888db50c59ceadabc584a5171753a46f9e [file] [log] [blame]
/*
* Copyright 2020 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "pc/peer_connection_message_handler.h"
#include <utility>
#include "api/jsep.h"
#include "api/media_stream_interface.h"
#include "api/peer_connection_interface.h"
#include "pc/stats_collector_interface.h"
#include "rtc_base/synchronization/sequence_checker.h"
namespace webrtc {
namespace {
enum {
MSG_SET_SESSIONDESCRIPTION_SUCCESS = 0,
MSG_SET_SESSIONDESCRIPTION_FAILED,
MSG_CREATE_SESSIONDESCRIPTION_FAILED,
MSG_GETSTATS,
MSG_REPORT_USAGE_PATTERN,
};
struct SetSessionDescriptionMsg : public rtc::MessageData {
explicit SetSessionDescriptionMsg(
webrtc::SetSessionDescriptionObserver* observer)
: observer(observer) {}
rtc::scoped_refptr<webrtc::SetSessionDescriptionObserver> observer;
RTCError error;
};
struct CreateSessionDescriptionMsg : public rtc::MessageData {
explicit CreateSessionDescriptionMsg(
webrtc::CreateSessionDescriptionObserver* observer)
: observer(observer) {}
rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer;
RTCError error;
};
struct GetStatsMsg : public rtc::MessageData {
GetStatsMsg(webrtc::StatsObserver* observer,
StatsCollectorInterface* stats,
webrtc::MediaStreamTrackInterface* track)
: observer(observer), stats(stats), track(track) {}
rtc::scoped_refptr<webrtc::StatsObserver> observer;
StatsCollectorInterface* stats;
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track;
};
struct RequestUsagePatternMsg : public rtc::MessageData {
explicit RequestUsagePatternMsg(std::function<void()> func)
: function(func) {}
std::function<void()> function;
};
} // namespace
PeerConnectionMessageHandler::~PeerConnectionMessageHandler() {
// Process all pending notifications in the message queue. If we don't do
// this, requests will linger and not know they succeeded or failed.
rtc::MessageList list;
signaling_thread()->Clear(this, rtc::MQID_ANY, &list);
for (auto& msg : list) {
if (msg.message_id == MSG_CREATE_SESSIONDESCRIPTION_FAILED) {
// Processing CreateOffer() and CreateAnswer() messages ensures their
// observers are invoked even if the PeerConnection is destroyed early.
OnMessage(&msg);
} else {
// TODO(hbos): Consider processing all pending messages. This would mean
// that SetLocalDescription() and SetRemoteDescription() observers are
// informed of successes and failures; this is currently NOT the case.
delete msg.pdata;
}
}
}
void PeerConnectionMessageHandler::OnMessage(rtc::Message* msg) {
RTC_DCHECK_RUN_ON(signaling_thread());
switch (msg->message_id) {
case MSG_SET_SESSIONDESCRIPTION_SUCCESS: {
SetSessionDescriptionMsg* param =
static_cast<SetSessionDescriptionMsg*>(msg->pdata);
param->observer->OnSuccess();
delete param;
break;
}
case MSG_SET_SESSIONDESCRIPTION_FAILED: {
SetSessionDescriptionMsg* param =
static_cast<SetSessionDescriptionMsg*>(msg->pdata);
param->observer->OnFailure(std::move(param->error));
delete param;
break;
}
case MSG_CREATE_SESSIONDESCRIPTION_FAILED: {
CreateSessionDescriptionMsg* param =
static_cast<CreateSessionDescriptionMsg*>(msg->pdata);
param->observer->OnFailure(std::move(param->error));
delete param;
break;
}
case MSG_GETSTATS: {
GetStatsMsg* param = static_cast<GetStatsMsg*>(msg->pdata);
StatsReports reports;
param->stats->GetStats(param->track, &reports);
param->observer->OnComplete(reports);
delete param;
break;
}
case MSG_REPORT_USAGE_PATTERN: {
RequestUsagePatternMsg* param =
static_cast<RequestUsagePatternMsg*>(msg->pdata);
param->function();
delete param;
break;
}
default:
RTC_NOTREACHED() << "Not implemented";
break;
}
}
void PeerConnectionMessageHandler::PostSetSessionDescriptionSuccess(
SetSessionDescriptionObserver* observer) {
SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
signaling_thread()->Post(RTC_FROM_HERE, this,
MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg);
}
void PeerConnectionMessageHandler::PostSetSessionDescriptionFailure(
SetSessionDescriptionObserver* observer,
RTCError&& error) {
RTC_DCHECK(!error.ok());
SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
msg->error = std::move(error);
signaling_thread()->Post(RTC_FROM_HERE, this,
MSG_SET_SESSIONDESCRIPTION_FAILED, msg);
}
void PeerConnectionMessageHandler::PostCreateSessionDescriptionFailure(
CreateSessionDescriptionObserver* observer,
RTCError error) {
RTC_DCHECK(!error.ok());
CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
msg->error = std::move(error);
signaling_thread()->Post(RTC_FROM_HERE, this,
MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
}
void PeerConnectionMessageHandler::PostGetStats(
StatsObserver* observer,
StatsCollectorInterface* stats,
MediaStreamTrackInterface* track) {
signaling_thread()->Post(RTC_FROM_HERE, this, MSG_GETSTATS,
new GetStatsMsg(observer, stats, track));
}
void PeerConnectionMessageHandler::RequestUsagePatternReport(
std::function<void()> func,
int delay_ms) {
signaling_thread()->PostDelayed(RTC_FROM_HERE, delay_ms, this,
MSG_REPORT_USAGE_PATTERN,
new RequestUsagePatternMsg(func));
}
} // namespace webrtc