diff --git a/content/media/webrtc/PeerIdentity.cpp b/content/media/webrtc/PeerIdentity.cpp index 79a1669e0005..e53c7d546e2e 100644 --- a/content/media/webrtc/PeerIdentity.cpp +++ b/content/media/webrtc/PeerIdentity.cpp @@ -9,7 +9,6 @@ #include "nsCOMPtr.h" #include "nsIIDNService.h" #include "nsNetCID.h" -#include "nsServiceManagerUtils.h" namespace mozilla { @@ -37,7 +36,7 @@ PeerIdentity::Equals(const nsAString& aOtherString) const nsresult rv; nsCOMPtr<nsIIDNService> idnService - = do_GetService("@mozilla.org/network/idn-service;1", &rv); + = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return host == otherHost; } diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index 6f1ce3535617..86374d147ffa 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -23,7 +23,6 @@ #include "nsIDocument.h" #include "nsISupportsPrimitives.h" #include "nsIInterfaceRequestorUtils.h" -#include "mozilla/PeerIdentity.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/MediaStreamBinding.h" #include "mozilla/dom/MediaStreamTrackBinding.h" @@ -38,8 +37,6 @@ #include "nsDOMFile.h" #include "nsGlobalWindow.h" -#include "mozilla/Preferences.h" - /* Using WebRTC backend on Desktops (Mac, Windows, Linux), otherwise default */ #include "MediaEngineDefault.h" #if defined(MOZ_WEBRTC) @@ -90,7 +87,7 @@ using dom::OwningBooleanOrMediaTrackConstraintsInternal; static nsresult CompareDictionaries(JSContext* aCx, JSObject *aA, const MediaTrackConstraintSet &aB, - nsAString &aDifference) + nsString *aDifference) { JS::Rooted<JSObject*> a(aCx, aA); JSAutoCompartment ac(aCx, aA); @@ -117,11 +114,11 @@ static nsresult CompareDictionaries(JSContext* aCx, JSObject *aA, JS::Rooted<JSString*> namestr(aCx, JS::ToString(aCx, nameval)); NS_ENSURE_TRUE(namestr, NS_ERROR_UNEXPECTED); - aDifference.Assign(JS_GetStringCharsZ(aCx, namestr)); + aDifference->Assign(JS_GetStringCharsZ(aCx, namestr)); return NS_OK; } } - aDifference.Truncate(); + aDifference->Truncate(); return NS_OK; } @@ -505,13 +502,11 @@ public: uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener* aListener, MediaEngineSource* aAudioSource, - MediaEngineSource* aVideoSource, - PeerIdentity* aPeerIdentity) + MediaEngineSource* aVideoSource) : mAudioSource(aAudioSource) , mVideoSource(aVideoSource) , mWindowID(aWindowID) , mListener(aListener) - , mPeerIdentity(aPeerIdentity) , mManager(MediaManager::GetInstance()) { mSuccess.swap(aSuccess); @@ -630,16 +625,9 @@ public: reinterpret_cast<uint64_t>(stream.get()), reinterpret_cast<int64_t>(trackunion->GetStream())); - nsCOMPtr<nsIPrincipal> principal; - if (mPeerIdentity) { - principal = do_CreateInstance("@mozilla.org/nullprincipal;1"); - trackunion->SetPeerIdentity(mPeerIdentity.forget()); - } else { - principal = window->GetExtantDoc()->NodePrincipal(); - } - trackunion->CombineWithPrincipal(principal); + trackunion->CombineWithPrincipal(window->GetExtantDoc()->NodePrincipal()); - // The listener was added at the beginning in an inactive state. + // The listener was added at the begining in an inactive state. // Activate our listener. We'll call Start() on the source when get a callback // that the MediaStream has started consuming. The listener is freed // when the page is invalidated (on navigation or close). @@ -680,7 +668,6 @@ private: nsRefPtr<MediaEngineSource> mVideoSource; uint64_t mWindowID; nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; - nsAutoPtr<PeerIdentity> mPeerIdentity; nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable }; @@ -1050,14 +1037,9 @@ public: return; } } - PeerIdentity* peerIdentity = nullptr; - if (!mConstraints.mPeerIdentity.IsEmpty()) { - peerIdentity = new PeerIdentity(mConstraints.mPeerIdentity); - } NS_DispatchToMainThread(new GetUserMediaStreamRunnable( - mSuccess, mError, mWindowID, mListener, aAudioSource, aVideoSource, - peerIdentity + mSuccess, mError, mWindowID, mListener, aAudioSource, aVideoSource )); MOZ_ASSERT(!mSuccess); @@ -1290,8 +1272,8 @@ MediaManager::NotifyRecordingStatusChange(nsPIDOMWindow* aWindow, props->SetPropertyAsAString(NS_LITERAL_STRING("requestURL"), requestURL); obs->NotifyObservers(static_cast<nsIPropertyBag2*>(props), - "recording-device-events", - aMsg.get()); + "recording-device-events", + aMsg.get()); // Forward recording events to parent process. // The events are gathered in chrome process and used for recording indicator @@ -1352,13 +1334,13 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged, if (audioObj) { nsresult rv = CompareDictionaries(aCx, audioObj, c.mAudio.GetAsMediaTrackConstraintsInternal().mMandatory, - unknownConstraintFound); + &unknownConstraintFound); NS_ENSURE_SUCCESS(rv, rv); } if (videoObj) { nsresult rv = CompareDictionaries(aCx, videoObj, c.mVideo.GetAsMediaTrackConstraintsInternal().mMandatory, - unknownConstraintFound); + &unknownConstraintFound); NS_ENSURE_SUCCESS(rv, rv); } @@ -1699,7 +1681,8 @@ MediaManager::RemoveFromWindowList(uint64_t aWindowID, // Notify the UI that this window no longer has gUM active char windowBuffer[32]; PR_snprintf(windowBuffer, sizeof(windowBuffer), "%llu", outerID); - nsString data = NS_ConvertUTF8toUTF16(windowBuffer); + nsAutoString data; + data.Append(NS_ConvertUTF8toUTF16(windowBuffer)); nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); obs->NotifyObservers(nullptr, "recording-window-ended", data.get()); diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js index 5367a17c5c9c..b4d52055aa46 100644 --- a/dom/media/PeerConnection.js +++ b/dom/media/PeerConnection.js @@ -292,8 +292,8 @@ RTCPeerConnection.prototype = { this._trickleIce = Services.prefs.getBoolPref("media.peerconnection.trickle_ice"); if (!rtcConfig.iceServers || !Services.prefs.getBoolPref("media.peerconnection.use_document_iceservers")) { - rtcConfig.iceServers = - JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers")); + rtcConfig = {iceServers: + JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers"))}; } this._mustValidateRTCConfiguration(rtcConfig, "RTCPeerConnection constructor passed invalid RTCConfiguration"); @@ -348,19 +348,6 @@ RTCPeerConnection.prototype = { return this._pc; }, - callCB: function(callback, arg) { - if (callback) { - try { - callback(arg); - } catch(e) { - // A content script (user-provided) callback threw an error. We don't - // want this to take down peerconnection, but we still want the user - // to see it, so we catch it, report it, and move on. - this.reportError(e.message, e.fileName, e.lineNumber); - } - } - }, - _initIdp: function() { let prefName = "media.peerconnection.identity.timeout"; let idpTimeout = Services.prefs.getIntPref(prefName); @@ -673,6 +660,15 @@ RTCPeerConnection.prototype = { "Invalid type " + desc.type + " provided to setRemoteDescription"); } + try { + let processIdentity = this._processIdentity.bind(this); + this._remoteIdp.verifyIdentityFromSDP(desc.sdp, processIdentity); + } catch (e) { + this.reportWarning(e.message, e.fileName, e.lineNumber); + // only happens if processing the SDP for identity doesn't work + // let _setRemoteDescription do the error reporting + } + this._queueOrRun({ func: this._setRemoteDescription, args: [type, desc.sdp, onSuccess, onError], @@ -681,84 +677,18 @@ RTCPeerConnection.prototype = { }); }, - /** - * Takes a result from the IdP and checks it against expectations. - * If OK, generates events. - * Returns true if it is either present and valid, or if there is no - * need for identity. - */ - _processIdpResult: function(message) { - let good = !!message; - // This might be a valid assertion, but if we are constrained to a single peer - // identity, then we also need to make sure that the assertion matches - if (good && this._impl.peerIdentity) { - good = (message.identity === this._impl.peerIdentity); - } - if (good) { - this._impl.peerIdentity = message.identity; + _processIdentity: function(message) { + if (message) { this._peerIdentity = new this._win.RTCIdentityAssertion( - this._remoteIdp.provider, message.identity); + this._remoteIdp.provider, message.identity); + + let args = { peerIdentity: this._peerIdentity }; this.dispatchEvent(new this._win.Event("peeridentity")); } - return good; }, _setRemoteDescription: function(type, sdp, onSuccess, onError) { - let idpComplete = false; - let setRemoteComplete = false; - let idpError = null; - - // we can run the IdP validation in parallel with setRemoteDescription this - // complicates much more than would be ideal, but it ensures that the IdP - // doesn't hold things up too much when it's not on the critical path - let allDone = () => { - if (!setRemoteComplete || !idpComplete || !onSuccess) { - return; - } - this._remoteType = this._pendingType; - this._pendingType = null; - this.callCB(onSuccess); - onSuccess = null; - this._executeNext(); - }; - - let setRemoteDone = () => { - setRemoteComplete = true; - allDone(); - }; - - // If we aren't waiting for something specific, allow this - // to complete asynchronously. - let idpDone; - if (!this._impl.peerIdentity) { - idpDone = this._processIdpResult.bind(this); - idpComplete = true; // lie about this for allDone() - } else { - idpDone = message => { - let idpGood = this._processIdpResult(message); - if (!idpGood) { - // iff we are waiting for a very specific peerIdentity - // call the error callback directly and then close - idpError = "Peer Identity mismatch, expected: " + - this._impl.peerIdentity; - this.callCB(onError, idpError); - this.close(); - } else { - idpComplete = true; - allDone(); - } - }; - } - - try { - this._remoteIdp.verifyIdentityFromSDP(sdp, idpDone); - } catch (e) { - // if processing the SDP for identity doesn't work - this.reportWarning(e.message, e.fileName, e.lineNumber); - idpDone(null); - } - - this._onSetRemoteDescriptionSuccess = setRemoteDone; + this._onSetRemoteDescriptionSuccess = onSuccess; this._onSetRemoteDescriptionFailure = onError; this._impl.setRemoteDescription(type, sdp); }, @@ -777,14 +707,14 @@ RTCPeerConnection.prototype = { getIdentityAssertion: function() { this._checkClosed(); - var gotAssertion = assertion => { + function gotAssertion(assertion) { if (assertion) { this._gotIdentityAssertion(assertion); } - }; + } this._localIdp.getIdentityAssertion(this._impl.fingerprint, - gotAssertion); + gotAssertion.bind(this)); }, updateIce: function(config, constraints) { @@ -1038,6 +968,19 @@ PeerConnectionObserver.prototype = { this._dompc.dispatchEvent(event); }, + callCB: function(callback, arg) { + if (callback) { + try { + callback(arg); + } catch(e) { + // A content script (user-provided) callback threw an error. We don't + // want this to take down peerconnection, but we still want the user + // to see it, so we catch it, report it, and move on. + this._dompc.reportError(e.message, e.fileName, e.lineNumber); + } + } + }, + onCreateOfferSuccess: function(sdp) { let pc = this._dompc; let fp = pc._impl.fingerprint; @@ -1045,15 +988,15 @@ PeerConnectionObserver.prototype = { if (assertion) { pc._gotIdentityAssertion(assertion); } - pc.callCB(pc._onCreateOfferSuccess, - new pc._win.mozRTCSessionDescription({ type: "offer", - sdp: sdp })); + this.callCB(pc._onCreateOfferSuccess, + new pc._win.mozRTCSessionDescription({ type: "offer", + sdp: sdp })); pc._executeNext(); }.bind(this)); }, onCreateOfferError: function(code, message) { - this._dompc.callCB(this._dompc._onCreateOfferFailure, new RTCError(code, message)); + this.callCB(this._dompc._onCreateOfferFailure, new RTCError(code, message)); this._dompc._executeNext(); }, @@ -1064,23 +1007,22 @@ PeerConnectionObserver.prototype = { if (assertion) { pc._gotIdentityAssertion(assertion); } - pc.callCB(pc._onCreateAnswerSuccess, - new pc._win.mozRTCSessionDescription({ type: "answer", - sdp: sdp })); + this.callCB (pc._onCreateAnswerSuccess, + new pc._win.mozRTCSessionDescription({ type: "answer", + sdp: sdp })); pc._executeNext(); }.bind(this)); }, onCreateAnswerError: function(code, message) { - this._dompc.callCB(this._dompc._onCreateAnswerFailure, - new RTCError(code, message)); + this.callCB(this._dompc._onCreateAnswerFailure, new RTCError(code, message)); this._dompc._executeNext(); }, onSetLocalDescriptionSuccess: function() { this._dompc._localType = this._dompc._pendingType; this._dompc._pendingType = null; - this._dompc.callCB(this._dompc._onSetLocalDescriptionSuccess); + this.callCB(this._dompc._onSetLocalDescriptionSuccess); if (this._dompc._iceGatheringState == "complete") { // If we are not trickling or we completed gathering prior @@ -1092,33 +1034,35 @@ PeerConnectionObserver.prototype = { }, onSetRemoteDescriptionSuccess: function() { - this._dompc._onSetRemoteDescriptionSuccess(); + this._dompc._remoteType = this._dompc._pendingType; + this._dompc._pendingType = null; + this.callCB(this._dompc._onSetRemoteDescriptionSuccess); + this._dompc._executeNext(); }, onSetLocalDescriptionError: function(code, message) { this._dompc._pendingType = null; - this._dompc.callCB(this._dompc._onSetLocalDescriptionFailure, - new RTCError(code, message)); + this.callCB(this._dompc._onSetLocalDescriptionFailure, + new RTCError(code, message)); this._dompc._executeNext(); }, onSetRemoteDescriptionError: function(code, message) { this._dompc._pendingType = null; - this._dompc.callCB(this._dompc._onSetRemoteDescriptionFailure, - new RTCError(code, message)); + this.callCB(this._dompc._onSetRemoteDescriptionFailure, + new RTCError(code, message)); this._dompc._executeNext(); }, onAddIceCandidateSuccess: function() { this._dompc._pendingType = null; - this._dompc.callCB(this._dompc._onAddIceCandidateSuccess); + this.callCB(this._dompc._onAddIceCandidateSuccess); this._dompc._executeNext(); }, onAddIceCandidateError: function(code, message) { this._dompc._pendingType = null; - this._dompc.callCB(this._dompc._onAddIceCandidateError, - new RTCError(code, message)); + this.callCB(this._dompc._onAddIceCandidateError, new RTCError(code, message)); this._dompc._executeNext(); }, @@ -1218,8 +1162,8 @@ PeerConnectionObserver.prototype = { onStateChange: function(state) { switch (state) { case "SignalingState": - this._dompc.callCB(this._dompc.onsignalingstatechange, - this._dompc.signalingState); + this.callCB(this._dompc.onsignalingstatechange, + this._dompc.signalingState); break; case "IceConnectionState": @@ -1253,20 +1197,18 @@ PeerConnectionObserver.prototype = { let webidlobj = this._dompc._win.RTCStatsReport._create(this._dompc._win, chromeobj); chromeobj.makeStatsPublic(); - this._dompc.callCB(this._dompc._onGetStatsSuccess, webidlobj); + this.callCB(this._dompc._onGetStatsSuccess, webidlobj); this._dompc._executeNext(); }, onGetStatsError: function(code, message) { - this._dompc.callCB(this._dompc._onGetStatsFailure, - new RTCError(code, message)); + this.callCB(this._dompc._onGetStatsFailure, new RTCError(code, message)); this._dompc._executeNext(); }, onAddStream: function(stream) { - let ev = new this._dompc._win.MediaStreamEvent("addstream", - { stream: stream }); - this._dompc.dispatchEvent(ev); + this.dispatchEvent(new this._dompc._win.MediaStreamEvent("addstream", + { stream: stream })); }, onRemoveStream: function(stream, type) { diff --git a/dom/media/moz.build b/dom/media/moz.build index 0f2a479aba39..66da2d464b7f 100644 --- a/dom/media/moz.build +++ b/dom/media/moz.build @@ -60,7 +60,6 @@ FAIL_ON_WARNINGS = True LOCAL_INCLUDES += [ '../base', '../camera', - '/caps/include', ] include('/ipc/chromium/chromium-config.mozbuild') diff --git a/dom/media/tests/identity/mochitest.ini b/dom/media/tests/identity/mochitest.ini index 199669824a5f..721e50dae985 100644 --- a/dom/media/tests/identity/mochitest.ini +++ b/dom/media/tests/identity/mochitest.ini @@ -5,8 +5,8 @@ support-files = /.well-known/idp-proxy/idp-proxy.js identityevent.js -# All tests are disabled on android&b2g due to lack of https support in -# mochitests (Bug 907770) +# All tests are disabled on android due to lack of https support in mochitest +# (Bug 975149) # All tests are disabled on b2g due to lack of e10s support in WebRTC identity # (Bug 975144) [test_idpproxy.html] @@ -17,7 +17,5 @@ skip-if = os == "android" || appname == "b2g" skip-if = os == "android" || appname == "b2g" [test_setIdentityProviderWithErrors.html] skip-if = os == "android" || appname == "b2g" -[test_peerConnection_peerIdentity.html] -skip-if = os == "android" || appname == "b2g" [../mochitest/test_zmedia_cleanup.html] skip-if = os == "android" || appname == "b2g" diff --git a/dom/media/tests/identity/test_getIdentityAssertion.html b/dom/media/tests/identity/test_getIdentityAssertion.html index 9d8e61ecf757..cbf60bce49a1 100644 --- a/dom/media/tests/identity/test_getIdentityAssertion.html +++ b/dom/media/tests/identity/test_getIdentityAssertion.html @@ -26,7 +26,6 @@ var test; function theTest() { test = new PeerConnectionTest(); test.setMediaConstraints([{audio: true}], [{audio: true}]); - test.chain.removeAfter('PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE'); test.chain.append([ [ "GET_IDENTITY_ASSERTION_FAILS_WITHOUT_PROVIDER", diff --git a/dom/media/tests/identity/test_peerConnection_peerIdentity.html b/dom/media/tests/identity/test_peerConnection_peerIdentity.html deleted file mode 100644 index a35f619b3276..000000000000 --- a/dom/media/tests/identity/test_peerConnection_peerIdentity.html +++ /dev/null @@ -1,90 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"/> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="../mochitest/head.js"></script> - <script type="application/javascript" src="../mochitest/pc.js"></script> - <script type="application/javascript" src="../mochitest/templates.js"></script> - <script type="application/javascript" src="../mochitest/blacksilence.js"></script> -</head> -<body> -<div id="display"></div> -<pre id="test"> -<script type="application/javascript"> - createHTML({ - title: "setIdentityProvider leads to peerIdentity and assertions in SDP" - }); - -var test; -function theTest() { - var id1 = 'someone@test1.example.com'; - var id2 = 'someone@test2.example.com'; - test = new PeerConnectionTest({ - config_pc1: { - peerIdentity: id2 - }, - config_pc2: { - peerIdentity: id1 - } - }); - test.setMediaConstraints([{ - audio: true, - peerIdentity: id2 - }, { - video: true, - peerIdentity: id2 - }], [{ - audio: true, - fake: true, - peerIdentity: id1 - }, { - video: true, - fake: true, - peerIdentity: id1 - }]); - test.setIdentityProvider(test.pcLocal, 'test1.example.com', 'idp.html'); - test.setIdentityProvider(test.pcRemote, 'test2.example.com', 'idp.html'); - test.chain.append([ - [ - "PEER_IDENTITY_IS_SET_CORRECTLY", - function(test) { - // no need to wait to check identity in this case, - // setRemoteDescription should wait for the IdP to complete - function checkIdentity(pc, pfx, idp, name) { - is(pc.peerIdentity.idp, idp, pfx + "IdP is correct"); - is(pc.peerIdentity.name, name + "@" + idp, pfx + "identity is correct"); - } - - checkIdentity(test.pcLocal._pc, "local: ", "test2.example.com", "someone"); - checkIdentity(test.pcRemote._pc, "remote: ", "test1.example.com", "someone"); - test.next(); - } - ], - [ - "REMOTE_STREAMS_ARE_RESTRICTED", - function(test) { - var remoteStream = test.pcLocal._pc.getRemoteStreams()[0]; - var oneDone = false; - function done() { - if (!oneDone) { - oneDone = true; - return; - } - test.next(); - } - - audioIsSilence(true, remoteStream, done); - videoIsBlack(true, remoteStream, done); - } - ], - ]); - test.run(); -} -runTest(theTest); - -</script> -</pre> -</body> -</html> diff --git a/dom/media/tests/mochitest/blacksilence.js b/dom/media/tests/mochitest/blacksilence.js deleted file mode 100644 index 2d8d357730b6..000000000000 --- a/dom/media/tests/mochitest/blacksilence.js +++ /dev/null @@ -1,114 +0,0 @@ -(function(global) { - 'use strict'; - - // an invertible check on the condition. - // if the constraint is applied, then the check is direct - // if not applied, then the result should be reversed - function check(constraintApplied, condition, message) { - var good = constraintApplied ? condition : !condition; - message = (constraintApplied ? 'with' : 'without') + - ' constraint: should ' + (constraintApplied ? '' : 'not ') + - message + ' = ' + (good ? 'OK' : 'waiting...'); - info(message); - return good; - } - - function isSilence(audioData) { - var silence = true; - for (var i = 0; i < audioData.length; ++i) { - if (audioData[i] !== 128) { - silence = false; - } - } - return silence; - } - - function periodicCheck(type, checkFunc, successMessage, done) { - var interval = setInterval(function periodic() { - if (checkFunc()) { - ok(true, type + ' is ' + successMessage); - clearInterval(interval); - interval = null; - done(); - } - }, 50); - return function cancel() { - if (interval) { - ok(false, 'timed out waiting for audio check'); - clearInterval(interval); - done(); - } - }; - } - - function checkAudio(constraintApplied, stream, done) { - var context = new AudioContext(); - var source = context.createMediaStreamSource(stream); - var analyser = context.createAnalyser(); - source.connect(analyser); - analyser.connect(context.destination); - - function testAudio() { - var sampleCount = analyser.frequencyBinCount; - info('got some audio samples: ' + sampleCount); - var bucket = new ArrayBuffer(sampleCount); - var view = new Uint8Array(bucket); - analyser.getByteTimeDomainData(view); - - var silent = check(constraintApplied, isSilence(view), 'be silence for audio'); - // TODO: silence cross origin input to webaudio, bug 966066 - silent ^= constraintApplied; - return sampleCount > 0 && silent; - } - return periodicCheck('audio', testAudio, - (constraintApplied ? '' : 'not ') + 'silent', done); - } - - function mkElement(type) { - var display = document.getElementById('display'); - var e = document.createElement(type); - e.width = 32; - e.height = 24; - display.appendChild(e); - return e; - } - - function checkVideo(constraintApplied, stream, done) { - var video = mkElement('video'); - video.mozSrcObject = stream; - video.play(); - - var ready = false; - video.onplaying = function() { - ready = true; - } - - function tryToRenderToCanvas() { - if (!ready) { - info('waiting for video to start'); - return false; - } - - try { - // every try needs a new canvas, otherwise a taint from an earlier call - // will affect subsequent calls - var canvas = mkElement('canvas'); - var ctx = canvas.getContext('2d'); - // have to guard drawImage with the try as well, due to bug 879717 - // if we get an error, this round fails, but that failure is usually - // just transitory - ctx.drawImage(video, 0, 0); - ctx.getImageData(0, 0, 1, 1); - return check(constraintApplied, false, 'throw on getImageData for video'); - } catch (e) { - return check(constraintApplied, e.name === 'SecurityError', 'get a security error'); - } - } - - return periodicCheck('video', tryToRenderToCanvas, - (constraintApplied ? '' : 'not ') + 'protected', done); - } - - global.audioIsSilence = checkAudio; - global.videoIsBlack = checkVideo; -}(this)); diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index 71a89e545313..35e1a1f1d9ce 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -5,7 +5,6 @@ support-files = pc.js templates.js NetworkPreparationChromeScript.js - blacksilence.js [test_dataChannel_basicAudio.html] skip-if = (toolkit == 'gonk' && debug) #Bug 962984, test fail on b2g debug build @@ -39,7 +38,6 @@ skip-if = (toolkit == 'gonk' && debug) #debug-only failure [test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html] [test_getUserMedia_stopVideoStream.html] [test_getUserMedia_stopVideoStreamWithFollowupVideo.html] -[test_getUserMedia_peerIdentity.html] [test_peerConnection_addCandidateInHaveLocalOffer.html] [test_peerConnection_basicAudio.html] skip-if = (toolkit == 'gonk' && debug) #Bug 962984, test fail on b2g debug build diff --git a/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html b/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html deleted file mode 100644 index 7a5d7a80ee0a..000000000000 --- a/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html +++ /dev/null @@ -1,59 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=942367 ---> -<head> - <meta charset="utf-8"> - <title>Test mozGetUserMedia peerIdentity Constraint</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="application/javascript" src="head.js"></script> - <script type="application/javascript" src="blacksilence.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=942367">Test mozGetUserMedia peerIdentity Constraint</a> -<p id="display"></p> -<div id="content" style="display: none"> - -</div> -<pre id="test"> -<script type="application/javascript"> -function theTest() { - function testPeerIdentityConstraint(withConstraint, done) { - var config = { audio: true, video: true, fake: true }; - if (withConstraint) { - config.peerIdentity = 'user@example.com'; - } - info('getting media with constraints: ' + JSON.stringify(config)); - navigator.mozGetUserMedia(config, function(stream) { - var oneDone = false; - function checkDone() { - if (oneDone) { - done(); - } - oneDone = true; - } - var cancelAudioCheck = audioIsSilence(withConstraint, stream, checkDone); - var cancelVideoCheck = videoIsBlack(withConstraint, stream, checkDone); - setTimeout(cancelAudioCheck, 1200); - setTimeout(cancelVideoCheck, 1200); - }, function(e) { - ok(false, 'gUM error: ' + e); - }); - }; - - // without constraint - testPeerIdentityConstraint(false, function() { - // with the constraint - testPeerIdentityConstraint(true, SimpleTest.finish.bind(SimpleTest)); - }); -} - -runTest(theTest); -SimpleTest.waitForExplicitFinish(); - -</script> -</pre> -</body> -</html> diff --git a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp index d7a83b45d78a..cab36bfb6228 100644 --- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp +++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp @@ -30,10 +30,6 @@ #include "nsServiceManagerUtils.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" -#ifdef MOZILLA_INTERNAL_API -#include "nsIPrincipal.h" -#include "nsIDocument.h" -#endif #include <stdlib.h> #include <stdio.h> @@ -168,40 +164,40 @@ void VcmSIPCCBinding::CandidateReady(NrIceMediaStream* stream, char *candidate_tmp = (char *)malloc(candidate.size() + 1); if (!candidate_tmp) - return; + return; sstrncpy(candidate_tmp, candidate.c_str(), candidate.size() + 1); // Send a message to the GSM thread. CC_CallFeature_FoundICECandidate(vcm_opaque->call_handle_, - candidate_tmp, - nullptr, - vcm_opaque->level_, - nullptr); + candidate_tmp, + nullptr, + vcm_opaque->level_, + nullptr); } void VcmSIPCCBinding::setStreamObserver(StreamObserver* obs) { - streamObserver = obs; + streamObserver = obs; } /* static */ StreamObserver * VcmSIPCCBinding::getStreamObserver() { if (gSelf != nullptr) - return gSelf->streamObserver; + return gSelf->streamObserver; return nullptr; } void VcmSIPCCBinding::setMediaProviderObserver(MediaProviderObserver* obs) { - mediaProviderObserver = obs; + mediaProviderObserver = obs; } MediaProviderObserver * VcmSIPCCBinding::getMediaProviderObserver() { if (gSelf != nullptr) - return gSelf->mediaProviderObserver; + return gSelf->mediaProviderObserver; return nullptr; } @@ -566,7 +562,7 @@ static short vcmGetIceStream_m(cc_mcapid_t mcap_id, * */ static short vcmRxAllocICE_s(TemporaryRef<NrIceCtx> ctx_in, - TemporaryRef<NrIceMediaStream> stream_in, + TemporaryRef<NrIceMediaStream> stream_in, cc_call_handle_t call_handle, cc_streamid_t stream_id, uint16_t level, @@ -1335,7 +1331,7 @@ short vcmRxOpen(cc_mcapid_t mcap_id, *port_allocated = -1; if(listen_ip) { - csf_sprintf(dottedIP, sizeof(dottedIP), "%u.%u.%u.%u", + csf_sprintf(dottedIP, sizeof(dottedIP), "%u.%u.%u.%u", (listen_ip->u.ip4 >> 24) & 0xff, (listen_ip->u.ip4 >> 16) & 0xff, (listen_ip->u.ip4 >> 8) & 0xff, listen_ip->u.ip4 & 0xff ); } @@ -1646,7 +1642,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id, return VCM_ERROR; // Now we have all the pieces, create the pipeline - mozilla::RefPtr<mozilla::MediaPipelineReceiveAudio> pipeline = + mozilla::RefPtr<mozilla::MediaPipeline> pipeline = new mozilla::MediaPipelineReceiveAudio( pc.impl()->GetHandle(), pc.impl()->GetMainThread().get(), @@ -1704,7 +1700,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id, return VCM_ERROR; // Now we have all the pieces, create the pipeline - mozilla::RefPtr<mozilla::MediaPipelineReceiveVideo> pipeline = + mozilla::RefPtr<mozilla::MediaPipeline> pipeline = new mozilla::MediaPipelineReceiveVideo( pc.impl()->GetHandle(), pc.impl()->GetMainThread().get(), @@ -1879,7 +1875,7 @@ void vcmRxReleasePort (cc_mcapid_t mcap_id, StreamObserver* obs = VcmSIPCCBinding::getStreamObserver(); if(obs != nullptr) - obs->deregisterStream(call_handle, stream_id); + obs->deregisterStream(call_handle, stream_id); } /* @@ -2217,97 +2213,6 @@ int vcmTxStart(cc_mcapid_t mcap_id, return VCM_ERROR; } -/** - * Create a conduit for audio transmission. - * - * @param[in] level - the m-line index - * @param[in] payload - codec info - * @param[in] pc - the peer connection - * @param [in] attrs - additional audio attributes - * @param[out] conduit - the conduit to create - */ -static int vcmTxCreateAudioConduit(int level, - const vcm_payload_info_t *payload, - sipcc::PeerConnectionWrapper &pc, - const vcm_mediaAttrs_t *attrs, - mozilla::RefPtr<mozilla::MediaSessionConduit> &conduit) -{ - mozilla::AudioCodecConfig *config_raw = - new mozilla::AudioCodecConfig( - payload->remote_rtp_pt, - ccsdpCodecName(payload->codec_type), - payload->audio.frequency, - payload->audio.packet_size, - payload->audio.channels, - payload->audio.bitrate, - pc.impl()->load_manager()); - - // Take possession of this pointer - mozilla::ScopedDeletePtr<mozilla::AudioCodecConfig> config(config_raw); - - // Instantiate an appropriate conduit - mozilla::RefPtr<mozilla::MediaSessionConduit> rx_conduit = - pc.impl()->media()->GetConduit(level, true); - MOZ_ASSERT_IF(rx_conduit, rx_conduit->type() == MediaSessionConduit::AUDIO); - - // The two sides of a send/receive pair of conduits each keep a raw pointer to the other, - // and are responsible for cleanly shutting down. - mozilla::RefPtr<mozilla::AudioSessionConduit> tx_conduit = - mozilla::AudioSessionConduit::Create( - static_cast<AudioSessionConduit *>(rx_conduit.get())); - - if (!tx_conduit || tx_conduit->ConfigureSendMediaCodec(config) || - tx_conduit->EnableAudioLevelExtension(attrs->audio_level, - attrs->audio_level_id)) { - return VCM_ERROR; - } - CSFLogError(logTag, "Created audio pipeline audio level %d %d", - attrs->audio_level, attrs->audio_level_id); - - conduit = tx_conduit; - return 0; -} - -/** - * Create a conduit for video transmission. - * - * @param[in] level - the m-line index - * @param[in] payload - codec info - * @param[in] pc - the peer connection - * @param[out] conduit - the conduit to create - */ -static int vcmTxCreateVideoConduit(int level, - const vcm_payload_info_t *payload, - sipcc::PeerConnectionWrapper &pc, - mozilla::RefPtr<mozilla::MediaSessionConduit> &conduit) -{ - mozilla::VideoCodecConfig *config_raw; - config_raw = new mozilla::VideoCodecConfig( - payload->remote_rtp_pt, - ccsdpCodecName(payload->codec_type), - payload->video.rtcp_fb_types, - payload->video.max_fs, - payload->video.max_fr, - pc.impl()->load_manager()); - - // Take possession of this pointer - mozilla::ScopedDeletePtr<mozilla::VideoCodecConfig> config(config_raw); - - // Instantiate an appropriate conduit - mozilla::RefPtr<mozilla::MediaSessionConduit> rx_conduit = - pc.impl()->media()->GetConduit(level, true); - MOZ_ASSERT_IF(rx_conduit, rx_conduit->type() == MediaSessionConduit::VIDEO); - - // The two sides of a send/receive pair of conduits each keep a raw pointer to the other, - // and are responsible for cleanly shutting down. - mozilla::RefPtr<mozilla::VideoSessionConduit> tx_conduit = - mozilla::VideoSessionConduit::Create(static_cast<VideoSessionConduit *>(rx_conduit.get())); - if (!tx_conduit || tx_conduit->ConfigureSendMediaCodec(config)) { - return VCM_ERROR; - } - conduit = tx_conduit; - return 0; -} /** * start tx stream @@ -2318,7 +2223,7 @@ static int vcmTxCreateVideoConduit(int level, * @param[in] stream_id - stream id of the given media type. * @param[in] level - the m-line index * @param[in] pc_stream_id - the media stream index (from PC.addStream()) - * @param[in] pc_track_id - the track within the media stream + * @param[i]n pc_track_id - the track within the media stream * @param[in] call_handle - call handle * @param[in] peerconnection - the peerconnection in use * @param[in] payload - payload information @@ -2334,21 +2239,21 @@ static int vcmTxCreateVideoConduit(int level, #define EXTRACT_DYNAMIC_PAYLOAD_TYPE(PTYPE) ((PTYPE)>>16) static int vcmTxStartICE_m(cc_mcapid_t mcap_id, - cc_groupid_t group_id, - cc_streamid_t stream_id, - int level, - int pc_stream_id, - int pc_track_id, - cc_call_handle_t call_handle, - const char *peerconnection, - const vcm_payload_info_t *payload, - short tos, - sdp_setup_type_e setup_type, - const char *fingerprint_alg, - const char *fingerprint, - vcm_mediaAttrs_t *attrs) + cc_groupid_t group_id, + cc_streamid_t stream_id, + int level, + int pc_stream_id, + int pc_track_id, + cc_call_handle_t call_handle, + const char *peerconnection, + const vcm_payload_info_t *payload, + short tos, + sdp_setup_type_e setup_type, + const char *fingerprint_alg, + const char *fingerprint, + vcm_mediaAttrs_t *attrs) { - CSFLogDebug(logTag, "%s(%s) track = %d, stream = %d, level = %d", + CSFLogDebug( logTag, "%s(%s) track = %d, stream = %d, level = %d", __FUNCTION__, peerconnection, pc_track_id, @@ -2358,20 +2263,19 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id, // Find the PC and get the stream sipcc::PeerConnectionWrapper pc(peerconnection); ENSURE_PC(pc, VCM_ERROR); - nsRefPtr<sipcc::LocalSourceStreamInfo> stream = - pc.impl()->media()->GetLocalStream(pc_stream_id); + nsRefPtr<sipcc::LocalSourceStreamInfo> stream = pc.impl()->media()-> + GetLocalStream(pc_stream_id); // Create the transport flows mozilla::RefPtr<TransportFlow> rtp_flow = - vcmCreateTransportFlow(pc.impl(), level, false, setup_type, - fingerprint_alg, fingerprint); + vcmCreateTransportFlow(pc.impl(), level, false, setup_type, + fingerprint_alg, fingerprint); if (!rtp_flow) { - CSFLogError(logTag, "Could not create RTP flow"); - return VCM_ERROR; + CSFLogError( logTag, "Could not create RTP flow"); + return VCM_ERROR; } - mozilla::RefPtr<TransportFlow> rtcp_flow = nullptr; - if (!attrs->rtcp_mux) { + if(!attrs->rtcp_mux) { rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true, setup_type, fingerprint_alg, fingerprint); if (!rtcp_flow) { @@ -2380,55 +2284,115 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id, } } - const char *mediaType; - mozilla::RefPtr<mozilla::MediaSessionConduit> conduit; - int err = VCM_ERROR; + if (CC_IS_AUDIO(mcap_id)) { - mediaType = "audio"; - err = vcmTxCreateAudioConduit(level, payload, pc, attrs, conduit); + mozilla::AudioCodecConfig *config_raw; + config_raw = new mozilla::AudioCodecConfig( + payload->remote_rtp_pt, + ccsdpCodecName(payload->codec_type), + payload->audio.frequency, + payload->audio.packet_size, + payload->audio.channels, + payload->audio.bitrate, + pc.impl()->load_manager()); + + // Take possession of this pointer + mozilla::ScopedDeletePtr<mozilla::AudioCodecConfig> config(config_raw); + + // Instantiate an appropriate conduit + mozilla::RefPtr<mozilla::MediaSessionConduit> rx_conduit = + pc.impl()->media()->GetConduit(level, true); + MOZ_ASSERT_IF(rx_conduit, rx_conduit->type() == MediaSessionConduit::AUDIO); + + // The two sides of a send/receive pair of conduits each keep a raw pointer to the other, + // and are responsible for cleanly shutting down. + mozilla::RefPtr<mozilla::AudioSessionConduit> conduit = + mozilla::AudioSessionConduit::Create(static_cast<AudioSessionConduit *>(rx_conduit.get())); + if (!conduit || conduit->ConfigureSendMediaCodec(config)) + return VCM_ERROR; + CSFLogError(logTag, "Created audio pipeline audio level %d %d", + attrs->audio_level, attrs->audio_level_id); + + if (!conduit || conduit->EnableAudioLevelExtension(attrs->audio_level, attrs->audio_level_id)) + return VCM_ERROR; + + pc.impl()->media()->AddConduit(level, false, conduit); + mozilla::RefPtr<mozilla::MediaPipeline> pipeline = + new mozilla::MediaPipelineTransmit( + pc.impl()->GetHandle(), + pc.impl()->GetMainThread().get(), + pc.impl()->GetSTSThread(), + stream->GetMediaStream(), + pc_track_id, + level, + conduit, rtp_flow, rtcp_flow); + + nsresult res = pipeline->Init(); + if (NS_FAILED(res)) { + CSFLogError(logTag, "Failure initializing audio pipeline"); + return VCM_ERROR; + } + CSFLogDebug(logTag, "Created audio pipeline %p, conduit=%p, pc_stream=%d pc_track=%d", + pipeline.get(), conduit.get(), pc_stream_id, pc_track_id); + + + // Now we have all the pieces, create the pipeline + stream->StorePipeline(pc_track_id, pipeline); + } else if (CC_IS_VIDEO(mcap_id)) { - mediaType = "video"; - err = vcmTxCreateVideoConduit(level, payload, pc, conduit); + mozilla::VideoCodecConfig *config_raw; + config_raw = new mozilla::VideoCodecConfig( + payload->remote_rtp_pt, + ccsdpCodecName(payload->codec_type), + payload->video.rtcp_fb_types, + payload->video.max_fs, + payload->video.max_fr, + pc.impl()->load_manager()); + + // Take possession of this pointer + mozilla::ScopedDeletePtr<mozilla::VideoCodecConfig> config(config_raw); + + // Instantiate an appropriate conduit + mozilla::RefPtr<mozilla::MediaSessionConduit> rx_conduit = + pc.impl()->media()->GetConduit(level, true); + MOZ_ASSERT_IF(rx_conduit, rx_conduit->type() == MediaSessionConduit::VIDEO); + + // The two sides of a send/receive pair of conduits each keep a raw pointer to the other, + // and are responsible for cleanly shutting down. + mozilla::RefPtr<mozilla::VideoSessionConduit> conduit = + mozilla::VideoSessionConduit::Create(static_cast<VideoSessionConduit *>(rx_conduit.get())); + + // Find the appropriate media conduit config + if (!conduit || conduit->ConfigureSendMediaCodec(config)) + return VCM_ERROR; + + pc.impl()->media()->AddConduit(level, false, conduit); + + // Now we have all the pieces, create the pipeline + mozilla::RefPtr<mozilla::MediaPipeline> pipeline = + new mozilla::MediaPipelineTransmit( + pc.impl()->GetHandle(), + pc.impl()->GetMainThread().get(), + pc.impl()->GetSTSThread(), + stream->GetMediaStream(), + pc_track_id, + level, + conduit, rtp_flow, rtcp_flow); + + nsresult res = pipeline->Init(); + if (NS_FAILED(res)) { + CSFLogError(logTag, "Failure initializing video pipeline"); + return VCM_ERROR; + } + + CSFLogDebug(logTag, "Created video pipeline %p, conduit=%p, pc_stream=%d pc_track=%d", + pipeline.get(), conduit.get(), pc_stream_id, pc_track_id); + + stream->StorePipeline(pc_track_id, pipeline); } else { CSFLogError(logTag, "%s: mcap_id unrecognized", __FUNCTION__); - } - if (err) { - return err; - } - - pc.impl()->media()->AddConduit(level, false, conduit); - - // Now we have all the pieces, create the pipeline - mozilla::RefPtr<mozilla::MediaPipelineTransmit> pipeline = - new mozilla::MediaPipelineTransmit( - pc.impl()->GetHandle(), - pc.impl()->GetMainThread().get(), - pc.impl()->GetSTSThread(), - stream->GetMediaStream(), - pc_track_id, - level, - conduit, rtp_flow, rtcp_flow); - - nsresult res = pipeline->Init(); - if (NS_FAILED(res)) { - CSFLogError(logTag, "Failure initializing %s pipeline", mediaType); return VCM_ERROR; } -#ifdef MOZILLA_INTERNAL_API - // implement checking for peerIdentity (where failure == black/silence) - nsIDocument* doc = pc.impl()->GetWindow()->GetExtantDoc(); - if (doc) { - pipeline->UpdateSinkIdentity_m(doc->NodePrincipal(), pc.impl()->GetPeerIdentity()); - } else { - CSFLogError(logTag, "Initializing pipeline without attached doc"); - } -#endif - - CSFLogDebug(logTag, - "Created %s pipeline %p, conduit=%p, pc_stream=%d pc_track=%d", - mediaType, pipeline.get(), conduit.get(), - pc_stream_id, pc_track_id); - stream->StorePipeline(pc_track_id, pipeline); // This tells the receive MediaPipeline (if there is one) whether we are // doing bundle, and if so, updates the filter. Once the filter is finalized, @@ -2652,7 +2616,7 @@ int vcmGetVideoCodecList(int request_type) CSFLogDebug( logTag, "%s(codec_mask = %X)", fname, codecMask); //return codecMask; - return VCM_CODEC_RESOURCE_H264; + return VCM_CODEC_RESOURCE_H264; #else int codecMask = VcmSIPCCBinding::getVideoCodecs(); CSFLogDebug(logTag, "GetVideoCodecList returning %X", codecMask); @@ -2686,11 +2650,11 @@ void vcmMediaControl(cc_call_handle_t call_handle, vcm_media_control_to_encoder { if ( to_encoder == VCM_MEDIA_CONTROL_PICTURE_FAST_UPDATE ) { - StreamObserver* obs = VcmSIPCCBinding::getStreamObserver(); - if (obs != nullptr) - { - obs->sendIFrame(call_handle); - } + StreamObserver* obs = VcmSIPCCBinding::getStreamObserver(); + if (obs != nullptr) + { + obs->sendIFrame(call_handle); + } } } @@ -2822,7 +2786,7 @@ cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level, void switch (media_type) { case RTP_VP8: - return TRUE; + return TRUE; case RTP_H264_P0: case RTP_H264_P1: @@ -2982,7 +2946,7 @@ int vcmDtmfBurst(int digit, int duration, int direction) CSFLogDebug( logTag, "vcmDtmfBurst(): digit=%d duration=%d, direction=%d", digit, duration, direction); StreamObserver* obs = VcmSIPCCBinding::getStreamObserver(); if(obs != nullptr) - obs->dtmfBurst(digit, duration, direction); + obs->dtmfBurst(digit, duration, direction); return 0; } @@ -3254,3 +3218,4 @@ short vcmGetVideoMaxFr(uint16_t codec, &ret)); return ret; } + diff --git a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp index f751133b74ed..a850b816719e 100644 --- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp +++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp @@ -39,9 +39,6 @@ #include "transportlayerice.h" #include "runnable_utils.h" #include "libyuv/convert.h" -#ifdef MOZILLA_INTERNAL_API -#include "mozilla/PeerIdentity.h" -#endif #include "mozilla/gfx/Point.h" #include "mozilla/gfx/Types.h" @@ -656,25 +653,6 @@ nsresult MediaPipelineTransmit::Init() { return MediaPipeline::Init(); } -#ifdef MOZILLA_INTERNAL_API -void MediaPipelineTransmit::UpdateSinkIdentity_m(nsIPrincipal* principal, - const PeerIdentity* sinkIdentity) { - ASSERT_ON_THREAD(main_thread_); - bool enableStream = principal->Subsumes(domstream_->GetPrincipal()); - if (!enableStream) { - // first try didn't work, but there's a chance that this is still available - // if our stream is bound to a peerIdentity, and the peer connection (our - // sink) is bound to the same identity, then we can enable the stream - PeerIdentity* streamIdentity = domstream_->GetPeerIdentity(); - if (sinkIdentity && streamIdentity) { - enableStream = (*sinkIdentity == *streamIdentity); - } - } - - listener_->SetEnabled(enableStream); -} -#endif - nsresult MediaPipelineTransmit::TransportReady_s(TransportInfo &info) { ASSERT_ON_THREAD(sts_thread_); // Call base ready function. @@ -683,6 +661,7 @@ nsresult MediaPipelineTransmit::TransportReady_s(TransportInfo &info) { // Should not be set for a transmitter MOZ_ASSERT(!possible_bundle_rtp_); if (&info == &rtp_) { + // TODO(ekr@rtfm.com): Move onto MSG thread. listener_->SetActive(true); } @@ -956,7 +935,6 @@ NewData(MediaStreamGraph* graph, TrackID tid, // Ignore data in case we have a muxed stream return; } - AudioSegment* audio = const_cast<AudioSegment *>( static_cast<const AudioSegment *>(&media)); @@ -972,7 +950,6 @@ NewData(MediaStreamGraph* graph, TrackID tid, // Ignore data in case we have a muxed stream return; } - VideoSegment* video = const_cast<VideoSegment *>( static_cast<const VideoSegment *>(&media)); @@ -995,7 +972,7 @@ void MediaPipelineTransmit::PipelineListener::ProcessAudioChunk( // TODO(ekr@rtfm.com): Do more than one channel nsAutoArrayPtr<int16_t> samples(new int16_t[chunk.mDuration]); - if (enabled_ && chunk.mBuffer) { + if (chunk.mBuffer) { switch (chunk.mBufferFormat) { case AUDIO_FORMAT_FLOAT32: { @@ -1103,7 +1080,7 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk( return; } - if (!enabled_ || chunk.mFrame.GetForceBlack()) { + if (chunk.mFrame.GetForceBlack()) { uint32_t yPlaneLen = size.width*size.height; uint32_t cbcrPlaneLen = yPlaneLen/2; uint32_t length = yPlaneLen + cbcrPlaneLen; diff --git a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h index a4e813927316..e909ab5fe161 100644 --- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h +++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h @@ -21,7 +21,6 @@ #include "MediaPipelineFilter.h" #include "AudioSegment.h" #include "mozilla/ReentrantMonitor.h" -#include "mozilla/Atomics.h" #include "SrtpFlow.h" #include "databuffer.h" #include "runnable_utils.h" @@ -35,8 +34,6 @@ namespace mozilla { -class PeerIdentity; - // A class that represents the pipeline of audio and video // The dataflow looks like: // @@ -357,7 +354,7 @@ private: // A specialization of pipeline for reading from an input device // and transmitting to the network. class MediaPipelineTransmit : public MediaPipeline { -public: + public: // Set rtcp_transport to nullptr to use rtcp-mux MediaPipelineTransmit(const std::string& pc, nsCOMPtr<nsIEventTarget> main_thread, @@ -376,14 +373,7 @@ public: {} // Initialize (stuff here may fail) - virtual nsresult Init() MOZ_OVERRIDE; - -#ifdef MOZILLA_INTERNAL_API - // when the principal of the PeerConnection changes, it calls through to here - // so that we can determine whether to enable stream transmission - virtual void UpdateSinkIdentity_m(nsIPrincipal* principal, - const PeerIdentity* sinkIdentity); -#endif + virtual nsresult Init(); // Called on the main thread. virtual void DetachMediaStream() { @@ -405,7 +395,6 @@ public: PipelineListener(const RefPtr<MediaSessionConduit>& conduit) : conduit_(conduit), active_(false), - enabled_(false), direct_connect_(false), samples_10ms_buffer_(nullptr), buffer_current_(0), @@ -427,8 +416,11 @@ public: } } + + // XXX. This is not thread-safe but the hazard is just + // that active_ = true takes a while to propagate. Revisit + // when 823600 lands. void SetActive(bool active) { active_ = active; } - void SetEnabled(bool enabled) { enabled_ = enabled; } // Implement MediaStreamListener virtual void NotifyQueuedTrackChanges(MediaStreamGraph* graph, TrackID tid, @@ -459,16 +451,9 @@ public: TrackRate rate, VideoChunk& chunk); #endif RefPtr<MediaSessionConduit> conduit_; - - // active is true if there is a transport to send on - mozilla::Atomic<bool> active_; - // enabled is true if the media access control permits sending - // actual content; when false you get black/silence - mozilla::Atomic<bool> enabled_; - + volatile bool active_; bool direct_connect_; - // These vars handle breaking audio samples into exact 10ms chunks: // The buffer of 10ms audio samples that we will send once full // (can be carried over from one call to another). @@ -564,7 +549,7 @@ class MediaPipelineReceiveAudio : public MediaPipelineReceive { stream_ = nullptr; } - virtual nsresult Init() MOZ_OVERRIDE; + virtual nsresult Init(); private: // Separate class to allow ref counting @@ -638,7 +623,7 @@ class MediaPipelineReceiveVideo : public MediaPipelineReceive { stream_ = nullptr; } - virtual nsresult Init() MOZ_OVERRIDE; + virtual nsresult Init(); private: class PipelineRenderer : public VideoRenderer { diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index c19375622b27..1a0d0f40c955 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -62,8 +62,6 @@ #include "nsNetUtil.h" #include "nsIDOMDataChannel.h" #include "nsIDOMLocation.h" -#include "nsNullPrincipal.h" -#include "mozilla/PeerIdentity.h" #include "mozilla/dom/RTCConfigurationBinding.h" #include "mozilla/dom/RTCStatsReportBinding.h" #include "mozilla/dom/RTCPeerConnectionBinding.h" @@ -477,7 +475,6 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal) , mSignalingState(PCImplSignalingState::SignalingStable) , mIceConnectionState(PCImplIceConnectionState::New) , mIceGatheringState(PCImplIceGatheringState::New) - , mDtlsConnected(false) , mWindow(nullptr) , mIdentity(nullptr) , mSTSThread(nullptr) @@ -545,27 +542,18 @@ PeerConnectionImpl::~PeerConnectionImpl() } already_AddRefed<DOMMediaStream> -PeerConnectionImpl::MakeMediaStream(uint32_t aHint) +PeerConnectionImpl::MakeMediaStream(nsPIDOMWindow* aWindow, + uint32_t aHint) { nsRefPtr<DOMMediaStream> stream = - DOMMediaStream::CreateSourceStream(GetWindow(), aHint); - + DOMMediaStream::CreateSourceStream(aWindow, aHint); #ifdef MOZILLA_INTERNAL_API - // Make the stream data (audio/video samples) accessible to the receiving page. - // We're only certain that privacy hasn't been requested if we're connected. - if (mDtlsConnected && !PrivacyRequested()) { - nsIDocument* doc = GetWindow()->GetExtantDoc(); - if (!doc) { - return nullptr; - } - stream->CombineWithPrincipal(doc->NodePrincipal()); - } else { - // we're either certain that we need isolation for the streams, OR - // we're not sure and we can fix the stream in SetDtlsConnected - nsCOMPtr<nsIPrincipal> principal = - do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID); - stream->CombineWithPrincipal(principal); + nsIDocument* doc = aWindow->GetExtantDoc(); + if (!doc) { + return nullptr; } + // Make the stream data (audio/video samples) accessible to the receiving page. + stream->CombineWithPrincipal(doc->NodePrincipal()); #endif CSFLogDebug(logTag, "Created media stream %p, inner: %p", stream.get(), stream->GetStream()); @@ -584,7 +572,7 @@ PeerConnectionImpl::CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo // needs to actually propagate a hint for local streams. // TODO(ekr@rtfm.com): Clean up when we have explicit track lists. // See bug 834835. - nsRefPtr<DOMMediaStream> stream = MakeMediaStream(0); + nsRefPtr<DOMMediaStream> stream = MakeMediaStream(mWindow, 0); if (!stream) { return NS_ERROR_FAILURE; } @@ -748,10 +736,6 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver, mWindow = aWindow; NS_ENSURE_STATE(mWindow); - if (!aRTCConfiguration->mPeerIdentity.IsEmpty()) { - mPeerIdentity = new PeerIdentity(aRTCConfiguration->mPeerIdentity); - mPrivacyRequested = true; - } #endif // MOZILLA_INTERNAL_API PRTime timestamp = PR_Now(); @@ -943,7 +927,7 @@ PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aR aHint &= ~MEDIA_STREAM_MUTE; } - nsRefPtr<DOMMediaStream> stream = MakeMediaStream(aHint); + nsRefPtr<DOMMediaStream> stream = MakeMediaStream(mWindow, aHint); if (!stream) { return NS_ERROR_FAILURE; } @@ -1269,17 +1253,6 @@ PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP) mTimeCard = nullptr; STAMP_TIMECARD(tc, "Set Local Description"); -#ifdef MOZILLA_INTERNAL_API - nsIDocument* doc = GetWindow()->GetExtantDoc(); - bool isolated = true; - if (doc) { - isolated = mMedia->AnyLocalStreamIsolated(doc->NodePrincipal()); - } else { - CSFLogInfo(logTag, "%s - no document, failing safe", __FUNCTION__); - } - mPrivacyRequested = mPrivacyRequested || isolated; -#endif - mLocalRequestedSDP = aSDP; mInternal->mCall->setLocalDescription((cc_jsep_action_t)aAction, mLocalRequestedSDP, tc); @@ -1399,67 +1372,16 @@ PeerConnectionImpl::CloseStreams() { return NS_OK; } -#ifdef MOZILLA_INTERNAL_API -nsresult -PeerConnectionImpl::SetPeerIdentity(const nsAString& aPeerIdentity) -{ - PC_AUTO_ENTER_API_CALL(true); - MOZ_ASSERT(!aPeerIdentity.IsEmpty()); - - // once set, this can't be changed - if (mPeerIdentity) { - if (!mPeerIdentity->Equals(aPeerIdentity)) { - return NS_ERROR_FAILURE; - } - } else { - mPeerIdentity = new PeerIdentity(aPeerIdentity); - nsIDocument* doc = GetWindow()->GetExtantDoc(); - if (!doc) { - CSFLogInfo(logTag, "Can't update principal on streams; document gone"); - return NS_ERROR_FAILURE; - } - mMedia->UpdateSinkIdentity_m(doc->NodePrincipal(), mPeerIdentity); - } - return NS_OK; -} -#endif - -nsresult -PeerConnectionImpl::SetDtlsConnected(bool aPrivacyRequested) -{ - PC_AUTO_ENTER_API_CALL(false); - - // For this, as with mPrivacyRequested, once we've connected to a peer, we - // fixate on that peer. Dealing with multiple peers or connections is more - // than this run-down wreck of an object can handle. - // Besides, this is only used to say if we have been connected ever. -#ifdef MOZILLA_INTERNAL_API - if (!mPrivacyRequested && !aPrivacyRequested && !mDtlsConnected) { - // now we know that privacy isn't needed for sure - nsIDocument* doc = GetWindow()->GetExtantDoc(); - if (!doc) { - CSFLogInfo(logTag, "Can't update principal on streams; document gone"); - return NS_ERROR_FAILURE; - } - mMedia->UpdateRemoteStreamPrincipals_m(doc->NodePrincipal()); - } -#endif - mDtlsConnected = true; - mPrivacyRequested = mPrivacyRequested || aPrivacyRequested; - return NS_OK; -} - -nsresult +NS_IMETHODIMP PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream, const MediaConstraintsInternal& aConstraints) { return AddStream(aMediaStream, MediaConstraintsExternal(aConstraints)); } -nsresult -PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream, - const MediaConstraintsExternal& aConstraints) -{ +NS_IMETHODIMP +PeerConnectionImpl::AddStream(DOMMediaStream& aMediaStream, + const MediaConstraintsExternal& aConstraints) { PC_AUTO_ENTER_API_CALL(true); uint32_t hints = aMediaStream.GetHintContents(); @@ -1486,9 +1408,8 @@ PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream, uint32_t stream_id; nsresult res = mMedia->AddStream(&aMediaStream, &stream_id); - if (NS_FAILED(res)) { + if (NS_FAILED(res)) return res; - } // TODO(ekr@rtfm.com): these integers should be the track IDs if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) { diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h index 5d3ee1fe85f4..066f35d299da 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h @@ -36,8 +36,6 @@ #include "VideoSegment.h" #include "nsNSSShutDown.h" #include "mozilla/dom/RTCStatsReportBinding.h" -#include "nsIPrincipal.h" -#include "mozilla/PeerIdentity.h" #endif namespace test { @@ -116,9 +114,6 @@ using mozilla::DtlsIdentity; using mozilla::ErrorResult; using mozilla::NrIceStunServer; using mozilla::NrIceTurnServer; -#ifdef MOZILLA_INTERNAL_API -using mozilla::PeerIdentity; -#endif class PeerConnectionWrapper; class PeerConnectionMedia; @@ -231,7 +226,8 @@ public: static PeerConnectionImpl* CreatePeerConnection(); static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc, IceConfiguration *aDst); - already_AddRefed<DOMMediaStream> MakeMediaStream(uint32_t aHint); + static already_AddRefed<DOMMediaStream> MakeMediaStream(nsPIDOMWindow* aWindow, + uint32_t aHint); nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo); @@ -281,7 +277,7 @@ public: return mSTSThread; } - // Get the DTLS identity (local side) + // Get the DTLS identity mozilla::RefPtr<DtlsIdentity> const GetIdentity() const; std::string GetFingerprint() const; std::string GetFingerprintAlgorithm() const; @@ -375,8 +371,8 @@ public: rv = AddStream(aMediaStream, aConstraints); } - nsresult AddStream(DOMMediaStream &aMediaStream, - const MediaConstraintsExternal& aConstraints); + NS_IMETHODIMP AddStream(DOMMediaStream & aMediaStream, + const MediaConstraintsExternal& aConstraints); NS_IMETHODIMP_TO_ERRORRESULT(RemoveStream, ErrorResult &rv, DOMMediaStream& aMediaStream) @@ -384,28 +380,6 @@ public: rv = RemoveStream(aMediaStream); } - - nsresult GetPeerIdentity(nsAString& peerIdentity) - { -#ifdef MOZILLA_INTERNAL_API - if (mPeerIdentity) { - peerIdentity = mPeerIdentity->ToString(); - return NS_OK; - } -#endif - - peerIdentity.SetIsVoid(true); - return NS_OK; - } - -#ifdef MOZILLA_INTERNAL_API - const PeerIdentity* GetPeerIdentity() const { return mPeerIdentity; } - nsresult SetPeerIdentity(const nsAString& peerIdentity); -#endif - - // this method checks to see if we've made a promise to protect media. - bool PrivacyRequested() const { return mPrivacyRequested; } - NS_IMETHODIMP GetFingerprint(char** fingerprint); void GetFingerprint(nsAString& fingerprint) { @@ -539,8 +513,6 @@ public: void SetSignalingState_m(mozilla::dom::PCImplSignalingState aSignalingState); bool IsClosed() const; - // called when DTLS connects; we only need this once - nsresult SetDtlsConnected(bool aPrivacyRequested); bool HasMedia() const; @@ -629,10 +601,6 @@ private: mozilla::dom::PCImplIceConnectionState mIceConnectionState; mozilla::dom::PCImplIceGatheringState mIceGatheringState; - // DTLS - // this is true if we have been connected ever, see SetDtlsConnected - bool mDtlsConnected; - nsCOMPtr<nsIThread> mThread; // TODO: Remove if we ever properly wire PeerConnection for cycle-collection. nsWeakPtr mPCObserver; @@ -650,20 +618,8 @@ private: std::string mFingerprint; std::string mRemoteFingerprint; - // identity-related fields + // The DTLS identity mozilla::RefPtr<DtlsIdentity> mIdentity; -#ifdef MOZILLA_INTERNAL_API - // The entity on the other end of the peer-to-peer connection; - // void if they are not yet identified, and no constraint has been set - nsAutoPtr<PeerIdentity> mPeerIdentity; -#endif - // Whether an app should be prevented from accessing media produced by the PC - // If this is true, then media will not be sent until mPeerIdentity matches - // local streams PeerIdentity; and remote streams are protected from content - // - // This can be false if mPeerIdentity is set, in the case where identity is - // provided, but the media is not protected from the app on either side - bool mPrivacyRequested; // A handle to refer to this PC with std::string mHandle; @@ -679,7 +635,7 @@ private: #ifdef MOZILLA_INTERNAL_API // DataConnection that's used to get all the DataChannels - nsRefPtr<mozilla::DataChannelConnection> mDataConnection; + nsRefPtr<mozilla::DataChannelConnection> mDataConnection; #endif nsRefPtr<PeerConnectionMedia> mMedia; diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp index 28b43f18065e..6cac31f18126 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp @@ -15,7 +15,6 @@ #include "AudioConduit.h" #include "VideoConduit.h" #include "runnable_utils.h" -#include "transportlayerdtls.h" #ifdef MOZILLA_INTERNAL_API #include "MediaStreamList.h" @@ -138,6 +137,7 @@ PeerConnectionImpl* PeerConnectionImpl::CreatePeerConnection() PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent) : mParent(parent), + mLocalSourceStreamsLock("PeerConnectionMedia.mLocalSourceStreamsLock"), mIceCtx(nullptr), mDNSResolver(new mozilla::NrIceResolver()), mMainThread(mParent->GetMainThread()), @@ -235,8 +235,6 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv nsresult PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id) { - ASSERT_ON_THREAD(mMainThread); - if (!aMediaStream) { CSFLogError(logTag, "%s - aMediaStream is NULL", __FUNCTION__); return NS_ERROR_FAILURE; @@ -265,6 +263,7 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream // allow one of each. // TODO(ekr@rtfm.com): remove this when multiple of each stream // is allowed + mozilla::MutexAutoLock lock(mLocalSourceStreamsLock); for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u]; @@ -296,13 +295,13 @@ nsresult PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id) { MOZ_ASSERT(aMediaStream); - ASSERT_ON_THREAD(mMainThread); DOMMediaStream* stream = static_cast<DOMMediaStream*>(aMediaStream); CSFLogDebug(logTag, "%s: MediaStream: %p", __FUNCTION__, aMediaStream); + mozilla::MutexAutoLock lock(mLocalSourceStreamsLock); for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u]; if (localSourceStream->GetMediaStream() == stream) { @@ -358,11 +357,6 @@ PeerConnectionMedia::ShutdownMediaTransport_s() CSFLogDebug(logTag, "%s: ", __FUNCTION__); - // Here we access m{Local|Remote}SourceStreams off the main thread. - // That's OK because by here PeerConnectionImpl has forgotten about us, - // so there is no chance of getting a call in here from outside. - // The dispatches from SelfDestruct() and to SelfDestruct_m() provide - // memory barriers that protect us from badness. for (uint32_t i=0; i < mLocalSourceStreams.Length(); ++i) { mLocalSourceStreams[i]->DetachTransport_s(); } @@ -383,7 +377,6 @@ PeerConnectionMedia::ShutdownMediaTransport_s() LocalSourceStreamInfo* PeerConnectionMedia::GetLocalStream(int aIndex) { - ASSERT_ON_THREAD(mMainThread); if(aIndex < 0 || aIndex >= (int) mLocalSourceStreams.Length()) { return nullptr; } @@ -395,7 +388,6 @@ PeerConnectionMedia::GetLocalStream(int aIndex) RemoteSourceStreamInfo* PeerConnectionMedia::GetRemoteStream(int aIndex) { - ASSERT_ON_THREAD(mMainThread); if(aIndex < 0 || aIndex >= (int) mRemoteSourceStreams.Length()) { return nullptr; } @@ -480,7 +472,6 @@ nsresult PeerConnectionMedia::AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo, int *aIndex) { - ASSERT_ON_THREAD(mMainThread); MOZ_ASSERT(aIndex); *aIndex = mRemoteSourceStreams.Length(); @@ -533,117 +524,9 @@ PeerConnectionMedia::IceStreamReady(NrIceMediaStream *aStream) CSFLogDebug(logTag, "%s: %s", __FUNCTION__, aStream->name().c_str()); } - void -PeerConnectionMedia::DtlsConnected(TransportLayer *dtlsLayer, - TransportLayer::State state) -{ - dtlsLayer->SignalStateChange.disconnect(this); - - bool privacyRequested = false; - // TODO (Bug 952678) set privacy mode, ask the DTLS layer about that - GetMainThread()->Dispatch( - WrapRunnable(mParent, &PeerConnectionImpl::SetDtlsConnected, privacyRequested), - NS_DISPATCH_NORMAL); -} - -void -PeerConnectionMedia::AddTransportFlow(int aIndex, bool aRtcp, - const RefPtr<TransportFlow> &aFlow) -{ - int index_inner = aIndex * 2 + (aRtcp ? 1 : 0); - - MOZ_ASSERT(!mTransportFlows[index_inner]); - mTransportFlows[index_inner] = aFlow; - - GetSTSThread()->Dispatch( - WrapRunnable(this, &PeerConnectionMedia::ConnectDtlsListener_s, aFlow), - NS_DISPATCH_NORMAL); -} - -void -PeerConnectionMedia::ConnectDtlsListener_s(const RefPtr<TransportFlow>& aFlow) -{ - TransportLayer* dtls = aFlow->GetLayer(TransportLayerDtls::ID()); - dtls->SignalStateChange.connect(this, &PeerConnectionMedia::DtlsConnected); -} - -#ifdef MOZILLA_INTERNAL_API -/** - * Tells you if any local streams is isolated. Obviously, we want all the - * streams to be isolated equally so that they can all be sent or not. But we - * can't make that determination for certain, because stream principals change. - * Therefore, we check once when we are setting a local description and that - * determines if we flip the "privacy requested" bit on. If a stream cannot be - * sent, then we'll be sending black/silence later; maybe this will correct - * itself and we can send actual content. - * - * @param scriptPrincipal the principal - * @returns true if any stream is isolated - */ -bool -PeerConnectionMedia::AnyLocalStreamIsolated(nsIPrincipal *scriptPrincipal) const -{ - ASSERT_ON_THREAD(mMainThread); - - for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { - // check if we should be asking for a private call for this stream - DOMMediaStream* stream = mLocalSourceStreams[u]->GetMediaStream(); - if (!scriptPrincipal->Subsumes(stream->GetPrincipal())) { - return true; - } - } - return false; -} - -void -PeerConnectionMedia::UpdateRemoteStreamPrincipals_m(nsIPrincipal* aPrincipal) -{ - ASSERT_ON_THREAD(mMainThread); - - for (uint32_t u = 0; u < mRemoteSourceStreams.Length(); u++) { - mRemoteSourceStreams[u]->UpdatePrincipal_m(aPrincipal); - } -} - -void -PeerConnectionMedia::UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, - const PeerIdentity* aSinkIdentity) -{ - ASSERT_ON_THREAD(mMainThread); - - for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { - mLocalSourceStreams[u]->UpdateSinkIdentity_m(aPrincipal, aSinkIdentity); - } -} - -void -LocalSourceStreamInfo::UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, - const PeerIdentity* aSinkIdentity) -{ - for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) { - MediaPipelineTransmit* pipeline = - static_cast<MediaPipelineTransmit*>((*it).second.get()); - pipeline->UpdateSinkIdentity_m(aPrincipal, aSinkIdentity); - } -} - -void RemoteSourceStreamInfo::UpdatePrincipal_m(nsIPrincipal* aPrincipal) -{ - // this blasts away the existing principal, which, if we're here - // will be the null principal - // we only do this when we become certain that the stream is safe to make - // accessible to the script principal - MOZ_ASSERT(aPrincipal); - DebugOnly<bool> isNull; - MOZ_ASSERT(NS_SUCCEEDED(aPrincipal->GetIsNullPrincipal(&isNull)) && isNull); - mMediaStream->SetPrincipal(aPrincipal); -} -#endif // MOZILLA_INTERNAL_API - -void -LocalSourceStreamInfo::StorePipeline( - int aTrack, mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline) +LocalSourceStreamInfo::StorePipeline(int aTrack, + mozilla::RefPtr<mozilla::MediaPipeline> aPipeline) { MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end()); if (mPipelines.find(aTrack) != mPipelines.end()) { @@ -656,9 +539,9 @@ LocalSourceStreamInfo::StorePipeline( } void -RemoteSourceStreamInfo::StorePipeline( - int aTrack, bool aIsVideo, - mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline) +RemoteSourceStreamInfo::StorePipeline(int aTrack, + bool aIsVideo, + mozilla::RefPtr<mozilla::MediaPipeline> aPipeline) { MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end()); if (mPipelines.find(aTrack) != mPipelines.end()) { diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h index fa5bc35bd764..5a50c2525ecc 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h @@ -31,11 +31,8 @@ #include "VideoSegment.h" #endif -class nsIPrincipal; - namespace mozilla { class DataChannel; -class PeerIdentity; namespace dom { class RTCInboundRTPStreamStats; class RTCOutboundRTPStreamStats; @@ -183,7 +180,7 @@ public: } SourceStreamInfo(already_AddRefed<DOMMediaStream>& aMediaStream, - PeerConnectionMedia *aParent) + PeerConnectionMedia *aParent) : mMediaStream(aMediaStream), mParent(aParent) { MOZ_ASSERT(mMediaStream); @@ -218,12 +215,7 @@ public: DOMMediaStream* GetMediaStream() { return mMediaStream; } - void StorePipeline(int aTrack, - mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline); - -#ifdef MOZILLA_INTERNAL_API - void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, const PeerIdentity* aSinkIdentity); -#endif + void StorePipeline(int aTrack, mozilla::RefPtr<mozilla::MediaPipeline> aPipeline); void ExpectAudio(const mozilla::TrackID); void ExpectVideo(const mozilla::TrackID); @@ -251,17 +243,13 @@ class RemoteSourceStreamInfo : public SourceStreamInfo { return mMediaStream; } void StorePipeline(int aTrack, bool aIsVideo, - mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline); + mozilla::RefPtr<mozilla::MediaPipeline> aPipeline); bool SetUsingBundle_m(int aLevel, bool decision); void DetachTransport_s(); void DetachMedia_m(); -#ifdef MOZILLA_INTERNAL_API - void UpdatePrincipal_m(nsIPrincipal* aPrincipal); -#endif - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteSourceStreamInfo) public: @@ -295,10 +283,10 @@ class PeerConnectionMedia : public sigslot::has_slots<> { return mIceStreams.size(); } - // Add a stream (main thread only) + // Add a stream nsresult AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id); - // Remove a stream (main thread only) + // Remove a stream nsresult RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id); // Get a specific local stream @@ -324,19 +312,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> { nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo, int *aIndex); nsresult AddRemoteStreamHint(int aIndex, bool aIsVideo); -#ifdef MOZILLA_INTERNAL_API - // In cases where the peer isn't yet identified, we disable the pipeline (not - // the stream, that would potentially affect others), so that it sends - // black/silence. Once the peer is identified, re-enable those streams. - void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, const PeerIdentity* aSinkIdentity); - // this determines if any stream is isolated, given the current - // document (or script) principal - bool AnyLocalStreamIsolated(nsIPrincipal *scriptPrincipal) const; - // When we finally learn who is on the other end, we need to change the ownership - // on streams - void UpdateRemoteStreamPrincipals_m(nsIPrincipal* aPrincipal); -#endif - const nsCOMPtr<nsIThread>& GetMainThread() const { return mMainThread; } const nsCOMPtr<nsIEventTarget>& GetSTSThread() const { return mSTSThread; } @@ -354,10 +329,12 @@ class PeerConnectionMedia : public sigslot::has_slots<> { // Add a transport flow void AddTransportFlow(int aIndex, bool aRtcp, - const mozilla::RefPtr<mozilla::TransportFlow> &aFlow); - void ConnectDtlsListener_s(const mozilla::RefPtr<mozilla::TransportFlow>& aFlow); - void DtlsConnected(mozilla::TransportLayer* aFlow, - mozilla::TransportLayer::State state); + const mozilla::RefPtr<mozilla::TransportFlow> &aFlow) { + int index_inner = aIndex * 2 + (aRtcp ? 1 : 0); + + MOZ_ASSERT(!mTransportFlows[index_inner]); + mTransportFlows[index_inner] = aFlow; + } mozilla::RefPtr<mozilla::MediaSessionConduit> GetConduit(int aStreamIndex, bool aReceive) { int index_inner = aStreamIndex * 2 + (aReceive ? 0 : 1); @@ -402,11 +379,10 @@ class PeerConnectionMedia : public sigslot::has_slots<> { PeerConnectionImpl *mParent; // A list of streams returned from GetUserMedia - // This is only accessed on the main thread (with one special exception) + mozilla::Mutex mLocalSourceStreamsLock; nsTArray<nsRefPtr<LocalSourceStreamInfo> > mLocalSourceStreams; // A list of streams provided by the other side - // This is only accessed on the main thread (with one special exception) nsTArray<nsRefPtr<RemoteSourceStreamInfo> > mRemoteSourceStreams; // ICE objects diff --git a/media/webrtc/signaling/test/FakeMediaStreams.h b/media/webrtc/signaling/test/FakeMediaStreams.h index a9193c5d0706..d8ff9d2fc0b3 100644 --- a/media/webrtc/signaling/test/FakeMediaStreams.h +++ b/media/webrtc/signaling/test/FakeMediaStreams.h @@ -90,7 +90,7 @@ class Fake_MediaStream { protected: std::set<Fake_MediaStreamListener *> mListeners; mozilla::Mutex mMutex; // Lock to prevent the listener list from being modified while - // executing Periodic(). + // executing Periodic(). }; class Fake_MediaPeriodic : public nsITimerCallback { @@ -242,8 +242,6 @@ public: uint32_t GetHintContents() const { return mHintContents; } void SetHintContents(uint32_t aHintContents) { mHintContents = aHintContents; } - void SetTrackEnabled(mozilla::TrackID aTrackID, bool aEnabled) {} - private: nsRefPtr<Fake_MediaStream> mMediaStream;