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 10 matching lines...) Expand all Loading... | |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Default value for unmuting, as a percent in the range [0, 100]. | 24 // Default value for unmuting, as a percent in the range [0, 100]. |
25 // Used when sound is unmuted, but volume was less than kMuteThresholdPercent. | 25 // Used when sound is unmuted, but volume was less than kMuteThresholdPercent. |
26 const int kDefaultUnmuteVolumePercent = 4; | 26 const int kDefaultUnmuteVolumePercent = 4; |
27 | 27 |
28 // Volume value which should be considered as muted in range [0, 100]. | 28 // Volume value which should be considered as muted in range [0, 100]. |
29 const int kMuteThresholdPercent = 1; | 29 const int kMuteThresholdPercent = 1; |
30 | 30 |
31 // The duration of HDMI output re-discover grace period in milliseconds. | |
32 const int kHDMIRediscoverGracePeriodDurationInMs = 2000; | |
33 | |
31 static CrasAudioHandler* g_cras_audio_handler = NULL; | 34 static CrasAudioHandler* g_cras_audio_handler = NULL; |
32 | 35 |
33 bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) { | 36 bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) { |
34 return a.id == b.id && a.is_input == b.is_input && a.type == b.type | 37 return a.id == b.id && a.is_input == b.is_input && a.type == b.type |
35 && a.device_name == b.device_name; | 38 && a.device_name == b.device_name; |
36 } | 39 } |
37 | 40 |
38 bool IsInNodeList(uint64_t node_id, | 41 bool IsInNodeList(uint64_t node_id, |
39 const CrasAudioHandler::NodeIdList& id_list) { | 42 const CrasAudioHandler::NodeIdList& id_list) { |
40 return std::find(id_list.begin(), id_list.end(), node_id) != id_list.end(); | 43 return std::find(id_list.begin(), id_list.end(), node_id) != id_list.end(); |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 const AudioDevice* device = GetDeviceFromId(device_id); | 428 const AudioDevice* device = GetDeviceFromId(device_id); |
426 // Input device's mute state is not recorded in the pref. crbug.com/365050. | 429 // Input device's mute state is not recorded in the pref. crbug.com/365050. |
427 if (device && !device->is_input) | 430 if (device && !device->is_input) |
428 audio_pref_handler_->SetMuteValue(*device, mute_on); | 431 audio_pref_handler_->SetMuteValue(*device, mute_on); |
429 } | 432 } |
430 | 433 |
431 void CrasAudioHandler::LogErrors() { | 434 void CrasAudioHandler::LogErrors() { |
432 log_errors_ = true; | 435 log_errors_ = true; |
433 } | 436 } |
434 | 437 |
438 // If the HDMI device is the active output device, when the device enters/exits | |
439 // docking mode, or HDMI display changes resolution, or chromeos device | |
440 // suspends/resumes, cras will lose the HDMI output node for a short period of | |
441 // time, then rediscover it. This hotplug behavior will cause the audio output | |
442 // be leaked to the alternatvie active audio output during HDMI re-discovering | |
443 // period. See crbug.com/503667. | |
444 void CrasAudioHandler::SetActiveHDMIOutoutRediscoveringIfNecessary( | |
445 bool force_rediscovering) { | |
446 if (!GetDeviceFromId(active_output_node_id_)) | |
447 return; | |
448 | |
449 // Marks the start of the HDMI re-discovering grace period, during which we | |
450 // will mute the audio output to prevent it to be be leaked to the | |
451 // alternative output device. | |
452 if ((hdmi_rediscovering_ && force_rediscovering) || | |
453 (!hdmi_rediscovering_ && IsHDMIPrimaryOutputDevice())) { | |
454 StartHDMIRediscoverGracePeriod(); | |
455 } | |
456 } | |
457 | |
435 CrasAudioHandler::CrasAudioHandler( | 458 CrasAudioHandler::CrasAudioHandler( |
436 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler) | 459 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler) |
437 : audio_pref_handler_(audio_pref_handler), | 460 : audio_pref_handler_(audio_pref_handler), |
438 output_mute_on_(false), | 461 output_mute_on_(false), |
439 input_mute_on_(false), | 462 input_mute_on_(false), |
440 output_volume_(0), | 463 output_volume_(0), |
441 input_gain_(0), | 464 input_gain_(0), |
442 active_output_node_id_(0), | 465 active_output_node_id_(0), |
443 active_input_node_id_(0), | 466 active_input_node_id_(0), |
444 has_alternative_input_(false), | 467 has_alternative_input_(false), |
445 has_alternative_output_(false), | 468 has_alternative_output_(false), |
446 output_mute_locked_(false), | 469 output_mute_locked_(false), |
447 log_errors_(false), | 470 log_errors_(false), |
471 hdmi_rediscover_grace_period_duration_in_ms_( | |
472 kHDMIRediscoverGracePeriodDurationInMs), | |
473 hdmi_rediscovering_(false), | |
448 weak_ptr_factory_(this) { | 474 weak_ptr_factory_(this) { |
449 if (!audio_pref_handler.get()) | 475 if (!audio_pref_handler.get()) |
450 return; | 476 return; |
451 // If the DBusThreadManager or the CrasAudioClient aren't available, there | 477 // If the DBusThreadManager or the CrasAudioClient aren't available, there |
452 // isn't much we can do. This should only happen when running tests. | 478 // isn't much we can do. This should only happen when running tests. |
453 if (!chromeos::DBusThreadManager::IsInitialized() || | 479 if (!chromeos::DBusThreadManager::IsInitialized() || |
454 !chromeos::DBusThreadManager::Get() || | 480 !chromeos::DBusThreadManager::Get() || |
455 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) | 481 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) |
456 return; | 482 return; |
457 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->AddObserver(this); | 483 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->AddObserver(this); |
458 audio_pref_handler_->AddAudioPrefObserver(this); | 484 audio_pref_handler_->AddAudioPrefObserver(this); |
459 if (chromeos::DBusThreadManager::Get()->GetSessionManagerClient()) { | 485 if (chromeos::DBusThreadManager::Get()->GetSessionManagerClient()) { |
460 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> | 486 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> |
461 AddObserver(this); | 487 AddObserver(this); |
462 } | 488 } |
463 InitializeAudioState(); | 489 InitializeAudioState(); |
464 } | 490 } |
465 | 491 |
466 CrasAudioHandler::~CrasAudioHandler() { | 492 CrasAudioHandler::~CrasAudioHandler() { |
493 hdmi_rediscover_timer_.Stop(); | |
467 if (!chromeos::DBusThreadManager::IsInitialized() || | 494 if (!chromeos::DBusThreadManager::IsInitialized() || |
468 !chromeos::DBusThreadManager::Get() || | 495 !chromeos::DBusThreadManager::Get() || |
469 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) | 496 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) |
470 return; | 497 return; |
471 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 498 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
472 RemoveObserver(this); | 499 RemoveObserver(this); |
473 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> | 500 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> |
474 RemoveObserver(this); | 501 RemoveObserver(this); |
475 if (audio_pref_handler_.get()) | 502 if (audio_pref_handler_.get()) |
476 audio_pref_handler_->RemoveAudioPrefObserver(this); | 503 audio_pref_handler_->RemoveAudioPrefObserver(this); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 | 590 |
564 void CrasAudioHandler::SetupAudioOutputState() { | 591 void CrasAudioHandler::SetupAudioOutputState() { |
565 const AudioDevice* device = GetDeviceFromId(active_output_node_id_); | 592 const AudioDevice* device = GetDeviceFromId(active_output_node_id_); |
566 if (!device) { | 593 if (!device) { |
567 LOG_IF(ERROR, log_errors_) | 594 LOG_IF(ERROR, log_errors_) |
568 << "Can't set up audio state for unknown output device id =" | 595 << "Can't set up audio state for unknown output device id =" |
569 << "0x" << std::hex << active_output_node_id_; | 596 << "0x" << std::hex << active_output_node_id_; |
570 return; | 597 return; |
571 } | 598 } |
572 DCHECK(!device->is_input); | 599 DCHECK(!device->is_input); |
573 output_mute_on_ = audio_pref_handler_->GetMuteValue(*device); | 600 // Mute the output during HDMI re-discovering grace period. |
601 if (hdmi_rediscovering_ && !IsHDMIPrimaryOutputDevice()) { | |
602 LOG(WARNING) << "Mute the output during HDMI re-discovering grace period"; | |
stevenjb
2015/06/29 21:57:20
VLOG?
jennyz
2015/06/29 22:07:30
Done.
| |
603 output_mute_on_ = true; | |
604 } else { | |
605 output_mute_on_ = audio_pref_handler_->GetMuteValue(*device); | |
606 } | |
574 output_volume_ = audio_pref_handler_->GetOutputVolumeValue(device); | 607 output_volume_ = audio_pref_handler_->GetOutputVolumeValue(device); |
575 | 608 |
576 SetOutputMuteInternal(output_mute_on_); | 609 SetOutputMuteInternal(output_mute_on_); |
577 SetOutputNodeVolume(active_output_node_id_, output_volume_); | 610 SetOutputNodeVolume(active_output_node_id_, output_volume_); |
578 } | 611 } |
579 | 612 |
580 // This sets up the state of an additional active node. | 613 // This sets up the state of an additional active node. |
581 void CrasAudioHandler::SetupAdditionalActiveAudioNodeState(uint64_t node_id) { | 614 void CrasAudioHandler::SetupAdditionalActiveAudioNodeState(uint64_t node_id) { |
582 const AudioDevice* device = GetDeviceFromId(node_id); | 615 const AudioDevice* device = GetDeviceFromId(node_id); |
583 if (!device) { | 616 if (!device) { |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
969 if (node_id == active_output_node_id_) | 1002 if (node_id == active_output_node_id_) |
970 active_output_node_id_ = 0; | 1003 active_output_node_id_ = 0; |
971 chromeos::DBusThreadManager::Get() | 1004 chromeos::DBusThreadManager::Get() |
972 ->GetCrasAudioClient() | 1005 ->GetCrasAudioClient() |
973 ->RemoveActiveOutputNode(node_id); | 1006 ->RemoveActiveOutputNode(node_id); |
974 if (notify) | 1007 if (notify) |
975 NotifyActiveNodeChanged(false); | 1008 NotifyActiveNodeChanged(false); |
976 } | 1009 } |
977 } | 1010 } |
978 | 1011 |
1012 void CrasAudioHandler::UpdateAudioAfterHDMIRediscoverGracePeriod() { | |
1013 LOG(WARNING) << "HDMI output re-discover grace period ends."; | |
stevenjb
2015/06/29 21:57:20
VLOG here and below also?
jennyz
2015/06/29 22:07:30
Done.
| |
1014 hdmi_rediscovering_ = false; | |
1015 if (!IsOutputMutedForDevice(active_output_node_id_)) { | |
1016 // Unmute the audio output after the HDMI transition period. | |
1017 LOG(WARNING) << "Unmute output after HDMI rediscovring grace period."; | |
1018 SetOutputMuteInternal(false); | |
1019 } | |
1020 } | |
1021 | |
1022 bool CrasAudioHandler::IsHDMIPrimaryOutputDevice() const { | |
1023 const AudioDevice* device = GetDeviceFromId(active_output_node_id_); | |
1024 return (device && device->type == chromeos::AUDIO_TYPE_HDMI); | |
1025 } | |
1026 | |
1027 void CrasAudioHandler::StartHDMIRediscoverGracePeriod() { | |
1028 LOG(WARNING) << "Start HDMI rediscovering grace period."; | |
1029 hdmi_rediscovering_ = true; | |
1030 hdmi_rediscover_timer_.Stop(); | |
1031 hdmi_rediscover_timer_.Start( | |
1032 FROM_HERE, base::TimeDelta::FromMilliseconds( | |
1033 hdmi_rediscover_grace_period_duration_in_ms_), | |
1034 this, &CrasAudioHandler::UpdateAudioAfterHDMIRediscoverGracePeriod); | |
1035 } | |
1036 | |
1037 void CrasAudioHandler::SetHDMIRediscoverGracePeriodForTesting( | |
1038 int duration_in_ms) { | |
1039 hdmi_rediscover_grace_period_duration_in_ms_ = duration_in_ms; | |
1040 } | |
1041 | |
979 } // namespace chromeos | 1042 } // namespace chromeos |
OLD | NEW |