Index: chromeos/audio/cras_audio_handler_unittest.cc |
diff --git a/chromeos/audio/cras_audio_handler_unittest.cc b/chromeos/audio/cras_audio_handler_unittest.cc |
index fa5dbc35ba60a5c266c49f4c1517455b8022c1ae..7472a7f16341c747967c360ef48862b287866090 100644 |
--- a/chromeos/audio/cras_audio_handler_unittest.cc |
+++ b/chromeos/audio/cras_audio_handler_unittest.cc |
@@ -4,9 +4,12 @@ |
#include "chromeos/audio/cras_audio_handler.h" |
+#include "base/bind.h" |
#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/run_loop.h" |
+#include "base/thread_task_runner_handle.h" |
#include "base/values.h" |
#include "chromeos/audio/audio_devices_pref_handler_stub.h" |
#include "chromeos/dbus/audio_node.h" |
@@ -343,6 +346,18 @@ class CrasAudioHandlerTest : public testing::Test { |
return num_active_nodes; |
} |
+ void SetActiveHDMIRediscover() { |
+ cras_audio_handler_->SetActiveHDMIOutoutRediscoveringIfNecessary(true); |
+ } |
+ |
+ void SetHDMIRediscoverGracePeriodDuration(int duration_in_ms) { |
+ cras_audio_handler_->SetHDMIRediscoverGracePeriodForTesting(duration_in_ms); |
+ } |
+ |
+ bool IsDuringHDMIRediscoverGracePeriod() { |
+ return cras_audio_handler_->hdmi_rediscovering(); |
+ } |
+ |
protected: |
base::MessageLoopForUI message_loop_; |
CrasAudioHandler* cras_audio_handler_; // Not owned. |
@@ -354,6 +369,46 @@ class CrasAudioHandlerTest : public testing::Test { |
DISALLOW_COPY_AND_ASSIGN(CrasAudioHandlerTest); |
}; |
+class HDMIRediscoverWaiter { |
+ public: |
+ HDMIRediscoverWaiter(CrasAudioHandlerTest* cras_audio_handler_test, |
+ int grace_period_duration_in_ms) |
+ : cras_audio_handler_test_(cras_audio_handler_test), |
+ grace_period_duration_in_ms_(grace_period_duration_in_ms) {} |
+ |
+ void WaitUntilTimeOut(int wait_duration_in_ms) { |
+ base::RunLoop run_loop; |
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
+ FROM_HERE, run_loop.QuitClosure(), |
+ base::TimeDelta::FromMilliseconds(wait_duration_in_ms)); |
+ run_loop.Run(); |
+ } |
+ |
+ void CheckHDMIRediscoverGracePeriodEnd(const base::Closure& quit_loop_func) { |
+ if (!cras_audio_handler_test_->IsDuringHDMIRediscoverGracePeriod()) { |
+ quit_loop_func.Run(); |
+ return; |
+ } |
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&HDMIRediscoverWaiter::CheckHDMIRediscoverGracePeriodEnd, |
+ base::Unretained(this), quit_loop_func), |
+ base::TimeDelta::FromMilliseconds(grace_period_duration_in_ms_ / 4)); |
+ } |
+ |
+ void WaitUntilHDMIRediscoverGracePeriodEnd() { |
+ base::RunLoop run_loop; |
+ CheckHDMIRediscoverGracePeriodEnd(run_loop.QuitClosure()); |
+ run_loop.Run(); |
+ } |
+ |
+ private: |
+ CrasAudioHandlerTest* cras_audio_handler_test_; // not owned |
+ int grace_period_duration_in_ms_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(HDMIRediscoverWaiter); |
+}; |
+ |
TEST_F(CrasAudioHandlerTest, InitializeWithOnlyDefaultAudioDevices) { |
AudioNodeList audio_nodes; |
audio_nodes.push_back(kInternalSpeaker); |
@@ -2493,4 +2548,53 @@ TEST_F(CrasAudioHandlerTest, ActiveNodeLostDuringLoginSession) { |
EXPECT_TRUE(headphone_resumed->active); |
} |
+// This test HDMI output rediscovering case in crbug.com/503667. |
+TEST_F(CrasAudioHandlerTest, HDMIOutputRediscover) { |
+ AudioNodeList audio_nodes; |
+ audio_nodes.push_back(kInternalSpeaker); |
+ audio_nodes.push_back(kHDMIOutput); |
+ SetUpCrasAudioHandler(audio_nodes); |
+ |
+ // Verify the HDMI device has been selected as the active output, and audio |
+ // output is not muted. |
+ AudioDevice active_output; |
+ EXPECT_TRUE( |
+ cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output)); |
+ EXPECT_EQ(kHDMIOutput.id, active_output.id); |
+ EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode()); |
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); |
+ EXPECT_FALSE(cras_audio_handler_->IsOutputMuted()); |
+ |
+ // Trigger HDMI rediscovering grace period, and remove the HDMI node. |
+ const int grace_period_in_ms = 200; |
+ SetHDMIRediscoverGracePeriodDuration(grace_period_in_ms); |
+ SetActiveHDMIRediscover(); |
+ AudioNodeList audio_nodes_lost_hdmi; |
+ audio_nodes_lost_hdmi.push_back(kInternalSpeaker); |
+ ChangeAudioNodes(audio_nodes_lost_hdmi); |
+ |
+ // Verify the active output is switched to internal speaker, it is not muted |
+ // by preference, but the system output is muted during the grace period. |
+ EXPECT_TRUE( |
+ cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output)); |
+ EXPECT_EQ(kInternalSpeaker.id, active_output.id); |
+ EXPECT_FALSE( |
+ cras_audio_handler_->IsOutputMutedForDevice(kInternalSpeaker.id)); |
+ EXPECT_TRUE(cras_audio_handler_->IsOutputMuted()); |
+ |
+ // Re-attach the HDMI device after a little delay. |
+ HDMIRediscoverWaiter waiter(this, grace_period_in_ms); |
+ waiter.WaitUntilTimeOut(grace_period_in_ms / 4); |
+ ChangeAudioNodes(audio_nodes); |
+ |
+ // After HDMI re-discover grace period, verify HDMI output is selected as the |
+ // active device and not muted. |
+ waiter.WaitUntilHDMIRediscoverGracePeriodEnd(); |
+ EXPECT_TRUE( |
+ cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output)); |
+ EXPECT_EQ(kHDMIOutput.id, active_output.id); |
+ EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode()); |
+ EXPECT_FALSE(cras_audio_handler_->IsOutputMuted()); |
+} |
+ |
} // namespace chromeos |