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