• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // AudioInputRendererHost serves audio related requests from audio capturer
6 // which lives inside the render process and provide access to audio hardware.
7 //
8 // Create stream sequence (AudioInputController = AIC):
9 //
10 // AudioInputHostMsg_CreateStream -> OnCreateStream -> AIC::CreateLowLatency ->
11 //   <- AudioInputMsg_NotifyStreamCreated <- DoCompleteCreation <- OnCreated <-
12 //
13 // Close stream sequence:
14 //
15 // AudioInputHostMsg_CloseStream -> OnCloseStream -> AIC::Close ->
16 //
17 // This class is owned by BrowserRenderProcessHost and instantiated on UI
18 // thread. All other operations and method calls happen on IO thread, so we
19 // need to be extra careful about the lifetime of this object.
20 //
21 // To ensure low latency audio, a SyncSocket pair is used to signal buffer
22 // readiness without having to route messages using the IO thread.
23 
24 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_RENDERER_HOST_H_
25 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_RENDERER_HOST_H_
26 
27 #include <map>
28 #include <string>
29 
30 #include "base/compiler_specific.h"
31 #include "base/gtest_prod_util.h"
32 #include "base/memory/ref_counted.h"
33 #include "base/memory/scoped_ptr.h"
34 #include "base/memory/shared_memory.h"
35 #include "base/process/process.h"
36 #include "base/sequenced_task_runner_helpers.h"
37 #include "content/common/media/audio_messages.h"
38 #include "content/public/browser/browser_message_filter.h"
39 #include "content/public/browser/browser_thread.h"
40 #include "media/audio/audio_input_controller.h"
41 #include "media/audio/audio_io.h"
42 #include "media/audio/audio_logging.h"
43 #include "media/audio/simple_sources.h"
44 
45 namespace media {
46 class AudioManager;
47 class AudioParameters;
48 class UserInputMonitor;
49 }
50 
51 namespace content {
52 class AudioMirroringManager;
53 class MediaStreamManager;
54 
55 class CONTENT_EXPORT AudioInputRendererHost
56     : public BrowserMessageFilter,
57       public media::AudioInputController::EventHandler {
58  public:
59 
60   // Error codes to make native loggin more clear. These error codes are added
61   // to generic error strings to provide a higher degree of details.
62   // Changing these values can lead to problems when matching native debug
63   // logs with the actual cause of error.
64   enum ErrorCode {
65     // An unspecified error occured.
66     UNKNOWN_ERROR = 0,
67 
68     // Failed to look up audio intry for the provided stream id.
69     INVALID_AUDIO_ENTRY,  // = 1
70 
71     // A stream with the specified stream id already exists.
72     STREAM_ALREADY_EXISTS,  // = 2
73 
74     // The page does not have permission to open the specified capture device.
75     PERMISSION_DENIED,  // = 3
76 
77     // Failed to create shared memory.
78     SHARED_MEMORY_CREATE_FAILED,  // = 4
79 
80     // Failed to initialize the AudioInputSyncWriter instance.
81     SYNC_WRITER_INIT_FAILED,  // = 5
82 
83     // Failed to create native audio input stream.
84     STREAM_CREATE_ERROR,  // = 6
85 
86     // Renderer process handle is invalid.
87     INVALID_PEER_HANDLE,  // = 7
88 
89     // Only low-latency mode is supported.
90     INVALID_LATENCY_MODE,  // = 8
91 
92     // Failed to map and share the shared memory.
93     MEMORY_SHARING_FAILED,  // = 9
94 
95     // Unable to prepare the foreign socket handle.
96     SYNC_SOCKET_ERROR,  // = 10
97 
98     // This error message comes from the AudioInputController instance.
99     AUDIO_INPUT_CONTROLLER_ERROR,  // = 11
100   };
101 
102   // Called from UI thread from the owner of this object.
103   // |user_input_monitor| is used for typing detection and can be NULL.
104   AudioInputRendererHost(media::AudioManager* audio_manager,
105                          MediaStreamManager* media_stream_manager,
106                          AudioMirroringManager* audio_mirroring_manager,
107                          media::UserInputMonitor* user_input_monitor);
108 
109   // BrowserMessageFilter implementation.
110   virtual void OnChannelClosing() OVERRIDE;
111   virtual void OnDestruct() const OVERRIDE;
112   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
113 
114   // AudioInputController::EventHandler implementation.
115   virtual void OnCreated(media::AudioInputController* controller) OVERRIDE;
116   virtual void OnRecording(media::AudioInputController* controller) OVERRIDE;
117   virtual void OnError(media::AudioInputController* controller,
118       media::AudioInputController::ErrorCode error_code) OVERRIDE;
119   virtual void OnData(media::AudioInputController* controller,
120                       const media::AudioBus* data) OVERRIDE;
121   virtual void OnLog(media::AudioInputController* controller,
122                      const std::string& message) OVERRIDE;
123 
124  private:
125   // TODO(henrika): extend test suite (compare AudioRenderHost)
126   friend class BrowserThread;
127   friend class TestAudioInputRendererHost;
128   friend class base::DeleteHelper<AudioInputRendererHost>;
129 
130   struct AudioEntry;
131   typedef std::map<int, AudioEntry*> AudioEntryMap;
132 
133   virtual ~AudioInputRendererHost();
134 
135   // Methods called on IO thread ----------------------------------------------
136 
137   // Audio related IPC message handlers.
138 
139   // For ChromeOS: Checks if the stream should contain keyboard mic, if so
140   // registers to AudioInputDeviceManager. Then calls DoCreateStream.
141   // For non-ChromeOS: Just calls DoCreateStream.
142   void OnCreateStream(int stream_id,
143                       int render_view_id,
144                       int session_id,
145                       const AudioInputHostMsg_CreateStream_Config& config);
146 
147   // Creates an audio input stream with the specified format whose data is
148   // consumed by an entity in the render view referenced by |render_view_id|.
149   // |session_id| is used to find out which device to be used for the stream.
150   // Upon success/failure, the peer is notified via the
151   // NotifyStreamCreated message.
152   void DoCreateStream(int stream_id,
153                       int render_view_id,
154                       int session_id,
155                       const AudioInputHostMsg_CreateStream_Config& config);
156 
157   // Record the audio input stream referenced by |stream_id|.
158   void OnRecordStream(int stream_id);
159 
160   // Close the audio stream referenced by |stream_id|.
161   void OnCloseStream(int stream_id);
162 
163   // Set the volume of the audio stream referenced by |stream_id|.
164   void OnSetVolume(int stream_id, double volume);
165 
166   // Complete the process of creating an audio input stream. This will set up
167   // the shared memory or shared socket in low latency mode and send the
168   // NotifyStreamCreated message to the peer.
169   void DoCompleteCreation(media::AudioInputController* controller);
170 
171   // Send a state change message to the renderer.
172   void DoSendRecordingMessage(media::AudioInputController* controller);
173 
174   // Handle error coming from audio stream.
175   void DoHandleError(media::AudioInputController* controller,
176       media::AudioInputController::ErrorCode error_code);
177 
178   // Log audio level of captured audio stream.
179   void DoLog(media::AudioInputController* controller,
180              const std::string& message);
181 
182   // Send an error message to the renderer.
183   void SendErrorMessage(int stream_id, ErrorCode error_code);
184 
185   // Delete all audio entry and all audio streams
186   void DeleteEntries();
187 
188   // Closes the stream. The stream is then deleted in DeleteEntry() after it
189   // is closed.
190   void CloseAndDeleteStream(AudioEntry* entry);
191 
192   // Delete an audio entry and close the related audio stream.
193   void DeleteEntry(AudioEntry* entry);
194 
195   // Delete audio entry and close the related audio input stream.
196   void DeleteEntryOnError(AudioEntry* entry, ErrorCode error_code);
197 
198   // A helper method to look up a AudioEntry identified by |stream_id|.
199   // Returns NULL if not found.
200   AudioEntry* LookupById(int stream_id);
201 
202   // Search for a AudioEntry having the reference to |controller|.
203   // This method is used to look up an AudioEntry after a controller
204   // event is received.
205   AudioEntry* LookupByController(media::AudioInputController* controller);
206 
207   // If ChromeOS and |config|'s layout has keyboard mic, unregister in
208   // AudioInputDeviceManager.
209   void MaybeUnregisterKeyboardMicStream(
210       const AudioInputHostMsg_CreateStream_Config& config);
211 
212   // Used to create an AudioInputController.
213   media::AudioManager* audio_manager_;
214 
215   // Used to access to AudioInputDeviceManager.
216   MediaStreamManager* media_stream_manager_;
217 
218   AudioMirroringManager* audio_mirroring_manager_;
219 
220   // A map of stream IDs to audio sources.
221   AudioEntryMap audio_entries_;
222 
223   // Raw pointer of the UserInputMonitor.
224   media::UserInputMonitor* user_input_monitor_;
225 
226   scoped_ptr<media::AudioLog> audio_log_;
227 
228   DISALLOW_COPY_AND_ASSIGN(AudioInputRendererHost);
229 };
230 
231 }  // namespace content
232 
233 #endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_RENDERER_HOST_H_
234