summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/common/browser_logging/WebRtcLog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webrtc/common/browser_logging/WebRtcLog.cpp')
-rw-r--r--dom/media/webrtc/common/browser_logging/WebRtcLog.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/dom/media/webrtc/common/browser_logging/WebRtcLog.cpp b/dom/media/webrtc/common/browser_logging/WebRtcLog.cpp
new file mode 100644
index 0000000000..ae5aac8022
--- /dev/null
+++ b/dom/media/webrtc/common/browser_logging/WebRtcLog.cpp
@@ -0,0 +1,190 @@
+/* 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 "WebRtcLog.h"
+
+#include "nsThreadUtils.h"
+#include "mozilla/Logging.h"
+#include "rtc_base/logging.h"
+
+#include "nscore.h"
+#include "nsStringFwd.h"
+#include "nsXULAppAPI.h"
+#include "mozilla/Preferences.h"
+
+#include "nsIFile.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsDirectoryServiceDefs.h"
+
+#ifdef XP_WIN
+# include "nsNativeCharsetUtils.h"
+#endif
+
+using mozilla::LogLevel;
+
+#define WEBRTC_LOG_MODULE_NAME "webrtc_trace"
+#define WEBRTC_LOG_PREF "logging." WEBRTC_LOG_MODULE_NAME
+static mozilla::LazyLogModule sWebRtcLog(WEBRTC_LOG_MODULE_NAME);
+
+static rtc::LoggingSeverity LevelToSeverity(mozilla::LogLevel aLevel) {
+ switch (aLevel) {
+ case mozilla::LogLevel::Verbose:
+ return rtc::LoggingSeverity::LS_VERBOSE;
+ case mozilla::LogLevel::Debug:
+ case mozilla::LogLevel::Info:
+ return rtc::LoggingSeverity::LS_INFO;
+ case mozilla::LogLevel::Warning:
+ return rtc::LoggingSeverity::LS_WARNING;
+ case mozilla::LogLevel::Error:
+ return rtc::LoggingSeverity::LS_ERROR;
+ case mozilla::LogLevel::Disabled:
+ return rtc::LoggingSeverity::LS_NONE;
+ }
+ MOZ_ASSERT_UNREACHABLE("Unexpected log level");
+ return rtc::LoggingSeverity::LS_NONE;
+}
+
+static LogLevel SeverityToLevel(rtc::LoggingSeverity aSeverity) {
+ switch (aSeverity) {
+ case rtc::LoggingSeverity::LS_VERBOSE:
+ return mozilla::LogLevel::Verbose;
+ case rtc::LoggingSeverity::LS_INFO:
+ return mozilla::LogLevel::Debug;
+ case rtc::LoggingSeverity::LS_WARNING:
+ return mozilla::LogLevel::Warning;
+ case rtc::LoggingSeverity::LS_ERROR:
+ return mozilla::LogLevel::Error;
+ case rtc::LoggingSeverity::LS_NONE:
+ return mozilla::LogLevel::Disabled;
+ }
+ MOZ_ASSERT_UNREACHABLE("Unexpected severity");
+ return LogLevel::Disabled;
+}
+
+/**
+ * Implementation of rtc::LogSink that forwards RTC_LOG() to MOZ_LOG().
+ */
+class LogSinkImpl : public WebrtcLogSinkHandle, public rtc::LogSink {
+ NS_INLINE_DECL_REFCOUNTING(LogSinkImpl, override)
+
+ public:
+ static already_AddRefed<WebrtcLogSinkHandle> EnsureLogSink() {
+ mozilla::AssertIsOnMainThread();
+ if (sSingleton) {
+ return do_AddRef(sSingleton);
+ }
+ return mozilla::MakeAndAddRef<LogSinkImpl>();
+ }
+
+ static void OnPrefChanged(const char* aPref, void* aData) {
+ mozilla::AssertIsOnMainThread();
+ MOZ_ASSERT(strcmp(aPref, WEBRTC_LOG_PREF) == 0);
+ MOZ_ASSERT(aData == sSingleton);
+
+ // Bounce to main thread again so the LogModule can settle on the new level
+ // via its own observer.
+ NS_DispatchToMainThread(mozilla::NewRunnableMethod(
+ __func__, sSingleton, &LogSinkImpl::UpdateLogLevels));
+ }
+
+ LogSinkImpl() {
+ mozilla::AssertIsOnMainThread();
+ MOZ_RELEASE_ASSERT(!sSingleton);
+
+ rtc::LogMessage::AddLogToStream(this, LevelToSeverity(mLevel));
+ sSingleton = this;
+
+ mozilla::Preferences::RegisterCallbackAndCall(&LogSinkImpl::OnPrefChanged,
+ WEBRTC_LOG_PREF, this);
+ }
+
+ private:
+ ~LogSinkImpl() {
+ mozilla::AssertIsOnMainThread();
+ MOZ_RELEASE_ASSERT(sSingleton == this);
+
+ mozilla::Preferences::UnregisterCallback(&LogSinkImpl::OnPrefChanged,
+ WEBRTC_LOG_PREF, this);
+ rtc::LogMessage::RemoveLogToStream(this);
+ sSingleton = nullptr;
+ }
+
+ void UpdateLogLevels() {
+ mozilla::AssertIsOnMainThread();
+ mozilla::LogModule* webrtcModule = sWebRtcLog;
+ mozilla::LogLevel webrtcLevel = webrtcModule->Level();
+
+ if (webrtcLevel == mLevel) {
+ return;
+ }
+
+ mLevel = webrtcLevel;
+
+ rtc::LogMessage::RemoveLogToStream(this);
+ rtc::LogMessage::AddLogToStream(this, LevelToSeverity(mLevel));
+ }
+
+ void OnLogMessage(const rtc::LogLineRef& aLogLine) override {
+ MOZ_LOG(sWebRtcLog, SeverityToLevel(aLogLine.severity()),
+ ("%s", aLogLine.DefaultLogLine().data()));
+ }
+
+ void OnLogMessage(const std::string&) override {
+ MOZ_CRASH(
+ "Called overriden OnLogMessage that is inexplicably pure virtual");
+ }
+
+ static LogSinkImpl* sSingleton MOZ_GUARDED_BY(mozilla::sMainThreadCapability);
+ LogLevel mLevel MOZ_GUARDED_BY(mozilla::sMainThreadCapability) =
+ LogLevel::Disabled;
+};
+
+LogSinkImpl* LogSinkImpl::sSingleton = nullptr;
+
+already_AddRefed<WebrtcLogSinkHandle> EnsureWebrtcLogging() {
+ mozilla::AssertIsOnMainThread();
+ return LogSinkImpl::EnsureLogSink();
+}
+
+nsCString ConfigAecLog() {
+ nsCString aecLogDir;
+ if (rtc::LogMessage::aec_debug()) {
+ return ""_ns;
+ }
+#if defined(ANDROID)
+ const char* default_tmp_dir = "/dev/null";
+ aecLogDir.Assign(default_tmp_dir);
+#else
+ nsCOMPtr<nsIFile> tempDir;
+ nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir));
+ if (NS_SUCCEEDED(rv)) {
+# ifdef XP_WIN
+ // WebRTC wants a path encoded in the native charset, not UTF-8.
+ nsAutoString temp;
+ tempDir->GetPath(temp);
+ NS_CopyUnicodeToNative(temp, aecLogDir);
+# else
+ tempDir->GetNativePath(aecLogDir);
+# endif
+ }
+#endif
+ rtc::LogMessage::set_aec_debug_filename(aecLogDir.get());
+
+ return aecLogDir;
+}
+
+nsCString StartAecLog() {
+ nsCString aecLogDir;
+ if (rtc::LogMessage::aec_debug()) {
+ return ""_ns;
+ }
+
+ aecLogDir = ConfigAecLog();
+
+ rtc::LogMessage::set_aec_debug(true);
+
+ return aecLogDir;
+}
+
+void StopAecLog() { rtc::LogMessage::set_aec_debug(false); }