12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// AudioMirroringManager is a singleton object that maintains a set of active
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// audio mirroring destinations and auto-connects/disconnects audio streams
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to/from those destinations.  It is meant to be used exclusively on the IO
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// thread.
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// How it works:
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   1. AudioRendererHost gets a CreateStream message from the render process
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      and, among other things, creates an AudioOutputController to control the
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//      audio data flow between the render and browser processes.  More
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//      importantly, it registers the AudioOutputController with
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//      AudioMirroringManager (as a Diverter).
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//   2. A user request to mirror all the audio for a WebContents is made.  A
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//      MirroringDestination is created, and StartMirroring() is called to begin
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//      the mirroring session.  The MirroringDestination is queried to determine
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//      which of all the known Diverters will re-route their audio to it.
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//   3a. During a mirroring session, AudioMirroringManager may encounter new
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//       Diverters, and will query all the MirroringDestinations to determine
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//       which is a match, if any.
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//   3b. During a mirroring session, a call to StartMirroring() can be made to
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//       request a "refresh" query on a MirroringDestination, and this will
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//       result in AudioMirroringManager starting/stopping only those Diverters
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//       that are not correctly routed to the destination.
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//   3c. When a mirroring session is stopped, the remaining destinations will be
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//       queried to determine whether diverting should continue to a different
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//       destination.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <set>
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <utility>
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector>
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback_forward.h"
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/threading/thread_checker.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/content_export.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_source_diverter.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioOutputStream;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CONTENT_EXPORT AudioMirroringManager {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Interface for diverting audio data to an alternative AudioOutputStream.
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef media::AudioSourceDiverter Diverter;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A SourceFrameRef is a RenderFrameHost identified by a <render_process_id,
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // render_frame_id> pair.
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef std::pair<int, int> SourceFrameRef;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Interface to be implemented by audio mirroring destinations.  See comments
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for StartMirroring() and StopMirroring() below.
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class MirroringDestination {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Asynchronously query whether this MirroringDestination wants to consume
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // audio sourced from each of the |candidates|.  |results_callback| is run
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // to indicate which of them (or none) should have audio routed to this
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // MirroringDestination.  |results_callback| must be run on the same thread
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // as the one that called QueryForMatches().
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    typedef base::Callback<void(const std::set<SourceFrameRef>&)>
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        MatchesCallback;
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    virtual void QueryForMatches(
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        const std::set<SourceFrameRef>& candidates,
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        const MatchesCallback& results_callback) = 0;
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Create a consumer of audio data in the format specified by |params|, and
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // connect it as an input to mirroring.  When Close() is called on the
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // returned AudioOutputStream, the input is disconnected and the object
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // becomes invalid.
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual media::AudioOutputStream* AddInput(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const media::AudioParameters& params) = 0;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   protected:
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual ~MirroringDestination() {}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: Use GetInstance() for non-test code.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioMirroringManager();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AudioMirroringManager();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns the global instance.
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static AudioMirroringManager* GetInstance();
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Add/Remove a diverter for an audio stream with a known RenderFrame source
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // (represented by |render_process_id| + |render_frame_id|).  Multiple
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // diverters may be added for the same source frame, but never the same
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // diverter.  |diverter| must live until after RemoveDiverter() is called.
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void AddDiverter(int render_process_id, int render_frame_id,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           Diverter* diverter);
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void RemoveDiverter(Diverter* diverter);
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // (Re-)Start/Stop mirroring to the given |destination|.  |destination| must
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // live until after StopMirroring() is called.  A client may request a
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // re-start by calling StartMirroring() again; and this will cause
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // AudioMirroringManager to query |destination| and only re-route those
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // diverters that are missing/new to the returned set of matches.
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void StartMirroring(MirroringDestination* destination);
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void StopMirroring(MirroringDestination* destination);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  friend class AudioMirroringManagerTest;
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct StreamRoutingState {
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The source render frame associated with the audio stream.
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SourceFrameRef source_render_frame;
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The diverter for re-routing the audio stream.
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Diverter* diverter;
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // If not NULL, the audio stream is currently being diverted to this
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // destination.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MirroringDestination* destination;
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    StreamRoutingState(const SourceFrameRef& source_frame,
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       Diverter* stream_diverter);
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ~StreamRoutingState();
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef std::vector<StreamRoutingState> StreamRoutes;
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef std::vector<MirroringDestination*> Destinations;
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Helper to find a destination other than |old_destination| for the given
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |candidates| to be diverted to.
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void InitiateQueriesToFindNewDestination(
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MirroringDestination* old_destination,
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const std::set<SourceFrameRef>& candidates);
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // MirroringDestination query callback.  |matches| contains all RenderFrame
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // sources that will be diverted to |destination|.  If |add_only| is false,
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // then any Diverters currently routed to |destination| but not found in
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |matches| will be stopped.
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void UpdateRoutesToDestination(MirroringDestination* destination,
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 bool add_only,
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 const std::set<SourceFrameRef>& matches);
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Starts diverting audio to the |new_destination|, if not NULL.  Otherwise,
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // stops diverting audio.
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static void ChangeRoute(StreamRoutingState* route,
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          MirroringDestination* new_destination);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Routing table.  Contains one entry for each Diverter.
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StreamRoutes routes_;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // All active mirroring sessions.
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Destinations sessions_;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Used to check that all AudioMirroringManager code runs on the same thread.
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ThreadChecker thread_checker_;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AudioMirroringManager);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // CONTENT_BROWSER_MEDIA_CAPTURE_AUDIO_MIRRORING_MANAGER_H_
165