summaryrefslogtreecommitdiffstats
path: root/chromeos
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos')
-rw-r--r--chromeos/audio/audio_device.cc85
-rw-r--r--chromeos/audio/audio_device.h43
-rw-r--r--chromeos/audio/cras_audio_handler.cc49
-rw-r--r--chromeos/audio/cras_audio_handler.h14
-rw-r--r--chromeos/chromeos.gyp2
-rw-r--r--chromeos/dbus/cras_audio_client.cc67
6 files changed, 245 insertions, 15 deletions
diff --git a/chromeos/audio/audio_device.cc b/chromeos/audio/audio_device.cc
new file mode 100644
index 0000000..f41acda
--- /dev/null
+++ b/chromeos/audio/audio_device.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/audio/audio_device.h"
+
+#include "base/format_macros.h"
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+
+namespace {
+
+std::string GetTypeString(chromeos::AudioDeviceType type) {
+ if (type == chromeos::AUDIO_TYPE_INTERNAL)
+ return "INTERNAL";
+ else if (type == chromeos::AUDIO_TYPE_HEADPHONE)
+ return "HEADPHONE";
+ else if (type == chromeos::AUDIO_TYPE_USB)
+ return "USB";
+ else if (type == chromeos::AUDIO_TYPE_BLUETOOTH)
+ return "BLUETOOTH";
+ else if (type == chromeos::AUDIO_TYPE_HDMI)
+ return "HDMI";
+ else
+ return "OTHER";
+}
+
+chromeos::AudioDeviceType GetAudioType(const std::string& node_type) {
+ if (node_type.find("INTERNAL_") != std::string::npos)
+ return chromeos::AUDIO_TYPE_INTERNAL;
+ else if (node_type.find("HEADPHONE") != std::string::npos)
+ return chromeos::AUDIO_TYPE_HEADPHONE;
+ else if (node_type.find("USB") != std::string::npos)
+ return chromeos::AUDIO_TYPE_USB;
+ else if (node_type.find("BLUETOOTH") != std::string::npos)
+ return chromeos::AUDIO_TYPE_BLUETOOTH;
+ else if (node_type.find("HDMI") != std::string::npos)
+ return chromeos::AUDIO_TYPE_HDMI;
+ else
+ return chromeos::AUDIO_TYPE_OTHER;
+}
+
+} // namespace
+
+namespace chromeos {
+
+AudioDevice::AudioDevice()
+ : is_input(false),
+ id(0),
+ active(false) {
+}
+
+AudioDevice::AudioDevice(const AudioNode& node) {
+ is_input = node.is_input;
+ id = node.id;
+ type = GetAudioType(node.type);
+ if (!node.name.empty() && node.name != "(default)")
+ display_name = UTF8ToUTF16(node.name);
+ else
+ display_name = UTF8ToUTF16(node.device_name);
+ active = node.active;
+}
+
+std::string AudioDevice::ToString() const {
+ std::string result;
+ base::StringAppendF(&result,
+ "is_input = %s ",
+ is_input ? "true" : "false");
+ base::StringAppendF(&result,
+ "id = %"PRIu64" ",
+ id);
+ base::StringAppendF(&result,
+ "display_name = %s ",
+ UTF16ToUTF8(display_name).c_str());
+ base::StringAppendF(&result,
+ "type = %s ",
+ GetTypeString(type).c_str());
+ base::StringAppendF(&result,
+ "active = %s ",
+ active ? "true" : "false");
+
+ return result;
+}
+
+} // namespace chromeos
diff --git a/chromeos/audio/audio_device.h b/chromeos/audio/audio_device.h
new file mode 100644
index 0000000..891f030
--- /dev/null
+++ b/chromeos/audio/audio_device.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_AUDIO_AUDIO_DEVICE_H_
+#define CHROMEOS_AUDIO_AUDIO_DEVICE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/string16.h"
+#include "chromeos/chromeos_export.h"
+#include "chromeos/dbus/audio_node.h"
+
+namespace chromeos {
+
+enum AudioDeviceType {
+ AUDIO_TYPE_INTERNAL,
+ AUDIO_TYPE_HEADPHONE,
+ AUDIO_TYPE_USB,
+ AUDIO_TYPE_BLUETOOTH,
+ AUDIO_TYPE_HDMI,
+ AUDIO_TYPE_OTHER,
+};
+
+struct CHROMEOS_EXPORT AudioDevice {
+ bool is_input;
+ uint64 id;
+ base::string16 display_name;
+ AudioDeviceType type;
+ bool active;
+
+ AudioDevice();
+ explicit AudioDevice(const AudioNode& node);
+ std::string ToString() const;
+};
+
+typedef std::vector<AudioDevice> AudioDeviceList;
+
+} // namespace chromeos
+
+#endif // CHROMEOS_AUDIO_AUDIO_DEVICE_H_
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc
index e5bcec7..9666cc1 100644
--- a/chromeos/audio/cras_audio_handler.cc
+++ b/chromeos/audio/cras_audio_handler.cc
@@ -109,15 +109,31 @@ uint64 CrasAudioHandler::GetActiveInputNode() const {
return active_input_node_id_;
}
+void CrasAudioHandler::GetAudioDevices(AudioDeviceList* device_list) const {
+ for (size_t i = 0; i < audio_devices_.size(); ++i)
+ device_list->push_back(audio_devices_[i]);
+}
+
+bool CrasAudioHandler::GetActiveOutputDevice(AudioDevice* device) const {
+ for (size_t i = 0; i < audio_devices_.size(); ++i) {
+ if (audio_devices_[i].id == active_output_node_id_) {
+ *device = audio_devices_[i];
+ return true;
+ }
+ }
+ NOTREACHED() << "Can't find active output audio device";
+ return false;
+}
+
void CrasAudioHandler::SetOutputVolumePercent(int volume_percent) {
volume_percent = min(max(volume_percent, 0), 100);
if (volume_percent <= kMuteThresholdPercent)
volume_percent = 0;
+ SetOutputVolumeInternal(volume_percent);
if (IsOutputMuted() && volume_percent > 0)
SetOutputMute(false);
if (!IsOutputMuted() && volume_percent == 0)
SetOutputMute(true);
- SetOutputVolumeInternal(volume_percent);
}
void CrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) {
@@ -171,6 +187,8 @@ CrasAudioHandler::CrasAudioHandler(
output_volume_(0),
active_output_node_id_(0),
active_input_node_id_(0),
+ has_alternative_input_(false),
+ has_alternative_output_(false),
output_mute_locked_(false),
input_mute_locked_(false) {
chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->AddObserver(this);
@@ -222,12 +240,20 @@ void CrasAudioHandler::NodesChanged() {
}
void CrasAudioHandler::ActiveOutputNodeChanged(uint64 node_id) {
+ if (active_output_node_id_ == node_id)
+ return;
+
active_output_node_id_ = node_id;
+ GetNodes();
FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveOutputNodeChanged());
}
void CrasAudioHandler::ActiveInputNodeChanged(uint64 node_id) {
+ if (active_input_node_id_ == node_id)
+ return;
+
active_input_node_id_ = node_id;
+ GetNodes();
FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveInputNodeChanged());
}
@@ -241,8 +267,8 @@ void CrasAudioHandler::SetupInitialAudioState() {
// Set the initial audio state to the ones read from audio prefs.
output_mute_on_ = audio_pref_handler_->GetOutputMuteValue();
output_volume_ = audio_pref_handler_->GetOutputVolumeValue();
- SetOutputMute(output_mute_on_);
SetOutputVolumeInternal(output_volume_);
+ SetOutputMute(output_mute_on_);
// Get the initial audio data.
GetNodes();
@@ -282,13 +308,28 @@ void CrasAudioHandler::HandleGetNodes(const chromeos::AudioNodeList& node_list,
return;
}
- audio_nodes_.clear();
+ audio_devices_.clear();
+ active_input_node_id_ = 0;
+ active_output_node_id_ = 0;
+ has_alternative_input_ = false;
+ has_alternative_output_ = false;
+
for (size_t i = 0; i < node_list.size(); ++i) {
if (node_list[i].is_input && node_list[i].active)
active_input_node_id_ = node_list[i].id;
else if (!node_list[i].is_input && node_list[i].active)
active_output_node_id_ = node_list[i].id;
- audio_nodes_.push_back(node_list[i]);
+ AudioDevice device(node_list[i]);
+ audio_devices_.push_back(device);
+ if (!has_alternative_input_ &&
+ device.is_input &&
+ device.type != AUDIO_TYPE_INTERNAL) {
+ has_alternative_input_ = true;
+ } else if (!has_alternative_output_ &&
+ !device.is_input &&
+ device.type != AUDIO_TYPE_INTERNAL) {
+ has_alternative_output_ = true;
+ }
}
FOR_EACH_OBSERVER(AudioObserver, observers_, OnAudioNodesChanged());
diff --git a/chromeos/audio/cras_audio_handler.h b/chromeos/audio/cras_audio_handler.h
index 7e5f47a..61b11f5d 100644
--- a/chromeos/audio/cras_audio_handler.h
+++ b/chromeos/audio/cras_audio_handler.h
@@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
+#include "chromeos/audio/audio_device.h"
#include "chromeos/audio/audio_pref_observer.h"
#include "chromeos/dbus/audio_node.h"
#include "chromeos/dbus/cras_audio_client.h"
@@ -83,6 +84,15 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Returns the node_id of the active input node.
uint64 GetActiveInputNode() const;
+ // Gets the audio devices back in |device_list|.
+ void GetAudioDevices(AudioDeviceList* device_list) const;
+
+ bool GetActiveOutputDevice(AudioDevice* device) const;
+
+ // Whether there is alternative input/output audio device.
+ bool has_alternative_input() const { return has_alternative_input_; }
+ bool has_alternative_output() const { return has_alternative_output_; }
+
// Sets volume level from 0-100%. If less than kMuteThresholdPercent, then
// mutes the sound. If it was muted, and |volume_percent| is larger than
// the threshold, then the sound is unmuted.
@@ -141,13 +151,15 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
ObserverList<AudioObserver> observers_;
// Audio data and state.
- AudioNodeList audio_nodes_;
+ AudioDeviceList audio_devices_;
VolumeState volume_state_;
bool output_mute_on_;
bool input_mute_on_;
int output_volume_;
uint64 active_output_node_id_;
uint64 active_input_node_id_;
+ bool has_alternative_input_;
+ bool has_alternative_output_;
bool output_mute_locked_;
bool input_mute_locked_;
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index 66d0461..2192796 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -31,6 +31,8 @@
'CHROMEOS_IMPLEMENTATION',
],
'sources': [
+ 'audio/audio_device.cc',
+ 'audio/audio_device.h',
'audio/audio_pref_observer.h',
'audio/audio_pref_handler.h',
'audio/cras_audio_handler.cc',
diff --git a/chromeos/dbus/cras_audio_client.cc b/chromeos/dbus/cras_audio_client.cc
index 342ce59..02260bb 100644
--- a/chromeos/dbus/cras_audio_client.cc
+++ b/chromeos/dbus/cras_audio_client.cc
@@ -384,25 +384,54 @@ class CrasAudioClientStubImpl : public CrasAudioClient {
CrasAudioClientStubImpl() {
VLOG(1) << "CrasAudioClientStubImpl is created";
- // Fake audio nodes.
+ // Fake audio output nodes.
AudioNode node_1;
node_1.is_input = false;
node_1.id = 10001;
- node_1.device_name = "Fake Audio Output";
+ node_1.device_name = "Fake Speaker";
node_1.type = "INTERNAL_SPEAKER";
- node_1.name = "Internal Speaker";
- node_1.active = true;
+ node_1.name = "Speaker";
+ node_1.active = false;
+ node_list_.push_back(node_1);
AudioNode node_2;
- node_2.is_input = true;
+ node_2.is_input = false;
node_2.id = 10002;
- node_2.device_name = "Fake Audio Input";
- node_2.type = "INTERNAL_MIC";
- node_2.name = "Internal Mic";
+ node_2.device_name = "Fake Headphone";
+ node_2.type = "HEADPHONE";
+ node_2.name = "Headphone";
node_2.active = true;
-
- node_list_.push_back(node_1);
node_list_.push_back(node_2);
+ active_output_node_id_ = node_2.id;
+
+ AudioNode node_3;
+ node_3.is_input = false;
+ node_3.id = 10003;
+ node_3.device_name = "Fake Audio Output";
+ node_3.type = "BLUETOOTH";
+ node_3.name = "Bluetooth Headphone";
+ node_3.active = false;
+ node_list_.push_back(node_3);
+
+ // Fake audio input ndoes
+ AudioNode node_4;
+ node_4.is_input = true;
+ node_4.id = 10004;
+ node_4.device_name = "Fake Internal Mic";
+ node_4.type = "INTERNAL_MIC";
+ node_4.name = "Internal Mic";
+ node_4.active = false;
+ node_list_.push_back(node_4);
+
+ AudioNode node_5;
+ node_5.is_input = true;
+ node_5.id = 10005;
+ node_5.device_name = "Fake Internal Mic";
+ node_5.type = "USB";
+ node_5.name = "USB Mic";
+ node_5.active = true;
+ node_list_.push_back(node_5);
+ active_input_node_id_ = node_5.id;
}
virtual ~CrasAudioClientStubImpl() {
}
@@ -459,6 +488,15 @@ class CrasAudioClientStubImpl : public CrasAudioClient {
}
virtual void SetActiveOutputNode(uint64 node_id) OVERRIDE {
+ if (active_output_node_id_ == node_id)
+ return;
+
+ for (size_t i = 0; i < node_list_.size(); ++i) {
+ if (node_list_[i].id == active_output_node_id_)
+ node_list_[i].active = false;
+ else if (node_list_[i].id == node_id)
+ node_list_[i].active = true;
+ }
active_output_node_id_ = node_id;
FOR_EACH_OBSERVER(Observer,
observers_,
@@ -466,6 +504,15 @@ class CrasAudioClientStubImpl : public CrasAudioClient {
}
virtual void SetActiveInputNode(uint64 node_id) OVERRIDE {
+ if (active_input_node_id_ == node_id)
+ return;
+
+ for (size_t i = 0; i < node_list_.size(); ++i) {
+ if (node_list_[i].id == active_input_node_id_)
+ node_list_[i].active = false;
+ else if (node_list_[i].id == node_id)
+ node_list_[i].active = true;
+ }
active_input_node_id_ = node_id;
FOR_EACH_OBSERVER(Observer,
observers_,