зеркало из https://github.com/mozilla/gecko-dev.git
Bug 906990: Part 10. Webidl and implementation for WebrtcGlobal. Encompasses things like global stats and logging. r=jib,bz
This commit is contained in:
Родитель
aecbe64228
Коммит
aebc089f65
3
CLOBBER
3
CLOBBER
|
@ -18,4 +18,5 @@
|
|||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||
#
|
||||
|
||||
Bug 942207 - apparently need clobber to avoid bustage
|
||||
WebIDL dictionary modification requires clobber on Windows (bug 928195), part of
|
||||
bug 906990.
|
||||
|
|
|
@ -10,6 +10,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const PC_CONTRACT = "@mozilla.org/dom/peerconnection;1";
|
||||
const WEBRTC_GLOBAL_CONTRACT = "@mozilla.org/dom/webrtcglobalinformation1";
|
||||
const PC_OBS_CONTRACT = "@mozilla.org/dom/peerconnectionobserver;1";
|
||||
const PC_ICE_CONTRACT = "@mozilla.org/dom/rtcicecandidate;1";
|
||||
const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
|
||||
|
@ -17,7 +18,8 @@ const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
|
|||
const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
|
||||
|
||||
const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
|
||||
const PC_OBS_CID = Components.ID("{1d44a18e-4545-4ff3-863d-6dbd6234a583}");
|
||||
const WEBRTC_GLOBAL_CID = Components.ID("{f6063d11-f467-49ad-9765-e7923050dc08}");
|
||||
const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
|
||||
const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
|
||||
const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
|
||||
const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
|
||||
|
@ -63,6 +65,10 @@ GlobalPCList.prototype = {
|
|||
}
|
||||
this._list[winID] = this._list[winID].filter(
|
||||
function (e,i,a) { return e.get() !== null; });
|
||||
|
||||
if (this._list[winID].length === 0) {
|
||||
delete this._list[winID];
|
||||
}
|
||||
},
|
||||
|
||||
hasActivePeerConnection: function(winID) {
|
||||
|
@ -111,9 +117,60 @@ GlobalPCList.prototype = {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
getStatsForEachPC: function(callback, errorCallback) {
|
||||
for (let winId in this._list) {
|
||||
if (this._list.hasOwnProperty(winId)) {
|
||||
this.removeNullRefs(winId);
|
||||
if (this._list[winId]) {
|
||||
this._list[winId].forEach(function(pcref) {
|
||||
pcref.get().getStatsInternal(null, callback, errorCallback);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getLoggingFromFirstPC: function(pattern, callback, errorCallback) {
|
||||
for (let winId in this._list) {
|
||||
this.removeNullRefs(winId);
|
||||
if (this._list[winId]) {
|
||||
// We expect removeNullRefs to not leave us with an empty array here
|
||||
let pcref = this._list[winId][0];
|
||||
pcref.get().getLogging(pattern, callback, errorCallback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
let _globalPCList = new GlobalPCList();
|
||||
|
||||
function WebrtcGlobalInformation() {
|
||||
}
|
||||
WebrtcGlobalInformation.prototype = {
|
||||
classDescription: "WebrtcGlobalInformation",
|
||||
classID: WEBRTC_GLOBAL_CID,
|
||||
contractID: WEBRTC_GLOBAL_CONTRACT,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||
|
||||
getAllStats: function(successCallback, failureCallback) {
|
||||
if (_globalPCList) {
|
||||
_globalPCList.getStatsForEachPC(successCallback, failureCallback);
|
||||
} else {
|
||||
failureCallback("No global PeerConnection list");
|
||||
}
|
||||
},
|
||||
|
||||
getCandPairLogs: function(candPairId, callback, errorCallback) {
|
||||
let pattern = 'CAND-PAIR(' + candPairId + ')';
|
||||
if (_globalPCList) {
|
||||
_globalPCList.getLoggingFromFirstPC(pattern, callback, errorCallback);
|
||||
} else {
|
||||
errorCallback("No global PeerConnection list");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function RTCIceCandidate() {
|
||||
this.candidate = this.sdpMid = this.sdpMLineIndex = null;
|
||||
}
|
||||
|
@ -151,9 +208,10 @@ RTCSessionDescription.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
function RTCStatsReport(win, report) {
|
||||
function RTCStatsReport(win, report, pcid) {
|
||||
this._win = win;
|
||||
this.report = report;
|
||||
this.mozPcid = pcid;
|
||||
}
|
||||
RTCStatsReport.prototype = {
|
||||
classDescription: "RTCStatsReport",
|
||||
|
@ -204,6 +262,8 @@ function RTCPeerConnection() {
|
|||
this._onCreateAnswerFailure = null;
|
||||
this._onGetStatsSuccess = null;
|
||||
this._onGetStatsFailure = null;
|
||||
this._onGetLoggingSuccess = null;
|
||||
this._onGetLoggingFailure = null;
|
||||
|
||||
this._pendingType = null;
|
||||
this._localType = null;
|
||||
|
@ -736,6 +796,21 @@ RTCPeerConnection.prototype = {
|
|||
this._getPC().getStats(selector, internal);
|
||||
},
|
||||
|
||||
getLogging: function(pattern, onSuccess, onError) {
|
||||
this._queueOrRun({
|
||||
func: this._getLogging,
|
||||
args: [pattern, onSuccess, onError],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
||||
_getLogging: function(pattern, onSuccess, onError) {
|
||||
this._onGetLoggingSuccess = onSuccess;
|
||||
this._onGetLoggingFailure = onError;
|
||||
|
||||
this._getPC().getLogging(pattern);
|
||||
},
|
||||
|
||||
createDataChannel: function(label, dict) {
|
||||
this._checkClosed();
|
||||
if (dict == undefined) {
|
||||
|
@ -1086,7 +1161,8 @@ PeerConnectionObserver.prototype = {
|
|||
this.callCB(this._dompc._onGetStatsSuccess,
|
||||
this._dompc._win.RTCStatsReport._create(this._dompc._win,
|
||||
new RTCStatsReport(this._dompc._win,
|
||||
report)));
|
||||
report,
|
||||
dict.pcid)));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
|
@ -1095,6 +1171,16 @@ PeerConnectionObserver.prototype = {
|
|||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onGetLoggingSuccess: function(logs) {
|
||||
this.callCB(this._dompc._onGetLoggingSuccess, logs);
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onGetLoggingError: function(code, message) {
|
||||
this.callCB(this._dompc._onGetLoggingFailure, new RTCError(code, message));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onAddStream: function(stream) {
|
||||
this.dispatchEvent(new this._dompc._win.MediaStreamEvent("addstream",
|
||||
{ stream: stream }));
|
||||
|
@ -1129,6 +1215,11 @@ PeerConnectionObserver.prototype = {
|
|||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
|
||||
[GlobalPCList, RTCIceCandidate, RTCSessionDescription, RTCPeerConnection,
|
||||
RTCStatsReport, PeerConnectionObserver]
|
||||
[GlobalPCList,
|
||||
RTCIceCandidate,
|
||||
RTCSessionDescription,
|
||||
RTCPeerConnection,
|
||||
RTCStatsReport,
|
||||
PeerConnectionObserver,
|
||||
WebrtcGlobalInformation]
|
||||
);
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
component {00e0e20d-1494-4776-8e0e-0f0acbea3c79} PeerConnection.js
|
||||
component {1d44a18e-4545-4ff3-863d-6dbd6234a583} PeerConnection.js
|
||||
component {f6063d11-f467-49ad-9765-e7923050dc08} PeerConnection.js
|
||||
component {d1748d4c-7f6a-4dc5-add6-d55b7678537e} PeerConnection.js
|
||||
component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
|
||||
component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
|
||||
component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
|
||||
component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
|
||||
|
||||
contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
|
||||
contract @mozilla.org/dom/peerconnectionobserver;1 {1d44a18e-4545-4ff3-863d-6dbd6234a583}
|
||||
contract @mozilla.org/dom/webrtcglobalinformation;1 {f6063d11-f467-49ad-9765-e7923050dc08}
|
||||
contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
|
||||
contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
|
||||
contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
|
||||
contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
|
||||
|
|
|
@ -33,10 +33,17 @@ interface PeerConnectionImpl {
|
|||
[Throws]
|
||||
void setRemoteDescription(long action, DOMString sdp);
|
||||
|
||||
/* Stats call */
|
||||
/* Stats call, calls either |onGetStatsSuccess| or |onGetStatsError| on our
|
||||
observer. (see the |PeerConnectionObserver| interface) */
|
||||
[Throws]
|
||||
void getStats(MediaStreamTrack? selector, boolean internalStats);
|
||||
|
||||
/* Scrapes the RLogRingbuffer, and calls either |onGetLoggingSuccess|
|
||||
or |onGetLoggingError| on our observer.
|
||||
(see the |PeerConnectionObserver| interface) */
|
||||
[Throws]
|
||||
void getLogging(DOMString pattern);
|
||||
|
||||
/* Adds the stream created by GetUserMedia */
|
||||
[Throws]
|
||||
void addStream(MediaStream stream);
|
||||
|
|
|
@ -28,6 +28,10 @@ interface PeerConnectionObserver
|
|||
void onGetStatsSuccess(optional RTCStatsReportInternal report);
|
||||
void onGetStatsError(unsigned long name, DOMString message);
|
||||
|
||||
/* Logging callbacks */
|
||||
void onGetLoggingSuccess(sequence<DOMString> logs);
|
||||
void onGetLoggingError(unsigned long name, DOMString message);
|
||||
|
||||
/* Data channel callbacks */
|
||||
void notifyDataChannel(DataChannel channel);
|
||||
void notifyConnection();
|
||||
|
|
|
@ -137,3 +137,19 @@ interface mozRTCPeerConnection : EventTarget {
|
|||
attribute EventHandler onconnection;
|
||||
attribute EventHandler onclosedconnection;
|
||||
};
|
||||
|
||||
callback RTCLogCallback = void (sequence<DOMString> logMessages);
|
||||
|
||||
[JSImplementation="@mozilla.org/dom/webrtcglobalinformation;1",
|
||||
ChromeOnly,
|
||||
Constructor ()]
|
||||
interface WebrtcGlobalInformation {
|
||||
void getAllStats(RTCStatsCallback callback,
|
||||
RTCPeerConnectionErrorCallback errorCallback);
|
||||
void getCandPairLogs(DOMString candPairId,
|
||||
RTCLogCallback callback,
|
||||
RTCPeerConnectionErrorCallback errorCallback);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ callback RTCStatsReportCallback = void (RTCStatsReport obj);
|
|||
// to be received from c++
|
||||
|
||||
dictionary RTCStatsReportInternal {
|
||||
DOMString pcid;
|
||||
sequence<RTCRTPStreamStats> rtpStreamStats;
|
||||
sequence<RTCInboundRTPStreamStats> inboundRTPStreamStats;
|
||||
sequence<RTCOutboundRTPStreamStats> outboundRTPStreamStats;
|
||||
|
@ -141,6 +142,8 @@ dictionary RTCStatsReportInternal {
|
|||
// MapClass(DOMString, object)
|
||||
JSImplementation="@mozilla.org/dom/rtcstatsreport;1"]
|
||||
interface RTCStatsReport {
|
||||
[ChromeOnly]
|
||||
readonly attribute DOMString mozPcid;
|
||||
void forEach(RTCStatsReportCallback callbackFn, optional any thisArg);
|
||||
object get(DOMString key);
|
||||
boolean has(DOMString key);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <cerrno>
|
||||
#include <deque>
|
||||
|
||||
#include "base/histogram.h"
|
||||
#include "vcm.h"
|
||||
|
@ -64,6 +65,7 @@
|
|||
#include "MediaStreamTrack.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "DOMMediaStream.h"
|
||||
#include "rlogringbuffer.h"
|
||||
#endif
|
||||
|
||||
#ifndef USE_FAKE_MEDIA_STREAMS
|
||||
|
@ -1200,6 +1202,23 @@ PeerConnectionImpl::GetStats(MediaStreamTrack *aSelector,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::GetLogging(const nsAString& aPattern) {
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
std::string pattern(NS_ConvertUTF16toUTF8(aPattern).get());
|
||||
nsRefPtr<PeerConnectionImpl> pc(this);
|
||||
RUN_ON_THREAD(mSTSThread,
|
||||
WrapRunnable(pc,
|
||||
&PeerConnectionImpl::GetLogging_s,
|
||||
pattern),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) {
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
@ -1704,6 +1723,8 @@ void PeerConnectionImpl::GetStats_s(
|
|||
if (!report) {
|
||||
result = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
report->mPcid.Construct(NS_ConvertASCIItoUTF16(mHandle.c_str()));
|
||||
if (mMedia) {
|
||||
RefPtr<NrIceMediaStream> mediaStream(
|
||||
mMedia->ice_media_stream(trackId));
|
||||
|
@ -1715,10 +1736,8 @@ void PeerConnectionImpl::GetStats_s(
|
|||
NS_ConvertASCIItoUTF16 componentId(mediaStream->name().c_str());
|
||||
for (auto p = candPairs.begin(); p != candPairs.end(); ++p) {
|
||||
NS_ConvertASCIItoUTF16 codeword(p->codeword.c_str());
|
||||
const nsString localCodeword(
|
||||
NS_ConvertASCIItoUTF16("local_") + codeword);
|
||||
const nsString remoteCodeword(
|
||||
NS_ConvertASCIItoUTF16("remote_") + codeword);
|
||||
NS_ConvertASCIItoUTF16 localCodeword(p->local.codeword.c_str());
|
||||
NS_ConvertASCIItoUTF16 remoteCodeword(p->remote.codeword.c_str());
|
||||
// Only expose candidate-pair statistics to chrome, until we've thought
|
||||
// through the implications of exposing it to content.
|
||||
|
||||
|
@ -1798,6 +1817,45 @@ void PeerConnectionImpl::OnStatsReport_m(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnectionImpl::GetLogging_s(const std::string& pattern) {
|
||||
RLogRingBuffer* logs = RLogRingBuffer::GetInstance();
|
||||
std::deque<std::string> result;
|
||||
logs->Filter(pattern, 0, &result);
|
||||
nsRefPtr<PeerConnectionImpl> pc(this);
|
||||
RUN_ON_THREAD(mThread,
|
||||
WrapRunnable(pc,
|
||||
&PeerConnectionImpl::OnGetLogging_m,
|
||||
pattern,
|
||||
result),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void PeerConnectionImpl::OnGetLogging_m(const std::string& pattern,
|
||||
const std::deque<std::string>& logging) {
|
||||
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSErrorResult rv;
|
||||
if (!logging.empty()) {
|
||||
Sequence<nsString> nsLogs;
|
||||
for (auto l = logging.begin(); l != logging.end(); ++l) {
|
||||
nsLogs.AppendElement(ObString(l->c_str()));
|
||||
}
|
||||
pco->OnGetLoggingSuccess(nsLogs, rv);
|
||||
} else {
|
||||
pco->OnGetLoggingError(kInternalError,
|
||||
ObString(("No logging matching pattern " + pattern).c_str()), rv);
|
||||
}
|
||||
|
||||
if (rv.Failed()) {
|
||||
CSFLogError(logTag, "Error firing stats observer callback");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef _PEER_CONNECTION_IMPL_H_
|
||||
#define _PEER_CONNECTION_IMPL_H_
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
@ -307,6 +308,12 @@ public:
|
|||
rv = GetStats(aSelector, internalStats);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(GetLogging, ErrorResult &rv,
|
||||
const nsAString& pattern)
|
||||
{
|
||||
rv = GetLogging(pattern);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP AddIceCandidate(const char* aCandidate, const char* aMid,
|
||||
unsigned short aLevel);
|
||||
void AddIceCandidate(const nsAString& aCandidate, const nsAString& aMid,
|
||||
|
@ -494,6 +501,13 @@ private:
|
|||
void OnStatsReport_m(uint32_t trackId,
|
||||
nsresult result,
|
||||
nsAutoPtr<mozilla::dom::RTCStatsReportInternal> report);
|
||||
|
||||
// Fetches logs matching pattern from RLogRingBuffer. Must be run on STS.
|
||||
void GetLogging_s(const std::string& pattern);
|
||||
|
||||
// Sends logging to JS. Must run on main thread.
|
||||
void OnGetLogging_m(const std::string& pattern,
|
||||
const std::deque<std::string>& logging);
|
||||
#endif
|
||||
|
||||
// Timecard used to measure processing time. This should be the first class
|
||||
|
|
Загрузка…
Ссылка в новой задаче