Added functions on libjingle API to start and stop the recording of an RtcEventLog.

BUG=webrtc:4741

Review URL: https://codereview.webrtc.org/1374253002

Cr-Commit-Position: refs/heads/master@{#10297}
diff --git a/talk/app/webrtc/peerconnectionfactory.cc b/talk/app/webrtc/peerconnectionfactory.cc
index 6619f31..54a32bc 100644
--- a/talk/app/webrtc/peerconnectionfactory.cc
+++ b/talk/app/webrtc/peerconnectionfactory.cc
@@ -218,6 +218,16 @@
   return channel_manager_->StartAecDump(file);
 }
 
+bool PeerConnectionFactory::StartRtcEventLog(rtc::PlatformFile file) {
+  RTC_DCHECK(signaling_thread_->IsCurrent());
+  return channel_manager_->StartRtcEventLog(file);
+}
+
+void PeerConnectionFactory::StopRtcEventLog() {
+  RTC_DCHECK(signaling_thread_->IsCurrent());
+  channel_manager_->StopRtcEventLog();
+}
+
 rtc::scoped_refptr<PeerConnectionInterface>
 PeerConnectionFactory::CreatePeerConnection(
     const PeerConnectionInterface::RTCConfiguration& configuration,
diff --git a/talk/app/webrtc/peerconnectionfactory.h b/talk/app/webrtc/peerconnectionfactory.h
index 8689199..f8e0a40 100644
--- a/talk/app/webrtc/peerconnectionfactory.h
+++ b/talk/app/webrtc/peerconnectionfactory.h
@@ -80,6 +80,8 @@
                        AudioSourceInterface* audio_source) override;
 
   bool StartAecDump(rtc::PlatformFile file) override;
+  bool StartRtcEventLog(rtc::PlatformFile file) override;
+  void StopRtcEventLog() override;
 
   virtual webrtc::MediaControllerInterface* CreateMediaController() const;
   virtual rtc::Thread* signaling_thread();
diff --git a/talk/app/webrtc/peerconnectionfactoryproxy.h b/talk/app/webrtc/peerconnectionfactoryproxy.h
index 4a8cd87..826d577 100644
--- a/talk/app/webrtc/peerconnectionfactoryproxy.h
+++ b/talk/app/webrtc/peerconnectionfactoryproxy.h
@@ -62,6 +62,8 @@
   PROXY_METHOD2(rtc::scoped_refptr<AudioTrackInterface>,
                 CreateAudioTrack, const std::string&,  AudioSourceInterface*)
   PROXY_METHOD1(bool, StartAecDump, rtc::PlatformFile)
+  PROXY_METHOD1(bool, StartRtcEventLog, rtc::PlatformFile)
+  PROXY_METHOD0(void, StopRtcEventLog)
 
  private:
   rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection_ot(
diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h
index d3d0d9e..f61f2f6 100644
--- a/talk/app/webrtc/peerconnectioninterface.h
+++ b/talk/app/webrtc/peerconnectioninterface.h
@@ -619,6 +619,22 @@
   // http://crbug.com/264611.
   virtual bool StartAecDump(rtc::PlatformFile file) = 0;
 
+  // Starts RtcEventLog using existing file. Takes ownership of |file| and
+  // passes it on to VoiceEngine, which will take the ownership. If the
+  // operation fails the file will be closed. The logging will stop
+  // automatically after 10 minutes have passed, or when the StopRtcEventLog
+  // function is called.
+  // This function as well as the StopRtcEventLog don't really belong on this
+  // interface, this is a temporary solution until we move the logging object
+  // from inside voice engine to webrtc::Call, which will happen when the VoE
+  // restructuring effort is further along.
+  // TODO(ivoc): Move this into being:
+  //             PeerConnection => MediaController => webrtc::Call.
+  virtual bool StartRtcEventLog(rtc::PlatformFile file) = 0;
+
+  // Stops logging the RtcEventLog.
+  virtual void StopRtcEventLog() = 0;
+
  protected:
   // Dtor and ctor protected as objects shouldn't be created or deleted via
   // this interface.
diff --git a/talk/media/base/fakemediaengine.h b/talk/media/base/fakemediaengine.h
index 57d0145..5a4f46a 100644
--- a/talk/media/base/fakemediaengine.h
+++ b/talk/media/base/fakemediaengine.h
@@ -785,6 +785,10 @@
 
   bool StartAecDump(rtc::PlatformFile file) { return false; }
 
+  bool StartRtcEventLog(rtc::PlatformFile file) { return false; }
+
+  void StopRtcEventLog() {}
+
  private:
   std::vector<FakeVoiceMediaChannel*> channels_;
   std::vector<AudioCodec> codecs_;
diff --git a/talk/media/base/mediaengine.h b/talk/media/base/mediaengine.h
index 8468e07..c5b9096 100644
--- a/talk/media/base/mediaengine.h
+++ b/talk/media/base/mediaengine.h
@@ -121,6 +121,12 @@
 
   // Starts AEC dump using existing file.
   virtual bool StartAecDump(rtc::PlatformFile file) = 0;
+
+  // Starts RtcEventLog using existing file.
+  virtual bool StartRtcEventLog(rtc::PlatformFile file) = 0;
+
+  // Stops recording an RtcEventLog.
+  virtual void StopRtcEventLog() = 0;
 };
 
 
