Reland the ULONG -> SIZE_T change from 317177
[chromium-blink-merge.git] / extensions / browser / api / audio / audio_service_chromeos.cc
blob8005ac69f22175600364894e4e8c047976ce9e33
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 "extensions/browser/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 "content/public/browser/browser_thread.h"
14 using content::BrowserThread;
16 namespace extensions {
18 using core_api::audio::OutputDeviceInfo;
19 using core_api::audio::InputDeviceInfo;
21 class AudioServiceImpl : public AudioService,
22 public chromeos::CrasAudioHandler::AudioObserver {
23 public:
24 AudioServiceImpl();
25 ~AudioServiceImpl() override;
27 // Called by listeners to this service to add/remove themselves as observers.
28 void AddObserver(AudioService::Observer* observer) override;
29 void RemoveObserver(AudioService::Observer* observer) override;
31 // Start to query audio device information.
32 void StartGetInfo(const GetInfoCallback& callback) override;
33 void SetActiveDevices(const DeviceIdList& device_list) override;
34 bool SetDeviceProperties(const std::string& device_id,
35 bool muted,
36 int volume,
37 int gain) override;
39 protected:
40 // chromeos::CrasAudioHandler::AudioObserver overrides.
41 void OnOutputVolumeChanged() override;
42 void OnInputGainChanged() override;
43 void OnOutputMuteChanged() override;
44 void OnInputMuteChanged() override;
45 void OnAudioNodesChanged() override;
46 void OnActiveOutputNodeChanged() override;
47 void OnActiveInputNodeChanged() override;
49 private:
50 void NotifyDeviceChanged();
52 bool FindDevice(uint64 id, chromeos::AudioDevice* device);
53 uint64 GetIdFromStr(const std::string& id_str);
55 // List of observers.
56 ObserverList<AudioService::Observer> observer_list_;
58 chromeos::CrasAudioHandler* cras_audio_handler_;
60 // Note: This should remain the last member so it'll be destroyed and
61 // invalidate the weak pointers before any other members are destroyed.
62 base::WeakPtrFactory<AudioServiceImpl> weak_ptr_factory_;
64 DISALLOW_COPY_AND_ASSIGN(AudioServiceImpl);
67 AudioServiceImpl::AudioServiceImpl()
68 : cras_audio_handler_(NULL),
69 weak_ptr_factory_(this) {
70 if (chromeos::CrasAudioHandler::IsInitialized()) {
71 cras_audio_handler_ = chromeos::CrasAudioHandler::Get();
72 cras_audio_handler_->AddAudioObserver(this);
76 AudioServiceImpl::~AudioServiceImpl() {
77 if (cras_audio_handler_ && chromeos::CrasAudioHandler::IsInitialized()) {
78 cras_audio_handler_->RemoveAudioObserver(this);
82 void AudioServiceImpl::AddObserver(AudioService::Observer* observer) {
83 observer_list_.AddObserver(observer);
86 void AudioServiceImpl::RemoveObserver(AudioService::Observer* observer) {
87 observer_list_.RemoveObserver(observer);
90 void AudioServiceImpl::StartGetInfo(const GetInfoCallback& callback) {
91 DCHECK_CURRENTLY_ON(BrowserThread::UI);
92 DCHECK(cras_audio_handler_);
93 DCHECK(!callback.is_null());
95 if (callback.is_null())
96 return;
98 OutputInfo output_info;
99 InputInfo input_info;
100 if (!cras_audio_handler_) {
101 callback.Run(output_info, input_info, false);
102 return;
105 chromeos::AudioDeviceList devices;
106 cras_audio_handler_->GetAudioDevices(&devices);
107 for (size_t i = 0; i < devices.size(); ++i) {
108 if (!devices[i].is_input) {
109 linked_ptr<OutputDeviceInfo> info(new OutputDeviceInfo());
110 info->id = base::Uint64ToString(devices[i].id);
111 info->name = devices[i].device_name + ": " + devices[i].display_name;
112 info->is_active = devices[i].active;
113 info->volume =
114 cras_audio_handler_->GetOutputVolumePercentForDevice(devices[i].id);
115 info->is_muted =
116 cras_audio_handler_->IsOutputMutedForDevice(devices[i].id);
117 output_info.push_back(info);
118 } else {
119 linked_ptr<InputDeviceInfo> info(new InputDeviceInfo());
120 info->id = base::Uint64ToString(devices[i].id);
121 info->name = devices[i].device_name + ": " + devices[i].display_name;
122 info->is_active = devices[i].active;
123 info->gain =
124 cras_audio_handler_->GetInputGainPercentForDevice(devices[i].id);
125 info->is_muted =
126 cras_audio_handler_->IsInputMutedForDevice(devices[i].id);
127 input_info.push_back(info);
130 callback.Run(output_info, input_info, true);
133 void AudioServiceImpl::SetActiveDevices(const DeviceIdList& device_list) {
134 DCHECK(cras_audio_handler_);
135 if (!cras_audio_handler_)
136 return;
138 chromeos::CrasAudioHandler::NodeIdList id_list;
139 for (size_t i = 0; i < device_list.size(); ++i) {
140 chromeos::AudioDevice device;
141 if (FindDevice(GetIdFromStr(device_list[i]), &device))
142 id_list.push_back(device.id);
144 cras_audio_handler_->ChangeActiveNodes(id_list);
147 bool AudioServiceImpl::SetDeviceProperties(const std::string& device_id,
148 bool muted,
149 int volume,
150 int gain) {
151 DCHECK(cras_audio_handler_);
152 if (!cras_audio_handler_)
153 return false;
155 chromeos::AudioDevice device;
156 bool found = FindDevice(GetIdFromStr(device_id), &device);
157 if (!found)
158 return false;
160 cras_audio_handler_->SetMuteForDevice(device.id, muted);
162 if (!device.is_input && volume != -1) {
163 cras_audio_handler_->SetVolumeGainPercentForDevice(device.id, volume);
164 return true;
165 } else if (device.is_input && gain != -1) {
166 cras_audio_handler_->SetVolumeGainPercentForDevice(device.id, gain);
167 return true;
170 return false;
173 bool AudioServiceImpl::FindDevice(uint64 id, chromeos::AudioDevice* device) {
174 chromeos::AudioDeviceList devices;
175 cras_audio_handler_->GetAudioDevices(&devices);
177 for (size_t i = 0; i < devices.size(); ++i) {
178 if (devices[i].id == id) {
179 *device = devices[i];
180 return true;
183 return false;
186 uint64 AudioServiceImpl::GetIdFromStr(const std::string& id_str) {
187 uint64 device_id;
188 if (!base::StringToUint64(id_str, &device_id))
189 return 0;
190 else
191 return device_id;
194 void AudioServiceImpl::OnOutputVolumeChanged() {
195 NotifyDeviceChanged();
198 void AudioServiceImpl::OnOutputMuteChanged() {
199 NotifyDeviceChanged();
202 void AudioServiceImpl::OnInputGainChanged() {
203 NotifyDeviceChanged();
206 void AudioServiceImpl::OnInputMuteChanged() {
207 NotifyDeviceChanged();
210 void AudioServiceImpl::OnAudioNodesChanged() {
211 NotifyDeviceChanged();
214 void AudioServiceImpl::OnActiveOutputNodeChanged() {
215 NotifyDeviceChanged();
218 void AudioServiceImpl::OnActiveInputNodeChanged() {
219 NotifyDeviceChanged();
222 void AudioServiceImpl::NotifyDeviceChanged() {
223 FOR_EACH_OBSERVER(AudioService::Observer, observer_list_, OnDeviceChanged());
226 AudioService* AudioService::CreateInstance() {
227 return new AudioServiceImpl;
230 } // namespace extensions