Commit b47947f8 authored by jennyz's avatar jennyz Committed by Commit bot

Supports multiple active input/output audio nodes in CrasAudioHandler.

BUG=402072
TBR=xiyuan,jamescook

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

Cr-Commit-Position: refs/heads/master@{#296593}
parent 756a9d59
......@@ -26,7 +26,7 @@ int TrayAudioDelegateChromeOs::GetOutputVolumeLevel() {
int TrayAudioDelegateChromeOs::GetActiveOutputDeviceIconId() {
chromeos::AudioDevice device;
if (!CrasAudioHandler::Get()->GetActiveOutputDevice(&device))
if (!CrasAudioHandler::Get()->GetPrimaryActiveOutputDevice(&device))
return kNoAudioDeviceIcon;
if (device.type == chromeos::AUDIO_TYPE_HEADPHONE)
......
......@@ -1122,7 +1122,7 @@ void LoginDisplayHostImpl::SetOobeProgressBarVisible(bool visible) {
void LoginDisplayHostImpl::TryToPlayStartupSound() {
if (startup_sound_played_ || login_prompt_visible_time_.is_null() ||
!CrasAudioHandler::Get()->GetActiveOutputNode()) {
!CrasAudioHandler::Get()->GetPrimaryActiveOutputNode()) {
return;
}
......
......@@ -9,8 +9,6 @@
#include "base/strings/string_number_conversions.h"
#include "chromeos/audio/audio_device.h"
#include "chromeos/audio/cras_audio_handler.h"
#include "chromeos/dbus/cras_audio_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
......@@ -137,62 +135,12 @@ void AudioServiceImpl::SetActiveDevices(const DeviceIdList& device_list) {
if (!cras_audio_handler_)
return;
// De-activate all the nodes with RemoveActive{Input/Output}Node API. This is
// kind of hacky, but we don't know which set of nodes are active from
// CrasAudioHandler.
// TODO(rkc): Fix it in http://crbug.com/402072.
chromeos::AudioDeviceList devices;
cras_audio_handler_->GetAudioDevices(&devices);
for (size_t i = 0; i < devices.size(); ++i) {
if (devices[i].is_input) {
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->RemoveActiveInputNode(devices[i].id);
} else { // output
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->RemoveActiveOutputNode(devices[i].id);
}
}
cras_audio_handler_->RemoveAllActiveNodes();
bool input_device_set = false;
bool output_device_set = false;
std::string active_input_node_ids, active_output_node_ids;
for (size_t i = 0; i < device_list.size(); ++i) {
chromeos::AudioDevice device;
bool found = FindDevice(GetIdFromStr(device_list[i]), &device);
if (found) {
if (device.is_input) {
if (!input_device_set) {
cras_audio_handler_->SwitchToDevice(device);
input_device_set = true;
} else {
active_input_node_ids.push_back(device.id);
}
} else { // output device
if (!output_device_set) {
cras_audio_handler_->SwitchToDevice(device);
output_device_set = true;
} else {
active_output_node_ids.push_back(device.id);
}
}
}
}
// Once we have set our devices to active and all the inactive ones have been
// set correctly to inactive, go through our active devices again and set
// them to active using the AddActiveNode API.
// TODO(rkc):Fix this ugly hack in http://crbug.com/402072.
for (size_t i = 0; i < active_input_node_ids.size(); ++i) {
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->AddActiveInputNode(active_input_node_ids[i]);
}
for (size_t i = 0; i < active_output_node_ids.size(); ++i) {
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->AddActiveOutputNode(active_output_node_ids[i]);
if (FindDevice(GetIdFromStr(device_list[i]), &device))
cras_audio_handler_->AddActiveNode(device.id);
}
}
......
......@@ -170,11 +170,11 @@ int CrasAudioHandler::GetInputGainPercentForDevice(uint64 device_id) {
}
}
uint64 CrasAudioHandler::GetActiveOutputNode() const {
uint64 CrasAudioHandler::GetPrimaryActiveOutputNode() const {
return active_output_node_id_;
}
uint64 CrasAudioHandler::GetActiveInputNode() const {
uint64 CrasAudioHandler::GetPrimaryActiveInputNode() const {
return active_input_node_id_;
}
......@@ -185,7 +185,7 @@ void CrasAudioHandler::GetAudioDevices(AudioDeviceList* device_list) const {
device_list->push_back(it->second);
}
bool CrasAudioHandler::GetActiveOutputDevice(AudioDevice* device) const {
bool CrasAudioHandler::GetPrimaryActiveOutputDevice(AudioDevice* device) const {
const AudioDevice* active_device = GetDeviceFromId(active_output_node_id_);
if (!active_device || !device)
return false;
......@@ -197,12 +197,59 @@ void CrasAudioHandler::SetKeyboardMicActive(bool active) {
const AudioDevice* keyboard_mic = GetKeyboardMic();
if (!keyboard_mic)
return;
if (active) {
chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
AddActiveInputNode(keyboard_mic->id);
} else {
chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
RemoveActiveInputNode(keyboard_mic->id);
// Keyboard mic is invisible to chromeos users. It is always added or removed
// as additional active node.
DCHECK(active_input_node_id_ && active_input_node_id_ != keyboard_mic->id);
if (active)
AddActiveNode(keyboard_mic->id);
else
RemoveActiveNode(keyboard_mic->id);
}
void CrasAudioHandler::AddActiveNode(uint64 node_id) {
const AudioDevice* device = GetDeviceFromId(node_id);
if (!device) {
VLOG(1) << "AddActiveInputNode: Cannot find device id="
<< "0x" << std::hex << node_id;
return;
}
// If there is no primary active device, set |node_id| to primary active node.
if ((device->is_input && !active_input_node_id_) ||
(!device->is_input && !active_output_node_id_)) {
SwitchToDevice(*device);
return;
}
AddAdditionalActiveNode(node_id);
}
void CrasAudioHandler::RemoveActiveNode(uint64 node_id) {
const AudioDevice* device = GetDeviceFromId(node_id);
if (!device) {
VLOG(1) << "RemoveActiveInputNode: Cannot find device id="
<< "0x" << std::hex << node_id;
return;
}
// We do NOT allow to remove the primary active node.
if (device->is_input && device->id == active_input_node_id_) {
VLOG(1) << "Cannot remove the primary active input node: "
<< "0x" << std::hex << node_id;
return;
}
if (!device->is_input && device->id == active_output_node_id_) {
VLOG(1) << "Cannot remove the primary active output node: "
<< "0x" << std::hex << node_id;
return;
}
RemoveActiveNodeInternal(node_id);
}
void CrasAudioHandler::RemoveAllActiveNodes() {
for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
it != audio_devices_.end();
++it) {
RemoveActiveNodeInternal(it->second.id);
}
}
......@@ -215,29 +262,26 @@ bool CrasAudioHandler::has_alternative_output() const {
}
void CrasAudioHandler::SetOutputVolumePercent(int volume_percent) {
volume_percent = min(max(volume_percent, 0), 100);
if (volume_percent <= kMuteThresholdPercent)
volume_percent = 0;
output_volume_ = volume_percent;
if (const AudioDevice* device = GetDeviceFromId(active_output_node_id_))
audio_pref_handler_->SetVolumeGainValue(*device, output_volume_);
SetOutputNodeVolume(active_output_node_id_, output_volume_);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputVolumeChanged());
// Set all active devices to the same volume.
for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
it != audio_devices_.end();
it++) {
const AudioDevice& device = it->second;
if (!device.is_input && device.active)
SetOutputNodeVolumePercent(device.id, volume_percent);
}
}
// TODO: Rename the 'Percent' to something more meaningful.
void CrasAudioHandler::SetInputGainPercent(int gain_percent) {
// NOTE: We do not sanitize input gain values since the range is completely
// dependent on the device.
input_gain_ = gain_percent;
if (const AudioDevice* device = GetDeviceFromId(active_input_node_id_))
audio_pref_handler_->SetVolumeGainValue(*device, input_gain_);
SetInputNodeGain(active_input_node_id_, input_gain_);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputGainChanged());
// TODO(jennyz): Should we set all input devices' gain to the same level?
for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
it != audio_devices_.end();
it++) {
const AudioDevice& device = it->second;
if (device.is_input && device.active)
SetInputNodeGainPercent(active_input_node_id_, gain_percent);
}
}
void CrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) {
......@@ -248,9 +292,14 @@ void CrasAudioHandler::SetOutputMute(bool mute_on) {
if (!SetOutputMuteInternal(mute_on))
return;
if (const AudioDevice* device = GetDeviceFromId(active_output_node_id_)) {
DCHECK(!device->is_input);
audio_pref_handler_->SetMuteValue(*device, output_mute_on_);
// Save the mute state for all active output audio devices.
for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
it != audio_devices_.end();
it++) {
const AudioDevice& device = it->second;
if (!device.is_input && device.active) {
audio_pref_handler_->SetMuteValue(device, output_mute_on_);
}
}
FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputMuteChanged());
......@@ -285,22 +334,14 @@ void CrasAudioHandler::SetActiveInputNode(uint64 node_id) {
void CrasAudioHandler::SetVolumeGainPercentForDevice(uint64 device_id,
int value) {
if (device_id == active_output_node_id_) {
SetOutputVolumePercent(value);
return;
} else if (device_id == active_input_node_id_) {
SetInputGainPercent(value);
const AudioDevice* device = GetDeviceFromId(device_id);
if (!device)
return;
}
if (const AudioDevice* device = GetDeviceFromId(device_id)) {
if (!device->is_input) {
value = min(max(value, 0), 100);
if (value <= kMuteThresholdPercent)
value = 0;
}
audio_pref_handler_->SetVolumeGainValue(*device, value);
}
if (device->is_input)
SetInputNodeGainPercent(device_id, value);
else
SetOutputNodeVolumePercent(device_id, value);
}
void CrasAudioHandler::SetMuteForDevice(uint64 device_id, bool mute_on) {
......@@ -470,6 +511,29 @@ void CrasAudioHandler::SetupAudioOutputState() {
SetOutputNodeVolume(active_output_node_id_, output_volume_);
}
// This sets up the state of an additional active node.
void CrasAudioHandler::SetupAdditionalActiveAudioNodeState(uint64 node_id) {
const AudioDevice* device = GetDeviceFromId(node_id);
if (!device) {
VLOG(1) << "Can't set up audio state for unknown device id ="
<< "0x" << std::hex << node_id;
return;
}
DCHECK(node_id != active_output_node_id_ && node_id != active_input_node_id_);
// Note: The mute state is a system wide state, we don't set mute per device,
// but just keep the mute state consistent for the active node in prefs.
// The output volume should be set to the same value for all active output
// devices. For input devices, we don't restore their gain value so far.
// TODO(jennyz): crbug.com/417418, track the status for the decison if
// we should persist input gain value in prefs.
if (!device->is_input) {
audio_pref_handler_->SetMuteValue(*device, IsOutputMuted());
SetOutputNodeVolumePercent(node_id, GetOutputVolumePercent());
}
}
void CrasAudioHandler::InitializeAudioState() {
ApplyAudioPolicy();
GetNodes();
......@@ -506,6 +570,26 @@ void CrasAudioHandler::SetOutputNodeVolume(uint64 node_id, int volume) {
SetOutputNodeVolume(node_id, volume);
}
void CrasAudioHandler::SetOutputNodeVolumePercent(uint64 node_id,
int volume_percent) {
const AudioDevice* device = this->GetDeviceFromId(node_id);
if (!device || device->is_input)
return;
volume_percent = min(max(volume_percent, 0), 100);
if (volume_percent <= kMuteThresholdPercent)
volume_percent = 0;
if (node_id == active_output_node_id_)
output_volume_ = volume_percent;
audio_pref_handler_->SetVolumeGainValue(*device, volume_percent);
if (device->active) {
SetOutputNodeVolume(node_id, volume_percent);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputVolumeChanged());
}
}
bool CrasAudioHandler::SetOutputMuteInternal(bool mute_on) {
if (output_mute_locked_)
return false;
......@@ -521,12 +605,29 @@ void CrasAudioHandler::SetInputNodeGain(uint64 node_id, int gain) {
SetInputNodeGain(node_id, gain);
}
void CrasAudioHandler::SetInputNodeGainPercent(uint64 node_id,
int gain_percent) {
const AudioDevice* device = GetDeviceFromId(node_id);
if (!device || !device->is_input)
return;
// NOTE: We do not sanitize input gain values since the range is completely
// dependent on the device.
if (active_input_node_id_ == node_id)
input_gain_ = gain_percent;
audio_pref_handler_->SetVolumeGainValue(*device, gain_percent);
if (device->active) {
SetInputNodeGain(node_id, gain_percent);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputGainChanged());
}
}
bool CrasAudioHandler::SetInputMuteInternal(bool mute_on) {
if (input_mute_locked_)
return false;
VLOG(1) << "SetInputMuteInternal sets active input device id="
<< "0x" << std::hex << active_input_node_id_ << " mute=" << mute_on;
input_mute_on_ = mute_on;
chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
SetInputMute(mute_on);
......@@ -604,14 +705,14 @@ bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes,
++num_new_devices;
// Look to see if the new device not in the old device list.
AudioDevice device(*it);
if (FoundNewDevice(device))
if (FoundNewOrChangedDevice(device))
return true;
}
}
return num_old_devices != num_new_devices;
}
bool CrasAudioHandler::FoundNewDevice(const AudioDevice& device) {
bool CrasAudioHandler::FoundNewOrChangedDevice(const AudioDevice& device) {
const AudioDevice* device_found = GetDeviceFromId(device.id);
if (!device_found)
return true;
......@@ -621,51 +722,11 @@ bool CrasAudioHandler::FoundNewDevice(const AudioDevice& device) {
<< " new device: " << device.ToString()
<< " old device: " << device_found->ToString();
return true;
} else if (device.active != device_found->active) {
return true;
}
return false;
}
// Sanitize the audio node data. When a device is plugged in or unplugged, there
// should be only one NodesChanged signal from cras. However, we've observed
// the case that multiple NodesChanged signals being sent from cras. After the
// first NodesChanged being processed, chrome sets the active node properly.
// However, the NodesChanged received after the first one, can return stale
// nodes data in GetNodes call, the staled nodes data does not reflect the
// latest active node state. Since active audio node should only be set by
// chrome, the inconsistent data from cras could be the result of stale data
// described above and sanitized.
AudioDevice CrasAudioHandler::GetSanitizedAudioDevice(const AudioNode& node) {
AudioDevice device(node);
if (device.is_input) {
if (device.active && device.id != active_input_node_id_) {
LOG(WARNING) << "Stale audio device data, should not be active: "
<< " device = " << device.ToString()
<< " current active input node id = 0x" << std::hex
<< active_input_node_id_;
device.active = false;
} else if (device.id == active_input_node_id_ && !device.active) {
LOG(WARNING) << "Stale audio device data, should be active:"
<< " device = " << device.ToString()
<< " current active input node id = 0x" << std::hex
<< active_input_node_id_;
device.active = true;
}
} else {
if (device.active && device.id != active_output_node_id_) {
LOG(WARNING) << "Stale audio device data, should not be active: "
<< " device = " << device.ToString()
<< " current active output node id = 0x" << std::hex
<< active_output_node_id_;
device.active = false;
} else if (device.id == active_output_node_id_ && !device.active) {
LOG(WARNING) << "Stale audio device data, should be active:"
<< " device = " << device.ToString()
<< " current active output node id = 0x" << std::hex
<< active_output_node_id_;
device.active = true;
}
}
return device;
return false;
}
void CrasAudioHandler::UpdateDevicesAndSwitchActive(
......@@ -683,7 +744,7 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
output_devices_pq_.pop();
for (size_t i = 0; i < nodes.size(); ++i) {
AudioDevice device = GetSanitizedAudioDevice(nodes[i]);
AudioDevice device(nodes[i]);
audio_devices_[device.id] = device;
if (!has_alternative_input_ &&
......@@ -737,4 +798,57 @@ void CrasAudioHandler::HandleGetNodesError(const std::string& error_name,
LOG_IF(ERROR, log_errors_) << "Failed to call GetNodes: "
<< error_name << ": " << error_msg;
}
void CrasAudioHandler::AddAdditionalActiveNode(uint64 node_id) {
const AudioDevice* device = GetDeviceFromId(node_id);
if (!device) {
VLOG(1) << "AddActiveInputNode: Cannot find device id="
<< "0x" << std::hex << node_id;
return;
}
audio_devices_[node_id].active = true;
SetupAdditionalActiveAudioNodeState(node_id);
if (device->is_input) {
DCHECK(node_id != active_input_node_id_);
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->AddActiveInputNode(node_id);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveInputNodeChanged());
} else {
DCHECK(node_id != active_output_node_id_);
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->AddActiveOutputNode(node_id);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveOutputNodeChanged());
}
}
void CrasAudioHandler::RemoveActiveNodeInternal(uint64 node_id) {
const AudioDevice* device = GetDeviceFromId(node_id);
if (!device) {
VLOG(1) << "RemoveActiveInputNode: Cannot find device id="
<< "0x" << std::hex << node_id;
return;
}
audio_devices_[node_id].active = false;
if (device->is_input) {
if (node_id == active_input_node_id_)
active_input_node_id_ = 0;
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->RemoveActiveInputNode(node_id);
FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveInputNodeChanged());
} else {
if (node_id == active_output_node_id_)
active_output_node_id_ = 0;
chromeos::DBusThreadManager::Get()
->GetCrasAudioClient()
->RemoveActiveOutputNode(node_id);
}
FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveOutputNodeChanged());
}
} // namespace chromeos
......@@ -87,7 +87,7 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Returns true if keyboard mic exists.
virtual bool HasKeyboardMic();
// Returns true if audio output is muted.
// Returns true if audio output is muted for the system.
virtual bool IsOutputMuted();
// Returns true if audio output is muted for a device.
......@@ -119,31 +119,35 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Gets volume level in 0-100% range (0 being pure silence) for a device.
virtual int GetInputGainPercentForDevice(uint64 device_id);
// Returns node_id of the active output node.
virtual uint64 GetActiveOutputNode() const;
// Returns node_id of the primary active output node.
virtual uint64 GetPrimaryActiveOutputNode() const;
// Returns the node_id of the active input node.
virtual uint64 GetActiveInputNode() const;
// Returns the node_id of the primary active input node.
virtual uint64 GetPrimaryActiveInputNode() const;
// Gets the audio devices back in |device_list|.
virtual void GetAudioDevices(AudioDeviceList* device_list) const;
virtual bool GetActiveOutputDevice(AudioDevice* device) const;
virtual bool GetPrimaryActiveOutputDevice(AudioDevice* device) const;
// Whether there is alternative input/output audio device.
virtual bool has_alternative_input() const;
virtual bool has_alternative_output() const;
// Sets volume level to |volume_percent|, whose range is from 0-100%.
// Sets all active output devices' volume level to |volume_percent|, whose
// range is from 0-100%.
virtual void SetOutputVolumePercent(int volume_percent);
// Sets gain level to |gain_percent|, whose range is from 0-100%.
// Sets all active input devices' gain level to |gain_percent|, whose range is
// from 0-100%.
virtual void SetInputGainPercent(int gain_percent);
// Adjusts volume up (positive percentage) or down (negative percentage).
// Adjusts all active output devices' volume up (positive percentage) or down
// (negative percentage).
virtual void AdjustOutputVolumeByPercent(int adjust_by_percent);
// Adjusts output volume to a minimum audible level if it is too low.
// Adjusts all active output devices' volume to a minimum audible level if it
// is too low.
virtual void AdjustOutputVolumeToAudibleLevel();
// Mutes or unmutes audio output device.
......@@ -164,6 +168,22 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Activates or deactivates keyboard mic if there's one.
virtual void SetKeyboardMicActive(bool active);
// Adds an active node.
// If there is no active node, |node_id| will be switched to become the
// primary active node. Otherwise, it will be added as an additional active
// node.
virtual void AddActiveNode(uint64 node_id);
// Removes an active audio node.
// If |node_id| is the only active input/output node, or is an additional
// active input/output node, it will be removed and becomes inactive.
// Note: It is not proper call this api to remove the primary active node
// while there are additional active nodes.
virtual void RemoveActiveNode(uint64 node_id);
// Removes all active audio nodes, including the primary active ones.
virtual void RemoveAllActiveNodes();
// Enables error logging.
virtual void LogErrors();
......@@ -173,6 +193,8 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
virtual ~CrasAudioHandler();
private:
friend class CrasAudioHandlerTest;
// CrasAudioClient::Observer overrides.
virtual void AudioClientRestarted() OVERRIDE;
virtual void NodesChanged() OVERRIDE;
......@@ -194,6 +216,9 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
void SetupAudioInputState();
void SetupAudioOutputState();
// Sets up the additional active audio node's state.
void SetupAdditionalActiveAudioNodeState(uint64 node_id);
const AudioDevice* GetDeviceFromId(uint64 device_id) const;
const AudioDevice* GetKeyboardMic() const;
......@@ -208,6 +233,8 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Sets output volume of |node_id| to |volume|.
void SetOutputNodeVolume(uint64 node_id, int volume);
void SetOutputNodeVolumePercent(uint64 node_id, int volume_percent);
// Sets output mute state to |mute_on| internally, returns true if output mute
// is set.
bool SetOutputMuteInternal(bool mute_on);
......@@ -215,6 +242,8 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Sets input gain of |node_id| to |gain|.
void SetInputNodeGain(uint64 node_id, int gain);
void SetInputNodeGainPercent(uint64 node_id, int gain_percent);
// Sets input mute state to |mute_on| internally, returns true if input mute
// is set.
bool SetInputMuteInternal(bool mute_on);
......@@ -248,11 +277,15 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
void HandleGetNodesError(const std::string& error_name,
const std::string& error_msg);
// Returns true if |device| is not found in audio_devices_.
bool FoundNewDevice(const AudioDevice& device);
// Adds |node_id| into additional active nodes.
void AddAdditionalActiveNode(uint64 node_id);
// Removes |node_id| from additional active nodes.
void RemoveActiveNodeInternal(uint64 node_id);
// Returns a sanitized AudioDevice from |node|.
AudioDevice GetSanitizedAudioDevice(const AudioNode& node);
// Returns true if |device| is not found in audio_devices_, or it is found
// but changed its |active| property.
bool FoundNewOrChangedDevice(const AudioDevice& device);
scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_;
ObserverList<AudioObserver> observers_;
......
......@@ -264,12 +264,32 @@ class CrasAudioHandlerTest : public testing::Test {
message_loop_.RunUntilIdle();
}
void SetUpCrasAudioHandlerWithPrimaryActiveNode(
const AudioNodeList& audio_nodes,
const AudioNode& primary_active_node) {
DBusThreadManager::Initialize();
cras_audio_client_stub_ = static_cast<CrasAudioClientStubImpl*>(
DBusThreadManager::Get()->GetCrasAudioClient());
cras_audio_client_stub_->SetAudioNodesForTesting(audio_nodes);
cras_audio_client_stub_->SetActiveOutputNode(primary_active_node.id),
audio_pref_handler_ = new AudioDevicesPrefHandlerStub();
CrasAudioHandler::Initialize(audio_pref_handler_);
cras_audio_handler_ = CrasAudioHandler::Get();
test_observer_.reset(new TestObserver);
cras_audio_handler_->AddAudioObserver(test_observer_.get());
message_loop_.RunUntilIdle();
}
void ChangeAudioNodes(const AudioNodeList& audio_nodes) {
cras_audio_client_stub_->SetAudioNodesAndNotifyObserversForTesting(
audio_nodes);
message_loop_.RunUntilIdle();
}
const AudioDevice* GetDeviceFromId(uint64 id) {
return cras_audio_handler_->GetDeviceFromId(id);
}
protected:
base::MessageLoopForUI message_loop_;
CrasAudioHandler* cras_audio_handler_; // Not owned.
......@@ -294,14 +314,16 @@ TEST_F(CrasAudioHandlerTest, InitializeWithOnlyDefaultAudioDevices) {
// Verify the internal speaker has been selected as the active output.
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
// Ensure the internal microphone has been selected as the active input.
AudioDevice active_input;
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
}
......@@ -320,14 +342,15 @@ TEST_F(CrasAudioHandlerTest, InitializeWithAlternativeAudioDevices) {
// Verify the headphone has been selected as the active output.
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Ensure the USB microphone has been selected as the active input.
AudioDevice active_input;
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
}
......@@ -342,19 +365,57 @@ TEST_F(CrasAudioHandlerTest, InitializeWithKeyboardMic) {
AudioDeviceList audio_devices;
cras_audio_handler_->GetAudioDevices(&audio_devices);
EXPECT_EQ(audio_nodes.size(), audio_devices.size());
EXPECT_TRUE(cras_audio_handler_->HasKeyboardMic());
// Verify the internal speaker has been selected as the active output.
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
// Ensure the internal microphone has been selected as the active input,
// not affected by keyboard mic.
AudioDevice active_input;
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
const AudioDevice* keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
EXPECT_FALSE(keyboard_mic->active);
}
TEST_F(CrasAudioHandlerTest, SetKeyboardMicActive) {
AudioNodeList audio_nodes;
audio_nodes.push_back(kInternalMic);
audio_nodes.push_back(kKeyboardMic);
SetUpCrasAudioHandler(audio_nodes);
// Verify the audio devices size.
AudioDeviceList audio_devices;
cras_audio_handler_->GetAudioDevices(&audio_devices);
EXPECT_EQ(audio_nodes.size(), audio_devices.size());
EXPECT_TRUE(cras_audio_handler_->HasKeyboardMic());
// Ensure the internal microphone has been selected as the active input,
// not affected by keyboard mic.
AudioDevice active_input;
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
const AudioDevice* keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
EXPECT_FALSE(keyboard_mic->active);
// Make keyboard mic active.
cras_audio_handler_->SetKeyboardMicActive(true);
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
const AudioDevice* active_keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
EXPECT_TRUE(active_keyboard_mic->active);
// Make keyboard mic inactive.
cras_audio_handler_->SetKeyboardMicActive(false);
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
const AudioDevice* inactive_keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
EXPECT_FALSE(inactive_keyboard_mic->active);
}
TEST_F(CrasAudioHandlerTest, SwitchActiveOutputDevice) {
......@@ -369,9 +430,10 @@ TEST_F(CrasAudioHandlerTest, SwitchActiveOutputDevice) {
// Verify the initial active output device is headphone.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
// Switch the active output to internal speaker.
AudioDevice internal_speaker(kInternalSpeaker);
......@@ -380,9 +442,11 @@ TEST_F(CrasAudioHandlerTest, SwitchActiveOutputDevice) {
// Verify the active output is switched to internal speaker, and the
// ActiveOutputNodeChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
}
TEST_F(CrasAudioHandlerTest, SwitchActiveInputDevice) {
......@@ -396,7 +460,7 @@ TEST_F(CrasAudioHandlerTest, SwitchActiveInputDevice) {
// Verify the initial active input device is USB mic.
EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
// Switch the active input to internal mic.
AudioDevice internal_mic(kInternalMic);
......@@ -405,7 +469,7 @@ TEST_F(CrasAudioHandlerTest, SwitchActiveInputDevice) {
// Verify the active output is switched to internal speaker, and the active
// ActiveInputNodeChanged event is fired.
EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
}
TEST_F(CrasAudioHandlerTest, PlugHeadphone) {
......@@ -424,9 +488,11 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphone) {
// Verify the internal speaker has been selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
// Plug the headphone.
......@@ -445,9 +511,10 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphone) {
// Verify the active output device is switched to headphone and
// ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -468,9 +535,10 @@ TEST_F(CrasAudioHandlerTest, UnplugHeadphone) {
// Verify the headphone has been selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Unplug the headphone.
......@@ -487,9 +555,11 @@ TEST_F(CrasAudioHandlerTest, UnplugHeadphone) {
// Verify the active output device is switched to internal speaker and
// ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
}
......@@ -508,9 +578,11 @@ TEST_F(CrasAudioHandlerTest, InitializeWithBluetoothHeadset) {
// Verify the bluetooth headset has been selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kBluetoothHeadset.id, active_output.id);
EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kBluetoothHeadset.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -531,9 +603,10 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectBluetoothHeadset) {
// Verify the headphone is selected as the active output initially.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Connect to bluetooth headset. Since it is plugged in later than
......@@ -557,9 +630,11 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectBluetoothHeadset) {
// Verify the active output device is switched to bluetooth headset, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kBluetoothHeadset.id, active_output.id);
EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kBluetoothHeadset.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Disconnect bluetooth headset.
......@@ -578,9 +653,10 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectBluetoothHeadset) {
// Verify the active output device is switched to headphone, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -599,9 +675,10 @@ TEST_F(CrasAudioHandlerTest, InitializeWithHDMIOutput) {
// Verify the HDMI device has been selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHDMIOutput.id, active_output.id);
EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -621,9 +698,11 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectHDMIOutput) {
// Verify the internal speaker is selected as the active output initially.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
// Connect to HDMI output.
......@@ -645,9 +724,10 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectHDMIOutput) {
// Verify the active output device is switched to hdmi output, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHDMIOutput.id, active_output.id);
EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Disconnect hdmi headset.
......@@ -664,9 +744,11 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectHDMIOutput) {
// Verify the active output device is switched to internal speaker, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
}
......@@ -688,9 +770,10 @@ TEST_F(CrasAudioHandlerTest, HandleHeadphoneAndHDMIOutput) {
// Verify the headphone is selected as the active output initially.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Disconnect HDMI output.
......@@ -708,9 +791,10 @@ TEST_F(CrasAudioHandlerTest, HandleHeadphoneAndHDMIOutput) {
// Verify the active output device is switched to HDMI output, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHDMIOutput.id, active_output.id);
EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -729,9 +813,11 @@ TEST_F(CrasAudioHandlerTest, InitializeWithUSBHeadphone) {
// Verify the usb headphone has been selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone1.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -751,9 +837,11 @@ TEST_F(CrasAudioHandlerTest, PlugAndUnplugUSBHeadphone) {
// Verify the internal speaker is selected as the active output initially.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
// Plug in usb headphone
......@@ -775,9 +863,11 @@ TEST_F(CrasAudioHandlerTest, PlugAndUnplugUSBHeadphone) {
// Verify the active output device is switched to usb headphone, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone1.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Unplug usb headphone.
......@@ -794,9 +884,11 @@ TEST_F(CrasAudioHandlerTest, PlugAndUnplugUSBHeadphone) {
// Verify the active output device is switched to internal speaker, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
}
......@@ -817,9 +909,11 @@ TEST_F(CrasAudioHandlerTest, HandleMultipleUSBHeadphones) {
// Verify the usb headphone is selected as the active output initially.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone1.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Plug in another usb headphone.
......@@ -842,9 +936,11 @@ TEST_F(CrasAudioHandlerTest, HandleMultipleUSBHeadphones) {
// Verify the active output device is switched to the 2nd usb headphone, which
// is plugged later, and ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kUSBHeadphone2.id, active_output.id);
EXPECT_EQ(kUSBHeadphone2.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone2.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Unplug the 2nd usb headphone.
......@@ -862,9 +958,11 @@ TEST_F(CrasAudioHandlerTest, HandleMultipleUSBHeadphones) {
// Verify the active output device is switched to the first usb headphone, and
// ActiveOutputChanged event is fired.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone1.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -885,9 +983,11 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBHeadphonesWithActiveSpeaker) {
// Verify the usb headphone is selected as the active output initially.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone1.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Plug in the headphone jack.
......@@ -910,9 +1010,10 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBHeadphonesWithActiveSpeaker) {
// Verify the active output device is switched to the headphone jack, which
// is plugged later, and ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Select the speaker to be the active output device.
......@@ -922,9 +1023,11 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBHeadphonesWithActiveSpeaker) {
// Verify the active output is switched to internal speaker, and the
// ActiveOutputNodeChanged event is fired.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
// Unplug the usb headphone.
audio_nodes.clear();
......@@ -944,9 +1047,11 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBHeadphonesWithActiveSpeaker) {
// Verify the active output device remains to be speaker.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
}
......@@ -966,7 +1071,7 @@ TEST_F(CrasAudioHandlerTest, OneActiveAudioOutputAfterLoginNewUserSession) {
AudioNode headphone_jack(kHeadphone);
headphone_jack.plugged_time = 80000000;
audio_nodes.push_back(headphone_jack);
SetUpCrasAudioHandler(audio_nodes);
SetUpCrasAudioHandlerWithPrimaryActiveNode(audio_nodes, bluetooth_headphone);
const size_t init_nodes_size = audio_nodes.size();
// Verify the audio devices size.
......@@ -979,9 +1084,10 @@ TEST_F(CrasAudioHandlerTest, OneActiveAudioOutputAfterLoginNewUserSession) {
// audio devices are not active.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kHeadphone.id, active_output.id);
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
for (size_t i = 0; i < audio_devices.size(); ++i) {
if (audio_devices[i].id != kHeadphone.id)
......@@ -1007,9 +1113,11 @@ TEST_F(CrasAudioHandlerTest, BluetoothSpeakerIdChangedOnFly) {
// audio devices are not active.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kBluetoothHeadset.id, active_output.id);
EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kBluetoothHeadset.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Cras changes the bluetooth headset's id on the fly.
......@@ -1034,7 +1142,8 @@ TEST_F(CrasAudioHandlerTest, BluetoothSpeakerIdChangedOnFly) {
// Verify ActiveOutputNodeChanged event is fired, and active device should be
// bluetooth headphone.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(bluetooth_headphone.id, active_output.id);
}
......@@ -1053,7 +1162,7 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMic) {
// Verify the internal mic is selected as the active input.
EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
// Plug the USB Mic.
......@@ -1072,7 +1181,7 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMic) {
// Verify the active input device is switched to USB mic and
// and ActiveInputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
}
......@@ -1092,7 +1201,7 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBMic) {
// Verify the USB mic is selected as the active output.
EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
// Unplug the USB Mic.
......@@ -1109,7 +1218,7 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBMic) {
// Verify the active input device is switched to internal mic, and
// and ActiveInputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
}
......@@ -1130,12 +1239,12 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMicNotAffectActiveOutput) {
// Verify the internal mic is selected as the active input.
EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
// Verify the headphone is selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kHeadphoneId, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphoneId, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Switch the active output to internal speaker.
......@@ -1146,9 +1255,11 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMicNotAffectActiveOutput) {
// ActiveOutputNodeChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
// Plug the USB Mic.
audio_nodes.clear();
......@@ -1170,14 +1281,16 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMicNotAffectActiveOutput) {
// Verify the active input device is switched to USB mic, and
// and ActiveInputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
// Verify the active output device is not changed.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
}
TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
......@@ -1197,12 +1310,13 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
// Verify the internal mic is selected as the active input.
EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
// Verify the USB headphone is selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kUSBHeadphoneId1, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphoneId1,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Plug the headphone and auto-unplug internal speaker.
......@@ -1226,7 +1340,7 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
// Verify the active output device is switched to headphone, and
// an ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Unplug the headphone and internal speaker auto-plugs back.
......@@ -1246,12 +1360,13 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
// Verify the active output device is switched back to USB, and
// an ActiveOutputChanged event is fired.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone1.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Verify the active input device is not changed.
EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
}
TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
......@@ -1272,12 +1387,13 @@ TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
// Verify the internal mic is selected as the active input.
EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
// Verify the internal speaker is selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kUSBHeadphoneId1, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphoneId1,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Plug the headphone and mic, auto-unplug internal mic and speaker.
......@@ -1304,13 +1420,13 @@ TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
// Verify the active output device is switched to headphone, and
// an ActiveOutputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Verify the active input device is switched to mic jack, and
// an ActiveInputChanged event is fired.
EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kMicJack.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kMicJack.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
// Unplug the headphone and internal speaker auto-plugs back.
......@@ -1333,13 +1449,14 @@ TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
// Verify the active output device is switched back to USB, and
// an ActiveOutputChanged event is fired.
EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kUSBHeadphone1.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Verify the active input device is switched back to USB mic, and
// an ActiveInputChanged event is fired.
EXPECT_EQ(2, test_observer_->active_input_node_changed_count());
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
}
......@@ -1359,9 +1476,11 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInHeadphone) {
// Verify the bluetooth headset is selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kBluetoothHeadsetId, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kBluetoothHeadsetId,
cras_audio_handler_->GetPrimaryActiveOutputNode());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Plug in headphone, but fire NodesChanged signal twice.
......@@ -1380,9 +1499,10 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInHeadphone) {
// Verify the active output device is set to headphone.
EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_EQ(headphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_LE(1, test_observer_->active_output_node_changed_count());
EXPECT_EQ(headphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(headphone.id, active_output.id);
// Verfiy the audio devices data is consistent, i.e., the active output device
......@@ -1416,7 +1536,7 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInUSBMic) {
// Verify the internal mic is selected as the active output.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
EXPECT_TRUE(audio_devices[0].active);
......@@ -1435,8 +1555,8 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInUSBMic) {
// Verify the active output device is set to headphone.
EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
EXPECT_EQ(usb_mic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_LE(1, test_observer_->active_input_node_changed_count());
EXPECT_EQ(usb_mic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
// Verfiy the audio devices data is consistent, i.e., the active input device
......@@ -1476,14 +1596,15 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnSystemBoot) {
// Verify the active output device is set to headphone.
EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_EQ(headphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_LE(1, test_observer_->active_output_node_changed_count());
EXPECT_EQ(headphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(headphone.id, active_output.id);
// Verify the active input device id is set to internal mic.
EXPECT_EQ(internal_mic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(internal_mic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
// Verfiy the audio devices data is consistent, i.e., the active output device
// should be headphone, and the active input device should internal mic.
......@@ -1564,7 +1685,7 @@ TEST_F(CrasAudioHandlerTest, SetOutputVolumePercent) {
EXPECT_EQ(kVolume, cras_audio_handler_->GetOutputVolumePercent());
EXPECT_EQ(1, test_observer_->output_volume_changed_count());
AudioDevice device;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&device));
EXPECT_TRUE(cras_audio_handler_->GetPrimaryActiveOutputDevice(&device));
EXPECT_EQ(device.id, kInternalSpeaker.id);
EXPECT_EQ(kVolume, audio_pref_handler_->GetOutputVolumeValue(&device));
}
......@@ -1596,7 +1717,7 @@ TEST_F(CrasAudioHandlerTest, SetMuteForDevice) {
SetUpCrasAudioHandler(audio_nodes);
// Mute the active output device.
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
cras_audio_handler_->SetMuteForDevice(kHeadphone.id, true);
// Verify the headphone is muted and mute value is saved in the preferences.
......@@ -1614,7 +1735,7 @@ TEST_F(CrasAudioHandlerTest, SetMuteForDevice) {
EXPECT_TRUE(audio_pref_handler_->GetMuteValue(internal_speaker));
// Mute the active input device.
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
cras_audio_handler_->SetMuteForDevice(kUSBMic.id, true);
// Verify the USB Mic is muted.
......@@ -1637,7 +1758,7 @@ TEST_F(CrasAudioHandlerTest, SetVolumeGainPercentForDevice) {
// Set volume percent for active output device.
const int kHeadphoneVolume = 30;
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
cras_audio_handler_->SetVolumeGainPercentForDevice(kHeadphone.id,
kHeadphoneVolume);
......@@ -1664,7 +1785,7 @@ TEST_F(CrasAudioHandlerTest, SetVolumeGainPercentForDevice) {
// Set gain percent for active input device.
const int kUSBMicGain = 30;
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
cras_audio_handler_->SetVolumeGainPercentForDevice(kUSBMic.id,
kUSBMicGain);
......@@ -1706,16 +1827,114 @@ TEST_F(CrasAudioHandlerTest, HandleOtherDeviceType) {
// Verify the internal speaker has been selected as the active output,
// and the output device with some randown unknown type is handled gracefully.
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
EXPECT_EQ(kInternalSpeaker.id, active_output.id);
EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_EQ(kInternalSpeaker.id,
cras_audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Ensure the internal microphone has been selected as the active input,
// and the input device with some random unknown type is handled gracefully.
AudioDevice active_input;
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
}
TEST_F(CrasAudioHandlerTest, MultipleActiveNodes) {
AudioNodeList audio_nodes;
audio_nodes.push_back(kInternalSpeaker);
audio_nodes.push_back(kUSBHeadphone1);
audio_nodes.push_back(kUSBHeadphone2);
SetUpCrasAudioHandler(audio_nodes);
// Verify the audio devices size.
AudioDeviceList audio_devices;
cras_audio_handler_->GetAudioDevices(&audio_devices);
EXPECT_EQ(audio_nodes.size(), audio_devices.size());
// Verify only 1 node is selected as active node by CrasAudioHandler.
AudioDevice active_output;
EXPECT_TRUE(
cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
int num_active_nodes = 0;
for (size_t i = 0; i < audio_devices.size(); ++i) {
if (audio_devices[i].active)
++num_active_nodes;
}
EXPECT_EQ(1, num_active_nodes);
// Switch the active output to internal speaker and mute it.
const AudioDevice* internal_speaker = GetDeviceFromId(kInternalSpeaker.id);
cras_audio_handler_->SwitchToDevice(*internal_speaker);
cras_audio_handler_->SetOutputMute(true);
EXPECT_TRUE(cras_audio_handler_->IsOutputMutedForDevice(kInternalSpeaker.id));
// Remove all active nodes.
cras_audio_handler_->RemoveAllActiveNodes();
// Verify there is no active nodes.
num_active_nodes = 0;
cras_audio_handler_->GetAudioDevices(&audio_devices);
for (size_t i = 0; i < audio_devices.size(); ++i) {
if (audio_devices[i].active)
++num_active_nodes;
}
EXPECT_EQ(0, num_active_nodes);
// Adds both USB headphones to active nodes.
cras_audio_handler_->AddActiveNode(kUSBHeadphone1.id);
cras_audio_handler_->AddActiveNode(kUSBHeadphone2.id);
// Verify both USB headphone nodes are made active.
num_active_nodes = 0;
cras_audio_handler_->GetAudioDevices(&audio_devices);
for (size_t i = 0; i < audio_devices.size(); ++i) {
if (audio_devices[i].active)
++num_active_nodes;
}
EXPECT_EQ(2, num_active_nodes);
const AudioDevice* active_device_1 = GetDeviceFromId(kUSBHeadphone1.id);
EXPECT_TRUE(active_device_1->active);
const AudioDevice* active_device_2 = GetDeviceFromId(kUSBHeadphone2.id);
EXPECT_TRUE(active_device_2->active);
AudioDevice primary_active_device;
EXPECT_TRUE(cras_audio_handler_->GetPrimaryActiveOutputDevice(
&primary_active_device));
EXPECT_EQ(kUSBHeadphone1.id, primary_active_device.id);
// Verify all active devices are the not muted and their volume values are
// the same.
EXPECT_FALSE(cras_audio_handler_->IsOutputMuted());
EXPECT_FALSE(cras_audio_handler_->IsOutputMutedForDevice(kUSBHeadphone1.id));
EXPECT_FALSE(cras_audio_handler_->IsOutputMutedForDevice(kUSBHeadphone2.id));
EXPECT_EQ(
cras_audio_handler_->GetOutputVolumePercent(),
cras_audio_handler_->GetOutputVolumePercentForDevice(kUSBHeadphone1.id));
EXPECT_EQ(
cras_audio_handler_->GetOutputVolumePercent(),
cras_audio_handler_->GetOutputVolumePercentForDevice(kUSBHeadphone2.id));
// Adjust the volume of output devices, verify all active nodes are set to
// the same volume.
cras_audio_handler_->SetOutputVolumePercent(25);
EXPECT_EQ(25, cras_audio_handler_->GetOutputVolumePercent());
EXPECT_EQ(
25,
cras_audio_handler_->GetOutputVolumePercentForDevice(kUSBHeadphone1.id));
EXPECT_EQ(
25,
cras_audio_handler_->GetOutputVolumePercentForDevice(kUSBHeadphone2.id));
// Add one more active node that is previously muted, verify it is not muted
// after made active, and set to the same volume as the rest of the active
// nodes.
cras_audio_handler_->AddActiveNode(kInternalSpeaker.id);
EXPECT_FALSE(
cras_audio_handler_->IsOutputMutedForDevice(kInternalSpeaker.id));
EXPECT_EQ(25,
cras_audio_handler_->GetOutputVolumePercentForDevice(
kInternalSpeaker.id));
}
} // namespace chromeos
......@@ -116,13 +116,13 @@ void ShellAudioController::ActivateDevices() {
best_output = it->id;
}
if (best_input && best_input != handler->GetActiveInputNode()) {
if (best_input && best_input != handler->GetPrimaryActiveInputNode()) {
const chromeos::AudioDevice* device = GetDevice(devices, best_input);
DCHECK(device);
VLOG(1) << "Activating input device: " << device->ToString();
handler->SwitchToDevice(*device);
}
if (best_output && best_output != handler->GetActiveOutputNode()) {
if (best_output && best_output != handler->GetPrimaryActiveOutputNode()) {
const chromeos::AudioDevice* device = GetDevice(devices, best_output);
DCHECK(device);
VLOG(1) << "Activating output device: " << device->ToString();
......
......@@ -97,8 +97,8 @@ TEST_F(ShellAudioControllerTest, SelectBestDevices) {
all_nodes.push_back(headphone);
all_nodes.push_back(external_mic);
audio_client_->SetAudioNodesAndNotifyObserversForTesting(all_nodes);
EXPECT_EQ(headphone.id, audio_handler_->GetActiveOutputNode());
EXPECT_EQ(external_mic.id, audio_handler_->GetActiveInputNode());
EXPECT_EQ(headphone.id, audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_EQ(external_mic.id, audio_handler_->GetPrimaryActiveInputNode());
// Unplug the headphones and mic and check that we switch to the internal
// devices.
......@@ -106,16 +106,16 @@ TEST_F(ShellAudioControllerTest, SelectBestDevices) {
internal_nodes.push_back(internal_speaker);
internal_nodes.push_back(internal_mic);
audio_client_->SetAudioNodesAndNotifyObserversForTesting(internal_nodes);
EXPECT_EQ(internal_speaker.id, audio_handler_->GetActiveOutputNode());
EXPECT_EQ(internal_mic.id, audio_handler_->GetActiveInputNode());
EXPECT_EQ(internal_speaker.id, audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_EQ(internal_mic.id, audio_handler_->GetPrimaryActiveInputNode());
// Switch back to the external devices. Mark the previously-activated internal
// devices as being active so CrasAudioHandler doesn't complain.
SetNodeActive(&all_nodes, internal_speaker.id, true);
SetNodeActive(&all_nodes, internal_mic.id, true);
audio_client_->SetAudioNodesAndNotifyObserversForTesting(all_nodes);
EXPECT_EQ(headphone.id, audio_handler_->GetActiveOutputNode());
EXPECT_EQ(external_mic.id, audio_handler_->GetActiveInputNode());
EXPECT_EQ(headphone.id, audio_handler_->GetPrimaryActiveOutputNode());
EXPECT_EQ(external_mic.id, audio_handler_->GetPrimaryActiveInputNode());
}
// Tests that active audio devices are unmuted and set to 100% volume.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment