Skip to content

Commit

Permalink
Fix the issue where the active output device is lost after the device…
Browse files Browse the repository at this point in the history
… suspend/resume without any active stream.

BUG=478968

Review URL: https://codereview.chromium.org/1109793005

Cr-Commit-Position: refs/heads/master@{#327399}
  • Loading branch information
jennyz authored and Commit bot committed Apr 29, 2015
1 parent a3bcdda commit 3147abc
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 3 deletions.
9 changes: 6 additions & 3 deletions chromeos/audio/cras_audio_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -852,10 +852,13 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
}

// If the previous active device is removed from the new node list,
// reset active_output_node_id_.
if (!GetDeviceFromId(active_output_node_id_))
// or changed to inactive by cras, reset active_output_node_id_.
// See crbug.com/478968.
const AudioDevice* active_output = GetDeviceFromId(active_output_node_id_);
if (!active_output || !active_output->active)
active_output_node_id_ = 0;
if (!GetDeviceFromId(active_input_node_id_))
const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_);
if (!active_input || !active_input->active)
active_input_node_id_ = 0;

// If audio nodes change is caused by unplugging some non-active audio
Expand Down
64 changes: 64 additions & 0 deletions chromeos/audio/cras_audio_handler_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2429,4 +2429,68 @@ TEST_F(CrasAudioHandlerTest, HotPlugHDMINotChangeActiveOutput) {
cras_audio_handler_->GetPrimaryActiveOutputNode());
}

// Test the case in which the active device was set to inactive from cras after
// resuming from suspension state. See crbug.com/478968.
TEST_F(CrasAudioHandlerTest, ActiveNodeLostAfterResume) {
AudioNodeList audio_nodes;
EXPECT_FALSE(kHeadphone.active);
audio_nodes.push_back(kHeadphone);
EXPECT_FALSE(kHDMIOutput.active);
audio_nodes.push_back(kHDMIOutput);
SetUpCrasAudioHandler(audio_nodes);

// Verify the headphone is selected as the active output.
AudioDeviceList audio_devices;
cras_audio_handler_->GetAudioDevices(&audio_devices);
EXPECT_EQ(audio_nodes.size(), audio_devices.size());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
const AudioDevice* active_headphone = GetDeviceFromId(kHeadphone.id);
EXPECT_EQ(kHeadphone.id, active_headphone->id);
EXPECT_TRUE(active_headphone->active);

// Simulate NodesChanged signal with headphone turning into inactive state,
// and HDMI node removed.
audio_nodes.clear();
audio_nodes.push_back(kHeadphone);
ChangeAudioNodes(audio_nodes);

// Verify the headphone is set to active again.
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
const AudioDevice* headphone_resumed = GetDeviceFromId(kHeadphone.id);
EXPECT_EQ(kHeadphone.id, headphone_resumed->id);
EXPECT_TRUE(headphone_resumed->active);
}

// Test the case in which there are two NodesChanged signal for discovering
// output devices, and there is race between NodesChange and SetActiveOutput
// during this process. See crbug.com/478968.
TEST_F(CrasAudioHandlerTest, ActiveNodeLostDuringLoginSession) {
AudioNodeList audio_nodes;
EXPECT_FALSE(kHeadphone.active);
audio_nodes.push_back(kHeadphone);
SetUpCrasAudioHandler(audio_nodes);

// Verify the headphone is selected as the active output.
AudioDeviceList audio_devices;
cras_audio_handler_->GetAudioDevices(&audio_devices);
EXPECT_EQ(audio_nodes.size(), audio_devices.size());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
const AudioDevice* active_headphone = GetDeviceFromId(kHeadphone.id);
EXPECT_EQ(kHeadphone.id, active_headphone->id);
EXPECT_TRUE(active_headphone->active);

// Simulate NodesChanged signal with headphone turning into inactive state,
// and add a new HDMI output node.
audio_nodes.clear();
audio_nodes.push_back(kHeadphone);
audio_nodes.push_back(kHDMIOutput);
ChangeAudioNodes(audio_nodes);

// Verify the headphone is set to active again.
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
const AudioDevice* headphone_resumed = GetDeviceFromId(kHeadphone.id);
EXPECT_EQ(kHeadphone.id, headphone_resumed->id);
EXPECT_TRUE(headphone_resumed->active);
}

} // namespace chromeos

0 comments on commit 3147abc

Please sign in to comment.