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