1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef _PEER_CONNECTION_MEDIA_H_
6 #define _PEER_CONNECTION_MEDIA_H_
7 
8 #include <string>
9 #include <vector>
10 #include <map>
11 
12 #include "mozilla/RefPtr.h"
13 #include "mozilla/UniquePtr.h"
14 #include "mozilla/net/StunAddrsRequestChild.h"
15 #include "MediaTransportHandler.h"
16 #include "nsIHttpChannelInternal.h"
17 
18 #include "TransceiverImpl.h"
19 
20 class nsIPrincipal;
21 
22 namespace mozilla {
23 class DataChannel;
24 class PeerIdentity;
25 namespace dom {
26 class MediaStreamTrack;
27 }
28 }  // namespace mozilla
29 
30 #include "nriceresolver.h"
31 #include "nricemediastream.h"
32 
33 namespace mozilla {
34 
35 class PeerConnectionImpl;
36 class PeerConnectionMedia;
37 class PCUuidGenerator;
38 class MediaPipeline;
39 class MediaPipelineReceive;
40 class MediaPipelineTransmit;
41 class MediaPipelineFilter;
42 class JsepSession;
43 
44 // TODO(bug 1402997): If we move the TransceiverImpl stuff out of here, this
45 // will be a class that handles just the transport stuff, and we can rename it
46 // to something more explanatory (say, PeerConnectionTransportManager).
47 class PeerConnectionMedia : public sigslot::has_slots<> {
48   ~PeerConnectionMedia();
49 
50  public:
51   explicit PeerConnectionMedia(PeerConnectionImpl* parent);
52 
53   nsresult Init();
54   // WARNING: This destroys the object!
55   void SelfDestruct();
56 
57   // Ensure ICE transports exist that we might need when offer/answer concludes
58   void EnsureTransports(const JsepSession& aSession);
59 
60   // Activate ICE transports at the conclusion of offer/answer,
61   // or when rollback occurs.
62   nsresult UpdateTransports(const JsepSession& aSession,
63                             const bool forceIceTcp);
64 
ResetStunAddrsForIceRestart()65   void ResetStunAddrsForIceRestart() { mStunAddrs.Clear(); }
66 
67   // Start ICE checks.
68   void StartIceChecks(const JsepSession& session);
69 
70   // Process a trickle ICE candidate.
71   void AddIceCandidate(const std::string& candidate,
72                        const std::string& aTransportId,
73                        const std::string& aUFrag);
74 
75   // Handle notifications of network online/offline events.
76   void UpdateNetworkState(bool online);
77 
78   // Handle complete media pipelines.
79   // This updates codec parameters, starts/stops send/receive, and other
80   // stuff that doesn't necessarily require negotiation. This can be called at
81   // any time, not just when an offer/answer exchange completes.
82   // TODO: Let's move this to PeerConnectionImpl
83   nsresult UpdateMediaPipelines();
84 
85   // TODO: Let's move the TransceiverImpl stuff to PeerConnectionImpl.
86   nsresult AddTransceiver(JsepTransceiver* aJsepTransceiver,
87                           dom::MediaStreamTrack* aSendTrack,
88                           RefPtr<TransceiverImpl>* aTransceiverImpl);
89 
90   void GetTransmitPipelinesMatching(
91       const dom::MediaStreamTrack* aTrack,
92       nsTArray<RefPtr<MediaPipelineTransmit>>* aPipelines);
93 
94   std::string GetTransportIdMatchingSendTrack(
95       const dom::MediaStreamTrack& aTrack) const;
96 
97   // In cases where the peer isn't yet identified, we disable the pipeline (not
98   // the stream, that would potentially affect others), so that it sends
99   // black/silence.  Once the peer is identified, re-enable those streams.
100   // aTrack will be set if this update came from a principal change on aTrack.
101   // TODO: Move to PeerConnectionImpl
102   void UpdateSinkIdentity_m(const dom::MediaStreamTrack* aTrack,
103                             nsIPrincipal* aPrincipal,
104                             const PeerIdentity* aSinkIdentity);
105   // this determines if any track is peerIdentity constrained
106   bool AnyLocalTrackHasPeerIdentity() const;
107 
108   bool AnyCodecHasPluginID(uint64_t aPluginID);
109 
GetMainThread()110   const nsCOMPtr<nsIThread>& GetMainThread() const { return mMainThread; }
GetSTSThread()111   const nsCOMPtr<nsISerialEventTarget>& GetSTSThread() const {
112     return mSTSThread;
113   }
114 
115   // Used by PCImpl in a couple of places. Might be good to move that code in
116   // here.
GetTransceivers()117   std::vector<RefPtr<TransceiverImpl>>& GetTransceivers() {
118     return mTransceivers;
119   }
120 
121   nsPIDOMWindowInner* GetWindow() const;
122   already_AddRefed<nsIHttpChannelInternal> GetChannel() const;
123 
124   void AlpnNegotiated_s(const std::string& aAlpn, bool aPrivacyRequested);
125   void AlpnNegotiated_m(bool aPrivacyRequested);
126 
127   // TODO: Move to PeerConnectionImpl
128   RefPtr<WebRtcCallWrapper> mCall;
129 
130   // mtransport objects
131   RefPtr<MediaTransportHandler> mTransportHandler;
132 
133  private:
134   void InitLocalAddrs();  // for stun local address IPC request
135   bool ShouldForceProxy() const;
136   std::unique_ptr<NrSocketProxyConfig> GetProxyConfig() const;
137 
138   class StunAddrsHandler : public net::StunAddrsListener {
139    public:
StunAddrsHandler(PeerConnectionMedia * pcm)140     explicit StunAddrsHandler(PeerConnectionMedia* pcm) : pcm_(pcm) {}
141 
142     void OnMDNSQueryComplete(const nsCString& hostname,
143                              const Maybe<nsCString>& address) override;
144 
145     void OnStunAddrsAvailable(
146         const mozilla::net::NrIceStunAddrArray& addrs) override;
147 
148    private:
149     RefPtr<PeerConnectionMedia> pcm_;
~StunAddrsHandler()150     virtual ~StunAddrsHandler() {}
151   };
152 
153   // Shutdown media transport. Must be called on STS thread.
154   void ShutdownMediaTransport_s();
155 
156   // Final destruction of the media stream. Must be called on the main
157   // thread.
158   void SelfDestruct_m();
159 
160   // Manage ICE transports.
161   void UpdateTransport(const JsepTransceiver& aTransceiver, bool aForceIceTcp);
162 
163   void GatherIfReady();
164   void FlushIceCtxOperationQueueIfReady();
165   void PerformOrEnqueueIceCtxOperation(nsIRunnable* runnable);
166   nsresult SetTargetForDefaultLocalAddressLookup();
167   void EnsureIceGathering(bool aDefaultRouteOnly, bool aObfuscateHostAddresses);
168 
169   bool GetPrefDefaultAddressOnly() const;
170   bool GetPrefObfuscateHostAddresses() const;
171 
172   void ConnectSignals();
173 
174   // ICE events
175   void IceGatheringStateChange_s(dom::RTCIceGatheringState aState);
176   void IceConnectionStateChange_s(dom::RTCIceConnectionState aState);
177   void OnCandidateFound_s(const std::string& aTransportId,
178                           const CandidateInfo& aCandidateInfo);
179 
180   void IceGatheringStateChange_m(dom::RTCIceGatheringState aState);
181   void IceConnectionStateChange_m(dom::RTCIceConnectionState aState);
182   void OnCandidateFound_m(const std::string& aTransportId,
183                           const CandidateInfo& aCandidateInfo);
184 
IsIceCtxReady()185   bool IsIceCtxReady() const {
186     return mLocalAddrsRequestState == STUN_ADDR_REQUEST_COMPLETE;
187   }
188 
189   // The parent PC
190   PeerConnectionImpl* mParent;
191   // and a loose handle on it for event driven stuff
192   std::string mParentHandle;
193   std::string mParentName;
194 
195   std::vector<RefPtr<TransceiverImpl>> mTransceivers;
196 
197   // The main thread.
198   nsCOMPtr<nsIThread> mMainThread;
199 
200   // The STS thread.
201   nsCOMPtr<nsISerialEventTarget> mSTSThread;
202 
203   // Used whenever we need to dispatch a runnable to STS to tweak something
204   // on our ICE ctx, but are not ready to do so at the moment (eg; we are
205   // waiting to get a callback with our http proxy config before we start
206   // gathering or start checking)
207   std::vector<nsCOMPtr<nsIRunnable>> mQueuedIceCtxOperations;
208 
209   // Set if prefs dictate that we should force the use of a web proxy.
210   bool mForceProxy;
211 
212   // Used to cancel incoming stun addrs response
213   RefPtr<net::StunAddrsRequestChild> mStunAddrsRequest;
214 
215   enum StunAddrRequestState {
216     STUN_ADDR_REQUEST_NONE,
217     STUN_ADDR_REQUEST_PENDING,
218     STUN_ADDR_REQUEST_COMPLETE
219   };
220   // Used to track the state of the stun addr IPC request
221   StunAddrRequestState mLocalAddrsRequestState;
222 
223   // Used to store the result of the stun addr IPC request
224   nsTArray<NrIceStunAddr> mStunAddrs;
225 
226   // Used to ensure the target for default local address lookup is only set
227   // once.
228   bool mTargetForDefaultLocalAddressLookupIsSet;
229 
230   // Set to true when the object is going to be released.
231   bool mDestroyed;
232 
233   // Keep track of local hostnames to register. Registration is deferred
234   // until StartIceChecks has run. Accessed on main thread only.
235   std::map<std::string, std::string> mMDNSHostnamesToRegister;
236   bool mCanRegisterMDNSHostnamesDirectly = false;
237 
238   // Used to store the mDNS hostnames that we have registered
239   std::set<std::string> mRegisteredMDNSHostnames;
240 
241   // Used to store the mDNS hostnames that we have queried
242   struct PendingIceCandidate {
243     std::vector<std::string> mTokenizedCandidate;
244     std::string mTransportId;
245     std::string mUfrag;
246   };
247   std::map<std::string, std::list<PendingIceCandidate>> mQueriedMDNSHostnames;
248 
249   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
250 };
251 
252 }  // namespace mozilla
253 
254 #endif
255