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

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

Issue 22801007: Adds the UserInputMonitor implementation for Mac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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
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"
11 #include "media/base/user_input_monitor.h"
11 12
12 namespace { 13 namespace {
13 const int kMaxInputChannels = 2; 14 const int kMaxInputChannels = 2;
14 15
15 // TODO(henrika): remove usage of timers and add support for proper 16 // TODO(henrika): remove usage of timers and add support for proper
16 // notification of when the input device is removed. This was originally added 17 // notification of when the input device is removed. This was originally added
17 // to resolve http://crbug.com/79936 for Windows platforms. This then caused 18 // to resolve http://crbug.com/79936 for Windows platforms. This then caused
18 // breakage (very hard to repro bugs!) on other platforms: See 19 // breakage (very hard to repro bugs!) on other platforms: See
19 // http://crbug.com/226327 and http://crbug.com/230972. 20 // http://crbug.com/226327 and http://crbug.com/230972.
20 const int kTimerResetIntervalSeconds = 1; 21 const int kTimerResetIntervalSeconds = 1;
(...skipping 18 matching lines...) Expand all
39 SyncWriter* sync_writer, 40 SyncWriter* sync_writer,
40 UserInputMonitor* user_input_monitor) 41 UserInputMonitor* user_input_monitor)
41 : creator_loop_(base::MessageLoopProxy::current()), 42 : creator_loop_(base::MessageLoopProxy::current()),
42 handler_(handler), 43 handler_(handler),
43 stream_(NULL), 44 stream_(NULL),
44 data_is_active_(false), 45 data_is_active_(false),
45 state_(kEmpty), 46 state_(kEmpty),
46 sync_writer_(sync_writer), 47 sync_writer_(sync_writer),
47 max_volume_(0.0), 48 max_volume_(0.0),
48 user_input_monitor_(user_input_monitor), 49 user_input_monitor_(user_input_monitor),
49 key_pressed_(false) { 50 prev_key_down_count_(0) {
50 DCHECK(creator_loop_.get()); 51 DCHECK(creator_loop_.get());
51 } 52 }
52 53
53 AudioInputController::~AudioInputController() { 54 AudioInputController::~AudioInputController() {
54 DCHECK(kClosed == state_ || kCreated == state_ || kEmpty == state_); 55 DCHECK(kClosed == state_ || kCreated == state_ || kEmpty == state_);
55 } 56 }
56 57
57 // static 58 // static
58 scoped_refptr<AudioInputController> AudioInputController::Create( 59 scoped_refptr<AudioInputController> AudioInputController::Create(
59 AudioManager* audio_manager, 60 AudioManager* audio_manager,
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 235
235 if (no_data_timer_) { 236 if (no_data_timer_) {
236 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, 237 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed,
237 // a callback to DoCheckForNoData() is made. 238 // a callback to DoCheckForNoData() is made.
238 no_data_timer_->Reset(); 239 no_data_timer_->Reset();
239 } 240 }
240 241
241 stream_->Start(this); 242 stream_->Start(this);
242 handler_->OnRecording(this); 243 handler_->OnRecording(this);
243 244
244 if (user_input_monitor_) 245 if (user_input_monitor_) {
245 user_input_monitor_->AddKeyStrokeListener(this); 246 user_input_monitor_->EnableKeyPressMonitoring();
247 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount();
248 }
246 } 249 }
247 250
248 void AudioInputController::DoClose() { 251 void AudioInputController::DoClose() {
249 DCHECK(message_loop_->BelongsToCurrentThread()); 252 DCHECK(message_loop_->BelongsToCurrentThread());
250 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 253 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
251 254
252 // Delete the timer on the same thread that created it. 255 // Delete the timer on the same thread that created it.
253 no_data_timer_.reset(); 256 no_data_timer_.reset();
254 257
255 if (state_ != kClosed) { 258 if (state_ != kClosed) {
256 DoStopCloseAndClearStream(NULL); 259 DoStopCloseAndClearStream(NULL);
257 SetDataIsActive(false); 260 SetDataIsActive(false);
258 261
259 if (LowLatencyMode()) { 262 if (LowLatencyMode()) {
260 sync_writer_->Close(); 263 sync_writer_->Close();
261 } 264 }
262 265
263 state_ = kClosed; 266 state_ = kClosed;
264 267
265 if (user_input_monitor_) 268 if (user_input_monitor_)
266 user_input_monitor_->RemoveKeyStrokeListener(this); 269 user_input_monitor_->DisableKeyPressMonitoring();
267 } 270 }
268 } 271 }
269 272
270 void AudioInputController::DoReportError() { 273 void AudioInputController::DoReportError() {
271 DCHECK(message_loop_->BelongsToCurrentThread()); 274 DCHECK(message_loop_->BelongsToCurrentThread());
272 handler_->OnError(this); 275 handler_->OnError(this);
273 } 276 }
274 277
275 void AudioInputController::DoSetVolume(double volume) { 278 void AudioInputController::DoSetVolume(double volume) {
276 DCHECK(message_loop_->BelongsToCurrentThread()); 279 DCHECK(message_loop_->BelongsToCurrentThread());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 // |kTimerResetIntervalSeconds|. 329 // |kTimerResetIntervalSeconds|.
327 no_data_timer_->Start( 330 no_data_timer_->Start(
328 FROM_HERE, base::TimeDelta::FromSeconds(kTimerResetIntervalSeconds), 331 FROM_HERE, base::TimeDelta::FromSeconds(kTimerResetIntervalSeconds),
329 base::Bind(&AudioInputController::DoCheckForNoData, 332 base::Bind(&AudioInputController::DoCheckForNoData,
330 base::Unretained(this))); 333 base::Unretained(this)));
331 } 334 }
332 335
333 void AudioInputController::OnData(AudioInputStream* stream, const uint8* data, 336 void AudioInputController::OnData(AudioInputStream* stream, const uint8* data,
334 uint32 size, uint32 hardware_delay_bytes, 337 uint32 size, uint32 hardware_delay_bytes,
335 double volume) { 338 double volume) {
336 bool key_pressed = false;
337 { 339 {
338 base::AutoLock auto_lock(lock_); 340 base::AutoLock auto_lock(lock_);
339 if (state_ != kRecording) 341 if (state_ != kRecording)
340 return; 342 return;
343 }
341 344
342 std::swap(key_pressed, key_pressed_); 345 bool key_pressed = false;
346 if (user_input_monitor_) {
347 size_t current_count = user_input_monitor_->GetKeyPressCount();
348 key_pressed = (current_count != prev_key_down_count_);
Mark Mentovai 2013/08/23 18:09:03 Outer (parentheses) are unnecessary.
349 prev_key_down_count_ = current_count;
343 } 350 }
344 351
345 // Mark data as active to ensure that the periodic calls to 352 // Mark data as active to ensure that the periodic calls to
346 // DoCheckForNoData() does not report an error to the event handler. 353 // DoCheckForNoData() does not report an error to the event handler.
347 SetDataIsActive(true); 354 SetDataIsActive(true);
348 355
349 // Use SyncSocket if we are in a low-latency mode. 356 // Use SyncSocket if we are in a low-latency mode.
350 if (LowLatencyMode()) { 357 if (LowLatencyMode()) {
351 sync_writer_->Write(data, size, volume, key_pressed); 358 sync_writer_->Write(data, size, volume, key_pressed);
352 sync_writer_->UpdateRecordedBytes(hardware_delay_bytes); 359 sync_writer_->UpdateRecordedBytes(hardware_delay_bytes);
353 return; 360 return;
354 } 361 }
355 362
356 handler_->OnData(this, data, size); 363 handler_->OnData(this, data, size);
357 } 364 }
358 365
359 void AudioInputController::OnClose(AudioInputStream* stream) { 366 void AudioInputController::OnClose(AudioInputStream* stream) {
360 DVLOG(1) << "AudioInputController::OnClose()"; 367 DVLOG(1) << "AudioInputController::OnClose()";
361 // TODO(satish): Sometimes the device driver closes the input stream without 368 // 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 369 // us asking for it (may be if the device was unplugged?). Check how to handle
363 // such cases here. 370 // such cases here.
364 } 371 }
365 372
366 void AudioInputController::OnError(AudioInputStream* stream) { 373 void AudioInputController::OnError(AudioInputStream* stream) {
367 // Handle error on the audio-manager thread. 374 // Handle error on the audio-manager thread.
368 message_loop_->PostTask(FROM_HERE, base::Bind( 375 message_loop_->PostTask(FROM_HERE, base::Bind(
369 &AudioInputController::DoReportError, this)); 376 &AudioInputController::DoReportError, this));
370 } 377 }
371 378
372 void AudioInputController::OnKeyStroke() {
373 base::AutoLock auto_lock(lock_);
374 key_pressed_ = true;
375 }
376
377 void AudioInputController::DoStopCloseAndClearStream( 379 void AudioInputController::DoStopCloseAndClearStream(
378 base::WaitableEvent* done) { 380 base::WaitableEvent* done) {
379 DCHECK(message_loop_->BelongsToCurrentThread()); 381 DCHECK(message_loop_->BelongsToCurrentThread());
380 382
381 // Allow calling unconditionally and bail if we don't have a stream to close. 383 // Allow calling unconditionally and bail if we don't have a stream to close.
382 if (stream_ != NULL) { 384 if (stream_ != NULL) {
383 stream_->Stop(); 385 stream_->Stop();
384 stream_->Close(); 386 stream_->Close();
385 stream_ = NULL; 387 stream_ = NULL;
386 } 388 }
387 389
388 // Should be last in the method, do not touch "this" from here on. 390 // Should be last in the method, do not touch "this" from here on.
389 if (done != NULL) 391 if (done != NULL)
390 done->Signal(); 392 done->Signal();
391 } 393 }
392 394
393 void AudioInputController::SetDataIsActive(bool enabled) { 395 void AudioInputController::SetDataIsActive(bool enabled) {
394 base::subtle::Release_Store(&data_is_active_, enabled); 396 base::subtle::Release_Store(&data_is_active_, enabled);
395 } 397 }
396 398
397 bool AudioInputController::GetDataIsActive() { 399 bool AudioInputController::GetDataIsActive() {
398 return (base::subtle::Acquire_Load(&data_is_active_) != false); 400 return (base::subtle::Acquire_Load(&data_is_active_) != false);
399 } 401 }
400 402
401 } // namespace media 403 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698