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

Side by Side Diff: chromeos/audio/cras_audio_handler.cc

Issue 1199413008: Work around for HDMI audio output rediscovering transistion loss. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changed to VLOG. Created 5 years, 5 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
« no previous file with comments | « chromeos/audio/cras_audio_handler.h ('k') | chromeos/audio/cras_audio_handler_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 VLOG(1) << "Mute the output during HDMI re-discovering grace period";
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
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 VLOG(1) << "HDMI output re-discover grace period ends.";
1014 hdmi_rediscovering_ = false;
1015 if (!IsOutputMutedForDevice(active_output_node_id_)) {
1016 // Unmute the audio output after the HDMI transition period.
1017 VLOG(1) << "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 VLOG(1) << "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
OLDNEW
« no previous file with comments | « chromeos/audio/cras_audio_handler.h ('k') | chromeos/audio/cras_audio_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698