diff --git a/dom/media/webrtc/PWebrtcGlobal.ipdl b/dom/media/webrtc/PWebrtcGlobal.ipdl index 12c991ac5ba2..cb1822ffa871 100644 --- a/dom/media/webrtc/PWebrtcGlobal.ipdl +++ b/dom/media/webrtc/PWebrtcGlobal.ipdl @@ -20,14 +20,12 @@ async protocol PWebrtcGlobal { parent: // child -> parent messages async __delete__(); #ifdef MOZ_WEBRTC - async GetStatsResult(int aRequestId, RTCStatsReportInternal[] aStats); - async GetLogResult(int aRequestId, WebrtcGlobalLog aLog); child: // parent -> child messages - async GetStatsRequest(int aRequestId, nsString aPcIdFilter); - async ClearStatsRequest(); - async GetLogRequest(int aRequestId, nsCString aPattern); - async ClearLogRequest(); + async GetStats(nsString aPcIdFilter) returns (RTCStatsReportInternal[] stats); + async ClearStats(); + async GetLog(nsCString aPattern) returns (WebrtcGlobalLog logs); + async ClearLog(); async SetAecLogging(bool aEnable); async SetDebugMode(int aLevel); #endif diff --git a/dom/media/webrtc/jsapi/PeerConnectionCtx.cpp b/dom/media/webrtc/jsapi/PeerConnectionCtx.cpp index b448cb5ded65..f8491d36d5d7 100644 --- a/dom/media/webrtc/jsapi/PeerConnectionCtx.cpp +++ b/dom/media/webrtc/jsapi/PeerConnectionCtx.cpp @@ -117,7 +117,7 @@ StaticRefPtr PeerConnectionCtx::gPeerConnectionCtxObserver; const std::map& -PeerConnectionCtx::mGetPeerConnections() { +PeerConnectionCtx::GetPeerConnections() { return mPeerConnections; } diff --git a/dom/media/webrtc/jsapi/PeerConnectionCtx.h b/dom/media/webrtc/jsapi/PeerConnectionCtx.h index 8d9aada0005d..098b39e1fe08 100644 --- a/dom/media/webrtc/jsapi/PeerConnectionCtx.h +++ b/dom/media/webrtc/jsapi/PeerConnectionCtx.h @@ -65,7 +65,7 @@ class PeerConnectionCtx { mozilla::dom::Sequence mStatsForClosedPeerConnections; - const std::map& mGetPeerConnections(); + const std::map& GetPeerConnections(); private: // We could make these available only via accessors but it's too much trouble. diff --git a/dom/media/webrtc/jsapi/RTCStatsReport.h b/dom/media/webrtc/jsapi/RTCStatsReport.h index 2ad0acf1be77..0de84114daba 100644 --- a/dom/media/webrtc/jsapi/RTCStatsReport.h +++ b/dom/media/webrtc/jsapi/RTCStatsReport.h @@ -38,6 +38,9 @@ class RTCStatsTimestampMaker { bool mCrossOriginIsolated = false; }; +// TODO(bug 1588303): If we ever get move semantics for webidl dictionaries, we +// can stop wrapping these in UniquePtr, which will allow us to simplify code +// in several places. typedef MozPromise, nsresult, true> RTCStatsPromise; diff --git a/dom/media/webrtc/jsapi/WebrtcGlobalChild.h b/dom/media/webrtc/jsapi/WebrtcGlobalChild.h index 15107a781232..5e684eb8abe2 100644 --- a/dom/media/webrtc/jsapi/WebrtcGlobalChild.h +++ b/dom/media/webrtc/jsapi/WebrtcGlobalChild.h @@ -18,15 +18,15 @@ class WebrtcGlobalChild : public PWebrtcGlobalChild { MOZ_IMPLICIT WebrtcGlobalChild(); virtual void ActorDestroy(ActorDestroyReason aWhy) override; - virtual mozilla::ipc::IPCResult RecvGetStatsRequest( - const int& aRequestId, const nsString& aPcIdFilter) override; - virtual mozilla::ipc::IPCResult RecvClearStatsRequest() override; + virtual mozilla::ipc::IPCResult RecvGetStats( + const nsString& aPcIdFilter, GetStatsResolver&& aResolve) override; + virtual mozilla::ipc::IPCResult RecvClearStats() override; // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we can't do MOZ_CAN_RUN_SCRIPT in // ipdl-generated things yet. MOZ_CAN_RUN_SCRIPT_BOUNDARY - virtual mozilla::ipc::IPCResult RecvGetLogRequest( - const int& aReqestId, const nsCString& aPattern) override; - virtual mozilla::ipc::IPCResult RecvClearLogRequest() override; + virtual mozilla::ipc::IPCResult RecvGetLog( + const nsCString& aPattern, GetLogResolver&& aResolve) override; + virtual mozilla::ipc::IPCResult RecvClearLog() override; virtual mozilla::ipc::IPCResult RecvSetAecLogging( const bool& aEnable) override; virtual mozilla::ipc::IPCResult RecvSetDebugMode(const int& aLevel) override; diff --git a/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp b/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp index 288f8c57564f..6f9537344f3c 100644 --- a/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp +++ b/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp @@ -7,12 +7,8 @@ #include "WebrtcGlobalChild.h" #include "WebrtcGlobalParent.h" -#include -#include #include #include -#include -#include #include #include "common/browser_logging/CSFLog.h" @@ -23,11 +19,9 @@ #include "nsNetCID.h" // NS_SOCKETTRANSPORTSERVICE_CONTRACTID #include "nsServiceManagerUtils.h" // do_GetService #include "mozilla/ErrorResult.h" -#include "mozilla/Vector.h" -#include "nsProxyRelease.h" +#include "nsProxyRelease.h" // nsMainThreadPtrHolder #include "mozilla/Telemetry.h" #include "mozilla/Unused.h" -#include "mozilla/StaticMutex.h" #include "mozilla/RefPtr.h" #include "transport/runnable_utils.h" @@ -44,133 +38,11 @@ static const char* wgiLogTag = "WebrtcGlobalInformation"; namespace mozilla { namespace dom { -typedef nsTArray Stats; - -template -class RequestManager { - public: - static Request* Create(Callback& aCallback, QueryParam& aParam) { - mozilla::StaticMutexAutoLock lock(sMutex); - - int id = ++sLastRequestId; - auto result = sRequests.try_emplace(id, 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> mContactList; - const int mRequestId; - - RefPtr GetNextParent() { - while (!mContactList.empty()) { - RefPtr next = mContactList.front(); - mContactList.pop(); - if (next->IsActive()) { - return next; - } - } - - return nullptr; - } - - MOZ_CAN_RUN_SCRIPT - void Complete() { - IgnoredErrorResult rv; - using RealCallbackType = std::remove_pointer_t; - RefPtr callback(mCallback.get()); - callback->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 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 -mozilla::StaticMutex - RequestManager::sMutex; -template -std::map - RequestManager::sRequests; -template -int RequestManager::sLastRequestId; - typedef nsMainThreadPtrHandle StatsRequestCallback; -class StatsRequest - : public RequestManager { - public: - const nsString mPcIdFilter; - explicit StatsRequest(int aId, StatsRequestCallback& aCallback, - nsAString& aFilter) - : RequestManager(aId, aCallback), mPcIdFilter(aFilter) {} - - private: - StatsRequest() = delete; - StatsRequest& operator=(const StatsRequest&) = delete; -}; - typedef nsMainThreadPtrHandle LogRequestCallback; -class LogRequest : public RequestManager, 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(); @@ -214,146 +86,48 @@ static PeerConnectionCtx* GetPeerConnectionCtx() { return nullptr; } -MOZ_CAN_RUN_SCRIPT -static void OnStatsReport_m( - WebrtcGlobalChild* aThisChild, const int aRequestId, - nsTArray>&& aReports) { - MOZ_ASSERT(NS_IsMainThread()); +static RefPtr +GetStatsPromiseForThisProcess(const nsAString& aPcIdFilter) { + nsTArray> promises; - if (aThisChild) { - Stats stats; - - // Copy stats generated for the currently active PeerConnections - for (auto& report : aReports) { - if (report) { - stats.AppendElement(*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; - } - - // This is the last stats report to be collected. (Must be the gecko process). - MOZ_ASSERT(XRE_IsParentProcess()); - - StatsRequest* request = StatsRequest::Get(aRequestId); - - if (!request) { - CSFLogError(LOGTAG, "Bad RequestId"); - return; - } - - for (auto& report : aReports) { - if (report) { - if (!request->mResult.mReports.AppendElement(*report, fallible)) { - mozalloc_handle_oom(0); - } - } - } - - // Reports saved for closed/destroyed PeerConnections - auto ctx = PeerConnectionCtx::GetInstance(); + PeerConnectionCtx* ctx = GetPeerConnectionCtx(); if (ctx) { - for (auto&& pc : ctx->mStatsForClosedPeerConnections) { - if (!request->mResult.mReports.AppendElement(pc, fallible)) { - // XXX(Bug 1632090) Instead of extending the array 1-by-1 (which might - // involve multiple reallocations) and potentially crashing here, - // SetCapacity could be called outside the loop once. - mozalloc_handle_oom(0); + // Grab stats for non-closed PCs + for (const auto& [id, pc] : ctx->GetPeerConnections()) { + if (aPcIdFilter.IsEmpty() || aPcIdFilter.EqualsASCII(id.c_str())) { + if (pc->HasMedia()) { + promises.AppendElement(pc->GetStats(nullptr, true)); + } } } - } - request->Complete(); - StatsRequest::Delete(aRequestId); -} - -MOZ_CAN_RUN_SCRIPT -static void OnGetLogging_m(WebrtcGlobalChild* aThisChild, const int aRequestId, - Sequence&& aLogList) { - MOZ_ASSERT(NS_IsMainThread()); - - if (!aLogList.IsEmpty()) { - if (!aLogList.AppendElement(u"+++++++ END ++++++++"_ns, fallible)) { - mozalloc_handle_oom(0); + // Grab stats for closed PCs + for (const auto& report : ctx->mStatsForClosedPeerConnections) { + promises.AppendElement(dom::RTCStatsReportPromise::CreateAndResolve( + MakeUnique(report), __func__)); } } - if (aThisChild) { - // Add this log to the collection of logs and call into - // the next content process. - Unused << aThisChild->SendGetLogResult(aRequestId, aLogList); - return; - } - - // This is the last log to be collected. (Must be the gecko process). - MOZ_ASSERT(XRE_IsParentProcess()); - - LogRequest* request = LogRequest::Get(aRequestId); - - if (!request) { - CSFLogError(LOGTAG, "Bad RequestId"); - return; - } - - if (!request->mResult.AppendElements(std::move(aLogList), fallible)) { - mozalloc_handle_oom(0); - } - request->Complete(); - LogRequest::Delete(aRequestId); -} - -static void RunStatsQuery( - const std::map& aPeerConnections, - const nsAString& aPcIdFilter, WebrtcGlobalChild* aThisChild, - const int aRequestId) { - nsTArray> promises; - - for (auto& idAndPc : aPeerConnections) { - MOZ_ASSERT(idAndPc.second); - PeerConnectionImpl& pc = *idAndPc.second; - if (aPcIdFilter.IsEmpty() || - aPcIdFilter.EqualsASCII(pc.GetIdAsAscii().c_str())) { - if (pc.HasMedia()) { - promises.AppendElement( - pc.GetStats(nullptr, true) - ->Then( - GetMainThreadSerialEventTarget(), __func__, - [=](UniquePtr&& aReport) { - return RTCStatsReportPromise::CreateAndResolve( - std::move(aReport), __func__); - }, - [=](nsresult aError) { - // Ignore errors! Just resolve with a nullptr. - return RTCStatsReportPromise::CreateAndResolve( - UniquePtr(), __func__); - })); + auto UnwrapUniquePtrs = [](dom::RTCStatsReportPromise::AllSettledPromiseType:: + ResolveOrRejectValue&& aResult) { + nsTArray reports; + MOZ_RELEASE_ASSERT(aResult.IsResolve(), "AllSettled should never reject!"); + for (auto& reportResult : aResult.ResolveValue()) { + if (reportResult.IsResolve()) { + reports.AppendElement(*reportResult.ResolveValue()); } } - } + return PWebrtcGlobalParent::GetStatsPromise::CreateAndResolve( + std::move(reports), __func__); + }; - RTCStatsReportPromise::All(GetMainThreadSerialEventTarget(), promises) - ->Then( - GetMainThreadSerialEventTarget(), __func__, - // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we're going to run that - // function async anyway. - [aThisChild, aRequestId]( - nsTArray>&& aReports) - MOZ_CAN_RUN_SCRIPT_BOUNDARY { - OnStatsReport_m(aThisChild, aRequestId, std::move(aReports)); - }, - [=](nsresult) { MOZ_CRASH(); }); + return dom::RTCStatsReportPromise::AllSettled( + GetMainThreadSerialEventTarget(), promises) + ->Then(GetMainThreadSerialEventTarget(), __func__, + std::move(UnwrapUniquePtrs)); } -void ClearClosedStats() { +static void ClearClosedStats() { PeerConnectionCtx* ctx = GetPeerConnectionCtx(); if (ctx) { @@ -371,8 +145,8 @@ void WebrtcGlobalInformation::ClearAllStats(const GlobalObject& aGlobal) { if (!WebrtcContentParents::Empty()) { // Pass on the request to any content process based PeerConnections. - for (auto& cp : WebrtcContentParents::GetAll()) { - Unused << cp->SendClearStatsRequest(); + for (const auto& cp : WebrtcContentParents::GetAll()) { + Unused << cp->SendClearStats(); } } @@ -390,98 +164,98 @@ void WebrtcGlobalInformation::GetAllStats( MOZ_ASSERT(XRE_IsParentProcess()); - // CallbackObject does not support threadsafe refcounting, and must be - // used and destroyed on main. - StatsRequestCallback callbackHandle( - new nsMainThreadPtrHolder( - "WebrtcGlobalStatisticsCallback", &aStatsCallback)); + nsTArray> statsPromises; nsString filter; if (pcIdFilter.WasPassed()) { filter = pcIdFilter.Value(); } - auto* request = StatsRequest::Create(callbackHandle, filter); - - if (!request) { - aRv.Throw(NS_ERROR_FAILURE); - return; + for (const auto& cp : WebrtcContentParents::GetAll()) { + statsPromises.AppendElement(cp->SendGetStats(filter)); } - if (!WebrtcContentParents::Empty()) { - // Pass on the request to any content based PeerConnections. - for (auto& cp : WebrtcContentParents::GetAll()) { - request->mContactList.push(cp); - } + // Stats from this (the parent) process. How long do we keep supporting this? + statsPromises.AppendElement(GetStatsPromiseForThisProcess(filter)); - 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(); + // CallbackObject does not support threadsafe refcounting, and must be + // used and destroyed on main. + StatsRequestCallback callbackHandle( + new nsMainThreadPtrHolder( + "WebrtcGlobalStatisticsCallback", &aStatsCallback)); - if (ctx) { - RunStatsQuery(ctx->mGetPeerConnections(), filter, nullptr, - request->mRequestId); - } else { - // Just send back an empty report. - request->Complete(); - StatsRequest::Delete(request->mRequestId); - } + auto FlattenAndCallback = + [callbackHandle]( + PWebrtcGlobalParent::GetStatsPromise::AllSettledPromiseType:: + ResolveOrRejectValue&& aResult) MOZ_CAN_RUN_SCRIPT_BOUNDARY { + WebrtcGlobalStatisticsReport flattened; + MOZ_RELEASE_ASSERT(aResult.IsResolve(), + "AllSettled should never reject!"); + for (auto& contentProcessResult : aResult.ResolveValue()) { + // TODO: Report rejection on individual content processes someday? + if (contentProcessResult.IsResolve()) { + if (!flattened.mReports.AppendElements( + std::move(contentProcessResult.ResolveValue()), fallible)) { + mozalloc_handle_oom(0); + } + } + } + IgnoredErrorResult rv; + callbackHandle->Call(flattened, rv); + }; + + PWebrtcGlobalParent::GetStatsPromise::AllSettled( + GetMainThreadSerialEventTarget(), statsPromises) + ->Then(GetMainThreadSerialEventTarget(), __func__, + std::move(FlattenAndCallback)); aRv = NS_OK; } -MOZ_CAN_RUN_SCRIPT -static nsresult RunLogQuery(const nsCString& aPattern, - WebrtcGlobalChild* aThisChild, - const int aRequestId) { +static RefPtr GetLogPromise( + const nsCString& aPattern) { PeerConnectionCtx* ctx = GetPeerConnectionCtx(); if (!ctx) { // This process has never created a PeerConnection, so no ICE logging. - OnGetLogging_m(aThisChild, aRequestId, Sequence()); - return NS_OK; + return PWebrtcGlobalParent::GetLogPromise::CreateAndResolve( + Sequence(), __func__); } nsresult rv; nsCOMPtr stsThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - return rv; - } - if (!stsThread) { - return NS_ERROR_FAILURE; + if (NS_WARN_IF(NS_FAILED(rv) || !stsThread)) { + return PWebrtcGlobalParent::GetLogPromise::CreateAndResolve( + Sequence(), __func__); } RefPtr transportHandler = ctx->GetTransportHandler(); - InvokeAsync(stsThread, __func__, - [transportHandler, aPattern]() { - return transportHandler->GetIceLog(aPattern); - }) - ->Then( - GetMainThreadSerialEventTarget(), __func__, - // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we're going to run that - // function async anyway. - [aRequestId, aThisChild](Sequence&& aLogLines) - MOZ_CAN_RUN_SCRIPT_BOUNDARY { - OnGetLogging_m(aThisChild, aRequestId, std::move(aLogLines)); - }, - // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we're going to run that - // function async anyway. - [aRequestId, aThisChild](nsresult aError) - MOZ_CAN_RUN_SCRIPT_BOUNDARY { - OnGetLogging_m(aThisChild, aRequestId, Sequence()); - }); + auto AddMarkers = + [](MediaTransportHandler::IceLogPromise::ResolveOrRejectValue&& aValue) { + nsString pid; + pid.AppendInt(getpid()); + Sequence logs; + if (aValue.IsResolve() && !aValue.ResolveValue().IsEmpty()) { + bool ok = logs.AppendElement( + u"+++++++ BEGIN (process id "_ns + pid + u") ++++++++"_ns, + fallible); + ok &= + !!logs.AppendElements(std::move(aValue.ResolveValue()), fallible); + ok &= !!logs.AppendElement( + u"+++++++ END (process id "_ns + pid + u") ++++++++"_ns, + fallible); + if (!ok) { + mozalloc_handle_oom(0); + } + } + return PWebrtcGlobalParent::GetLogPromise::CreateAndResolve( + std::move(logs), __func__); + }; - return NS_OK; + return transportHandler->GetIceLog(aPattern)->Then( + GetMainThreadSerialEventTarget(), __func__, std::move(AddMarkers)); } static nsresult RunLogClear() { @@ -520,8 +294,8 @@ void WebrtcGlobalInformation::ClearLogging(const GlobalObject& aGlobal) { if (!WebrtcContentParents::Empty()) { // Clear content process signaling logs - for (auto& cp : WebrtcContentParents::GetAll()) { - Unused << cp->SendClearLogRequest(); + for (const auto& cp : WebrtcContentParents::GetAll()) { + Unused << cp->SendClearLog(); } } @@ -539,44 +313,49 @@ void WebrtcGlobalInformation::GetLogging( MOZ_ASSERT(XRE_IsParentProcess()); + nsTArray> logPromises; + + nsAutoCString pattern; + CopyUTF16toUTF8(aPattern, pattern); + + for (const auto& cp : WebrtcContentParents::GetAll()) { + logPromises.AppendElement(cp->SendGetLog(pattern)); + } + + // Get logs from this (the parent) process. + logPromises.AppendElement(GetLogPromise(pattern)); + // CallbackObject does not support threadsafe refcounting, and must be // destroyed on main. LogRequestCallback callbackHandle( new nsMainThreadPtrHolder( "WebrtcGlobalLoggingCallback", &aLoggingCallback)); - nsAutoCString pattern; - CopyUTF16toUTF8(aPattern, pattern); + auto FlattenAndCallback = + [callbackHandle](WebrtcGlobalParent::GetLogPromise:: + AllSettledPromiseType::ResolveOrRejectValue&& aValue) + MOZ_CAN_RUN_SCRIPT_BOUNDARY { + dom::Sequence flattened; + MOZ_RELEASE_ASSERT(aValue.IsResolve(), + "AllSettled should never reject!"); + for (auto& logResult : aValue.ResolveValue()) { + if (logResult.IsResolve()) { + if (!flattened.AppendElements( + std::move(logResult.ResolveValue()), fallible)) { + mozalloc_handle_oom(0); + } + } + } + IgnoredErrorResult rv; + callbackHandle->Call(flattened, rv); + }; - LogRequest* request = LogRequest::Create(callbackHandle, pattern); + PWebrtcGlobalParent::GetLogPromise::AllSettled( + GetMainThreadSerialEventTarget(), logPromises) + ->Then(GetMainThreadSerialEventTarget(), __func__, + std::move(FlattenAndCallback)); - 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)) { - LogRequest::Delete(request->mRequestId); - } - - aRv = rv; + aRv = NS_OK; } static int32_t sLastSetLevel = 0; @@ -592,7 +371,7 @@ void WebrtcGlobalInformation::SetDebugLevel(const GlobalObject& aGlobal, } sLastSetLevel = aLevel; - for (auto& cp : WebrtcContentParents::GetAll()) { + for (const auto& cp : WebrtcContentParents::GetAll()) { Unused << cp->SendSetDebugMode(aLevel); } } @@ -611,7 +390,7 @@ void WebrtcGlobalInformation::SetAecDebug(const GlobalObject& aGlobal, sLastAECDebug = aEnable; - for (auto& cp : WebrtcContentParents::GetAll()) { + for (const auto& cp : WebrtcContentParents::GetAll()) { Unused << cp->SendSetAecLogging(aEnable); } } @@ -625,85 +404,6 @@ void WebrtcGlobalInformation::GetAecDebugLogDir(const GlobalObject& aGlobal, aDir = NS_ConvertASCIItoUTF16(sAecDebugLogDir.valueOr(""_ns)); } -mozilla::ipc::IPCResult WebrtcGlobalParent::RecvGetStatsResult( - const int& aRequestId, nsTArray&& Stats) { - MOZ_ASSERT(NS_IsMainThread()); - - StatsRequest* request = StatsRequest::Get(aRequestId); - - if (!request) { - CSFLogError(LOGTAG, "Bad RequestId"); - return IPC_FAIL_NO_REASON(this); - } - - for (auto& s : Stats) { - if (!request->mResult.mReports.AppendElement(s, fallible)) { - CSFLogError(LOGTAG, "Out of memory"); - return IPC_FAIL_NO_REASON(this); - } - } - - auto next = request->GetNextParent(); - if (next) { - // There are more content instances to query. - if (!next->SendGetStatsRequest(request->mRequestId, request->mPcIdFilter)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - - // Content queries complete, run chrome instance query if applicable - PeerConnectionCtx* ctx = GetPeerConnectionCtx(); - - if (ctx) { - RunStatsQuery(ctx->mGetPeerConnections(), request->mPcIdFilter, nullptr, - aRequestId); - } else { - // No instance in the process, return the collections as is - request->Complete(); - StatsRequest::Delete(aRequestId); - } - - return IPC_OK(); -} - -mozilla::ipc::IPCResult WebrtcGlobalParent::RecvGetLogResult( - const int& aRequestId, const WebrtcGlobalLog& aLog) { - MOZ_ASSERT(NS_IsMainThread()); - - LogRequest* request = LogRequest::Get(aRequestId); - - if (!request) { - CSFLogError(LOGTAG, "Bad RequestId"); - return IPC_FAIL_NO_REASON(this); - } - if (!request->mResult.AppendElements(aLog, fallible)) { - CSFLogError(LOGTAG, "Out of memory"); - return IPC_FAIL_NO_REASON(this); - } - - auto next = request->GetNextParent(); - if (next) { - // There are more content instances to query. - if (!next->SendGetLogRequest(request->mRequestId, request->mPattern)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - - // 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 IPC_OK(); -} - WebrtcGlobalParent* WebrtcGlobalParent::Alloc() { return WebrtcContentParents::Alloc(); } @@ -729,26 +429,25 @@ MOZ_IMPLICIT WebrtcGlobalParent::~WebrtcGlobalParent() { MOZ_COUNT_DTOR(WebrtcGlobalParent); } -mozilla::ipc::IPCResult WebrtcGlobalChild::RecvGetStatsRequest( - const int& aRequestId, const nsString& aPcIdFilter) { - if (mShutdown) { +mozilla::ipc::IPCResult WebrtcGlobalChild::RecvGetStats( + const nsString& aPcIdFilter, GetStatsResolver&& aResolve) { + if (!mShutdown) { + GetStatsPromiseForThisProcess(aPcIdFilter) + ->Then( + GetMainThreadSerialEventTarget(), __func__, + [resolve = std::move(aResolve)]( + nsTArray&& aReports) { + resolve(std::move(aReports)); + }, + []() { MOZ_CRASH(); }); return IPC_OK(); } - PeerConnectionCtx* ctx = GetPeerConnectionCtx(); - - if (ctx) { - RunStatsQuery(ctx->mGetPeerConnections(), aPcIdFilter, this, aRequestId); - return IPC_OK(); - } - - nsTArray empty_stats; - SendGetStatsResult(aRequestId, empty_stats); - + aResolve(nsTArray()); return IPC_OK(); } -mozilla::ipc::IPCResult WebrtcGlobalChild::RecvClearStatsRequest() { +mozilla::ipc::IPCResult WebrtcGlobalChild::RecvClearStats() { if (mShutdown) { return IPC_OK(); } @@ -757,23 +456,28 @@ mozilla::ipc::IPCResult WebrtcGlobalChild::RecvClearStatsRequest() { return IPC_OK(); } -mozilla::ipc::IPCResult WebrtcGlobalChild::RecvGetLogRequest( - const int& aRequestId, const nsCString& aPattern) { +mozilla::ipc::IPCResult WebrtcGlobalChild::RecvGetLog( + const nsCString& aPattern, GetLogResolver&& aResolve) { if (mShutdown) { + aResolve(Sequence()); return IPC_OK(); } - nsresult rv = RunLogQuery(aPattern, this, aRequestId); - - if (NS_FAILED(rv)) { - Sequence empty_log; - SendGetLogResult(aRequestId, empty_log); - } + GetLogPromise(aPattern)->Then( + GetMainThreadSerialEventTarget(), __func__, + [aResolve = std::move(aResolve)]( + PWebrtcGlobalParent::GetLogPromise::ResolveOrRejectValue&& aValue) { + if (aValue.IsResolve()) { + aResolve(aValue.ResolveValue()); + } else { + aResolve(Sequence()); + } + }); return IPC_OK(); } -mozilla::ipc::IPCResult WebrtcGlobalChild::RecvClearLogRequest() { +mozilla::ipc::IPCResult WebrtcGlobalChild::RecvClearLog() { if (mShutdown) { return IPC_OK(); } diff --git a/dom/media/webrtc/jsapi/WebrtcGlobalParent.h b/dom/media/webrtc/jsapi/WebrtcGlobalParent.h index 34857074a1b8..c7eebd70604e 100644 --- a/dom/media/webrtc/jsapi/WebrtcGlobalParent.h +++ b/dom/media/webrtc/jsapi/WebrtcGlobalParent.h @@ -6,7 +6,6 @@ #define _WEBRTC_GLOBAL_PARENT_H_ #include "mozilla/dom/PWebrtcGlobalParent.h" -#include "mozilla/dom/RTCStatsReportBinding.h" #include "mozilla/dom/BindingDeclarations.h" #include "nsISupportsImpl.h" @@ -27,18 +26,6 @@ class WebrtcGlobalParent : public PWebrtcGlobalParent { static WebrtcGlobalParent* Alloc(); static bool Dealloc(WebrtcGlobalParent* aActor); - // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we can't do MOZ_CAN_RUN_SCRIPT in - // ipdl-generated things yet. - MOZ_CAN_RUN_SCRIPT_BOUNDARY - virtual mozilla::ipc::IPCResult RecvGetStatsResult( - const int& aRequestId, - nsTArray&& aStats) override; - // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we can't do MOZ_CAN_RUN_SCRIPT in - // ipdl-generated things yet. - MOZ_CAN_RUN_SCRIPT_BOUNDARY - virtual mozilla::ipc::IPCResult RecvGetLogResult( - const int& aRequestId, const WebrtcGlobalLog& aLog) override; - virtual void ActorDestroy(ActorDestroyReason aWhy) override; virtual mozilla::ipc::IPCResult Recv__delete__() override;