Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / media / webrtc_internals.cc
index 713da32..d8a0314 100644 (file)
@@ -4,16 +4,17 @@
 
 #include "content/browser/media/webrtc_internals.h"
 
-#include "base/command_line.h"
+#include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
 #include "content/browser/media/webrtc_internals_ui_observer.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/child_process_data.h"
+#include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
+#include "content/public/browser/power_save_blocker.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "content/public/common/content_switches.h"
 
 using base::ProcessId;
 using std::string;
@@ -21,6 +22,10 @@ using std::string;
 namespace content {
 
 namespace {
+
+static base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals =
+    LAZY_INSTANCE_INITIALIZER;
+
 // Makes sure that |dict| has a ListValue under path "log".
 static base::ListValue* EnsureLogList(base::DictionaryValue* dict) {
   base::ListValue* log = NULL;
@@ -38,42 +43,36 @@ WebRTCInternals::WebRTCInternals()
     : aec_dump_enabled_(false) {
   registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
                  NotificationService::AllBrowserContextsAndSources());
-  BrowserChildProcessObserver::Add(this);
 // TODO(grunell): Shouldn't all the webrtc_internals* files be excluded from the
 // build if WebRTC is disabled?
 #if defined(ENABLE_WEBRTC)
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableWebRtcAecRecordings)) {
-    aec_dump_enabled_ = true;
-    aec_dump_file_path_ = CommandLine::ForCurrentProcess()->GetSwitchValuePath(
-        switches::kEnableWebRtcAecRecordings);
+  aec_dump_file_path_ =
+      GetContentClient()->browser()->GetDefaultDownloadDirectory();
+  if (aec_dump_file_path_.empty()) {
+    // In this case the default path (|aec_dump_file_path_|) will be empty and
+    // the platform default path will be used in the file dialog (with no
+    // default file name). See SelectFileDialog::SelectFile. On Android where
+    // there's no dialog we'll fail to open the file.
+    VLOG(1) << "Could not get the download directory.";
   } else {
-#if defined(OS_CHROMEOS)
     aec_dump_file_path_ =
-        base::FilePath(FILE_PATH_LITERAL("/tmp/audio.aecdump"));
-#elif defined(OS_ANDROID)
-    aec_dump_file_path_ =
-        base::FilePath(FILE_PATH_LITERAL("/sdcard/audio.aecdump"));
-#else
-    aec_dump_file_path_ = base::FilePath(FILE_PATH_LITERAL("audio.aecdump"));
-#endif
+        aec_dump_file_path_.Append(FILE_PATH_LITERAL("audio.aecdump"));
   }
 #endif  // defined(ENABLE_WEBRTC)
 }
 
 WebRTCInternals::~WebRTCInternals() {
-  BrowserChildProcessObserver::Remove(this);
 }
 
 WebRTCInternals* WebRTCInternals::GetInstance() {
-  return Singleton<WebRTCInternals>::get();
+  return g_webrtc_internals.Pointer();
 }
 
 void WebRTCInternals::OnAddPeerConnection(int render_process_id,
                                           ProcessId pid,
                                           int lid,
                                           const string& url,
-                                          const string& servers,
+                                          const string& rtc_configuration,
                                           const string& constraints) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
@@ -84,10 +83,11 @@ void WebRTCInternals::OnAddPeerConnection(int render_process_id,
   dict->SetInteger("rid", render_process_id);
   dict->SetInteger("pid", static_cast<int>(pid));
   dict->SetInteger("lid", lid);
-  dict->SetString("servers", servers);
+  dict->SetString("rtcConfiguration", rtc_configuration);
   dict->SetString("constraints", constraints);
   dict->SetString("url", url);
   peer_connection_data_.Append(dict);
+  CreateOrReleasePowerSaveBlocker();
 
   if (observers_.might_have_observers())
     SendUpdate("addPeerConnection", dict);
@@ -108,6 +108,7 @@ void WebRTCInternals::OnRemovePeerConnection(ProcessId pid, int lid) {
       continue;
 
     peer_connection_data_.Remove(i, NULL);
+    CreateOrReleasePowerSaveBlocker();
 
     if (observers_.might_have_observers()) {
       base::DictionaryValue id;
@@ -143,6 +144,9 @@ void WebRTCInternals::OnUpdatePeerConnection(
     if (!log_entry)
       return;
 
+    double epoch_time = base::Time::Now().ToJsTime();
+    string time = base::DoubleToString(epoch_time);
+    log_entry->SetString("time", time);
     log_entry->SetString("type", type);
     log_entry->SetString("value", value);
     log->Append(log_entry);
@@ -151,8 +155,7 @@ void WebRTCInternals::OnUpdatePeerConnection(
       base::DictionaryValue update;
       update.SetInteger("pid", static_cast<int>(pid));
       update.SetInteger("lid", lid);
-      update.SetString("type", type);
-      update.SetString("value", value);
+      update.MergeDictionary(log_entry);
 
       SendUpdate("updatePeerConnection", &update);
     }
@@ -231,6 +234,9 @@ void WebRTCInternals::UpdateObserver(WebRTCInternalsUIObserver* observer) {
 
 void WebRTCInternals::EnableAecDump(content::WebContents* web_contents) {
 #if defined(ENABLE_WEBRTC)
+#if defined(OS_ANDROID)
+  EnableAecDumpOnAllRenderProcessHosts();
+#else
   select_file_dialog_ = ui::SelectFileDialog::Create(this, NULL);
   select_file_dialog_->SelectFile(
       ui::SelectFileDialog::SELECT_SAVEAS_FILE,
@@ -239,14 +245,19 @@ void WebRTCInternals::EnableAecDump(content::WebContents* web_contents) {
       NULL,
       0,
       FILE_PATH_LITERAL(""),
-      web_contents->GetView()->GetTopLevelNativeWindow(),
+      web_contents->GetTopLevelNativeWindow(),
       NULL);
 #endif
+#endif
 }
 
 void WebRTCInternals::DisableAecDump() {
 #if defined(ENABLE_WEBRTC)
   aec_dump_enabled_ = false;
+
+  // Tear down the dialog since the user has unchecked the AEC dump box.
+  select_file_dialog_ = NULL;
+
   for (RenderProcessHost::iterator i(
            content::RenderProcessHost::AllHostsIterator());
        !i.IsAtEnd(); i.Advance()) {
@@ -255,6 +266,15 @@ void WebRTCInternals::DisableAecDump() {
 #endif
 }
 
+void WebRTCInternals::ResetForTesting() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  observers_.Clear();
+  peer_connection_data_.Clear();
+  CreateOrReleasePowerSaveBlocker();
+  get_user_media_requests_.Clear();
+  aec_dump_enabled_ = false;
+}
+
 void WebRTCInternals::SendUpdate(const string& command, base::Value* value) {
   DCHECK(observers_.might_have_observers());
 
@@ -263,12 +283,6 @@ void WebRTCInternals::SendUpdate(const string& command, base::Value* value) {
                     OnUpdate(command, value));
 }
 
-void WebRTCInternals::BrowserChildProcessCrashed(
-    const ChildProcessData& data) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  OnRendererExit(data.id);
-}
-
 void WebRTCInternals::Observe(int type,
                               const NotificationSource& source,
                               const NotificationDetails& details) {
@@ -281,17 +295,20 @@ void WebRTCInternals::FileSelected(const base::FilePath& path,
                                    int /* unused_index */,
                                    void* /*unused_params */) {
 #if defined(ENABLE_WEBRTC)
-  aec_dump_enabled_ = true;
   aec_dump_file_path_ = path;
-  for (RenderProcessHost::iterator i(
-           content::RenderProcessHost::AllHostsIterator());
-       !i.IsAtEnd(); i.Advance()) {
-    i.GetCurrentValue()->EnableAecDump(aec_dump_file_path_);
-  }
+  EnableAecDumpOnAllRenderProcessHosts();
+#endif
+}
+
+void WebRTCInternals::FileSelectionCanceled(void* params) {
+#if defined(ENABLE_WEBRTC)
+  SendUpdate("aecRecordingFileSelectionCancelled", NULL);
 #endif
 }
 
 void WebRTCInternals::OnRendererExit(int render_process_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
   // Iterates from the end of the list to remove the PeerConnections created
   // by the exitting renderer.
   for (int i = peer_connection_data_.GetSize() - 1; i >= 0; --i) {
@@ -315,6 +332,7 @@ void WebRTCInternals::OnRendererExit(int render_process_id) {
       peer_connection_data_.Remove(i, NULL);
     }
   }
+  CreateOrReleasePowerSaveBlocker();
 
   bool found_any = false;
   // Iterates from the end of the list to remove the getUserMedia requests
@@ -339,12 +357,31 @@ void WebRTCInternals::OnRendererExit(int render_process_id) {
   }
 }
 
-void WebRTCInternals::ResetForTesting() {
+#if defined(ENABLE_WEBRTC)
+void WebRTCInternals::EnableAecDumpOnAllRenderProcessHosts() {
+  aec_dump_enabled_ = true;
+  for (RenderProcessHost::iterator i(
+           content::RenderProcessHost::AllHostsIterator());
+       !i.IsAtEnd(); i.Advance()) {
+    i.GetCurrentValue()->EnableAecDump(aec_dump_file_path_);
+  }
+}
+#endif
+
+void WebRTCInternals::CreateOrReleasePowerSaveBlocker() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  observers_.Clear();
-  peer_connection_data_.Clear();
-  get_user_media_requests_.Clear();
-  aec_dump_enabled_ = false;
+
+  if (peer_connection_data_.empty() && power_save_blocker_) {
+    DVLOG(1) << ("Releasing the block on application suspension since no "
+                 "PeerConnections are active anymore.");
+    power_save_blocker_.reset();
+  } else if (!peer_connection_data_.empty() && !power_save_blocker_) {
+    DVLOG(1) << ("Preventing the application from being suspended while one or "
+                 "more PeerConnections are active.");
+    power_save_blocker_ = content::PowerSaveBlocker::Create(
+        content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
+        "WebRTC has active PeerConnections.").Pass();
+  }
 }
 
 }  // namespace content