1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_TRACKER_H_
6 #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_TRACKER_H_
7 
8 #include "base/macros.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/threading/thread_checker.h"
11 #include "mojo/public/cpp/bindings/receiver.h"
12 #include "mojo/public/cpp/bindings/remote.h"
13 #include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
14 #include "third_party/blink/renderer/modules/modules_export.h"
15 #include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
16 #include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
17 #include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
18 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
19 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
20 #include "third_party/webrtc/api/peer_connection_interface.h"
21 
22 namespace webrtc {
23 class DataChannelInterface;
24 }  // namespace webrtc
25 
26 namespace blink {
27 class MediaConstraints;
28 class RTCAnswerOptionsPlatform;
29 class RTCIceCandidatePlatform;
30 class RTCOfferOptionsPlatform;
31 class RTCPeerConnectionHandler;
32 class UserMediaRequest;
33 class WebLocalFrame;
34 
35 // This class collects data about each peer connection,
36 // sends it to the browser process, and handles messages
37 // from the browser process.
38 class MODULES_EXPORT PeerConnectionTracker
39     : public blink::mojom::blink::PeerConnectionManager,
40       public base::SupportsWeakPtr<PeerConnectionTracker> {
41  public:
42   static PeerConnectionTracker* GetInstance();
43 
44   ~PeerConnectionTracker() override;
45 
46   enum Source { SOURCE_LOCAL, SOURCE_REMOTE };
47 
48   enum Action {
49     ACTION_SET_LOCAL_DESCRIPTION,
50     ACTION_SET_LOCAL_DESCRIPTION_IMPLICIT,
51     ACTION_SET_REMOTE_DESCRIPTION,
52     ACTION_CREATE_OFFER,
53     ACTION_CREATE_ANSWER
54   };
55 
56   // In Plan B: "Transceiver" refers to RTCRtpSender or RTCRtpReceiver.
57   // In Unified Plan: "Transceiver" refers to RTCRtpTransceiver.
58   enum class TransceiverUpdatedReason {
59     kAddTransceiver,
60     kAddTrack,
61     kRemoveTrack,
62     kSetLocalDescription,
63     kSetRemoteDescription,
64   };
65 
66   void Bind(mojo::PendingReceiver<blink::mojom::blink::PeerConnectionManager>
67                 receiver);
68 
69   // The following methods send an update to the browser process when a
70   // PeerConnection update happens. The caller should call the Track* methods
71   // after calling RegisterPeerConnection and before calling
72   // UnregisterPeerConnection, otherwise the Track* call has no effect.
73 
74   // Sends an update when a PeerConnection has been created in Javascript. This
75   // should be called once and only once for each PeerConnection. The
76   // |pc_handler| is the handler object associated with the PeerConnection, the
77   // |servers| are the server configurations used to establish the connection,
78   // the |constraints| are the media constraints used to initialize the
79   // PeerConnection, the |frame| is the WebLocalFrame object representing the
80   // page in which the PeerConnection is created.
81   void RegisterPeerConnection(
82       RTCPeerConnectionHandler* pc_handler,
83       const webrtc::PeerConnectionInterface::RTCConfiguration& config,
84       const MediaConstraints& constraints,
85       const blink::WebLocalFrame* frame);
86 
87   // Sends an update when a PeerConnection has been destroyed.
88   virtual void UnregisterPeerConnection(RTCPeerConnectionHandler* pc_handler);
89 
90   // Sends an update when createOffer/createAnswer has been called.
91   // The |pc_handler| is the handler object associated with the PeerConnection,
92   // the |constraints| is the media constraints used to create the offer/answer.
93   virtual void TrackCreateOffer(RTCPeerConnectionHandler* pc_handler,
94                                 RTCOfferOptionsPlatform* options);
95   // TODO(hta): Get rid of the version below.
96   virtual void TrackCreateOffer(RTCPeerConnectionHandler* pc_handler,
97                                 const MediaConstraints& options);
98   virtual void TrackCreateAnswer(RTCPeerConnectionHandler* pc_handler,
99                                  blink::RTCAnswerOptionsPlatform* options);
100   virtual void TrackCreateAnswer(RTCPeerConnectionHandler* pc_handler,
101                                  const MediaConstraints& constraints);
102 
103   // Sends an update when setLocalDescription or setRemoteDescription is called.
104   virtual void TrackSetSessionDescription(RTCPeerConnectionHandler* pc_handler,
105                                           const String& sdp,
106                                           const String& type,
107                                           Source source);
108   virtual void TrackSetSessionDescriptionImplicit(
109       RTCPeerConnectionHandler* pc_handler);
110 
111   // Sends an update when setConfiguration is called.
112   virtual void TrackSetConfiguration(
113       RTCPeerConnectionHandler* pc_handler,
114       const webrtc::PeerConnectionInterface::RTCConfiguration& config);
115 
116   // Sends an update when an Ice candidate is added.
117   virtual void TrackAddIceCandidate(RTCPeerConnectionHandler* pc_handler,
118                                     RTCIceCandidatePlatform* candidate,
119                                     Source source,
120                                     bool succeeded);
121   // Sends an update when an Ice candidate error is receiver.
122   virtual void TrackIceCandidateError(RTCPeerConnectionHandler* pc_handler,
123                                       const String& address,
124                                       base::Optional<uint16_t> port,
125                                       const String& host_candidate,
126                                       const String& url,
127                                       int error_code,
128                                       const String& error_text);
129 
130   // Sends an update when a transceiver is added, modified or removed. This can
131   // happen as a result of any of the methods indicated by |reason|.
132   // In Plan B: |transceiver| refers to its Sender() or Receiver() depending on
133   // ImplementationType(). Example events: "senderAdded", "receiverRemoved".
134   // In Plan B: |transceiver| has a fully implemented ImplementationType().
135   // Example events: "transceiverAdded", "transceiverModified".
136   // See peer_connection_tracker_unittest.cc for expected resulting event
137   // strings.
138   virtual void TrackAddTransceiver(RTCPeerConnectionHandler* pc_handler,
139                                    TransceiverUpdatedReason reason,
140                                    const RTCRtpTransceiverPlatform& transceiver,
141                                    size_t transceiver_index);
142   virtual void TrackModifyTransceiver(
143       RTCPeerConnectionHandler* pc_handler,
144       TransceiverUpdatedReason reason,
145       const RTCRtpTransceiverPlatform& transceiver,
146       size_t transceiver_index);
147   // TODO(hbos): When Plan B is removed this is no longer applicable.
148   // https://crbug.com/857004
149   virtual void TrackRemoveTransceiver(
150       RTCPeerConnectionHandler* pc_handler,
151       TransceiverUpdatedReason reason,
152       const RTCRtpTransceiverPlatform& transceiver,
153       size_t transceiver_index);
154 
155   // Sends an update when a DataChannel is created.
156   virtual void TrackCreateDataChannel(
157       RTCPeerConnectionHandler* pc_handler,
158       const webrtc::DataChannelInterface* data_channel,
159       Source source);
160 
161   // Sends an update when a PeerConnection has been stopped.
162   virtual void TrackStop(RTCPeerConnectionHandler* pc_handler);
163 
164   // Sends an update when the signaling state of a PeerConnection has changed.
165   virtual void TrackSignalingStateChange(
166       RTCPeerConnectionHandler* pc_handler,
167       webrtc::PeerConnectionInterface::SignalingState state);
168 
169   // Sends an update when the ICE connection state of a PeerConnection has
170   // changed. There's a legacy and non-legacy version. The non-legacy version
171   // reflects the blink::RTCPeerConnection::iceConnectionState.
172   //
173   // "Legacy" usage: In Unifed Plan, TrackLegacyIceConnectionStateChange() is
174   // used to report the webrtc::PeerConnection layer implementation of the
175   // state, which might not always be the same as the
176   // blink::RTCPeerConnection::iceConnectionState reported with
177   // TrackIceConnectionStateChange(). In Plan B, the webrtc::PeerConnection
178   // layer implementation is the only iceConnectionState version, and
179   // TrackLegacyIceConnectionStateChange() is not applicable.
180   virtual void TrackLegacyIceConnectionStateChange(
181       RTCPeerConnectionHandler* pc_handler,
182       webrtc::PeerConnectionInterface::IceConnectionState state);
183   virtual void TrackIceConnectionStateChange(
184       RTCPeerConnectionHandler* pc_handler,
185       webrtc::PeerConnectionInterface::IceConnectionState state);
186 
187   // Sends an update when the connection state
188   // of a PeerConnection has changed.
189   virtual void TrackConnectionStateChange(
190       RTCPeerConnectionHandler* pc_handler,
191       webrtc::PeerConnectionInterface::PeerConnectionState state);
192 
193   // Sends an update when the Ice gathering state
194   // of a PeerConnection has changed.
195   virtual void TrackIceGatheringStateChange(
196       RTCPeerConnectionHandler* pc_handler,
197       webrtc::PeerConnectionInterface::IceGatheringState state);
198 
199   // Sends an update when the SetSessionDescription or CreateOffer or
200   // CreateAnswer callbacks are called.
201   virtual void TrackSessionDescriptionCallback(
202       RTCPeerConnectionHandler* pc_handler,
203       Action action,
204       const String& type,
205       const String& value);
206 
207   // Sends an update when the session description's ID is set.
208   virtual void TrackSessionId(RTCPeerConnectionHandler* pc_handler,
209                               const String& session_id);
210 
211   // Sends an update when onRenegotiationNeeded is called.
212   virtual void TrackOnRenegotiationNeeded(RTCPeerConnectionHandler* pc_handler);
213 
214   // Sends an update when getUserMedia is called.
215   virtual void TrackGetUserMedia(UserMediaRequest* user_media_request);
216 
217   // Sends a new fragment on an RtcEventLog.
218   virtual void TrackRtcEventLogWrite(RTCPeerConnectionHandler* pc_handler,
219                                      const WTF::Vector<uint8_t>& output);
220 
221  private:
222   // For tests.
223   friend class PeerConnectionTrackerTest;
224   friend class MockPeerConnectionTracker;
225 
226   FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, CreatingObject);
227   FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend);
228 
229   explicit PeerConnectionTracker(
230       scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
231   PeerConnectionTracker(
232       mojo::Remote<mojom::blink::PeerConnectionTrackerHost> host,
233       scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
234 
235   // Assign a local ID to a peer connection so that the browser process can
236   // uniquely identify a peer connection in the renderer process.
237   // The return value will always be positive.
238   int GetNextLocalID();
239 
240   // Looks up a handler in our map and if found, returns its ID. If the handler
241   // is not registered, the return value will be -1.
242   int GetLocalIDForHandler(RTCPeerConnectionHandler* handler) const;
243 
244   void TrackTransceiver(const char* callback_type_ending,
245                         RTCPeerConnectionHandler* pc_handler,
246                         PeerConnectionTracker::TransceiverUpdatedReason reason,
247                         const RTCRtpTransceiverPlatform& transceiver,
248                         size_t transceiver_index);
249 
250   // PeerConnectionTracker implementation.
251   void OnSuspend() override;
252   void StartEventLog(int peer_connection_local_id,
253                      int output_period_ms) override;
254   void StopEventLog(int peer_connection_local_id) override;
255   void GetStandardStats() override;
256   void GetLegacyStats() override;
257 
258   // Called to deliver an update to the host (PeerConnectionTrackerHost).
259   // |local_id| - The id of the registered RTCPeerConnectionHandler.
260   //              Using an id instead of the hander pointer is done on purpose
261   //              to force doing the lookup before building the callback data
262   //              in case the handler isn't registered.
263   // |callback_type| - A string, most often static, that represents the type
264   //                   of operation that the data stored in |value| comes from.
265   //                   E.g. "createOffer", "createAnswer",
266   //                   "setRemoteDescription" etc.
267   // |value| - A json serialized string containing all the information for the
268   //           update event.
269   void SendPeerConnectionUpdate(int local_id,
270                                 const String& callback_type,
271                                 const String& value);
272 
273   void AddStandardStats(int lid, base::Value value);
274   void AddLegacyStats(int lid, base::Value value);
275 
276   // This map stores the local ID assigned to each RTCPeerConnectionHandler.
277   typedef WTF::HashMap<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap;
278   PeerConnectionLocalIdMap peer_connection_local_id_map_;
279 
280   // This keeps track of the next available local ID.
281   int next_local_id_;
282   THREAD_CHECKER(main_thread_);
283   mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost>
284       peer_connection_tracker_host_;
285   mojo::Receiver<blink::mojom::blink::PeerConnectionManager> receiver_{this};
286 
287   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
288 
289   DISALLOW_COPY_AND_ASSIGN(PeerConnectionTracker);
290 };
291 
292 }  // namespace blink
293 
294 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_TRACKER_H_
295