OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/audio/cras_audio_handler.h" | 5 #include "chromeos/audio/cras_audio_handler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 | 97 |
98 void CrasAudioHandler::RemoveAudioObserver(AudioObserver* observer) { | 98 void CrasAudioHandler::RemoveAudioObserver(AudioObserver* observer) { |
99 observers_.RemoveObserver(observer); | 99 observers_.RemoveObserver(observer); |
100 } | 100 } |
101 | 101 |
102 bool CrasAudioHandler::IsOutputMuted() { | 102 bool CrasAudioHandler::IsOutputMuted() { |
103 return output_mute_on_; | 103 return output_mute_on_; |
104 } | 104 } |
105 | 105 |
106 bool CrasAudioHandler::IsOutputMutedForDevice(uint64 device_id) { | 106 bool CrasAudioHandler::IsOutputMutedForDevice(uint64 device_id) { |
107 if (device_id == active_output_node_id_) | 107 return audio_pref_handler_->GetMuteValue(device_id); |
108 return output_mute_on_; | 108 } |
109 else | 109 |
110 return audio_pref_handler_->GetMuteValue(device_id); | 110 bool CrasAudioHandler::IsOutputVolumeBelowDefaultMuteLvel() { |
| 111 return output_volume_ <= kMuteThresholdPercent; |
111 } | 112 } |
112 | 113 |
113 bool CrasAudioHandler::IsInputMuted() { | 114 bool CrasAudioHandler::IsInputMuted() { |
114 return input_mute_on_; | 115 return input_mute_on_; |
115 } | 116 } |
116 | 117 |
117 bool CrasAudioHandler::IsInputMutedForDevice(uint64 device_id) { | 118 bool CrasAudioHandler::IsInputMutedForDevice(uint64 device_id) { |
118 if (device_id == active_input_node_id_) | 119 return audio_pref_handler_->GetMuteValue(device_id); |
119 return input_mute_on_; | |
120 else | |
121 return audio_pref_handler_->GetMuteValue(device_id); | |
122 } | 120 } |
123 | 121 |
124 int CrasAudioHandler::GetOutputVolumePercent() { | 122 int CrasAudioHandler::GetOutputVolumePercent() { |
125 return output_volume_; | 123 return output_volume_; |
126 } | 124 } |
127 | 125 |
128 int CrasAudioHandler::GetOutputVolumePercentForDevice(uint64 device_id) { | 126 int CrasAudioHandler::GetOutputVolumePercentForDevice(uint64 device_id) { |
129 if (device_id == active_output_node_id_) | 127 if (device_id == active_output_node_id_) |
130 return output_volume_; | 128 return output_volume_; |
131 else | 129 else |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 } | 169 } |
172 | 170 |
173 bool CrasAudioHandler::has_alternative_output() const { | 171 bool CrasAudioHandler::has_alternative_output() const { |
174 return has_alternative_output_; | 172 return has_alternative_output_; |
175 } | 173 } |
176 | 174 |
177 void CrasAudioHandler::SetOutputVolumePercent(int volume_percent) { | 175 void CrasAudioHandler::SetOutputVolumePercent(int volume_percent) { |
178 volume_percent = min(max(volume_percent, 0), 100); | 176 volume_percent = min(max(volume_percent, 0), 100); |
179 if (volume_percent <= kMuteThresholdPercent) | 177 if (volume_percent <= kMuteThresholdPercent) |
180 volume_percent = 0; | 178 volume_percent = 0; |
181 SetOutputVolumeInternal(volume_percent); | 179 output_volume_ = volume_percent; |
| 180 audio_pref_handler_->SetVolumeGainValue(active_output_node_id_, |
| 181 output_volume_); |
| 182 SetOutputVolumeInternal(output_volume_); |
| 183 FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputVolumeChanged()); |
182 } | 184 } |
183 | 185 |
184 void CrasAudioHandler::SetInputGainPercent(int gain_percent) { | 186 void CrasAudioHandler::SetInputGainPercent(int gain_percent) { |
185 gain_percent = min(max(gain_percent, 0), 100); | 187 gain_percent = min(max(gain_percent, 0), 100); |
186 if (gain_percent <= kMuteThresholdPercent) | 188 if (gain_percent <= kMuteThresholdPercent) |
187 gain_percent = 0; | 189 gain_percent = 0; |
188 SetInputGainInternal(gain_percent); | 190 input_gain_ = gain_percent; |
| 191 audio_pref_handler_->SetVolumeGainValue(active_input_node_id_, input_gain_); |
| 192 SetInputGainInternal(input_gain_); |
| 193 FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputGainChanged()); |
189 } | 194 } |
190 | 195 |
191 void CrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) { | 196 void CrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) { |
192 SetOutputVolumePercent(output_volume_ + adjust_by_percent); | 197 SetOutputVolumePercent(output_volume_ + adjust_by_percent); |
193 } | 198 } |
194 | 199 |
195 void CrasAudioHandler::SetOutputMute(bool mute_on) { | 200 void CrasAudioHandler::SetOutputMute(bool mute_on) { |
196 if (!SetOutputMuteInternal(mute_on)) | 201 if (!SetOutputMuteInternal(mute_on)) |
197 return; | 202 return; |
198 | 203 |
199 if (mute_on) | 204 output_mute_on_ = mute_on; |
200 return; | 205 audio_pref_handler_->SetMuteValue(active_output_node_id_, output_mute_on_); |
| 206 FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputMuteChanged()); |
| 207 } |
201 | 208 |
202 // Adjust volume level if user unmute the device and makes sure the volume | 209 void CrasAudioHandler::AdjustOutputVolumeToAudibleLevel() { |
203 // is set to a minimum audible level. | |
204 if (output_volume_ <= kMuteThresholdPercent) { | 210 if (output_volume_ <= kMuteThresholdPercent) { |
205 // Avoid the situation when sound has been unmuted, but the volume | 211 // Avoid the situation when sound has been unmuted, but the volume |
206 // is set to a very low value, so user still can't hear any sound. | 212 // is set to a very low value, so user still can't hear any sound. |
207 SetOutputVolumeInternal(kDefaultUnmuteVolumePercent); | 213 SetOutputVolumePercent(kDefaultUnmuteVolumePercent); |
208 } | 214 } |
209 } | 215 } |
210 | 216 |
211 bool CrasAudioHandler::SetOutputMuteInternal(bool mute_on) { | |
212 if (output_mute_locked_) | |
213 return false; | |
214 | |
215 output_mute_on_ = mute_on; | |
216 audio_pref_handler_->SetMuteValue(active_output_node_id_, mute_on); | |
217 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | |
218 SetOutputMute(mute_on); | |
219 return true; | |
220 } | |
221 | |
222 void CrasAudioHandler::SetInputMute(bool mute_on) { | 217 void CrasAudioHandler::SetInputMute(bool mute_on) { |
223 if (input_mute_locked_) | 218 if (!SetInputMuteInternal(mute_on)) |
224 return; | 219 return; |
225 | 220 |
226 input_mute_on_ = mute_on; | 221 input_mute_on_ = mute_on; |
227 audio_pref_handler_->SetMuteValue(active_input_node_id_, mute_on); | 222 audio_pref_handler_->SetMuteValue(active_input_node_id_, input_mute_on_); |
228 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 223 FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputMuteChanged()); |
229 SetInputMute(mute_on); | |
230 } | 224 } |
231 | 225 |
232 void CrasAudioHandler::SetActiveOutputNode(uint64 node_id) { | 226 void CrasAudioHandler::SetActiveOutputNode(uint64 node_id) { |
233 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 227 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
234 SetActiveOutputNode(node_id); | 228 SetActiveOutputNode(node_id); |
235 } | 229 } |
236 | 230 |
237 void CrasAudioHandler::SetActiveInputNode(uint64 node_id) { | 231 void CrasAudioHandler::SetActiveInputNode(uint64 node_id) { |
238 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 232 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
239 SetActiveInputNode(node_id); | 233 SetActiveInputNode(node_id); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 if (audio_pref_handler_) | 298 if (audio_pref_handler_) |
305 audio_pref_handler_->RemoveAudioPrefObserver(this); | 299 audio_pref_handler_->RemoveAudioPrefObserver(this); |
306 audio_pref_handler_ = NULL; | 300 audio_pref_handler_ = NULL; |
307 } | 301 } |
308 | 302 |
309 void CrasAudioHandler::AudioClientRestarted() { | 303 void CrasAudioHandler::AudioClientRestarted() { |
310 InitializeAudioState(); | 304 InitializeAudioState(); |
311 } | 305 } |
312 | 306 |
313 void CrasAudioHandler::OutputVolumeChanged(int volume) { | 307 void CrasAudioHandler::OutputVolumeChanged(int volume) { |
314 if (output_volume_ == volume) | 308 if (output_volume_ != volume) { |
| 309 LOG(WARNING) << "Output volume state inconsistent, internal volume=" |
| 310 << output_volume_ << ", dbus signal volume=" << volume; |
315 return; | 311 return; |
316 | 312 } |
317 output_volume_ = volume; | |
318 audio_pref_handler_->SetVolumeGainValue(active_output_node_id_, volume); | |
319 FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputVolumeChanged()); | |
320 } | 313 } |
321 | 314 |
322 void CrasAudioHandler::InputGainChanged(int gain) { | 315 void CrasAudioHandler::InputGainChanged(int gain) { |
323 if (input_gain_ == gain) | 316 if (input_gain_ != gain) { |
324 return; | 317 LOG(WARNING) << "input gain state inconsistent, internal gain=" |
325 | 318 << input_gain_ << ", dbus signal gain=" << gain; |
326 input_gain_ = gain; | 319 } |
327 audio_pref_handler_->SetVolumeGainValue(active_input_node_id_, gain); | |
328 FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputGainChanged()); | |
329 } | 320 } |
330 | 321 |
331 void CrasAudioHandler::OutputMuteChanged(bool mute_on) { | 322 void CrasAudioHandler::OutputMuteChanged(bool mute_on) { |
332 if (output_mute_on_ == mute_on) | 323 if (output_mute_on_ != mute_on) { |
333 return; | 324 LOG(WARNING) << "output mute state inconsistent, internal mute=" |
334 | 325 << output_mute_on_ << ", dbus signal mute=" << mute_on; |
335 output_mute_on_ = mute_on; | 326 } |
336 // TODO(rkc,jennyz): We need to save the mute preferences here. See | |
337 // crbug.com/239646. | |
338 FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputMuteChanged()); | |
339 } | 327 } |
340 | 328 |
341 void CrasAudioHandler::InputMuteChanged(bool mute_on) { | 329 void CrasAudioHandler::InputMuteChanged(bool mute_on) { |
342 if (input_mute_on_ == mute_on) | 330 if (input_mute_on_ != mute_on) { |
343 return; | 331 LOG(WARNING) << "input mute state inconsistent, internal mute=" |
344 | 332 << input_mute_on_ << ", dbus signal mute=" << mute_on; |
345 input_mute_on_ = mute_on; | 333 } |
346 // TODO(rkc,jennyz): Fix this also when fixing the output mute. See | |
347 // crbug.com/239646. | |
348 FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputMuteChanged()); | |
349 } | 334 } |
350 | 335 |
351 void CrasAudioHandler::NodesChanged() { | 336 void CrasAudioHandler::NodesChanged() { |
352 // Refresh audio nodes data. | 337 // Refresh audio nodes data. |
353 GetNodes(); | 338 GetNodes(); |
354 } | 339 } |
355 | 340 |
356 void CrasAudioHandler::ActiveOutputNodeChanged(uint64 node_id) { | 341 void CrasAudioHandler::ActiveOutputNodeChanged(uint64 node_id) { |
357 if (active_output_node_id_ == node_id) | 342 if (active_output_node_id_ == node_id) |
358 return; | 343 return; |
(...skipping 15 matching lines...) Expand all Loading... |
374 void CrasAudioHandler::OnAudioPolicyPrefChanged() { | 359 void CrasAudioHandler::OnAudioPolicyPrefChanged() { |
375 ApplyAudioPolicy(); | 360 ApplyAudioPolicy(); |
376 } | 361 } |
377 | 362 |
378 void CrasAudioHandler::SetupAudioInputState() { | 363 void CrasAudioHandler::SetupAudioInputState() { |
379 // Set the initial audio state to the ones read from audio prefs. | 364 // Set the initial audio state to the ones read from audio prefs. |
380 if (active_input_node_id_) { | 365 if (active_input_node_id_) { |
381 input_mute_on_ = audio_pref_handler_->GetMuteValue(active_input_node_id_); | 366 input_mute_on_ = audio_pref_handler_->GetMuteValue(active_input_node_id_); |
382 input_gain_ = audio_pref_handler_->GetVolumeGainValue( | 367 input_gain_ = audio_pref_handler_->GetVolumeGainValue( |
383 active_input_node_id_); | 368 active_input_node_id_); |
384 SetInputMute(input_mute_on_); | |
385 SetInputGainInternal(input_gain_); | |
386 } else { | 369 } else { |
387 SetInputMute(kPrefMuteOff); | 370 input_mute_on_ = kPrefMuteOff; |
388 SetInputGainInternal(kDefaultVolumeGainPercent); | 371 input_gain_ = kDefaultVolumeGainPercent; |
389 } | 372 } |
| 373 |
| 374 SetInputMuteInternal(input_mute_on_); |
| 375 SetInputGainInternal(input_gain_); |
390 } | 376 } |
391 | 377 |
392 void CrasAudioHandler::SetupAudioOutputState() { | 378 void CrasAudioHandler::SetupAudioOutputState() { |
393 if (active_output_node_id_) { | 379 if (active_output_node_id_) { |
394 output_mute_on_ = audio_pref_handler_->GetMuteValue(active_output_node_id_); | 380 output_mute_on_ = audio_pref_handler_->GetMuteValue(active_output_node_id_); |
395 output_volume_ = audio_pref_handler_->GetVolumeGainValue( | 381 output_volume_ = audio_pref_handler_->GetVolumeGainValue( |
396 active_output_node_id_); | 382 active_output_node_id_); |
397 } else { | 383 } else { |
398 output_mute_on_ = kPrefMuteOff; | 384 output_mute_on_ = kPrefMuteOff; |
399 output_volume_ = kDefaultVolumeGainPercent; | 385 output_volume_ = kDefaultVolumeGainPercent; |
(...skipping 22 matching lines...) Expand all Loading... |
422 SetInputMute(true); | 408 SetInputMute(true); |
423 input_mute_locked_ = true; | 409 input_mute_locked_ = true; |
424 } | 410 } |
425 } | 411 } |
426 | 412 |
427 void CrasAudioHandler::SetOutputVolumeInternal(int volume) { | 413 void CrasAudioHandler::SetOutputVolumeInternal(int volume) { |
428 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 414 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
429 SetOutputVolume(volume); | 415 SetOutputVolume(volume); |
430 } | 416 } |
431 | 417 |
| 418 bool CrasAudioHandler::SetOutputMuteInternal(bool mute_on) { |
| 419 if (output_mute_locked_) |
| 420 return false; |
| 421 |
| 422 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
| 423 SetOutputMute(mute_on); |
| 424 return true; |
| 425 } |
| 426 |
432 void CrasAudioHandler::SetInputGainInternal(int gain) { | 427 void CrasAudioHandler::SetInputGainInternal(int gain) { |
433 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 428 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
434 SetInputGain(gain); | 429 SetInputGain(gain); |
435 } | 430 } |
436 | 431 |
| 432 bool CrasAudioHandler::SetInputMuteInternal(bool mute_on) { |
| 433 if (input_mute_locked_) |
| 434 return false; |
| 435 |
| 436 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
| 437 SetInputMute(mute_on); |
| 438 return true; |
| 439 } |
| 440 |
437 void CrasAudioHandler::GetNodes() { | 441 void CrasAudioHandler::GetNodes() { |
438 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->GetNodes( | 442 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->GetNodes( |
439 base::Bind(&CrasAudioHandler::HandleGetNodes, | 443 base::Bind(&CrasAudioHandler::HandleGetNodes, |
440 weak_ptr_factory_.GetWeakPtr())); | 444 weak_ptr_factory_.GetWeakPtr())); |
441 } | 445 } |
442 | 446 |
443 void CrasAudioHandler::SwitchToDevice(const AudioDevice& device) { | 447 void CrasAudioHandler::SwitchToDevice(const AudioDevice& device) { |
444 // The flow we follow is this, | 448 // The flow we follow is this, |
445 // .) Global mute. | 449 // .) Global mute. |
446 // .) Switch to active device. | 450 // .) Switch to active device. |
447 // .) Once device is switched, set sound state for new device. | 451 // .) Once device is switched, set sound state for new device. |
448 // We do this since during the state from when a device is plugged in or out, | 452 // We do this since during the state from when a device is plugged in or out, |
449 // we are in between devices. We cannot switch to the new device with the | 453 // we are in between devices. We cannot switch to the new device with the |
450 // old devices volume, since in certain situations it might be a very jarring | 454 // old devices volume, since in certain situations it might be a very jarring |
451 // or disturbing sound (for example, plugging out headphones, which were set | 455 // or disturbing sound (for example, plugging out headphones, which were set |
452 // to high volume, and switching to speakers, that were set to low volume). | 456 // to high volume, and switching to speakers, that were set to low volume). |
453 // To avoid this, we mute all sound, do our switch, and then directly set | 457 // To avoid this, we mute all sound, do our switch, and then directly set |
454 // the volume and mute to that of the new device. This way the user never has | 458 // the volume and mute to that of the new device. This way the user never has |
455 // to hear the wrong volume for a device. | 459 // to hear the wrong volume for a device. |
456 LOG(INFO) << "Switching active device to: " << device.ToString(); | 460 LOG(INFO) << "Switching active device to: " << device.ToString(); |
457 if (device.is_input) { | 461 if (device.is_input) { |
458 DBusThreadManager::Get()->GetCrasAudioClient()->SetInputMute(true); | 462 SetInputMuteInternal(true); |
459 DBusThreadManager::Get()->GetCrasAudioClient()->SetActiveInputNode( | 463 DBusThreadManager::Get()->GetCrasAudioClient()->SetActiveInputNode( |
460 device.id); | 464 device.id); |
461 } else { | 465 } else { |
462 DBusThreadManager::Get()->GetCrasAudioClient()->SetOutputMute(true); | 466 SetOutputMuteInternal(true); |
463 DBusThreadManager::Get()->GetCrasAudioClient()->SetActiveOutputNode( | 467 DBusThreadManager::Get()->GetCrasAudioClient()->SetActiveOutputNode( |
464 device.id); | 468 device.id); |
465 } | 469 } |
466 } | 470 } |
467 | 471 |
468 void CrasAudioHandler::UpdateDevicesAndSwitchActive( | 472 void CrasAudioHandler::UpdateDevicesAndSwitchActive( |
469 const AudioNodeList& nodes) { | 473 const AudioNodeList& nodes) { |
470 bool input_device_removed = false; | 474 bool input_device_removed = false; |
471 bool output_device_removed = false; | 475 bool output_device_removed = false; |
472 | 476 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 if (!success) { | 541 if (!success) { |
538 LOG(ERROR) << "Failed to retrieve audio nodes data"; | 542 LOG(ERROR) << "Failed to retrieve audio nodes data"; |
539 return; | 543 return; |
540 } | 544 } |
541 | 545 |
542 UpdateDevicesAndSwitchActive(node_list); | 546 UpdateDevicesAndSwitchActive(node_list); |
543 FOR_EACH_OBSERVER(AudioObserver, observers_, OnAudioNodesChanged()); | 547 FOR_EACH_OBSERVER(AudioObserver, observers_, OnAudioNodesChanged()); |
544 } | 548 } |
545 | 549 |
546 } // namespace chromeos | 550 } // namespace chromeos |
OLD | NEW |