@@ -219,6 +225,12 @@
     return voice_.StartAecDump(file);
   }
 
+  virtual bool StartRtcEventLog(rtc::PlatformFile file) {
+    return voice_.StartRtcEventLog(file);
+  }
+
+  virtual void StopRtcEventLog() { voice_.StopRtcEventLog(); }
+
  protected:
   VOICE voice_;
   VIDEO video_;
@@ -251,6 +263,8 @@
   }
   void SetLogging(int min_sev, const char* filter) {}
   bool StartAecDump(rtc::PlatformFile file) { return false; }
+  bool StartRtcEventLog(rtc::PlatformFile file) { return false; }
+  void StopRtcEventLog() {}
 
  private:
   std::vector<AudioCodec> codecs_;
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index caaf87e..2a3df2d 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -50,6 +50,7 @@
 #include "webrtc/base/logging.h"
 #include "webrtc/base/stringencode.h"
 #include "webrtc/base/stringutils.h"
+#include "webrtc/call/rtc_event_log.h"
 #include "webrtc/common.h"
 #include "webrtc/modules/audio_processing/include/audio_processing.h"
 #include "webrtc/system_wrappers/interface/field_trial.h"
@@ -1306,6 +1307,14 @@
   }
 }
 
+bool WebRtcVoiceEngine::StartRtcEventLog(rtc::PlatformFile file) {
+  return voe_wrapper_->codec()->GetEventLog()->StartLogging(file);
+}
+
+void WebRtcVoiceEngine::StopRtcEventLog() {
+  voe_wrapper_->codec()->GetEventLog()->StopLogging();
+}
+
 int WebRtcVoiceEngine::CreateVoiceChannel(VoEWrapper* voice_engine_wrapper) {
   return voice_engine_wrapper->base()->CreateChannel(voe_config_);
 }
diff --git a/talk/media/webrtc/webrtcvoiceengine.h b/talk/media/webrtc/webrtcvoiceengine.h
index cba9456..cd792bc 100644
--- a/talk/media/webrtc/webrtcvoiceengine.h
+++ b/talk/media/webrtc/webrtcvoiceengine.h
@@ -108,6 +108,13 @@
   // Starts AEC dump using existing file.
   bool StartAecDump(rtc::PlatformFile file);
 
+  // Starts recording an RtcEventLog using an existing file until 10 minutes
+  // pass or the StopRtcEventLog function is called.
+  bool StartRtcEventLog(rtc::PlatformFile file);
+
+  // Stops recording the RtcEventLog.
+  void StopRtcEventLog();
+
   // Create a VoiceEngine Channel.
   int CreateMediaVoiceChannel();
 
