1 /*
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 "api/scoped_refptr.h"
19 #include "api/sequence_checker.h"
20 #include "api/stats_types.h"
21 #include "pc/stats_collector_interface.h"
22 #include "rtc_base/checks.h"
23 #include "rtc_base/location.h"
24
25 namespace webrtc {
26
27 namespace {
28
29 enum {
30 MSG_SET_SESSIONDESCRIPTION_SUCCESS = 0,
31 MSG_SET_SESSIONDESCRIPTION_FAILED,
32 MSG_CREATE_SESSIONDESCRIPTION_FAILED,
33 MSG_GETSTATS,
34 MSG_REPORT_USAGE_PATTERN,
35 };
36
37 struct SetSessionDescriptionMsg : public rtc::MessageData {
SetSessionDescriptionMsgwebrtc::__anonac870d370111::SetSessionDescriptionMsg38 explicit SetSessionDescriptionMsg(
39 webrtc::SetSessionDescriptionObserver* observer)
40 : observer(observer) {}
41
42 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserver> observer;
43 RTCError error;
44 };
45
46 struct CreateSessionDescriptionMsg : public rtc::MessageData {
CreateSessionDescriptionMsgwebrtc::__anonac870d370111::CreateSessionDescriptionMsg47 explicit CreateSessionDescriptionMsg(
48 webrtc::CreateSessionDescriptionObserver* observer)
49 : observer(observer) {}
50
51 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer;
52 RTCError error;
53 };
54
55 struct GetStatsMsg : public rtc::MessageData {
GetStatsMsgwebrtc::__anonac870d370111::GetStatsMsg56 GetStatsMsg(webrtc::StatsObserver* observer,
57 StatsCollectorInterface* stats,
58 webrtc::MediaStreamTrackInterface* track)
59 : observer(observer), stats(stats), track(track) {}
60 rtc::scoped_refptr<webrtc::StatsObserver> observer;
61 StatsCollectorInterface* stats;
62 rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track;
63 };
64
65 struct RequestUsagePatternMsg : public rtc::MessageData {
RequestUsagePatternMsgwebrtc::__anonac870d370111::RequestUsagePatternMsg66 explicit RequestUsagePatternMsg(std::function<void()> func)
67 : function(func) {}
68 std::function<void()> function;
69 };
70
71 } // namespace
72
~PeerConnectionMessageHandler()73 PeerConnectionMessageHandler::~PeerConnectionMessageHandler() {
74 // Process all pending notifications in the message queue. If we don't do
75 // this, requests will linger and not know they succeeded or failed.
76 rtc::MessageList list;
77 signaling_thread()->Clear(this, rtc::MQID_ANY, &list);
78 for (auto& msg : list) {
79 if (msg.message_id == MSG_CREATE_SESSIONDESCRIPTION_FAILED) {
80 // Processing CreateOffer() and CreateAnswer() messages ensures their
81 // observers are invoked even if the PeerConnection is destroyed early.
82 OnMessage(&msg);
83 } else {
84 // TODO(hbos): Consider processing all pending messages. This would mean
85 // that SetLocalDescription() and SetRemoteDescription() observers are
86 // informed of successes and failures; this is currently NOT the case.
87 delete msg.pdata;
88 }
89 }
90 }
91
OnMessage(rtc::Message * msg)92 void PeerConnectionMessageHandler::OnMessage(rtc::Message* msg) {
93 RTC_DCHECK_RUN_ON(signaling_thread());
94 switch (msg->message_id) {
95 case MSG_SET_SESSIONDESCRIPTION_SUCCESS: {
96 SetSessionDescriptionMsg* param =
97 static_cast<SetSessionDescriptionMsg*>(msg->pdata);
98 param->observer->OnSuccess();
99 delete param;
100 break;
101 }
102 case MSG_SET_SESSIONDESCRIPTION_FAILED: {
103 SetSessionDescriptionMsg* param =
104 static_cast<SetSessionDescriptionMsg*>(msg->pdata);
105 param->observer->OnFailure(std::move(param->error));
106 delete param;
107 break;
108 }
109 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: {
110 CreateSessionDescriptionMsg* param =
111 static_cast<CreateSessionDescriptionMsg*>(msg->pdata);
112 param->observer->OnFailure(std::move(param->error));
113 delete param;
114 break;
115 }
116 case MSG_GETSTATS: {
117 GetStatsMsg* param = static_cast<GetStatsMsg*>(msg->pdata);
118 StatsReports reports;
119 param->stats->GetStats(param->track, &reports);
120 param->observer->OnComplete(reports);
121 delete param;
122 break;
123 }
124 case MSG_REPORT_USAGE_PATTERN: {
125 RequestUsagePatternMsg* param =
126 static_cast<RequestUsagePatternMsg*>(msg->pdata);
127 param->function();
128 delete param;
129 break;
130 }
131 default:
132 RTC_NOTREACHED() << "Not implemented";
133 break;
134 }
135 }
136
PostSetSessionDescriptionSuccess(SetSessionDescriptionObserver * observer)137 void PeerConnectionMessageHandler::PostSetSessionDescriptionSuccess(
138 SetSessionDescriptionObserver* observer) {
139 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
140 signaling_thread()->Post(RTC_FROM_HERE, this,
141 MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg);
142 }
143
PostSetSessionDescriptionFailure(SetSessionDescriptionObserver * observer,RTCError && error)144 void PeerConnectionMessageHandler::PostSetSessionDescriptionFailure(
145 SetSessionDescriptionObserver* observer,
146 RTCError&& error) {
147 RTC_DCHECK(!error.ok());
148 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
149 msg->error = std::move(error);
150 signaling_thread()->Post(RTC_FROM_HERE, this,
151 MSG_SET_SESSIONDESCRIPTION_FAILED, msg);
152 }
153
PostCreateSessionDescriptionFailure(CreateSessionDescriptionObserver * observer,RTCError error)154 void PeerConnectionMessageHandler::PostCreateSessionDescriptionFailure(
155 CreateSessionDescriptionObserver* observer,
156 RTCError error) {
157 RTC_DCHECK(!error.ok());
158 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
159 msg->error = std::move(error);
160 signaling_thread()->Post(RTC_FROM_HERE, this,
161 MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
162 }
163
PostGetStats(StatsObserver * observer,StatsCollectorInterface * stats,MediaStreamTrackInterface * track)164 void PeerConnectionMessageHandler::PostGetStats(
165 StatsObserver* observer,
166 StatsCollectorInterface* stats,
167 MediaStreamTrackInterface* track) {
168 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_GETSTATS,
169 new GetStatsMsg(observer, stats, track));
170 }
171
RequestUsagePatternReport(std::function<void ()> func,int delay_ms)172 void PeerConnectionMessageHandler::RequestUsagePatternReport(
173 std::function<void()> func,
174 int delay_ms) {
175 signaling_thread()->PostDelayed(RTC_FROM_HERE, delay_ms, this,
176 MSG_REPORT_USAGE_PATTERN,
177 new RequestUsagePatternMsg(func));
178 }
179
180 } // namespace webrtc
181