mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1100502: about:webrtc e10s fix. Content and chrome connections are reported. r=rjesup
This commit is contained in:
parent
f864e34010
commit
26a44a8d8d
@ -54,6 +54,7 @@
|
|||||||
#include "mozilla/net/NeckoChild.h"
|
#include "mozilla/net/NeckoChild.h"
|
||||||
#include "mozilla/plugins/PluginInstanceParent.h"
|
#include "mozilla/plugins/PluginInstanceParent.h"
|
||||||
#include "mozilla/plugins/PluginModuleParent.h"
|
#include "mozilla/plugins/PluginModuleParent.h"
|
||||||
|
#include "mozilla/media/webrtc/WebrtcGlobalChild.h"
|
||||||
#include "mozilla/widget/WidgetMessageUtils.h"
|
#include "mozilla/widget/WidgetMessageUtils.h"
|
||||||
|
|
||||||
#if defined(MOZ_CONTENT_SANDBOX)
|
#if defined(MOZ_CONTENT_SANDBOX)
|
||||||
@ -1829,6 +1830,21 @@ ContentChild::DeallocPSpeechSynthesisChild(PSpeechSynthesisChild* aActor)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PWebrtcGlobalChild *
|
||||||
|
ContentChild::AllocPWebrtcGlobalChild()
|
||||||
|
{
|
||||||
|
WebrtcGlobalChild *child = new WebrtcGlobalChild();
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentChild::DeallocPWebrtcGlobalChild(PWebrtcGlobalChild *aActor)
|
||||||
|
{
|
||||||
|
delete static_cast<WebrtcGlobalChild*>(aActor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentChild::RecvRegisterChrome(InfallibleTArray<ChromePackage>&& packages,
|
ContentChild::RecvRegisterChrome(InfallibleTArray<ChromePackage>&& packages,
|
||||||
InfallibleTArray<ResourceMapping>&& resources,
|
InfallibleTArray<ResourceMapping>&& resources,
|
||||||
|
@ -457,6 +457,9 @@ public:
|
|||||||
virtual bool
|
virtual bool
|
||||||
DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* offlineCacheUpdate) override;
|
DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* offlineCacheUpdate) override;
|
||||||
|
|
||||||
|
virtual PWebrtcGlobalChild* AllocPWebrtcGlobalChild() override;
|
||||||
|
virtual bool DeallocPWebrtcGlobalChild(PWebrtcGlobalChild *aActor) override;
|
||||||
|
|
||||||
virtual PContentPermissionRequestChild*
|
virtual PContentPermissionRequestChild*
|
||||||
AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests,
|
AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests,
|
||||||
const IPC::Principal& aPrincipal,
|
const IPC::Principal& aPrincipal,
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
|
#include "mozilla/media/webrtc/WebrtcGlobalParent.h"
|
||||||
#include "nsAnonymousTemporaryFile.h"
|
#include "nsAnonymousTemporaryFile.h"
|
||||||
#include "nsAppRunner.h"
|
#include "nsAppRunner.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
@ -4907,6 +4908,19 @@ ContentParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PWebrtcGlobalParent *
|
||||||
|
ContentParent::AllocPWebrtcGlobalParent()
|
||||||
|
{
|
||||||
|
return WebrtcGlobalParent::Alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentParent::DeallocPWebrtcGlobalParent(PWebrtcGlobalParent *aActor)
|
||||||
|
{
|
||||||
|
WebrtcGlobalParent::Dealloc(static_cast<WebrtcGlobalParent*>(aActor));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentParent::RecvSetOfflinePermission(const Principal& aPrincipal)
|
ContentParent::RecvSetOfflinePermission(const Principal& aPrincipal)
|
||||||
{
|
{
|
||||||
|
@ -843,6 +843,10 @@ private:
|
|||||||
virtual bool RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
|
virtual bool RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
|
||||||
PDocAccessibleParent* aParentDoc, const uint64_t& aParentID) override;
|
PDocAccessibleParent* aParentDoc, const uint64_t& aParentID) override;
|
||||||
|
|
||||||
|
virtual PWebrtcGlobalParent* AllocPWebrtcGlobalParent() override;
|
||||||
|
virtual bool DeallocPWebrtcGlobalParent(PWebrtcGlobalParent *aActor) override;
|
||||||
|
|
||||||
|
|
||||||
virtual bool RecvUpdateDropEffect(const uint32_t& aDragAction,
|
virtual bool RecvUpdateDropEffect(const uint32_t& aDragAction,
|
||||||
const uint32_t& aDropEffect) override;
|
const uint32_t& aDropEffect) override;
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ include protocol PTestShell;
|
|||||||
include protocol PVoicemail;
|
include protocol PVoicemail;
|
||||||
include protocol PJavaScript;
|
include protocol PJavaScript;
|
||||||
include protocol PRemoteSpellcheckEngine;
|
include protocol PRemoteSpellcheckEngine;
|
||||||
|
include protocol PWebrtcGlobal;
|
||||||
include DOMTypes;
|
include DOMTypes;
|
||||||
include JavaScriptTypes;
|
include JavaScriptTypes;
|
||||||
include InputStreamParams;
|
include InputStreamParams;
|
||||||
@ -443,6 +444,7 @@ prio(normal upto urgent) sync protocol PContent
|
|||||||
manages PVoicemail;
|
manages PVoicemail;
|
||||||
manages PJavaScript;
|
manages PJavaScript;
|
||||||
manages PRemoteSpellcheckEngine;
|
manages PRemoteSpellcheckEngine;
|
||||||
|
manages PWebrtcGlobal;
|
||||||
|
|
||||||
both:
|
both:
|
||||||
// Depending on exactly how the new browser is being created, it might be
|
// Depending on exactly how the new browser is being created, it might be
|
||||||
@ -763,6 +765,8 @@ parent:
|
|||||||
|
|
||||||
PAsmJSCacheEntry(OpenMode openMode, WriteParams write, Principal principal);
|
PAsmJSCacheEntry(OpenMode openMode, WriteParams write, Principal principal);
|
||||||
|
|
||||||
|
PWebrtcGlobal();
|
||||||
|
|
||||||
// Services remoting
|
// Services remoting
|
||||||
|
|
||||||
async StartVisitedQuery(URIParams uri);
|
async StartVisitedQuery(URIParams uri);
|
||||||
|
@ -36,6 +36,16 @@ webrtc_non_unified_sources = [
|
|||||||
'trunk/webrtc/modules/video_capture/windows/sink_filter_ds.cc', # Because of the MEDIASUBTYPE_HDYC variable and initguid.h
|
'trunk/webrtc/modules/video_capture/windows/sink_filter_ds.cc', # Because of the MEDIASUBTYPE_HDYC variable and initguid.h
|
||||||
]
|
]
|
||||||
|
|
||||||
|
IPDL_SOURCES += [
|
||||||
|
'signaling/src/peerconnection/PWebrtcGlobal.ipdl',
|
||||||
|
]
|
||||||
|
|
||||||
|
EXPORTS.mozilla.media.webrtc += [
|
||||||
|
'signaling/src/peerconnection/WebrtcGlobal.h',
|
||||||
|
'signaling/src/peerconnection/WebrtcGlobalChild.h',
|
||||||
|
'signaling/src/peerconnection/WebrtcGlobalParent.h'
|
||||||
|
]
|
||||||
|
|
||||||
GYP_DIRS += ['trunk']
|
GYP_DIRS += ['trunk']
|
||||||
|
|
||||||
GYP_DIRS['trunk'].input = 'trunk/peerconnection.gyp'
|
GYP_DIRS['trunk'].input = 'trunk/peerconnection.gyp'
|
||||||
|
@ -148,7 +148,6 @@ void ConfigWebRtcLog(uint32_t trace_mask, nsCString &aLogFile, nsCString &aAECLo
|
|||||||
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
|
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
|
||||||
// Capture the final choices for the trace settings.
|
// Capture the final choices for the trace settings.
|
||||||
mozilla::Preferences::SetCString("media.webrtc.debug.log_file", aLogFile);
|
mozilla::Preferences::SetCString("media.webrtc.debug.log_file", aLogFile);
|
||||||
mozilla::Preferences::SetUint("media.webrtc.debug.trace_mask", trace_mask);
|
|
||||||
mozilla::Preferences::SetCString("media.webrtc.debug.aec_log_dir", aAECLogDir);
|
mozilla::Preferences::SetCString("media.webrtc.debug.aec_log_dir", aAECLogDir);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
31
media/webrtc/signaling/src/peerconnection/PWebrtcGlobal.ipdl
Normal file
31
media/webrtc/signaling/src/peerconnection/PWebrtcGlobal.ipdl
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
include protocol PContent;
|
||||||
|
|
||||||
|
include "mozilla/media/webrtc/WebrtcGlobal.h";
|
||||||
|
|
||||||
|
using struct mozilla::dom::RTCStatsReportInternal from "mozilla/dom/RTCStatsReportBinding.h";
|
||||||
|
using WebrtcGlobalLog from "mozilla/media/webrtc/WebrtcGlobal.h";
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
async protocol PWebrtcGlobal {
|
||||||
|
manager PContent;
|
||||||
|
|
||||||
|
child: // parent -> child messages
|
||||||
|
GetStatsRequest(int aRequestId, nsString aPcIdFilter);
|
||||||
|
GetLogRequest(int aRequestId, nsCString aPattern);
|
||||||
|
SetAecLogging(bool aEnable);
|
||||||
|
SetDebugMode(int aLevel);
|
||||||
|
|
||||||
|
parent: // child -> parent messages
|
||||||
|
GetStatsResult(int aRequestId, RTCStatsReportInternal[] aStats);
|
||||||
|
GetLogResult(int aRequestId, WebrtcGlobalLog aLog);
|
||||||
|
__delete__();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace net
|
||||||
|
} // end namespace mozilla
|
@ -100,6 +100,12 @@ PeerConnectionCtx* PeerConnectionCtx::gInstance;
|
|||||||
nsIThread* PeerConnectionCtx::gMainThread;
|
nsIThread* PeerConnectionCtx::gMainThread;
|
||||||
StaticRefPtr<PeerConnectionCtxShutdown> PeerConnectionCtx::gPeerConnectionCtxShutdown;
|
StaticRefPtr<PeerConnectionCtxShutdown> PeerConnectionCtx::gPeerConnectionCtxShutdown;
|
||||||
|
|
||||||
|
const std::map<const std::string, PeerConnectionImpl *>&
|
||||||
|
PeerConnectionCtx::mGetPeerConnections()
|
||||||
|
{
|
||||||
|
return mPeerConnections;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread,
|
nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread,
|
||||||
nsIEventTarget* stsThread) {
|
nsIEventTarget* stsThread) {
|
||||||
if (!gMainThread) {
|
if (!gMainThread) {
|
||||||
@ -319,6 +325,10 @@ nsresult PeerConnectionCtx::Initialize() {
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
mTelemetryTimer->InitWithFuncCallback(EverySecondTelemetryCallback_m, this, 1000,
|
mTelemetryTimer->InitWithFuncCallback(EverySecondTelemetryCallback_m, this, 1000,
|
||||||
nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP);
|
nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP);
|
||||||
|
|
||||||
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||||
|
WebrtcGlobalChild::Create();
|
||||||
|
}
|
||||||
#endif // MOZILLA_INTERNAL_API
|
#endif // MOZILLA_INTERNAL_API
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
|
||||||
|
#include "mozilla/media/webrtc/WebrtcGlobalChild.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "StaticPtr.h"
|
#include "StaticPtr.h"
|
||||||
#include "PeerConnectionImpl.h"
|
#include "PeerConnectionImpl.h"
|
||||||
@ -56,6 +60,7 @@ class PeerConnectionCtx {
|
|||||||
mStatsForClosedPeerConnections;
|
mStatsForClosedPeerConnections;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const std::map<const std::string, PeerConnectionImpl *>& mGetPeerConnections();
|
||||||
private:
|
private:
|
||||||
// We could make these available only via accessors but it's too much trouble.
|
// We could make these available only via accessors but it's too much trouble.
|
||||||
std::map<const std::string, PeerConnectionImpl *> mPeerConnections;
|
std::map<const std::string, PeerConnectionImpl *> mPeerConnections;
|
||||||
|
495
media/webrtc/signaling/src/peerconnection/WebrtcGlobal.h
Normal file
495
media/webrtc/signaling/src/peerconnection/WebrtcGlobal.h
Normal file
@ -0,0 +1,495 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef _WEBRTC_GLOBAL_H_
|
||||||
|
#define _WEBRTC_GLOBAL_H_
|
||||||
|
|
||||||
|
#include "ipc/IPCMessageUtils.h"
|
||||||
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
|
#include "mozilla/dom/RTCStatsReportBinding.h"
|
||||||
|
|
||||||
|
typedef mozilla::dom::RTCStatsReportInternal StatsReport;
|
||||||
|
typedef nsTArray< nsAutoPtr<StatsReport>> RTCReports;
|
||||||
|
typedef mozilla::dom::Sequence<nsString> WebrtcGlobalLog;
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ParamTraits<mozilla::dom::Optional<T>>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::Optional<T> paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
if (aParam.WasPassed()) {
|
||||||
|
WriteParam(aMsg, true);
|
||||||
|
WriteParam(aMsg, aParam.Value());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteParam(aMsg, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
bool was_passed = false;
|
||||||
|
|
||||||
|
if (!ReadParam(aMsg, aIter, &was_passed)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
aResult->Reset(); //XXX Optional_base seems to reach this point with isSome true.
|
||||||
|
|
||||||
|
if (was_passed) {
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->Construct()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ParamTraits<mozilla::dom::Sequence<T>>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::Sequence<T> paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, static_cast<const FallibleTArray<T>&>(aParam));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
return ReadParam(aMsg, aIter, dynamic_cast<FallibleTArray<T>*>(aResult));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCStatsType> :
|
||||||
|
public ContiguousEnumSerializer<
|
||||||
|
mozilla::dom::RTCStatsType,
|
||||||
|
mozilla::dom::RTCStatsType::Inboundrtp,
|
||||||
|
mozilla::dom::RTCStatsType::EndGuard_>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCStatsIceCandidatePairState> :
|
||||||
|
public ContiguousEnumSerializer<
|
||||||
|
mozilla::dom::RTCStatsIceCandidatePairState,
|
||||||
|
mozilla::dom::RTCStatsIceCandidatePairState::Frozen,
|
||||||
|
mozilla::dom::RTCStatsIceCandidatePairState::EndGuard_>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCStatsIceCandidateType> :
|
||||||
|
public ContiguousEnumSerializer<
|
||||||
|
mozilla::dom::RTCStatsIceCandidateType,
|
||||||
|
mozilla::dom::RTCStatsIceCandidateType::Host,
|
||||||
|
mozilla::dom::RTCStatsIceCandidateType::EndGuard_>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCStatsReportInternal>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCStatsReportInternal paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mClosed);
|
||||||
|
WriteParam(aMsg, aParam.mCodecStats);
|
||||||
|
WriteParam(aMsg, aParam.mIceCandidatePairStats);
|
||||||
|
WriteParam(aMsg, aParam.mIceCandidateStats);
|
||||||
|
WriteParam(aMsg, aParam.mIceComponentStats);
|
||||||
|
WriteParam(aMsg, aParam.mInboundRTPStreamStats);
|
||||||
|
WriteParam(aMsg, aParam.mLocalSdp);
|
||||||
|
WriteParam(aMsg, aParam.mMediaStreamStats);
|
||||||
|
WriteParam(aMsg, aParam.mMediaStreamTrackStats);
|
||||||
|
WriteParam(aMsg, aParam.mOutboundRTPStreamStats);
|
||||||
|
WriteParam(aMsg, aParam.mPcid);
|
||||||
|
WriteParam(aMsg, aParam.mRemoteSdp);
|
||||||
|
WriteParam(aMsg, aParam.mTimestamp);
|
||||||
|
WriteParam(aMsg, aParam.mTransportStats);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mClosed)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mCodecStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mIceCandidatePairStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mIceCandidateStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mIceComponentStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mInboundRTPStreamStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mLocalSdp)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMediaStreamStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMediaStreamTrackStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mOutboundRTPStreamStats)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mPcid)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mRemoteSdp)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTimestamp)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTransportStats))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef mozilla::dom::RTCStats RTCStats;
|
||||||
|
|
||||||
|
static void WriteRTCStats(Message* aMsg, const RTCStats& aParam)
|
||||||
|
{
|
||||||
|
// RTCStats base class
|
||||||
|
WriteParam(aMsg, aParam.mId);
|
||||||
|
WriteParam(aMsg, aParam.mTimestamp);
|
||||||
|
WriteParam(aMsg, aParam.mType);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ReadRTCStats(const Message* aMsg, void** aIter, RTCStats* aResult)
|
||||||
|
{
|
||||||
|
// RTCStats base class
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTimestamp)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mType))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCCodecStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCCodecStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mChannels);
|
||||||
|
WriteParam(aMsg, aParam.mClockRate);
|
||||||
|
WriteParam(aMsg, aParam.mCodec);
|
||||||
|
WriteParam(aMsg, aParam.mParameters);
|
||||||
|
WriteParam(aMsg, aParam.mPayloadType);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mChannels)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mClockRate)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mCodec)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mParameters)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mPayloadType)) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCIceCandidatePairStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCIceCandidatePairStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mComponentId);
|
||||||
|
WriteParam(aMsg, aParam.mLocalCandidateId);
|
||||||
|
WriteParam(aMsg, aParam.mMozPriority);
|
||||||
|
WriteParam(aMsg, aParam.mNominated);
|
||||||
|
WriteParam(aMsg, aParam.mReadable);
|
||||||
|
WriteParam(aMsg, aParam.mRemoteCandidateId);
|
||||||
|
WriteParam(aMsg, aParam.mSelected);
|
||||||
|
WriteParam(aMsg, aParam.mState);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mLocalCandidateId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMozPriority)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mNominated)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mReadable)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mRemoteCandidateId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mSelected)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mState)) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCIceCandidateStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCIceCandidateStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mCandidateId);
|
||||||
|
WriteParam(aMsg, aParam.mCandidateType);
|
||||||
|
WriteParam(aMsg, aParam.mComponentId);
|
||||||
|
WriteParam(aMsg, aParam.mIpAddress);
|
||||||
|
WriteParam(aMsg, aParam.mMozLocalTransport);
|
||||||
|
WriteParam(aMsg, aParam.mPortNumber);
|
||||||
|
WriteParam(aMsg, aParam.mTransport);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mCandidateId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mCandidateType)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mIpAddress)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMozLocalTransport)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mPortNumber)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTransport)) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCIceComponentStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCIceComponentStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mActiveConnection);
|
||||||
|
WriteParam(aMsg, aParam.mBytesReceived);
|
||||||
|
WriteParam(aMsg, aParam.mBytesSent);
|
||||||
|
WriteParam(aMsg, aParam.mComponent);
|
||||||
|
WriteParam(aMsg, aParam.mTransportId);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mActiveConnection)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mComponent)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTransportId)) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void WriteRTCRTPStreamStats(
|
||||||
|
Message* aMsg,
|
||||||
|
const mozilla::dom::RTCRTPStreamStats& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mBitrateMean);
|
||||||
|
WriteParam(aMsg, aParam.mBitrateStdDev);
|
||||||
|
WriteParam(aMsg, aParam.mCodecId);
|
||||||
|
WriteParam(aMsg, aParam.mFramerateMean);
|
||||||
|
WriteParam(aMsg, aParam.mFramerateStdDev);
|
||||||
|
WriteParam(aMsg, aParam.mIsRemote);
|
||||||
|
WriteParam(aMsg, aParam.mMediaTrackId);
|
||||||
|
WriteParam(aMsg, aParam.mMediaType);
|
||||||
|
WriteParam(aMsg, aParam.mRemoteId);
|
||||||
|
WriteParam(aMsg, aParam.mSsrc);
|
||||||
|
WriteParam(aMsg, aParam.mTransportId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ReadRTCRTPStreamStats(
|
||||||
|
const Message* aMsg, void** aIter,
|
||||||
|
mozilla::dom::RTCRTPStreamStats* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mBitrateMean)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mBitrateStdDev)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mCodecId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramerateMean)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramerateStdDev)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mIsRemote)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMediaTrackId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMediaType)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mRemoteId)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mSsrc)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTransportId))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCInboundRTPStreamStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCInboundRTPStreamStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mBytesReceived);
|
||||||
|
WriteParam(aMsg, aParam.mDiscardedPackets);
|
||||||
|
WriteParam(aMsg, aParam.mJitter);
|
||||||
|
WriteParam(aMsg, aParam.mMozAvSyncDelay);
|
||||||
|
WriteParam(aMsg, aParam.mMozJitterBufferDelay);
|
||||||
|
WriteParam(aMsg, aParam.mMozRtt);
|
||||||
|
WriteParam(aMsg, aParam.mPacketsLost);
|
||||||
|
WriteParam(aMsg, aParam.mPacketsReceived);
|
||||||
|
WriteRTCRTPStreamStats(aMsg, aParam);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mDiscardedPackets)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mJitter)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMozAvSyncDelay)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMozJitterBufferDelay)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mMozRtt)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mPacketsLost)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mPacketsReceived)) ||
|
||||||
|
!ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCOutboundRTPStreamStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCOutboundRTPStreamStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mBytesSent);
|
||||||
|
WriteParam(aMsg, aParam.mDroppedFrames);
|
||||||
|
WriteParam(aMsg, aParam.mPacketsSent);
|
||||||
|
WriteParam(aMsg, aParam.mTargetBitrate);
|
||||||
|
WriteRTCRTPStreamStats(aMsg, aParam);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mDroppedFrames)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mPacketsSent)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTargetBitrate)) ||
|
||||||
|
!ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCMediaStreamStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCMediaStreamStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mStreamIdentifier);
|
||||||
|
WriteParam(aMsg, aParam.mTrackIds);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mStreamIdentifier)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTrackIds)) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCTransportStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCTransportStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mBytesReceived);
|
||||||
|
WriteParam(aMsg, aParam.mBytesSent);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::dom::RTCMediaStreamTrackStats>
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::RTCMediaStreamTrackStats paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
WriteParam(aMsg, aParam.mAudioLevel);
|
||||||
|
WriteParam(aMsg, aParam.mEchoReturnLoss);
|
||||||
|
WriteParam(aMsg, aParam.mEchoReturnLossEnhancement);
|
||||||
|
WriteParam(aMsg, aParam.mFrameHeight);
|
||||||
|
WriteParam(aMsg, aParam.mFrameWidth);
|
||||||
|
WriteParam(aMsg, aParam.mFramesCorrupted);
|
||||||
|
WriteParam(aMsg, aParam.mFramesDecoded);
|
||||||
|
WriteParam(aMsg, aParam.mFramesDropped);
|
||||||
|
WriteParam(aMsg, aParam.mFramesPerSecond);
|
||||||
|
WriteParam(aMsg, aParam.mFramesReceived);
|
||||||
|
WriteParam(aMsg, aParam.mFramesSent);
|
||||||
|
WriteParam(aMsg, aParam.mRemoteSource);
|
||||||
|
WriteParam(aMsg, aParam.mSsrcIds);
|
||||||
|
WriteParam(aMsg, aParam.mTrackIdentifier);
|
||||||
|
WriteRTCStats(aMsg, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!ReadParam(aMsg, aIter, &(aResult->mAudioLevel)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mEchoReturnLoss)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mEchoReturnLossEnhancement)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFrameHeight)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFrameWidth)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramesCorrupted)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramesDecoded)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramesDropped)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramesPerSecond)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramesReceived)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mFramesSent)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mRemoteSource)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mSsrcIds)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mTrackIdentifier)) ||
|
||||||
|
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace ipc
|
||||||
|
|
||||||
|
#endif // _WEBRTC_GLOBAL_H_
|
@ -0,0 +1,38 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef _WEBRTC_GLOBAL_CHILD_H_
|
||||||
|
#define _WEBRTC_GLOBAL_CHILD_H_
|
||||||
|
|
||||||
|
#include "mozilla/dom/PWebrtcGlobalChild.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class WebrtcGlobalChild :
|
||||||
|
public PWebrtcGlobalChild
|
||||||
|
{
|
||||||
|
friend class ContentChild;
|
||||||
|
|
||||||
|
bool mShutdown;
|
||||||
|
|
||||||
|
MOZ_IMPLICIT WebrtcGlobalChild();
|
||||||
|
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
|
|
||||||
|
virtual bool RecvGetStatsRequest(const int& aRequestId,
|
||||||
|
const nsString& aPcIdFilter) override;
|
||||||
|
virtual bool RecvGetLogRequest(const int& aReqestId,
|
||||||
|
const nsCString& aPattern) override;
|
||||||
|
virtual bool RecvSetAecLogging(const bool& aEnable) override;
|
||||||
|
virtual bool RecvSetDebugMode(const int& aLevel) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~WebrtcGlobalChild();
|
||||||
|
static WebrtcGlobalChild* Create();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // _WEBRTC_GLOBAL_CHILD_H_
|
@ -3,13 +3,21 @@
|
|||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "WebrtcGlobalInformation.h"
|
#include "WebrtcGlobalInformation.h"
|
||||||
|
#include "WebrtcGlobalChild.h"
|
||||||
|
#include "WebrtcGlobalParent.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include "CSFLog.h"
|
#include "CSFLog.h"
|
||||||
#include "WebRtcLog.h"
|
#include "WebRtcLog.h"
|
||||||
#include "mozilla/dom/WebrtcGlobalInformationBinding.h"
|
#include "mozilla/dom/WebrtcGlobalInformationBinding.h"
|
||||||
|
#include "WebrtcGlobal.h"
|
||||||
|
#include "mozilla/dom/ContentChild.h"
|
||||||
|
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsNetCID.h" // NS_SOCKETTRANSPORTSERVICE_CONTRACTID
|
#include "nsNetCID.h" // NS_SOCKETTRANSPORTSERVICE_CONTRACTID
|
||||||
@ -18,6 +26,9 @@
|
|||||||
#include "mozilla/Vector.h"
|
#include "mozilla/Vector.h"
|
||||||
#include "nsProxyRelease.h"
|
#include "nsProxyRelease.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
|
#include "mozilla/unused.h"
|
||||||
|
#include "mozilla/StaticMutex.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
|
|
||||||
#include "rlogringbuffer.h"
|
#include "rlogringbuffer.h"
|
||||||
#include "runnable_utils.h"
|
#include "runnable_utils.h"
|
||||||
@ -28,10 +39,190 @@
|
|||||||
static const char* logTag = "WebrtcGlobalInformation";
|
static const char* logTag = "WebrtcGlobalInformation";
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
typedef Vector<nsAutoPtr<RTCStatsQuery>> RTCStatsQueries;
|
typedef Vector<nsAutoPtr<RTCStatsQuery>> RTCStatsQueries;
|
||||||
|
typedef nsTArray<RTCStatsReportInternal> Stats;
|
||||||
|
|
||||||
|
template<class Request, typename Callback,
|
||||||
|
typename Result, typename QueryParam>
|
||||||
|
class RequestManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Request* Create(Callback& aCallback, QueryParam& aParam)
|
||||||
|
{
|
||||||
|
mozilla::StaticMutexAutoLock lock(sMutex);
|
||||||
|
|
||||||
|
int id = ++sLastRequestId;
|
||||||
|
auto result = sRequests.insert(
|
||||||
|
std::make_pair(id, Request(id, aCallback, aParam)));
|
||||||
|
|
||||||
|
if (!result.second) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &result.first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Delete(int aId)
|
||||||
|
{
|
||||||
|
mozilla::StaticMutexAutoLock lock(sMutex);
|
||||||
|
sRequests.erase(aId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Request* Get(int aId)
|
||||||
|
{
|
||||||
|
mozilla::StaticMutexAutoLock lock(sMutex);
|
||||||
|
auto r = sRequests.find(aId);
|
||||||
|
|
||||||
|
if (r == sRequests.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &r->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result mResult;
|
||||||
|
std::queue<RefPtr<WebrtcGlobalParent>> mContactList;
|
||||||
|
const int mRequestId;
|
||||||
|
|
||||||
|
RefPtr<WebrtcGlobalParent> GetNextParent()
|
||||||
|
{
|
||||||
|
while (!mContactList.empty()) {
|
||||||
|
RefPtr<WebrtcGlobalParent> next = mContactList.front();
|
||||||
|
mContactList.pop();
|
||||||
|
if (next->IsActive()) {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Complete()
|
||||||
|
{
|
||||||
|
ErrorResult rv;
|
||||||
|
mCallback.get()->Call(mResult, rv);
|
||||||
|
|
||||||
|
if (rv.Failed()) {
|
||||||
|
CSFLogError(logTag, "Error firing stats observer callback");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// The mutex is used to protect two related operations involving the sRequest map
|
||||||
|
// and the sLastRequestId. For the map, it prevents more than one thread from
|
||||||
|
// adding or deleting map entries at the same time. For id generation,
|
||||||
|
// it creates an atomic allocation and increment.
|
||||||
|
static mozilla::StaticMutex sMutex;
|
||||||
|
static std::map<int, Request> sRequests;
|
||||||
|
static int sLastRequestId;
|
||||||
|
|
||||||
|
Callback mCallback;
|
||||||
|
|
||||||
|
explicit RequestManager(int aId, Callback& aCallback)
|
||||||
|
: mRequestId(aId)
|
||||||
|
, mCallback(aCallback)
|
||||||
|
{}
|
||||||
|
~RequestManager() {}
|
||||||
|
private:
|
||||||
|
|
||||||
|
RequestManager() = delete;
|
||||||
|
RequestManager& operator=(const RequestManager&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Request, typename Callback,
|
||||||
|
typename Result, typename QueryParam>
|
||||||
|
mozilla::StaticMutex RequestManager<Request, Callback, Result, QueryParam>::sMutex;
|
||||||
|
template<class Request, typename Callback,
|
||||||
|
typename Result, typename QueryParam>
|
||||||
|
std::map<int, Request> RequestManager<Request, Callback, Result, QueryParam>::sRequests;
|
||||||
|
template<class Request, typename Callback,
|
||||||
|
typename Result, typename QueryParam>
|
||||||
|
int RequestManager<Request, Callback, Result, QueryParam>::sLastRequestId;
|
||||||
|
|
||||||
|
typedef nsMainThreadPtrHandle<WebrtcGlobalStatisticsCallback> StatsRequestCallback;
|
||||||
|
|
||||||
|
class StatsRequest
|
||||||
|
: public RequestManager<StatsRequest,
|
||||||
|
StatsRequestCallback,
|
||||||
|
WebrtcGlobalStatisticsReport,
|
||||||
|
nsAString>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const nsString mPcIdFilter;
|
||||||
|
explicit StatsRequest(int aId, StatsRequestCallback& aCallback, nsAString& aFilter)
|
||||||
|
: RequestManager(aId, aCallback)
|
||||||
|
, mPcIdFilter(aFilter)
|
||||||
|
{
|
||||||
|
mResult.mReports.Construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
StatsRequest() = delete;
|
||||||
|
StatsRequest& operator=(const StatsRequest&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef nsMainThreadPtrHandle<WebrtcGlobalLoggingCallback> LogRequestCallback;
|
||||||
|
|
||||||
|
class LogRequest
|
||||||
|
: public RequestManager<LogRequest,
|
||||||
|
LogRequestCallback,
|
||||||
|
Sequence<nsString>,
|
||||||
|
const nsACString>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const nsCString mPattern;
|
||||||
|
explicit LogRequest(int aId, LogRequestCallback& aCallback, const nsACString& aPattern)
|
||||||
|
: RequestManager(aId, aCallback)
|
||||||
|
, mPattern(aPattern)
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LogRequest() = delete;
|
||||||
|
LogRequest& operator=(const LogRequest&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebrtcContentParents
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static WebrtcGlobalParent* Alloc();
|
||||||
|
static void Dealloc(WebrtcGlobalParent* aParent);
|
||||||
|
static bool Empty()
|
||||||
|
{
|
||||||
|
return sContentParents.empty();
|
||||||
|
}
|
||||||
|
static const std::vector<RefPtr<WebrtcGlobalParent>>& GetAll()
|
||||||
|
{
|
||||||
|
return sContentParents;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static std::vector<RefPtr<WebrtcGlobalParent>> sContentParents;
|
||||||
|
WebrtcContentParents() = delete;
|
||||||
|
WebrtcContentParents(const WebrtcContentParents&) = delete;
|
||||||
|
WebrtcContentParents& operator=(const WebrtcContentParents&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<RefPtr<WebrtcGlobalParent>> WebrtcContentParents::sContentParents;
|
||||||
|
|
||||||
|
WebrtcGlobalParent* WebrtcContentParents::Alloc()
|
||||||
|
{
|
||||||
|
RefPtr<WebrtcGlobalParent> cp = new WebrtcGlobalParent;
|
||||||
|
sContentParents.push_back(cp);
|
||||||
|
return cp.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebrtcContentParents::Dealloc(WebrtcGlobalParent* aParent)
|
||||||
|
{
|
||||||
|
if (aParent) {
|
||||||
|
aParent->mShutdown = true;
|
||||||
|
auto cp = std::find(sContentParents.begin(), sContentParents.end(), aParent);
|
||||||
|
if (cp != sContentParents.end()) {
|
||||||
|
sContentParents.erase(cp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static PeerConnectionCtx* GetPeerConnectionCtx()
|
static PeerConnectionCtx* GetPeerConnectionCtx()
|
||||||
{
|
{
|
||||||
@ -42,89 +233,201 @@ static PeerConnectionCtx* GetPeerConnectionCtx()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnStatsReport_m(
|
static void
|
||||||
nsMainThreadPtrHandle<WebrtcGlobalStatisticsCallback> aStatsCallback,
|
OnStatsReport_m(WebrtcGlobalChild* aThisChild,
|
||||||
nsAutoPtr<RTCStatsQueries> aQueryList)
|
const int aRequestId,
|
||||||
|
nsAutoPtr<RTCStatsQueries> aQueryList)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(aQueryList);
|
MOZ_ASSERT(aQueryList);
|
||||||
|
|
||||||
WebrtcGlobalStatisticsReport report;
|
if (aThisChild) {
|
||||||
report.mReports.Construct();
|
Stats stats;
|
||||||
|
|
||||||
// Reports for the currently active PeerConnections
|
// Copy stats generated for the currently active PeerConnections
|
||||||
for (auto q = aQueryList->begin(); q != aQueryList->end(); ++q) {
|
for (auto&& query : *aQueryList) {
|
||||||
MOZ_ASSERT(*q);
|
stats.AppendElement(*(query->report));
|
||||||
report.mReports.Value().AppendElement(*(*q)->report);
|
}
|
||||||
|
// Reports saved for closed/destroyed PeerConnections
|
||||||
|
auto ctx = PeerConnectionCtx::GetInstance();
|
||||||
|
if (ctx) {
|
||||||
|
for (auto&& pc : ctx->mStatsForClosedPeerConnections) {
|
||||||
|
stats.AppendElement(pc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unused << aThisChild->SendGetStatsResult(aRequestId, stats);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerConnectionCtx* ctx = GetPeerConnectionCtx();
|
// This is the last stats report to be collected. (Must be the gecko process).
|
||||||
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
|
|
||||||
|
StatsRequest* request = StatsRequest::Get(aRequestId);
|
||||||
|
|
||||||
|
if (!request) {
|
||||||
|
CSFLogError(logTag, "Bad RequestId");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto&& query : *aQueryList) {
|
||||||
|
request->mResult.mReports.Value().AppendElement(*(query->report));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reports saved for closed/destroyed PeerConnections
|
||||||
|
auto ctx = PeerConnectionCtx::GetInstance();
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
// Reports for closed/destroyed PeerConnections
|
for (auto&& pc : ctx->mStatsForClosedPeerConnections) {
|
||||||
report.mReports.Value().AppendElements(ctx->mStatsForClosedPeerConnections);
|
request->mResult.mReports.Value().AppendElement(pc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorResult rv;
|
request->Complete();
|
||||||
aStatsCallback.get()->Call(report, rv);
|
StatsRequest::Delete(aRequestId);
|
||||||
|
|
||||||
if (rv.Failed()) {
|
|
||||||
CSFLogError(logTag, "Error firing stats observer callback");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetAllStats_s(
|
static void
|
||||||
nsMainThreadPtrHandle<WebrtcGlobalStatisticsCallback> aStatsCallback,
|
GetAllStats_s(WebrtcGlobalChild* aThisChild,
|
||||||
nsAutoPtr<RTCStatsQueries> aQueryList)
|
const int aRequestId,
|
||||||
|
nsAutoPtr<RTCStatsQueries> aQueryList)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aQueryList);
|
MOZ_ASSERT(aQueryList);
|
||||||
|
// The call to PeerConnetionImpl must happen on the from a runnable
|
||||||
|
// dispatched on the STS thread.
|
||||||
|
|
||||||
for (auto q = aQueryList->begin(); q != aQueryList->end(); ++q) {
|
// Get stats from active connections.
|
||||||
MOZ_ASSERT(*q);
|
for (auto&& query : *aQueryList) {
|
||||||
PeerConnectionImpl::ExecuteStatsQuery_s(*q);
|
PeerConnectionImpl::ExecuteStatsQuery_s(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// After the RTCStatsQueries have been filled in, control must return
|
||||||
|
// to the main thread before their eventual destruction.
|
||||||
NS_DispatchToMainThread(WrapRunnableNM(&OnStatsReport_m,
|
NS_DispatchToMainThread(WrapRunnableNM(&OnStatsReport_m,
|
||||||
aStatsCallback,
|
aThisChild,
|
||||||
|
aRequestId,
|
||||||
aQueryList),
|
aQueryList),
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnGetLogging_m(
|
static void OnGetLogging_m(WebrtcGlobalChild* aThisChild,
|
||||||
nsMainThreadPtrHandle<WebrtcGlobalLoggingCallback> aLoggingCallback,
|
const int aRequestId,
|
||||||
const std::string& aPattern,
|
nsAutoPtr<std::deque<std::string>> aLogList)
|
||||||
nsAutoPtr<std::deque<std::string>> aLogList)
|
|
||||||
{
|
{
|
||||||
ErrorResult rv;
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
if (!aLogList->empty()) {
|
|
||||||
|
if (aThisChild) {
|
||||||
|
// Add this log to the collection of logs and call into
|
||||||
|
// the next content process.
|
||||||
Sequence<nsString> nsLogs;
|
Sequence<nsString> nsLogs;
|
||||||
for (auto l = aLogList->begin(); l != aLogList->end(); ++l) {
|
|
||||||
nsLogs.AppendElement(NS_ConvertUTF8toUTF16(l->c_str()));
|
if (!aLogList->empty()) {
|
||||||
|
for (auto& line : *aLogList) {
|
||||||
|
nsLogs.AppendElement(NS_ConvertUTF8toUTF16(line.c_str()));
|
||||||
|
}
|
||||||
|
nsLogs.AppendElement(NS_LITERAL_STRING("+++++++ END ++++++++"));
|
||||||
}
|
}
|
||||||
aLoggingCallback.get()->Call(nsLogs, rv);
|
|
||||||
|
unused << aThisChild->SendGetLogResult(aRequestId, nsLogs);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv.Failed()) {
|
// This is the last log to be collected. (Must be the gecko process).
|
||||||
CSFLogError(logTag, "Error firing logging observer callback");
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
|
|
||||||
|
LogRequest* request = LogRequest::Get(aRequestId);
|
||||||
|
|
||||||
|
if (!request) {
|
||||||
|
CSFLogError(logTag, "Bad RequestId");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!aLogList->empty()) {
|
||||||
|
for (auto& line : *aLogList) {
|
||||||
|
request->mResult.AppendElement(NS_ConvertUTF8toUTF16(line.c_str()));
|
||||||
|
}
|
||||||
|
request->mResult.AppendElement(NS_LITERAL_STRING("+++++++ END ++++++++"));
|
||||||
|
}
|
||||||
|
|
||||||
|
request->Complete();
|
||||||
|
LogRequest::Delete(aRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetLogging_s(
|
static void GetLogging_s(WebrtcGlobalChild* aThisChild,
|
||||||
nsMainThreadPtrHandle<WebrtcGlobalLoggingCallback> aLoggingCallback,
|
const int aRequestId,
|
||||||
const std::string& aPattern)
|
const std::string& aPattern)
|
||||||
{
|
{
|
||||||
|
// Request log while not on the main thread.
|
||||||
RLogRingBuffer* logs = RLogRingBuffer::GetInstance();
|
RLogRingBuffer* logs = RLogRingBuffer::GetInstance();
|
||||||
nsAutoPtr<std::deque<std::string>> result(new std::deque<std::string>);
|
nsAutoPtr<std::deque<std::string>> result(new std::deque<std::string>);
|
||||||
// Might not exist yet.
|
// Might not exist yet.
|
||||||
if (logs) {
|
if (logs) {
|
||||||
logs->Filter(aPattern, 0, result);
|
logs->Filter(aPattern, 0, result);
|
||||||
}
|
}
|
||||||
|
// Return to main thread to complete processing.
|
||||||
NS_DispatchToMainThread(WrapRunnableNM(&OnGetLogging_m,
|
NS_DispatchToMainThread(WrapRunnableNM(&OnGetLogging_m,
|
||||||
aLoggingCallback,
|
aThisChild,
|
||||||
aPattern,
|
aRequestId,
|
||||||
result),
|
result),
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
BuildStatsQueryList(
|
||||||
|
const std::map<const std::string, PeerConnectionImpl *>& aPeerConnections,
|
||||||
|
const nsAString& aPcIdFilter,
|
||||||
|
RTCStatsQueries* queries)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
for (auto&& pc : aPeerConnections) {
|
||||||
|
MOZ_ASSERT(pc.second);
|
||||||
|
if (aPcIdFilter.IsEmpty() ||
|
||||||
|
aPcIdFilter.EqualsASCII(pc.second->GetIdAsAscii().c_str())) {
|
||||||
|
if (pc.second->HasMedia()) {
|
||||||
|
queries->append(nsAutoPtr<RTCStatsQuery>(new RTCStatsQuery(true)));
|
||||||
|
rv = pc.second->BuildStatsQuery_m(nullptr, queries->back()); // all tracks
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(queries->back()->report);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
RunStatsQuery(
|
||||||
|
const std::map<const std::string, PeerConnectionImpl *>& aPeerConnections,
|
||||||
|
const nsAString& aPcIdFilter,
|
||||||
|
WebrtcGlobalChild* aThisChild,
|
||||||
|
const int aRequestId)
|
||||||
|
{
|
||||||
|
auto* queries = new RTCStatsQueries;
|
||||||
|
nsresult rv = BuildStatsQueryList(aPeerConnections, aPcIdFilter, queries);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIEventTarget> stsThread =
|
||||||
|
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
} else if (!stsThread) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = RUN_ON_THREAD(stsThread,
|
||||||
|
WrapRunnableNM(&GetAllStats_s,
|
||||||
|
aThisChild,
|
||||||
|
aRequestId,
|
||||||
|
nsAutoPtr<RTCStatsQueries>(queries)),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WebrtcGlobalInformation::GetAllStats(
|
WebrtcGlobalInformation::GetAllStats(
|
||||||
@ -138,55 +441,83 @@ WebrtcGlobalInformation::GetAllStats(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
|
|
||||||
|
// CallbackObject does not support threadsafe refcounting, and must be
|
||||||
|
// destroyed on main.
|
||||||
|
StatsRequestCallback callbackHandle(
|
||||||
|
new nsMainThreadPtrHolder<WebrtcGlobalStatisticsCallback>(&aStatsCallback));
|
||||||
|
|
||||||
|
nsString filter;
|
||||||
|
if (pcIdFilter.WasPassed()) {
|
||||||
|
filter = pcIdFilter.Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
StatsRequest* request = StatsRequest::Create(callbackHandle, filter);
|
||||||
|
|
||||||
|
if (!request) {
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WebrtcContentParents::Empty()) {
|
||||||
|
// Pass on the request to any content based PeerConnections.
|
||||||
|
for (auto& cp : WebrtcContentParents::GetAll()) {
|
||||||
|
request->mContactList.push(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = request->GetNextParent();
|
||||||
|
if (next) {
|
||||||
|
aRv = next->SendGetStatsRequest(request->mRequestId, request->mPcIdFilter) ?
|
||||||
|
NS_OK : NS_ERROR_FAILURE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No content resident PeerConnectionCtx instances.
|
||||||
|
// Check this process.
|
||||||
|
PeerConnectionCtx* ctx = GetPeerConnectionCtx();
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
rv = RunStatsQuery(ctx->mGetPeerConnections(),
|
||||||
|
filter, nullptr, request->mRequestId);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
StatsRequest::Delete(request->mRequestId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Just send back an empty report.
|
||||||
|
rv = NS_OK;
|
||||||
|
request->Complete();
|
||||||
|
StatsRequest::Delete(request->mRequestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
aRv = rv;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
RunLogQuery(const nsCString& aPattern,
|
||||||
|
WebrtcGlobalChild* aThisChild,
|
||||||
|
const int aRequestId)
|
||||||
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIEventTarget> stsThread =
|
nsCOMPtr<nsIEventTarget> stsThread =
|
||||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
aRv.Throw(rv);
|
return rv;
|
||||||
return;
|
} else if (!stsThread) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stsThread) {
|
|
||||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<RTCStatsQueries> queries(new RTCStatsQueries);
|
|
||||||
|
|
||||||
// If there is no PeerConnectionCtx, go through the same motions, since
|
|
||||||
// the API consumer doesn't care why there are no PeerConnectionImpl.
|
|
||||||
PeerConnectionCtx *ctx = GetPeerConnectionCtx();
|
|
||||||
if (ctx) {
|
|
||||||
for (auto p = ctx->mPeerConnections.begin();
|
|
||||||
p != ctx->mPeerConnections.end();
|
|
||||||
++p) {
|
|
||||||
MOZ_ASSERT(p->second);
|
|
||||||
|
|
||||||
if (!pcIdFilter.WasPassed() ||
|
|
||||||
pcIdFilter.Value().EqualsASCII(p->second->GetIdAsAscii().c_str())) {
|
|
||||||
if (p->second->HasMedia()) {
|
|
||||||
queries->append(nsAutoPtr<RTCStatsQuery>(new RTCStatsQuery(true)));
|
|
||||||
rv = p->second->BuildStatsQuery_m(nullptr, queries->back()); // all tracks
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
aRv.Throw(rv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(queries->back()->report);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CallbackObject does not support threadsafe refcounting, and must be
|
|
||||||
// destroyed on main.
|
|
||||||
nsMainThreadPtrHandle<WebrtcGlobalStatisticsCallback> callbackHandle(
|
|
||||||
new nsMainThreadPtrHolder<WebrtcGlobalStatisticsCallback>(&aStatsCallback));
|
|
||||||
|
|
||||||
rv = RUN_ON_THREAD(stsThread,
|
rv = RUN_ON_THREAD(stsThread,
|
||||||
WrapRunnableNM(&GetAllStats_s, callbackHandle, queries),
|
WrapRunnableNM(&GetLogging_s,
|
||||||
|
aThisChild,
|
||||||
|
aRequestId,
|
||||||
|
aPattern.get()),
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
aRv = rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -201,36 +532,45 @@ WebrtcGlobalInformation::GetLogging(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv;
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
nsCOMPtr<nsIEventTarget> stsThread =
|
|
||||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
aRv.Throw(rv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stsThread) {
|
|
||||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string pattern(NS_ConvertUTF16toUTF8(aPattern).get());
|
|
||||||
|
|
||||||
// CallbackObject does not support threadsafe refcounting, and must be
|
// CallbackObject does not support threadsafe refcounting, and must be
|
||||||
// destroyed on main.
|
// destroyed on main.
|
||||||
nsMainThreadPtrHandle<WebrtcGlobalLoggingCallback> callbackHandle(
|
LogRequestCallback callbackHandle(
|
||||||
new nsMainThreadPtrHolder<WebrtcGlobalLoggingCallback>(&aLoggingCallback));
|
new nsMainThreadPtrHolder<WebrtcGlobalLoggingCallback>(&aLoggingCallback));
|
||||||
|
|
||||||
rv = RUN_ON_THREAD(stsThread,
|
nsAutoCString pattern;
|
||||||
WrapRunnableNM(&GetLogging_s, callbackHandle, pattern),
|
CopyUTF16toUTF8(aPattern, pattern);
|
||||||
NS_DISPATCH_NORMAL);
|
|
||||||
|
LogRequest* request = LogRequest::Create(callbackHandle, pattern);
|
||||||
|
|
||||||
|
if (!request) {
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WebrtcContentParents::Empty()) {
|
||||||
|
// Pass on the request to any content based PeerConnections.
|
||||||
|
for (auto& cp : WebrtcContentParents::GetAll()) {
|
||||||
|
request->mContactList.push(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = request->GetNextParent();
|
||||||
|
if (next) {
|
||||||
|
aRv = next->SendGetLogRequest(request->mRequestId, request->mPattern) ?
|
||||||
|
NS_OK : NS_ERROR_FAILURE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = RunLogQuery(request->mPattern, nullptr, request->mRequestId);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
aLoggingCallback.Release();
|
LogRequest::Delete(request->mRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
aRv = rv;
|
aRv = rv;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t sLastSetLevel = 0;
|
static int32_t sLastSetLevel = 0;
|
||||||
@ -241,6 +581,10 @@ WebrtcGlobalInformation::SetDebugLevel(const GlobalObject& aGlobal, int32_t aLev
|
|||||||
{
|
{
|
||||||
StartWebRtcLog(webrtc::TraceLevel(aLevel));
|
StartWebRtcLog(webrtc::TraceLevel(aLevel));
|
||||||
sLastSetLevel = aLevel;
|
sLastSetLevel = aLevel;
|
||||||
|
|
||||||
|
for (auto& cp : WebrtcContentParents::GetAll()){
|
||||||
|
unused << cp->SendSetDebugMode(aLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
@ -255,6 +599,10 @@ WebrtcGlobalInformation::SetAecDebug(const GlobalObject& aGlobal, bool aEnable)
|
|||||||
StartWebRtcLog(sLastSetLevel); // to make it read the aec path
|
StartWebRtcLog(sLastSetLevel); // to make it read the aec path
|
||||||
webrtc::Trace::set_aec_debug(aEnable);
|
webrtc::Trace::set_aec_debug(aEnable);
|
||||||
sLastAECDebug = aEnable;
|
sLastAECDebug = aEnable;
|
||||||
|
|
||||||
|
for (auto& cp : WebrtcContentParents::GetAll()){
|
||||||
|
unused << cp->SendSetAecLogging(aEnable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -263,6 +611,209 @@ WebrtcGlobalInformation::AecDebug(const GlobalObject& aGlobal)
|
|||||||
return sLastAECDebug;
|
return sLastAECDebug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalParent::RecvGetStatsResult(const int& aRequestId,
|
||||||
|
nsTArray<RTCStatsReportInternal>&& Stats)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
StatsRequest* request = StatsRequest::Get(aRequestId);
|
||||||
|
|
||||||
|
if (!request) {
|
||||||
|
CSFLogError(logTag, "Bad RequestId");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto&& s : Stats) {
|
||||||
|
request->mResult.mReports.Value().AppendElement(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = request->GetNextParent();
|
||||||
|
if (next) {
|
||||||
|
// There are more content instances to query.
|
||||||
|
return next->SendGetStatsRequest(request->mRequestId, request->mPcIdFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content queries complete, run chrome instance query if applicable
|
||||||
|
PeerConnectionCtx* ctx = GetPeerConnectionCtx();
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
rv = RunStatsQuery(ctx->mGetPeerConnections(),
|
||||||
|
request->mPcIdFilter, nullptr, aRequestId);
|
||||||
|
} else {
|
||||||
|
// No instance in the process, return the collections as is
|
||||||
|
request->Complete();
|
||||||
|
StatsRequest::Delete(aRequestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_SUCCEEDED(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalParent::RecvGetLogResult(const int& aRequestId,
|
||||||
|
const WebrtcGlobalLog& aLog)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
LogRequest* request = LogRequest::Get(aRequestId);
|
||||||
|
|
||||||
|
if (!request) {
|
||||||
|
CSFLogError(logTag, "Bad RequestId");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
request->mResult.AppendElements(aLog);
|
||||||
|
|
||||||
|
auto next = request->GetNextParent();
|
||||||
|
if (next) {
|
||||||
|
// There are more content instances to query.
|
||||||
|
return next->SendGetLogRequest(request->mRequestId, request->mPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content queries complete, run chrome instance query if applicable
|
||||||
|
nsresult rv = RunLogQuery(request->mPattern, nullptr, aRequestId);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
//Unable to get gecko process log. Return what has been collected.
|
||||||
|
CSFLogError(logTag, "Unable to extract chrome process log");
|
||||||
|
request->Complete();
|
||||||
|
LogRequest::Delete(aRequestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebrtcGlobalParent*
|
||||||
|
WebrtcGlobalParent::Alloc()
|
||||||
|
{
|
||||||
|
return WebrtcContentParents::Alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalParent::Dealloc(WebrtcGlobalParent * aActor)
|
||||||
|
{
|
||||||
|
WebrtcContentParents::Dealloc(aActor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebrtcGlobalParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||||
|
{
|
||||||
|
mShutdown = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalParent::Recv__delete__()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_IMPLICIT WebrtcGlobalParent::WebrtcGlobalParent()
|
||||||
|
: mShutdown(false)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(WebrtcGlobalParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_IMPLICIT WebrtcGlobalParent::~WebrtcGlobalParent()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(WebrtcGlobalParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalChild::RecvGetStatsRequest(const int& aRequestId,
|
||||||
|
const nsString& aPcIdFilter)
|
||||||
|
{
|
||||||
|
if (mShutdown) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PeerConnectionCtx* ctx = GetPeerConnectionCtx();
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
nsresult rv = RunStatsQuery(ctx->mGetPeerConnections(),
|
||||||
|
aPcIdFilter, this, aRequestId);
|
||||||
|
return NS_SUCCEEDED(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsTArray<RTCStatsReportInternal> empty_stats;
|
||||||
|
SendGetStatsResult(aRequestId, empty_stats);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalChild::RecvGetLogRequest(const int& aRequestId,
|
||||||
|
const nsCString& aPattern)
|
||||||
|
{
|
||||||
|
if (mShutdown) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIEventTarget> stsThread =
|
||||||
|
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) && stsThread) {
|
||||||
|
rv = RUN_ON_THREAD(stsThread,
|
||||||
|
WrapRunnableNM(&GetLogging_s, this, aRequestId, aPattern.get()),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sequence<nsString> empty_log;
|
||||||
|
SendGetLogResult(aRequestId, empty_log);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalChild::RecvSetAecLogging(const bool& aEnable)
|
||||||
|
{
|
||||||
|
if (!mShutdown) {
|
||||||
|
StartWebRtcLog(sLastSetLevel); // to make it read the aec path
|
||||||
|
webrtc::Trace::set_aec_debug(aEnable);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebrtcGlobalChild::RecvSetDebugMode(const int& aLevel)
|
||||||
|
{
|
||||||
|
if (!mShutdown) {
|
||||||
|
StartWebRtcLog(webrtc::TraceLevel(aLevel));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebrtcGlobalChild*
|
||||||
|
WebrtcGlobalChild::Create()
|
||||||
|
{
|
||||||
|
WebrtcGlobalChild* child =
|
||||||
|
static_cast<WebrtcGlobalChild*>(
|
||||||
|
ContentChild::GetSingleton()->SendPWebrtcGlobalConstructor());
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebrtcGlobalChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||||
|
{
|
||||||
|
mShutdown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_IMPLICIT WebrtcGlobalChild::WebrtcGlobalChild()
|
||||||
|
: mShutdown(false)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(WebrtcGlobalChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_IMPLICIT WebrtcGlobalChild::~WebrtcGlobalChild()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(WebrtcGlobalChild);
|
||||||
|
}
|
||||||
|
|
||||||
struct StreamResult {
|
struct StreamResult {
|
||||||
StreamResult() : candidateTypeBitpattern(0), streamSucceeded(false) {}
|
StreamResult() : candidateTypeBitpattern(0), streamSucceeded(false) {}
|
||||||
@ -522,7 +1073,5 @@ void WebrtcGlobalInformation::StoreLongTermICEStatistics(
|
|||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ class PeerConnectionImpl;
|
|||||||
class ErrorResult;
|
class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class GlobalObject;
|
class GlobalObject;
|
||||||
class WebrtcGlobalStatisticsCallback;
|
class WebrtcGlobalStatisticsCallback;
|
||||||
class WebrtcGlobalLoggingCallback;
|
class WebrtcGlobalLoggingCallback;
|
||||||
@ -49,4 +50,3 @@ private:
|
|||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // _WEBRTC_GLOBAL_INFORMATION_H_
|
#endif // _WEBRTC_GLOBAL_INFORMATION_H_
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef _WEBRTC_GLOBAL_PARENT_H_
|
||||||
|
#define _WEBRTC_GLOBAL_PARENT_H_
|
||||||
|
|
||||||
|
#include "mozilla/dom/PWebrtcGlobalParent.h"
|
||||||
|
#include "mozilla/dom/RTCStatsReportBinding.h"
|
||||||
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class WebrtcParents;
|
||||||
|
|
||||||
|
class WebrtcGlobalParent
|
||||||
|
: public PWebrtcGlobalParent
|
||||||
|
, public RefCounted<WebrtcGlobalParent>
|
||||||
|
{
|
||||||
|
friend class ContentParent;
|
||||||
|
friend class WebrtcGlobalInformation;
|
||||||
|
friend class WebrtcContentParents;
|
||||||
|
|
||||||
|
bool mShutdown;
|
||||||
|
|
||||||
|
MOZ_IMPLICIT WebrtcGlobalParent();
|
||||||
|
|
||||||
|
static WebrtcGlobalParent* Alloc();
|
||||||
|
static bool Dealloc(WebrtcGlobalParent* aActor);
|
||||||
|
|
||||||
|
virtual bool RecvGetStatsResult(const int& aRequestId,
|
||||||
|
nsTArray<RTCStatsReportInternal>&& aStats) override;
|
||||||
|
virtual bool RecvGetLogResult(const int& aRequestId,
|
||||||
|
const WebrtcGlobalLog& aLog) override;
|
||||||
|
|
||||||
|
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
|
virtual bool Recv__delete__() override;
|
||||||
|
public:
|
||||||
|
virtual ~WebrtcGlobalParent();
|
||||||
|
MOZ_DECLARE_REFCOUNTED_TYPENAME(WebrtcGlobalParent)
|
||||||
|
bool IsActive()
|
||||||
|
{
|
||||||
|
return !mShutdown;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // _WEBRTC_GLOBAL_PARENT_H_
|
@ -293,7 +293,7 @@ let AboutWebRTC = {
|
|||||||
let connections = document.createDocumentFragment();
|
let connections = document.createDocumentFragment();
|
||||||
|
|
||||||
let reports = [...this._reports];
|
let reports = [...this._reports];
|
||||||
reports.sort((a, b) => a.timestamp - b.timestamp);
|
reports.sort((a, b) => b.timestamp - a.timestamp);
|
||||||
for (let report of reports) {
|
for (let report of reports) {
|
||||||
let peerConnection = new PeerConnection(report);
|
let peerConnection = new PeerConnection(report);
|
||||||
connections.appendChild(peerConnection.render());
|
connections.appendChild(peerConnection.render());
|
||||||
@ -306,6 +306,10 @@ let AboutWebRTC = {
|
|||||||
let content = document.createElement("div");
|
let content = document.createElement("div");
|
||||||
content.className = "log";
|
content.className = "log";
|
||||||
|
|
||||||
|
if (!this._log.length) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
let elem = document.createElement("h3");
|
let elem = document.createElement("h3");
|
||||||
elem.textContent = getString("log_heading");
|
elem.textContent = getString("log_heading");
|
||||||
content.appendChild(elem);
|
content.appendChild(elem);
|
||||||
|
Loading…
Reference in New Issue
Block a user