diff --git a/talk/session/media/channelmanager.cc b/talk/session/media/channelmanager.cc
index 5930dfd..5caf3c4 100644
--- a/talk/session/media/channelmanager.cc
+++ b/talk/session/media/channelmanager.cc
@@ -630,4 +630,14 @@
       Bind(&MediaEngineInterface::StartAecDump, media_engine_.get(), file));
 }
 
+bool ChannelManager::StartRtcEventLog(rtc::PlatformFile file) {
+  return worker_thread_->Invoke<bool>(
+      Bind(&MediaEngineInterface::StartRtcEventLog, media_engine_.get(), file));
+}
+
+void ChannelManager::StopRtcEventLog() {
+  worker_thread_->Invoke<void>(
+      Bind(&MediaEngineInterface::StopRtcEventLog, media_engine_.get()));
+}
+
 }  // namespace cricket
diff --git a/talk/session/media/channelmanager.h b/talk/session/media/channelmanager.h
index c17a60f..2417662 100644
--- a/talk/session/media/channelmanager.h
+++ b/talk/session/media/channelmanager.h
@@ -170,6 +170,12 @@
   // Starts AEC dump using existing file.
   bool StartAecDump(rtc::PlatformFile file);
 
+  // Starts RtcEventLog using existing file.
+  bool StartRtcEventLog(rtc::PlatformFile file);
+
+  // Stops logging RtcEventLog.
+  void StopRtcEventLog();
+
   sigslot::signal2<VideoCapturer*, CaptureState> SignalVideoCaptureStateChange;
 
  protected:
