Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: trunk/src/media/audio/audio_input_controller.cc

Issue 22871007: Revert 217768 "Adding key press detection in the browser process." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/audio_input_controller.h" 5 #include "media/audio/audio_input_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/threading/thread_restrictions.h" 8 #include "base/threading/thread_restrictions.h"
9 #include "media/base/limits.h" 9 #include "media/base/limits.h"
10 #include "media/base/scoped_histogram_timer.h" 10 #include "media/base/scoped_histogram_timer.h"
(...skipping 18 matching lines...) Expand all
29 const int kTimerInitialIntervalSeconds = 5; 29 const int kTimerInitialIntervalSeconds = 5;
30 #endif // defined(OS_IOS) 30 #endif // defined(OS_IOS)
31 } 31 }
32 32
33 namespace media { 33 namespace media {
34 34
35 // static 35 // static
36 AudioInputController::Factory* AudioInputController::factory_ = NULL; 36 AudioInputController::Factory* AudioInputController::factory_ = NULL;
37 37
38 AudioInputController::AudioInputController(EventHandler* handler, 38 AudioInputController::AudioInputController(EventHandler* handler,
39 SyncWriter* sync_writer, 39 SyncWriter* sync_writer)
40 UserInputMonitor* user_input_monitor)
41 : creator_loop_(base::MessageLoopProxy::current()), 40 : creator_loop_(base::MessageLoopProxy::current()),
42 handler_(handler), 41 handler_(handler),
43 stream_(NULL), 42 stream_(NULL),
44 data_is_active_(false), 43 data_is_active_(false),
45 state_(kEmpty), 44 state_(kEmpty),
46 sync_writer_(sync_writer), 45 sync_writer_(sync_writer),
47 max_volume_(0.0), 46 max_volume_(0.0) {
48 user_input_monitor_(user_input_monitor),
49 key_pressed_(false) {
50 DCHECK(creator_loop_.get()); 47 DCHECK(creator_loop_.get());
51 } 48 }
52 49
53 AudioInputController::~AudioInputController() { 50 AudioInputController::~AudioInputController() {
54 DCHECK(kClosed == state_ || kCreated == state_ || kEmpty == state_); 51 DCHECK(kClosed == state_ || kCreated == state_ || kEmpty == state_);
55 } 52 }
56 53
57 // static 54 // static
58 scoped_refptr<AudioInputController> AudioInputController::Create( 55 scoped_refptr<AudioInputController> AudioInputController::Create(
59 AudioManager* audio_manager, 56 AudioManager* audio_manager,
60 EventHandler* event_handler, 57 EventHandler* event_handler,
61 const AudioParameters& params, 58 const AudioParameters& params,
62 const std::string& device_id, 59 const std::string& device_id) {
63 UserInputMonitor* user_input_monitor) {
64 DCHECK(audio_manager); 60 DCHECK(audio_manager);
65 61
66 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 62 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
67 return NULL; 63 return NULL;
68 64
69 if (factory_) { 65 if (factory_)
70 return factory_->Create( 66 return factory_->Create(audio_manager, event_handler, params);
71 audio_manager, event_handler, params, user_input_monitor); 67
72 } 68 scoped_refptr<AudioInputController> controller(new AudioInputController(
73 scoped_refptr<AudioInputController> controller( 69 event_handler, NULL));
74 new AudioInputController(event_handler, NULL, user_input_monitor));
75 70
76 controller->message_loop_ = audio_manager->GetMessageLoop(); 71 controller->message_loop_ = audio_manager->GetMessageLoop();
77 72
78 // Create and open a new audio input stream from the existing 73 // Create and open a new audio input stream from the existing
79 // audio-device thread. 74 // audio-device thread.
80 if (!controller->message_loop_->PostTask(FROM_HERE, 75 if (!controller->message_loop_->PostTask(FROM_HERE,
81 base::Bind(&AudioInputController::DoCreate, controller, 76 base::Bind(&AudioInputController::DoCreate, controller,
82 base::Unretained(audio_manager), params, device_id))) { 77 base::Unretained(audio_manager), params, device_id))) {
83 controller = NULL; 78 controller = NULL;
84 } 79 }
85 80
86 return controller; 81 return controller;
87 } 82 }
88 83
89 // static 84 // static
90 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( 85 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
91 AudioManager* audio_manager, 86 AudioManager* audio_manager,
92 EventHandler* event_handler, 87 EventHandler* event_handler,
93 const AudioParameters& params, 88 const AudioParameters& params,
94 const std::string& device_id, 89 const std::string& device_id,
95 SyncWriter* sync_writer, 90 SyncWriter* sync_writer) {
96 UserInputMonitor* user_input_monitor) {
97 DCHECK(audio_manager); 91 DCHECK(audio_manager);
98 DCHECK(sync_writer); 92 DCHECK(sync_writer);
99 93
100 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 94 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
101 return NULL; 95 return NULL;
102 96
103 // Create the AudioInputController object and ensure that it runs on 97 // Create the AudioInputController object and ensure that it runs on
104 // the audio-manager thread. 98 // the audio-manager thread.
105 scoped_refptr<AudioInputController> controller( 99 scoped_refptr<AudioInputController> controller(new AudioInputController(
106 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 100 event_handler, sync_writer));
107 controller->message_loop_ = audio_manager->GetMessageLoop(); 101 controller->message_loop_ = audio_manager->GetMessageLoop();
108 102
109 // Create and open a new audio input stream from the existing 103 // Create and open a new audio input stream from the existing
110 // audio-device thread. Use the provided audio-input device. 104 // audio-device thread. Use the provided audio-input device.
111 if (!controller->message_loop_->PostTask(FROM_HERE, 105 if (!controller->message_loop_->PostTask(FROM_HERE,
112 base::Bind(&AudioInputController::DoCreate, controller, 106 base::Bind(&AudioInputController::DoCreate, controller,
113 base::Unretained(audio_manager), params, device_id))) { 107 base::Unretained(audio_manager), params, device_id))) {
114 controller = NULL; 108 controller = NULL;
115 } 109 }
116 110
117 return controller; 111 return controller;
118 } 112 }
119 113
120 // static 114 // static
121 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( 115 scoped_refptr<AudioInputController> AudioInputController::CreateForStream(
122 const scoped_refptr<base::MessageLoopProxy>& message_loop, 116 const scoped_refptr<base::MessageLoopProxy>& message_loop,
123 EventHandler* event_handler, 117 EventHandler* event_handler,
124 AudioInputStream* stream, 118 AudioInputStream* stream,
125 SyncWriter* sync_writer, 119 SyncWriter* sync_writer) {
126 UserInputMonitor* user_input_monitor) {
127 DCHECK(sync_writer); 120 DCHECK(sync_writer);
128 DCHECK(stream); 121 DCHECK(stream);
129 122
130 // Create the AudioInputController object and ensure that it runs on 123 // Create the AudioInputController object and ensure that it runs on
131 // the audio-manager thread. 124 // the audio-manager thread.
132 scoped_refptr<AudioInputController> controller( 125 scoped_refptr<AudioInputController> controller(new AudioInputController(
133 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 126 event_handler, sync_writer));
134 controller->message_loop_ = message_loop; 127 controller->message_loop_ = message_loop;
135 128
136 // TODO(miu): See TODO at top of file. Until that's resolved, we need to 129 // TODO(miu): See TODO at top of file. Until that's resolved, we need to
137 // disable the error auto-detection here (since the audio mirroring 130 // disable the error auto-detection here (since the audio mirroring
138 // implementation will reliably report error and close events). Note, of 131 // implementation will reliably report error and close events). Note, of
139 // course, that we're assuming CreateForStream() has been called for the audio 132 // course, that we're assuming CreateForStream() has been called for the audio
140 // mirroring use case only. 133 // mirroring use case only.
141 if (!controller->message_loop_->PostTask( 134 if (!controller->message_loop_->PostTask(
142 FROM_HERE, 135 FROM_HERE,
143 base::Bind(&AudioInputController::DoCreateForStream, controller, 136 base::Bind(&AudioInputController::DoCreateForStream, controller,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 226 }
234 227
235 if (no_data_timer_) { 228 if (no_data_timer_) {
236 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, 229 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed,
237 // a callback to DoCheckForNoData() is made. 230 // a callback to DoCheckForNoData() is made.
238 no_data_timer_->Reset(); 231 no_data_timer_->Reset();
239 } 232 }
240 233
241 stream_->Start(this); 234 stream_->Start(this);
242 handler_->OnRecording(this); 235 handler_->OnRecording(this);
243
244 if (user_input_monitor_)
245 user_input_monitor_->AddKeyStrokeListener(this);
246 } 236 }
247 237
248 void AudioInputController::DoClose() { 238 void AudioInputController::DoClose() {
249 DCHECK(message_loop_->BelongsToCurrentThread()); 239 DCHECK(message_loop_->BelongsToCurrentThread());
250 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 240 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
251 241
252 // Delete the timer on the same thread that created it. 242 // Delete the timer on the same thread that created it.
253 no_data_timer_.reset(); 243 no_data_timer_.reset();
254 244
255 if (state_ != kClosed) { 245 if (state_ != kClosed) {
256 DoStopCloseAndClearStream(NULL); 246 DoStopCloseAndClearStream(NULL);
257 SetDataIsActive(false); 247 SetDataIsActive(false);
258 248
259 if (LowLatencyMode()) { 249 if (LowLatencyMode()) {
260 sync_writer_->Close(); 250 sync_writer_->Close();
261 } 251 }
262 252
263 state_ = kClosed; 253 state_ = kClosed;
264
265 if (user_input_monitor_)
266 user_input_monitor_->RemoveKeyStrokeListener(this);
267 } 254 }
268 } 255 }
269 256
270 void AudioInputController::DoReportError() { 257 void AudioInputController::DoReportError() {
271 DCHECK(message_loop_->BelongsToCurrentThread()); 258 DCHECK(message_loop_->BelongsToCurrentThread());
272 handler_->OnError(this); 259 handler_->OnError(this);
273 } 260 }
274 261
275 void AudioInputController::DoSetVolume(double volume) { 262 void AudioInputController::DoSetVolume(double volume) {
276 DCHECK(message_loop_->BelongsToCurrentThread()); 263 DCHECK(message_loop_->BelongsToCurrentThread());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 // |kTimerResetIntervalSeconds|. 313 // |kTimerResetIntervalSeconds|.
327 no_data_timer_->Start( 314 no_data_timer_->Start(
328 FROM_HERE, base::TimeDelta::FromSeconds(kTimerResetIntervalSeconds), 315 FROM_HERE, base::TimeDelta::FromSeconds(kTimerResetIntervalSeconds),
329 base::Bind(&AudioInputController::DoCheckForNoData, 316 base::Bind(&AudioInputController::DoCheckForNoData,
330 base::Unretained(this))); 317 base::Unretained(this)));
331 } 318 }
332 319
333 void AudioInputController::OnData(AudioInputStream* stream, const uint8* data, 320 void AudioInputController::OnData(AudioInputStream* stream, const uint8* data,
334 uint32 size, uint32 hardware_delay_bytes, 321 uint32 size, uint32 hardware_delay_bytes,
335 double volume) { 322 double volume) {
336 bool key_pressed = false;
337 { 323 {
338 base::AutoLock auto_lock(lock_); 324 base::AutoLock auto_lock(lock_);
339 if (state_ != kRecording) 325 if (state_ != kRecording)
340 return; 326 return;
341
342 std::swap(key_pressed, key_pressed_);
343 } 327 }
344 328
345 // Mark data as active to ensure that the periodic calls to 329 // Mark data as active to ensure that the periodic calls to
346 // DoCheckForNoData() does not report an error to the event handler. 330 // DoCheckForNoData() does not report an error to the event handler.
347 SetDataIsActive(true); 331 SetDataIsActive(true);
348 332
349 // Use SyncSocket if we are in a low-latency mode. 333 // Use SyncSocket if we are in a low-latency mode.
350 if (LowLatencyMode()) { 334 if (LowLatencyMode()) {
351 sync_writer_->Write(data, size, volume, key_pressed); 335 sync_writer_->Write(data, size, volume);
352 sync_writer_->UpdateRecordedBytes(hardware_delay_bytes); 336 sync_writer_->UpdateRecordedBytes(hardware_delay_bytes);
353 return; 337 return;
354 } 338 }
355 339
356 handler_->OnData(this, data, size); 340 handler_->OnData(this, data, size);
357 } 341 }
358 342
359 void AudioInputController::OnClose(AudioInputStream* stream) { 343 void AudioInputController::OnClose(AudioInputStream* stream) {
360 DVLOG(1) << "AudioInputController::OnClose()"; 344 DVLOG(1) << "AudioInputController::OnClose()";
361 // TODO(satish): Sometimes the device driver closes the input stream without 345 // TODO(satish): Sometimes the device driver closes the input stream without
362 // us asking for it (may be if the device was unplugged?). Check how to handle 346 // us asking for it (may be if the device was unplugged?). Check how to handle
363 // such cases here. 347 // such cases here.
364 } 348 }
365 349
366 void AudioInputController::OnError(AudioInputStream* stream) { 350 void AudioInputController::OnError(AudioInputStream* stream) {
367 // Handle error on the audio-manager thread. 351 // Handle error on the audio-manager thread.
368 message_loop_->PostTask(FROM_HERE, base::Bind( 352 message_loop_->PostTask(FROM_HERE, base::Bind(
369 &AudioInputController::DoReportError, this)); 353 &AudioInputController::DoReportError, this));
370 } 354 }
371 355
372 void AudioInputController::OnKeyStroke() {
373 base::AutoLock auto_lock(lock_);
374 key_pressed_ = true;
375 }
376
377 void AudioInputController::DoStopCloseAndClearStream( 356 void AudioInputController::DoStopCloseAndClearStream(
378 base::WaitableEvent* done) { 357 base::WaitableEvent *done) {
379 DCHECK(message_loop_->BelongsToCurrentThread()); 358 DCHECK(message_loop_->BelongsToCurrentThread());
380 359
381 // Allow calling unconditionally and bail if we don't have a stream to close. 360 // Allow calling unconditionally and bail if we don't have a stream to close.
382 if (stream_ != NULL) { 361 if (stream_ != NULL) {
383 stream_->Stop(); 362 stream_->Stop();
384 stream_->Close(); 363 stream_->Close();
385 stream_ = NULL; 364 stream_ = NULL;
386 } 365 }
387 366
388 // Should be last in the method, do not touch "this" from here on. 367 // Should be last in the method, do not touch "this" from here on.
389 if (done != NULL) 368 if (done != NULL)
390 done->Signal(); 369 done->Signal();
391 } 370 }
392 371
393 void AudioInputController::SetDataIsActive(bool enabled) { 372 void AudioInputController::SetDataIsActive(bool enabled) {
394 base::subtle::Release_Store(&data_is_active_, enabled); 373 base::subtle::Release_Store(&data_is_active_, enabled);
395 } 374 }
396 375
397 bool AudioInputController::GetDataIsActive() { 376 bool AudioInputController::GetDataIsActive() {
398 return (base::subtle::Acquire_Load(&data_is_active_) != false); 377 return (base::subtle::Acquire_Load(&data_is_active_) != false);
399 } 378 }
400 379
401 } // namespace media 380 } // namespace media
OLDNEW
« no previous file with comments | « trunk/src/media/audio/audio_input_controller.h ('k') | trunk/src/media/audio/audio_input_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698