1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "WebRtcLog.h" 6 7 #include "mozilla/Logging.h" 8 #include "mozilla/StaticPtr.h" 9 #include "prenv.h" 10 #include "common_types.h" 11 #include "rtc_base/logging.h" 12 13 #include "nscore.h" 14 #include "nsString.h" 15 #include "nsXULAppAPI.h" 16 #include "mozilla/Preferences.h" 17 18 #include "nsIFile.h" 19 #include "nsDirectoryServiceUtils.h" 20 #include "nsDirectoryServiceDefs.h" 21 #include "nsNativeCharsetUtils.h" 22 23 using mozilla::LogLevel; 24 25 #if defined(ANDROID) 26 static const char* default_tmp_dir = "/dev/null"; 27 static const char* default_log_name = "nspr"; 28 #else // Assume a POSIX environment 29 constexpr auto default_log_name = "WebRTC.log"_ns; 30 #endif 31 32 static mozilla::LazyLogModule sWebRtcLog("webrtc_trace"); 33 static mozilla::LazyLogModule sLogAEC("AEC"); 34 35 class LogSinkImpl : public rtc::LogSink { 36 public: LogSinkImpl()37 LogSinkImpl() {} 38 39 private: OnLogMessage(const std::string & message)40 void OnLogMessage(const std::string& message) override { 41 MOZ_LOG(sWebRtcLog, LogLevel::Debug, ("%s", message.data())); 42 } 43 }; 44 45 // For RTC_LOG() 46 static mozilla::StaticAutoPtr<LogSinkImpl> sSink; 47 GetWebRtcLogPrefs()48void GetWebRtcLogPrefs() { 49 rtc::LogMessage::set_aec_debug_size( 50 mozilla::Preferences::GetUint("media.webrtc.debug.aec_dump_max_size")); 51 } 52 CheckOverrides()53mozilla::LogLevel CheckOverrides() { 54 mozilla::LogModule* log_info = sWebRtcLog; 55 mozilla::LogLevel log_level = log_info->Level(); 56 57 log_info = sLogAEC; 58 if (sLogAEC && (log_info->Level() != mozilla::LogLevel::Disabled)) { 59 rtc::LogMessage::set_aec_debug(true); 60 } 61 62 return log_level; 63 } 64 ConfigWebRtcLog(mozilla::LogLevel level)65void ConfigWebRtcLog(mozilla::LogLevel level) { 66 rtc::LoggingSeverity log_level; 67 switch (level) { 68 case mozilla::LogLevel::Verbose: 69 log_level = rtc::LoggingSeverity::LS_VERBOSE; 70 break; 71 case mozilla::LogLevel::Debug: 72 case mozilla::LogLevel::Info: 73 log_level = rtc::LoggingSeverity::LS_INFO; 74 break; 75 case mozilla::LogLevel::Warning: 76 log_level = rtc::LoggingSeverity::LS_WARNING; 77 break; 78 case mozilla::LogLevel::Error: 79 log_level = rtc::LoggingSeverity::LS_ERROR; 80 break; 81 case mozilla::LogLevel::Disabled: 82 log_level = rtc::LoggingSeverity::LS_NONE; 83 break; 84 default: 85 MOZ_ASSERT(false); 86 break; 87 } 88 rtc::LogMessage::LogToDebug(log_level); 89 if (level != mozilla::LogLevel::Disabled) { 90 // always capture LOG(...) << ... logging in webrtc.org code to nspr logs 91 if (!sSink) { 92 sSink = new LogSinkImpl(); 93 rtc::LogMessage::AddLogToStream(sSink, log_level); 94 // it's ok if this leaks to program end 95 } 96 } else if (sSink) { 97 rtc::LogMessage::RemoveLogToStream(sSink); 98 sSink = nullptr; 99 } 100 } 101 StartWebRtcLog(mozilla::LogLevel log_level)102void StartWebRtcLog(mozilla::LogLevel log_level) { 103 if (log_level == mozilla::LogLevel::Disabled) { 104 return; 105 } 106 107 GetWebRtcLogPrefs(); 108 mozilla::LogLevel level = CheckOverrides(); 109 110 ConfigWebRtcLog(level); 111 } 112 EnableWebRtcLog()113void EnableWebRtcLog() { 114 GetWebRtcLogPrefs(); 115 mozilla::LogLevel level = CheckOverrides(); 116 ConfigWebRtcLog(level); 117 } 118 119 // Called when we destroy the singletons from PeerConnectionCtx or if the 120 // user changes logging in about:webrtc StopWebRtcLog()121void StopWebRtcLog() { 122 if (sSink) { 123 rtc::LogMessage::RemoveLogToStream(sSink); 124 sSink = nullptr; 125 } 126 } 127 ConfigAecLog()128nsCString ConfigAecLog() { 129 nsCString aecLogDir; 130 if (rtc::LogMessage::aec_debug()) { 131 return ""_ns; 132 } 133 #if defined(ANDROID) 134 aecLogDir.Assign(default_tmp_dir); 135 #else 136 nsCOMPtr<nsIFile> tempDir; 137 nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir)); 138 if (NS_SUCCEEDED(rv)) { 139 # ifdef XP_WIN 140 // WebRTC wants a path encoded in the native charset, not UTF-8. 141 nsAutoString temp; 142 tempDir->GetPath(temp); 143 NS_CopyUnicodeToNative(temp, aecLogDir); 144 # else 145 tempDir->GetNativePath(aecLogDir); 146 # endif 147 } 148 #endif 149 rtc::LogMessage::set_aec_debug_filename(aecLogDir.get()); 150 151 return aecLogDir; 152 } 153 StartAecLog()154nsCString StartAecLog() { 155 nsCString aecLogDir; 156 if (rtc::LogMessage::aec_debug()) { 157 return ""_ns; 158 } 159 160 GetWebRtcLogPrefs(); 161 CheckOverrides(); 162 aecLogDir = ConfigAecLog(); 163 164 rtc::LogMessage::set_aec_debug(true); 165 166 return aecLogDir; 167 } 168 StopAecLog()169void StopAecLog() { rtc::LogMessage::set_aec_debug(false); } 170