diff --git a/webrtc/call/rtc_event_log.cc b/webrtc/call/rtc_event_log.cc
index 97885cc..6a15912 100644
--- a/webrtc/call/rtc_event_log.cc
+++ b/webrtc/call/rtc_event_log.cc
@@ -37,6 +37,7 @@
 class RtcEventLogImpl final : public RtcEventLog {
  public:
   void StartLogging(const std::string& file_name, int duration_ms) override {}
+  bool StartLogging(rtc::PlatformFile log_file) override { return false; }
   void StopLogging(void) override {}
   void LogVideoReceiveStreamConfig(
       const VideoReceiveStream::Config& config) override {}
@@ -57,9 +58,8 @@
 
 class RtcEventLogImpl final : public RtcEventLog {
  public:
-  RtcEventLogImpl();
-
   void StartLogging(const std::string& file_name, int duration_ms) override;
+  bool StartLogging(rtc::PlatformFile log_file) override;
   void StopLogging() override;
   void LogVideoReceiveStreamConfig(
       const VideoReceiveStream::Config& config) override;
@@ -75,6 +75,9 @@
   void LogAudioPlayout(uint32_t ssrc) override;
 
  private:
+  // Starts logging. This function assumes the file_ has been opened succesfully
+  // and that the start_time_us_ and _duration_us_ have been set.
+  void StartLoggingLocked() EXCLUSIVE_LOCKS_REQUIRED(crit_);
   // Stops logging and clears the stored data and buffers.
   void StopLoggingLocked() EXCLUSIVE_LOCKS_REQUIRED(crit_);
   // Adds a new event to the logfile if logging is active, or adds it to the
@@ -93,13 +96,16 @@
   const int recent_log_duration_us = 10000000;
 
   rtc::CriticalSection crit_;
-  rtc::scoped_ptr<FileWrapper> file_ GUARDED_BY(crit_);
+  rtc::scoped_ptr<FileWrapper> file_ GUARDED_BY(crit_) =
+      rtc::scoped_ptr<FileWrapper>(FileWrapper::Create());
+  rtc::PlatformFile platform_file_ GUARDED_BY(crit_) =
+      rtc::kInvalidPlatformFileValue;
   rtclog::EventStream stream_ GUARDED_BY(crit_);
   std::deque<rtclog::Event> recent_log_events_ GUARDED_BY(crit_);
-  bool currently_logging_ GUARDED_BY(crit_);
-  int64_t start_time_us_ GUARDED_BY(crit_);
-  int64_t duration_us_ GUARDED_BY(crit_);
-  const Clock* const clock_;
+  bool currently_logging_ GUARDED_BY(crit_) = false;
+  int64_t start_time_us_ GUARDED_BY(crit_) = 0;
+  int64_t duration_us_ GUARDED_BY(crit_) = 0;
+  const Clock* const clock_ = Clock::GetRealTimeClock();
 };
 
 namespace {
@@ -143,14 +149,6 @@
 }  // namespace
 
 // RtcEventLogImpl member functions.
-RtcEventLogImpl::RtcEventLogImpl()
-    : file_(FileWrapper::Create()),
-      stream_(),
-      currently_logging_(false),
-      start_time_us_(0),
-      duration_us_(0),
-      clock_(Clock::GetRealTimeClock()) {
-}
 
 void RtcEventLogImpl::StartLogging(const std::string& file_name,
                                    int duration_ms) {
@@ -161,9 +159,39 @@
   if (file_->OpenFile(file_name.c_str(), false) != 0) {
     return;
   }
-  currently_logging_ = true;
   start_time_us_ = clock_->TimeInMicroseconds();
   duration_us_ = static_cast<int64_t>(duration_ms) * 1000;
+  StartLoggingLocked();
+}
+
+bool RtcEventLogImpl::StartLogging(rtc::PlatformFile log_file) {
+  rtc::CritScope lock(&crit_);
+
+  if (currently_logging_) {
+    StopLoggingLocked();
+  }
+  RTC_DCHECK(platform_file_ == rtc::kInvalidPlatformFileValue);
+
+  FILE* file_stream = rtc::FdopenPlatformFileForWriting(log_file);
+  if (!file_stream) {
+    rtc::ClosePlatformFile(log_file);
+    return false;
+  }
+
+  if (file_->OpenFromFileHandle(file_stream, true, false) != 0) {
+    rtc::ClosePlatformFile(log_file);
+    return false;
+  }
+  platform_file_ = log_file;
+  // Set the start time and duration to keep logging for 10 minutes.
+  start_time_us_ = clock_->TimeInMicroseconds();
+  duration_us_ = 10 * 60 * 1000000;
+  StartLoggingLocked();
+  return true;
+}
+
+void RtcEventLogImpl::StartLoggingLocked() {
+  currently_logging_ = true;
   // Write all the recent events to the log file, ignoring any old events.
   for (auto& event : recent_log_events_) {
     if (event.timestamp_us() >= start_time_us_ - recent_log_duration_us) {
@@ -339,6 +367,10 @@
     RTC_DCHECK(file_->Open());
     StoreToFile(&event);
     file_->CloseFile();
+    if (platform_file_ != rtc::kInvalidPlatformFileValue) {
+      rtc::ClosePlatformFile(platform_file_);
+      platform_file_ = rtc::kInvalidPlatformFileValue;
+    }
   }
   RTC_DCHECK(!file_->Open());
   stream_.Clear();
diff --git a/webrtc/call/rtc_event_log.h b/webrtc/call/rtc_event_log.h
index a4b7cad..02bbdc6 100644
--- a/webrtc/call/rtc_event_log.h
+++ b/webrtc/call/rtc_event_log.h
@@ -13,6 +13,7 @@
 
 #include <string>
 
+#include "webrtc/base/platform_file.h"
 #include "webrtc/base/scoped_ptr.h"
 #include "webrtc/video_receive_stream.h"
 #include "webrtc/video_send_stream.h"
@@ -41,6 +42,11 @@
   // If the file cannot be opened, the RtcEventLog will not start logging.
   virtual void StartLogging(const std::string& file_name, int duration_ms) = 0;
 
+  // Starts logging until either the 10 minute timer runs out or the StopLogging
+  // function is called. The RtcEventLog takes ownership of the supplied
+  // rtc::PlatformFile.
+  virtual bool StartLogging(rtc::PlatformFile log_file) = 0;
+
   virtual void StopLogging() = 0;
 
   // Logs configuration information for webrtc::VideoReceiveStream