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