Disable TabDragController tests that fail with a real compositor.
[chromium-blink-merge.git] / chrome / browser / extensions / api / audio / audio_service_chromeos.cc
blobabce101b1c3e9197ff88c972b726b90d07ae5b1b
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/audio/audio_service.h"
7 #include "base/callback.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "chromeos/audio/audio_device.h"
11 #include "chromeos/audio/cras_audio_handler.h"
12 #include "chromeos/dbus/audio_node.h"
13 #include "chromeos/dbus/cras_audio_client.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "content/public/browser/browser_thread.h"
17 using content::BrowserThread;
19 namespace extensions {
21 using api::audio::OutputDeviceInfo;
22 using api::audio::InputDeviceInfo;
24 class AudioServiceImpl : public AudioService,
25 public chromeos::CrasAudioHandler::AudioObserver {
26 public:
27 AudioServiceImpl();
28 virtual ~AudioServiceImpl();
30 // Called by listeners to this service to add/remove themselves as observers.
31 virtual void AddObserver(AudioService::Observer* observer) OVERRIDE;
32 virtual void RemoveObserver(AudioService::Observer* observer) OVERRIDE;
34 // Start to query audio device information.
35 virtual void StartGetInfo(const GetInfoCallback& callback) OVERRIDE;
36 virtual void SetActiveDevices(const DeviceIdList& device_list) OVERRIDE;
37 virtual bool SetDeviceProperties(const std::string& device_id,
38 bool muted,
39 int volume,
40 int gain) OVERRIDE;
42 protected:
43 // chromeos::CrasAudioHandler::AudioObserver overrides.
44 virtual void OnOutputVolumeChanged() OVERRIDE;
45 virtual void OnInputGainChanged() OVERRIDE;
46 virtual void OnOutputMuteChanged() OVERRIDE;
47 virtual void OnInputMuteChanged() OVERRIDE;
48 virtual void OnAudioNodesChanged() OVERRIDE;
49 virtual void OnActiveOutputNodeChanged() OVERRIDE;
50 virtual void OnActiveInputNodeChanged() OVERRIDE;
52 private:
53 void NotifyDeviceChanged();
55 // Callback for CrasAudioClient::GetNodes().
56 void OnGetNodes(const GetInfoCallback& callback,
57 const chromeos::AudioNodeList& audio_nodes,
58 bool success);
60 // ErrorCallback for CrasAudioClient::GetNodes().
61 void OnGetNodesError(const std::string& error_name,
62 const std::string& error_msg);
64 bool FindDevice(uint64 id, chromeos::AudioDevice* device);
65 uint64 GetIdFromStr(const std::string& id_str);
67 // List of observers.
68 ObserverList<AudioService::Observer> observer_list_;
70 chromeos::CrasAudioClient* cras_audio_client_;
71 chromeos::CrasAudioHandler* cras_audio_handler_;
73 // Note: This should remain the last member so it'll be destroyed and
74 // invalidate the weak pointers before any other members are destroyed.
75 base::WeakPtrFactory<AudioServiceImpl> weak_ptr_factory_;
77 DISALLOW_COPY_AND_ASSIGN(AudioServiceImpl);
80 AudioServiceImpl::AudioServiceImpl()
81 : cras_audio_client_(NULL),
82 cras_audio_handler_(NULL),
83 weak_ptr_factory_(this) {
84 if (chromeos::DBusThreadManager::IsInitialized() &&
85 chromeos::DBusThreadManager::Get()) {
86 cras_audio_client_ =
87 chromeos::DBusThreadManager::Get()->GetCrasAudioClient();
88 if (chromeos::CrasAudioHandler::IsInitialized()) {
89 cras_audio_handler_ = chromeos::CrasAudioHandler::Get();
90 cras_audio_handler_->AddAudioObserver(this);
95 AudioServiceImpl::~AudioServiceImpl() {
96 if (cras_audio_handler_ && chromeos::CrasAudioHandler::IsInitialized()) {
97 cras_audio_handler_->RemoveAudioObserver(this);
101 void AudioServiceImpl::AddObserver(AudioService::Observer* observer) {
102 observer_list_.AddObserver(observer);
105 void AudioServiceImpl::RemoveObserver(AudioService::Observer* observer) {
106 observer_list_.RemoveObserver(observer);
109 void AudioServiceImpl::StartGetInfo(const GetInfoCallback& callback) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
111 DCHECK(cras_audio_client_);
112 // TODO(jennyz,rkc): Replace cras_audio_client_ call with CrasAudioHandler
113 // Api call.
114 if (cras_audio_client_)
115 cras_audio_client_->GetNodes(base::Bind(&AudioServiceImpl::OnGetNodes,
116 weak_ptr_factory_.GetWeakPtr(),
117 callback),
118 base::Bind(&AudioServiceImpl::OnGetNodesError,
119 weak_ptr_factory_.GetWeakPtr()));
122 void AudioServiceImpl::SetActiveDevices(const DeviceIdList& device_list) {
123 DCHECK(cras_audio_handler_);
124 if (!cras_audio_handler_)
125 return;
127 bool input_device_set = false;
128 bool output_device_set = false;
130 for (size_t i = 0; i < device_list.size(); ++i) {
131 chromeos::AudioDevice device;
132 bool found = FindDevice(GetIdFromStr(device_list[i]), &device);
133 if (found) {
134 if (device.is_input && !input_device_set) {
135 cras_audio_handler_->SwitchToDevice(device);
136 input_device_set = true;
137 } else if (!device.is_input && !output_device_set) {
138 cras_audio_handler_->SwitchToDevice(device);
139 output_device_set = true;
145 bool AudioServiceImpl::SetDeviceProperties(const std::string& device_id,
146 bool muted,
147 int volume,
148 int gain) {
149 DCHECK(cras_audio_handler_);
150 if (!cras_audio_handler_)
151 return false;
153 chromeos::AudioDevice device;
154 bool found = FindDevice(GetIdFromStr(device_id), &device);
155 if (!found)
156 return false;
158 cras_audio_handler_->SetMuteForDevice(device.id, muted);
160 if (!device.is_input && volume != -1) {
161 cras_audio_handler_->SetVolumeGainPercentForDevice(device.id, volume);
162 return true;
163 } else if (device.is_input && gain != -1) {
164 cras_audio_handler_->SetVolumeGainPercentForDevice(device.id, gain);
165 return true;
168 return false;
171 void AudioServiceImpl::OnGetNodes(const GetInfoCallback& callback,
172 const chromeos::AudioNodeList& audio_nodes,
173 bool success) {
174 OutputInfo output_info;
175 InputInfo input_info;
176 if (success) {
177 for (chromeos::AudioNodeList::const_iterator iter = audio_nodes.begin();
178 iter != audio_nodes.end(); ++iter) {
179 if (!iter->is_input) {
180 linked_ptr<OutputDeviceInfo> info(new OutputDeviceInfo());
181 info->id = base::Uint64ToString(iter->id);
182 info->name = iter->device_name + ": " + iter->name;
183 info->is_active = iter->active;
184 info->volume = cras_audio_handler_->GetOutputVolumePercentForDevice(
185 iter->id);
186 info->is_muted = cras_audio_handler_->IsOutputMutedForDevice(iter->id);
187 output_info.push_back(info);
188 } else {
189 linked_ptr<InputDeviceInfo> info(new InputDeviceInfo());
190 info->id = base::Uint64ToString(iter->id);
191 info->name = iter->device_name + ": " + iter->name;
192 info->is_active = iter->active;
193 info->gain = cras_audio_handler_->GetInputGainPercentForDevice(
194 iter->id);
195 info->is_muted = cras_audio_handler_->IsInputMutedForDevice(iter->id);
196 input_info.push_back(info);
201 DCHECK(!callback.is_null());
202 if (!callback.is_null())
203 callback.Run(output_info, input_info, success);
206 void AudioServiceImpl::OnGetNodesError(const std::string& error_name,
207 const std::string& error_msg) {
210 bool AudioServiceImpl::FindDevice(uint64 id, chromeos::AudioDevice* device) {
211 chromeos::AudioDeviceList devices;
212 cras_audio_handler_->GetAudioDevices(&devices);
214 for (size_t i = 0; i < devices.size(); ++i) {
215 if (devices[i].id == id) {
216 *device = devices[i];
217 return true;
220 return false;
223 uint64 AudioServiceImpl::GetIdFromStr(const std::string& id_str) {
224 uint64 device_id;
225 if (!base::StringToUint64(id_str, &device_id))
226 return 0;
227 else
228 return device_id;
231 void AudioServiceImpl::OnOutputVolumeChanged() {
232 NotifyDeviceChanged();
235 void AudioServiceImpl::OnOutputMuteChanged() {
236 NotifyDeviceChanged();
239 void AudioServiceImpl::OnInputGainChanged() {
240 NotifyDeviceChanged();
243 void AudioServiceImpl::OnInputMuteChanged() {
244 NotifyDeviceChanged();
247 void AudioServiceImpl::OnAudioNodesChanged() {
248 NotifyDeviceChanged();
251 void AudioServiceImpl::OnActiveOutputNodeChanged() {
252 NotifyDeviceChanged();
255 void AudioServiceImpl::OnActiveInputNodeChanged() {
256 NotifyDeviceChanged();
259 void AudioServiceImpl::NotifyDeviceChanged() {
260 FOR_EACH_OBSERVER(AudioService::Observer, observer_list_, OnDeviceChanged());
263 AudioService* AudioService::CreateInstance() {
264 return new AudioServiceImpl;
267 } // namespace extensions