Add ForwardingAudioStreamFactory to WebContentsImpl.

Also add accessor to ForwardingAudioStreamFactory.

Approximate diagram of stuff:
https://docs.google.com/drawings/d/1_ZIKj6lihGKRjq4Mflduitmkn_REqpHFeqVNelBGHHk/edit

Bug: 830493
Change-Id: I309aedf43fed5e646545eb94d00a77abc6ac66ea
Reviewed-on: https://chromium-review.googlesource.com/1039707
Reviewed-by: Nasko Oskov <[email protected]>
Reviewed-by: Olga Sharonova <[email protected]>
Commit-Queue: Max Morin <[email protected]>
Cr-Commit-Position: refs/heads/master@{#557111}
diff --git a/content/browser/media/forwarding_audio_stream_factory.cc b/content/browser/media/forwarding_audio_stream_factory.cc
index e94f4b3..30edea5 100644
--- a/content/browser/media/forwarding_audio_stream_factory.cc
+++ b/content/browser/media/forwarding_audio_stream_factory.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "content/browser/media/capture/audio_mirroring_manager.h"
+#include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
@@ -34,6 +35,17 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
+// static
+ForwardingAudioStreamFactory* ForwardingAudioStreamFactory::ForFrame(
+    RenderFrameHost* frame) {
+  auto* contents =
+      static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(frame));
+  if (!contents)
+    return nullptr;
+
+  return contents->GetAudioStreamFactory();
+}
+
 void ForwardingAudioStreamFactory::CreateInputStream(
     RenderFrameHost* frame,
     const std::string& device_id,
diff --git a/content/browser/media/forwarding_audio_stream_factory.h b/content/browser/media/forwarding_audio_stream_factory.h
index fce7320d..ea0748aa 100644
--- a/content/browser/media/forwarding_audio_stream_factory.h
+++ b/content/browser/media/forwarding_audio_stream_factory.h
@@ -43,6 +43,11 @@
 
   ~ForwardingAudioStreamFactory() final;
 
+  // Returns the ForwardingAudioStreamFactory which takes care of stream
+  // creation for |frame|. Returns null if |frame| is null or if the frame
+  // doesn't belong to a WebContents.
+  static ForwardingAudioStreamFactory* ForFrame(RenderFrameHost* frame);
+
   const base::UnguessableToken& group_id() { return group_id_; }
 
   // TODO(https://crbug.com/803102): Add loopback and muting streams.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 189b3f0..6a9a264 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -60,6 +60,7 @@
 #include "content/browser/loader/loader_io_thread_notifier.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/manifest/manifest_manager_host.h"
+#include "content/browser/media/audio_stream_broker.h"
 #include "content/browser/media/audio_stream_monitor.h"
 #include "content/browser/media/capture/web_contents_audio_muter.h"
 #include "content/browser/media/media_web_contents_observer.h"
@@ -6158,6 +6159,19 @@
   view_size_before_emulation_ = gfx::Size();
 }
 
+ForwardingAudioStreamFactory* WebContentsImpl::GetAudioStreamFactory() {
+  if (!audio_stream_factory_) {
+    audio_stream_factory_.emplace(
+        this,
+        content::ServiceManagerConnection::GetForProcess()
+            ->GetConnector()
+            ->Clone(),
+        AudioStreamBrokerFactory::CreateImpl());
+  }
+
+  return &*audio_stream_factory_;
+}
+
 void WebContentsImpl::MediaStartedPlaying(
     const WebContentsObserver::MediaPlayerInfo& media_info,
     const WebContentsObserver::MediaPlayerId& id) {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index a5cfbff9..730b9d3 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -19,6 +19,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
+#include "base/optional.h"
 #include "base/process/process.h"
 #include "base/time/time.h"
 #include "base/values.h"
@@ -33,6 +34,7 @@
 #include "content/browser/frame_host/render_frame_host_delegate.h"
 #include "content/browser/frame_host/render_frame_host_manager.h"
 #include "content/browser/media/audio_stream_monitor.h"
+#include "content/browser/media/forwarding_audio_stream_factory.h"
 #include "content/browser/renderer_host/render_view_host_delegate.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
@@ -871,6 +873,8 @@
     return &audio_stream_monitor_;
   }
 
+  ForwardingAudioStreamFactory* GetAudioStreamFactory();
+
   // Called by MediaWebContentsObserver when playback starts or stops.  See the
   // WebContentsObserver function stubs for more details.
   void MediaStartedPlaying(
@@ -1649,6 +1653,9 @@
   // Monitors power levels for audio streams associated with this WebContents.
   AudioStreamMonitor audio_stream_monitor_;
 
+  // Coordinates all the audio streams for this WebContents. Lazily initialized.
+  base::Optional<ForwardingAudioStreamFactory> audio_stream_factory_;
+
   // Created on-demand to mute all audio output from this WebContents.
   std::unique_ptr<WebContentsAudioMuter> audio_muter_;