blob: b3ffcf888db50c59ceadabc584a5171753a46f9e [file] [log] [blame]
Harald Alvestrand1090e442020-10-05 07:01:09 +00001/*
2 * Copyright 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "pc/peer_connection_message_handler.h"
12
13#include <utility>
14
15#include "api/jsep.h"
16#include "api/media_stream_interface.h"
17#include "api/peer_connection_interface.h"
18#include "pc/stats_collector_interface.h"
19#include "rtc_base/synchronization/sequence_checker.h"
20
21namespace webrtc {
22
23namespace {
24
25enum {
26 MSG_SET_SESSIONDESCRIPTION_SUCCESS = 0,
27 MSG_SET_SESSIONDESCRIPTION_FAILED,
28 MSG_CREATE_SESSIONDESCRIPTION_FAILED,
29 MSG_GETSTATS,
30 MSG_REPORT_USAGE_PATTERN,
31};
32
33struct SetSessionDescriptionMsg : public rtc::MessageData {
34 explicit SetSessionDescriptionMsg(
35 webrtc::SetSessionDescriptionObserver* observer)
36 : observer(observer) {}
37
38 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserver> observer;
39 RTCError error;
40};
41
42struct CreateSessionDescriptionMsg : public rtc::MessageData {
43 explicit CreateSessionDescriptionMsg(
44 webrtc::CreateSessionDescriptionObserver* observer)
45 : observer(observer) {}
46
47 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer;
48 RTCError error;
49};
50
51struct GetStatsMsg : public rtc::MessageData {
52 GetStatsMsg(webrtc::StatsObserver* observer,
53 StatsCollectorInterface* stats,
54 webrtc::MediaStreamTrackInterface* track)
55 : observer(observer), stats(stats), track(track) {}
56 rtc::scoped_refptr<webrtc::StatsObserver> observer;
57 StatsCollectorInterface* stats;
58 rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track;
59};
60
61struct RequestUsagePatternMsg : public rtc::MessageData {
62 explicit RequestUsagePatternMsg(std::function<void()> func)
63 : function(func) {}
64 std::function<void()> function;
65};
66
67} // namespace
68
69PeerConnectionMessageHandler::~PeerConnectionMessageHandler() {
70 // Process all pending notifications in the message queue. If we don't do
71 // this, requests will linger and not know they succeeded or failed.
72 rtc::MessageList list;
73 signaling_thread()->Clear(this, rtc::MQID_ANY, &list);
74 for (auto& msg : list) {
75 if (msg.message_id == MSG_CREATE_SESSIONDESCRIPTION_FAILED) {
76 // Processing CreateOffer() and CreateAnswer() messages ensures their
77 // observers are invoked even if the PeerConnection is destroyed early.
78 OnMessage(&msg);
79 } else {
80 // TODO(hbos): Consider processing all pending messages. This would mean
81 // that SetLocalDescription() and SetRemoteDescription() observers are
82 // informed of successes and failures; this is currently NOT the case.
83 delete msg.pdata;
84 }
85 }
86}
87
88void PeerConnectionMessageHandler::OnMessage(rtc::Message* msg) {
89 RTC_DCHECK_RUN_ON(signaling_thread());
90 switch (msg->message_id) {
91 case MSG_SET_SESSIONDESCRIPTION_SUCCESS: {
92 SetSessionDescriptionMsg* param =
93 static_cast<SetSessionDescriptionMsg*>(msg->pdata);
94 param->observer->OnSuccess();
95 delete param;
96 break;
97 }
98 case MSG_SET_SESSIONDESCRIPTION_FAILED: {
99 SetSessionDescriptionMsg* param =
100 static_cast<SetSessionDescriptionMsg*>(msg->pdata);
101 param->observer->OnFailure(std::move(param->error));
102 delete param;
103 break;
104 }
105 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: {
106 CreateSessionDescriptionMsg* param =
107 static_cast<CreateSessionDescriptionMsg*>(msg->pdata);
108 param->observer->OnFailure(std::move(param->error));
109 delete param;
110 break;
111 }
112 case MSG_GETSTATS: {
113 GetStatsMsg* param = static_cast<GetStatsMsg*>(msg->pdata);
114 StatsReports reports;
115 param->stats->GetStats(param->track, &reports);
116 param->observer->OnComplete(reports);
117 delete param;
118 break;
119 }
120 case MSG_REPORT_USAGE_PATTERN: {
121 RequestUsagePatternMsg* param =
122 static_cast<RequestUsagePatternMsg*>(msg->pdata);
123 param->function();
124 delete param;
125 break;
126 }
127 default:
128 RTC_NOTREACHED() << "Not implemented";
129 break;
130 }
131}
132
133void PeerConnectionMessageHandler::PostSetSessionDescriptionSuccess(
134 SetSessionDescriptionObserver* observer) {
135 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
136 signaling_thread()->Post(RTC_FROM_HERE, this,
137 MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg);
138}
139
140void PeerConnectionMessageHandler::PostSetSessionDescriptionFailure(
141 SetSessionDescriptionObserver* observer,
142 RTCError&& error) {
143 RTC_DCHECK(!error.ok());
144 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
145 msg->error = std::move(error);
146 signaling_thread()->Post(RTC_FROM_HERE, this,
147 MSG_SET_SESSIONDESCRIPTION_FAILED, msg);
148}
149
150void PeerConnectionMessageHandler::PostCreateSessionDescriptionFailure(
151 CreateSessionDescriptionObserver* observer,
152 RTCError error) {
153 RTC_DCHECK(!error.ok());
154 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
155 msg->error = std::move(error);
156 signaling_thread()->Post(RTC_FROM_HERE, this,
157 MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
158}
159
160void PeerConnectionMessageHandler::PostGetStats(
161 StatsObserver* observer,
162 StatsCollectorInterface* stats,
163 MediaStreamTrackInterface* track) {
164 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_GETSTATS,
165 new GetStatsMsg(observer, stats, track));
166}
167
168void PeerConnectionMessageHandler::RequestUsagePatternReport(
169 std::function<void()> func,
170 int delay_ms) {
171 signaling_thread()->PostDelayed(RTC_FROM_HERE, delay_ms, this,
172 MSG_REPORT_USAGE_PATTERN,
173 new RequestUsagePatternMsg(func));
174}
175
176} // namespace webrtc