OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chromeos/audio/cras_audio_handler.h" | 5 #include "chromeos/audio/cras_audio_handler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 } else if (device_id == active_input_node_id_) { | 281 } else if (device_id == active_input_node_id_) { |
282 SetInputMute(mute_on); | 282 SetInputMute(mute_on); |
283 return; | 283 return; |
284 } | 284 } |
285 | 285 |
286 AudioDevice device; | 286 AudioDevice device; |
287 if (const AudioDevice* device = GetDeviceFromId(device_id)) | 287 if (const AudioDevice* device = GetDeviceFromId(device_id)) |
288 audio_pref_handler_->SetMuteValue(*device, mute_on); | 288 audio_pref_handler_->SetMuteValue(*device, mute_on); |
289 } | 289 } |
290 | 290 |
| 291 void CrasAudioHandler::LogErrors() { |
| 292 log_errors_ = true; |
| 293 } |
| 294 |
291 CrasAudioHandler::CrasAudioHandler( | 295 CrasAudioHandler::CrasAudioHandler( |
292 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler) | 296 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler) |
293 : audio_pref_handler_(audio_pref_handler), | 297 : audio_pref_handler_(audio_pref_handler), |
294 weak_ptr_factory_(this), | 298 weak_ptr_factory_(this), |
295 output_mute_on_(false), | 299 output_mute_on_(false), |
296 input_mute_on_(false), | 300 input_mute_on_(false), |
297 output_volume_(0), | 301 output_volume_(0), |
298 input_gain_(0), | 302 input_gain_(0), |
299 active_output_node_id_(0), | 303 active_output_node_id_(0), |
300 active_input_node_id_(0), | 304 active_input_node_id_(0), |
301 has_alternative_input_(false), | 305 has_alternative_input_(false), |
302 has_alternative_output_(false), | 306 has_alternative_output_(false), |
303 output_mute_locked_(false), | 307 output_mute_locked_(false), |
304 input_mute_locked_(false) { | 308 input_mute_locked_(false), |
| 309 log_errors_(false) { |
305 if (!audio_pref_handler.get()) | 310 if (!audio_pref_handler.get()) |
306 return; | 311 return; |
307 // If the DBusThreadManager or the CrasAudioClient aren't available, there | 312 // If the DBusThreadManager or the CrasAudioClient aren't available, there |
308 // isn't much we can do. This should only happen when running tests. | 313 // isn't much we can do. This should only happen when running tests. |
309 if (!chromeos::DBusThreadManager::IsInitialized() || | 314 if (!chromeos::DBusThreadManager::IsInitialized() || |
310 !chromeos::DBusThreadManager::Get() || | 315 !chromeos::DBusThreadManager::Get() || |
311 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) | 316 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) |
312 return; | 317 return; |
313 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->AddObserver(this); | 318 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->AddObserver(this); |
314 audio_pref_handler_->AddAudioPrefObserver(this); | 319 audio_pref_handler_->AddAudioPrefObserver(this); |
| 320 if (chromeos::DBusThreadManager::Get()->GetSessionManagerClient()) { |
| 321 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> |
| 322 AddObserver(this); |
| 323 } |
315 InitializeAudioState(); | 324 InitializeAudioState(); |
316 } | 325 } |
317 | 326 |
318 CrasAudioHandler::~CrasAudioHandler() { | 327 CrasAudioHandler::~CrasAudioHandler() { |
319 if (!chromeos::DBusThreadManager::IsInitialized() || | 328 if (!chromeos::DBusThreadManager::IsInitialized() || |
320 !chromeos::DBusThreadManager::Get() || | 329 !chromeos::DBusThreadManager::Get() || |
321 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) | 330 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) |
322 return; | 331 return; |
323 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 332 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
324 RemoveObserver(this); | 333 RemoveObserver(this); |
| 334 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> |
| 335 RemoveObserver(this); |
325 if (audio_pref_handler_.get()) | 336 if (audio_pref_handler_.get()) |
326 audio_pref_handler_->RemoveAudioPrefObserver(this); | 337 audio_pref_handler_->RemoveAudioPrefObserver(this); |
327 audio_pref_handler_ = NULL; | 338 audio_pref_handler_ = NULL; |
328 } | 339 } |
329 | 340 |
330 void CrasAudioHandler::AudioClientRestarted() { | 341 void CrasAudioHandler::AudioClientRestarted() { |
| 342 // Make sure the logging is enabled in case cras server |
| 343 // restarts after crashing. |
| 344 LogErrors(); |
331 InitializeAudioState(); | 345 InitializeAudioState(); |
332 } | 346 } |
333 | 347 |
334 void CrasAudioHandler::NodesChanged() { | 348 void CrasAudioHandler::NodesChanged() { |
335 // Refresh audio nodes data. | 349 // Refresh audio nodes data. |
336 GetNodes(); | 350 GetNodes(); |
337 } | 351 } |
338 | 352 |
339 void CrasAudioHandler::ActiveOutputNodeChanged(uint64 node_id) { | 353 void CrasAudioHandler::ActiveOutputNodeChanged(uint64 node_id) { |
340 if (active_output_node_id_ == node_id) | 354 if (active_output_node_id_ == node_id) |
341 return; | 355 return; |
342 | 356 |
343 // Active audio output device should always be changed by chrome. | 357 // Active audio output device should always be changed by chrome. |
344 LOG(WARNING) << "Active output node changed unexpectedly by system node_id=" | 358 // During system boot, cras may change active input to unknown device 0x1, |
345 << "0x" << std::hex << node_id; | 359 // we don't need to log it, since it is not an valid device. |
| 360 if (GetDeviceFromId(node_id)) { |
| 361 LOG_IF(WARNING, log_errors_) |
| 362 << "Active output node changed unexpectedly by system node_id=" |
| 363 << "0x" << std::hex << node_id; |
| 364 } |
346 } | 365 } |
347 | 366 |
348 void CrasAudioHandler::ActiveInputNodeChanged(uint64 node_id) { | 367 void CrasAudioHandler::ActiveInputNodeChanged(uint64 node_id) { |
349 if (active_input_node_id_ == node_id) | 368 if (active_input_node_id_ == node_id) |
350 return; | 369 return; |
351 | 370 |
352 // Active audio input device should always be changed by chrome. | 371 // Active audio input device should always be changed by chrome. |
353 LOG(WARNING) << "Active input node changed unexpectedly by system node_id=" | 372 // During system boot, cras may change active input to unknown device 0x2, |
354 << "0x" << std::hex << node_id; | 373 // we don't need to log it, since it is not an valid device. |
| 374 if (GetDeviceFromId(node_id)) { |
| 375 LOG_IF(WARNING, log_errors_) |
| 376 << "Active input node changed unexpectedly by system node_id=" |
| 377 << "0x" << std::hex << node_id; |
| 378 } |
355 } | 379 } |
356 | 380 |
357 void CrasAudioHandler::OnAudioPolicyPrefChanged() { | 381 void CrasAudioHandler::OnAudioPolicyPrefChanged() { |
358 ApplyAudioPolicy(); | 382 ApplyAudioPolicy(); |
359 } | 383 } |
360 | 384 |
| 385 void CrasAudioHandler::EmitLoginPromptVisibleCalled() { |
| 386 // Enable logging after cras server is started, which will be after |
| 387 // EmitLoginPromptVisible. |
| 388 LogErrors(); |
| 389 } |
| 390 |
361 const AudioDevice* CrasAudioHandler::GetDeviceFromId(uint64 device_id) const { | 391 const AudioDevice* CrasAudioHandler::GetDeviceFromId(uint64 device_id) const { |
362 AudioDeviceMap::const_iterator it = audio_devices_.find(device_id); | 392 AudioDeviceMap::const_iterator it = audio_devices_.find(device_id); |
363 if (it == audio_devices_.end()) | 393 if (it == audio_devices_.end()) |
364 return NULL; | 394 return NULL; |
365 | 395 |
366 return &(it->second); | 396 return &(it->second); |
367 } | 397 } |
368 | 398 |
369 void CrasAudioHandler::SetupAudioInputState() { | 399 void CrasAudioHandler::SetupAudioInputState() { |
370 // Set the initial audio state to the ones read from audio prefs. | 400 // Set the initial audio state to the ones read from audio prefs. |
371 const AudioDevice* device = GetDeviceFromId(active_input_node_id_); | 401 const AudioDevice* device = GetDeviceFromId(active_input_node_id_); |
372 if (!device) { | 402 if (!device) { |
373 LOG(ERROR) << "Can't set up audio state for unknow input device id =" | 403 LOG_IF(ERROR, log_errors_) |
| 404 << "Can't set up audio state for unknown input device id =" |
374 << "0x" << std::hex << active_input_node_id_; | 405 << "0x" << std::hex << active_input_node_id_; |
375 return; | 406 return; |
376 } | 407 } |
377 input_mute_on_ = audio_pref_handler_->GetMuteValue(*device); | 408 input_mute_on_ = audio_pref_handler_->GetMuteValue(*device); |
378 input_gain_ = audio_pref_handler_->GetInputGainValue(device); | 409 input_gain_ = audio_pref_handler_->GetInputGainValue(device); |
379 SetInputMuteInternal(input_mute_on_); | 410 SetInputMuteInternal(input_mute_on_); |
380 // TODO(rkc,jennyz): Set input gain once we decide on how to store | 411 // TODO(rkc,jennyz): Set input gain once we decide on how to store |
381 // the gain values since the range and step are both device specific. | 412 // the gain values since the range and step are both device specific. |
382 } | 413 } |
383 | 414 |
384 void CrasAudioHandler::SetupAudioOutputState() { | 415 void CrasAudioHandler::SetupAudioOutputState() { |
385 const AudioDevice* device = GetDeviceFromId(active_output_node_id_); | 416 const AudioDevice* device = GetDeviceFromId(active_output_node_id_); |
386 if (!device) { | 417 if (!device) { |
387 LOG(ERROR) << "Can't set up audio state for unknow output device id =" | 418 LOG_IF(ERROR, log_errors_) |
388 << "0x" << std::hex << active_output_node_id_; | 419 << "Can't set up audio state for unknown output device id =" |
| 420 << "0x" << std::hex << active_output_node_id_; |
389 return; | 421 return; |
390 } | 422 } |
391 output_mute_on_ = audio_pref_handler_->GetMuteValue(*device); | 423 output_mute_on_ = audio_pref_handler_->GetMuteValue(*device); |
392 output_volume_ = audio_pref_handler_->GetOutputVolumeValue(device); | 424 output_volume_ = audio_pref_handler_->GetOutputVolumeValue(device); |
393 | 425 |
394 SetOutputMuteInternal(output_mute_on_); | 426 SetOutputMuteInternal(output_mute_on_); |
395 SetOutputNodeVolume(active_output_node_id_, output_volume_); | 427 SetOutputNodeVolume(active_output_node_id_, output_volume_); |
396 } | 428 } |
397 | 429 |
398 void CrasAudioHandler::InitializeAudioState() { | 430 void CrasAudioHandler::InitializeAudioState() { |
399 ApplyAudioPolicy(); | 431 ApplyAudioPolicy(); |
400 GetNodes(); | 432 GetNodes(); |
401 } | 433 } |
402 | 434 |
403 void CrasAudioHandler::ApplyAudioPolicy() { | 435 void CrasAudioHandler::ApplyAudioPolicy() { |
404 output_mute_locked_ = false; | 436 output_mute_locked_ = false; |
405 if (!audio_pref_handler_->GetAudioOutputAllowedValue()) { | 437 if (!audio_pref_handler_->GetAudioOutputAllowedValue()) { |
406 // Mute the device, but do not update the preference. | 438 // Mute the device, but do not update the preference. |
407 SetOutputMuteInternal(true); | 439 SetOutputMuteInternal(true); |
408 output_mute_locked_ = true; | 440 output_mute_locked_ = true; |
409 } else { | 441 } else { |
410 // Restore the mute state. | 442 // Restore the mute state. |
411 const AudioDevice* device = GetDeviceFromId(active_output_node_id_); | 443 const AudioDevice* device = GetDeviceFromId(active_output_node_id_); |
412 if (device) | 444 if (device) |
413 SetOutputMuteInternal(audio_pref_handler_->GetMuteValue(*device)); | 445 SetOutputMuteInternal(audio_pref_handler_->GetMuteValue(*device)); |
414 } | 446 } |
415 | 447 |
416 input_mute_locked_ = false; | 448 input_mute_locked_ = false; |
417 if (audio_pref_handler_->GetAudioCaptureAllowedValue()) { | 449 if (audio_pref_handler_->GetAudioCaptureAllowedValue()) { |
418 SetInputMute(false); | 450 // Set input mute if we have discovered active input device. |
| 451 const AudioDevice* device = GetDeviceFromId(active_input_node_id_); |
| 452 if (device) |
| 453 SetInputMuteInternal(false); |
419 } else { | 454 } else { |
420 SetInputMute(true); | 455 SetInputMute(true); |
421 input_mute_locked_ = true; | 456 input_mute_locked_ = true; |
422 } | 457 } |
423 } | 458 } |
424 | 459 |
425 void CrasAudioHandler::SetOutputNodeVolume(uint64 node_id, int volume) { | 460 void CrasAudioHandler::SetOutputNodeVolume(uint64 node_id, int volume) { |
426 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 461 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
427 SetOutputNodeVolume(node_id, volume); | 462 SetOutputNodeVolume(node_id, volume); |
428 } | 463 } |
(...skipping 19 matching lines...) Expand all Loading... |
448 | 483 |
449 input_mute_on_ = mute_on; | 484 input_mute_on_ = mute_on; |
450 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 485 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
451 SetInputMute(mute_on); | 486 SetInputMute(mute_on); |
452 return true; | 487 return true; |
453 } | 488 } |
454 | 489 |
455 void CrasAudioHandler::GetNodes() { | 490 void CrasAudioHandler::GetNodes() { |
456 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->GetNodes( | 491 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->GetNodes( |
457 base::Bind(&CrasAudioHandler::HandleGetNodes, | 492 base::Bind(&CrasAudioHandler::HandleGetNodes, |
| 493 weak_ptr_factory_.GetWeakPtr()), |
| 494 base::Bind(&CrasAudioHandler::HandleGetNodesError, |
458 weak_ptr_factory_.GetWeakPtr())); | 495 weak_ptr_factory_.GetWeakPtr())); |
459 } | 496 } |
460 | 497 |
461 bool CrasAudioHandler::ChangeActiveDevice(const AudioDevice& new_active_device, | 498 bool CrasAudioHandler::ChangeActiveDevice(const AudioDevice& new_active_device, |
462 uint64* current_active_node_id) { | 499 uint64* current_active_node_id) { |
463 // If the device we want to switch to is already the current active device, | 500 // If the device we want to switch to is already the current active device, |
464 // do nothing. | 501 // do nothing. |
465 if (new_active_device.active && | 502 if (new_active_device.active && |
466 new_active_device.id == *current_active_node_id) { | 503 new_active_device.id == *current_active_node_id) { |
467 return false; | 504 return false; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 audio_devices_.size(), | 616 audio_devices_.size(), |
580 active_output_node_id_) && | 617 active_output_node_id_) && |
581 !output_devices_pq_.empty()) { | 618 !output_devices_pq_.empty()) { |
582 SwitchToDevice(output_devices_pq_.top()); | 619 SwitchToDevice(output_devices_pq_.top()); |
583 } | 620 } |
584 } | 621 } |
585 | 622 |
586 void CrasAudioHandler::HandleGetNodes(const chromeos::AudioNodeList& node_list, | 623 void CrasAudioHandler::HandleGetNodes(const chromeos::AudioNodeList& node_list, |
587 bool success) { | 624 bool success) { |
588 if (!success) { | 625 if (!success) { |
589 LOG(ERROR) << "Failed to retrieve audio nodes data"; | 626 LOG_IF(ERROR, log_errors_) << "Failed to retrieve audio nodes data"; |
590 return; | 627 return; |
591 } | 628 } |
592 | 629 |
593 UpdateDevicesAndSwitchActive(node_list); | 630 UpdateDevicesAndSwitchActive(node_list); |
594 FOR_EACH_OBSERVER(AudioObserver, observers_, OnAudioNodesChanged()); | 631 FOR_EACH_OBSERVER(AudioObserver, observers_, OnAudioNodesChanged()); |
595 } | 632 } |
596 | 633 |
| 634 void CrasAudioHandler::HandleGetNodesError(const std::string& error_name, |
| 635 const std::string& error_msg) { |
| 636 LOG_IF(ERROR, log_errors_) << "Failed to call GetNodes: " |
| 637 << error_name << ": " << error_msg; |
| 638 } |
597 } // namespace chromeos | 639 } // namespace chromeos |
OLD | NEW |