| 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 |