| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 const int kMuteThresholdPercent = 1; | 34 const int kMuteThresholdPercent = 1; |
| 35 | 35 |
| 36 // The duration of HDMI output re-discover grace period in milliseconds. | 36 // The duration of HDMI output re-discover grace period in milliseconds. |
| 37 const int kHDMIRediscoverGracePeriodDurationInMs = 2000; | 37 const int kHDMIRediscoverGracePeriodDurationInMs = 2000; |
| 38 | 38 |
| 39 // Mixer matrix, [0.5, 0.5; 0.5, 0.5] | 39 // Mixer matrix, [0.5, 0.5; 0.5, 0.5] |
| 40 const std::vector<double> kStereoToMono = {0.5, 0.5, 0.5, 0.5}; | 40 const std::vector<double> kStereoToMono = {0.5, 0.5, 0.5, 0.5}; |
| 41 // Mixer matrix, [1, 0; 0, 1] | 41 // Mixer matrix, [1, 0; 0, 1] |
| 42 const std::vector<double> kStereoToStereo = {1, 0, 0, 1}; | 42 const std::vector<double> kStereoToStereo = {1, 0, 0, 1}; |
| 43 | 43 |
| 44 static CrasAudioHandler* g_cras_audio_handler = NULL; | 44 static CrasAudioHandler* g_cras_audio_handler = nullptr; |
| 45 | 45 |
| 46 bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) { | 46 bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) { |
| 47 return a.stable_device_id == b.stable_device_id && a.is_input == b.is_input && | 47 return a.stable_device_id == b.stable_device_id && a.is_input == b.is_input && |
| 48 a.type == b.type && a.device_name == b.device_name; | 48 a.type == b.type && a.device_name == b.device_name; |
| 49 } | 49 } |
| 50 | 50 |
| 51 bool IsDeviceInList(const AudioDevice& device, const AudioNodeList& node_list) { | 51 bool IsDeviceInList(const AudioDevice& device, const AudioNodeList& node_list) { |
| 52 for (const AudioNode& node : node_list) { | 52 for (const AudioNode& node : node_list) { |
| 53 if (device.stable_device_id == node.StableDeviceId()) | 53 if (device.stable_device_id == node.StableDeviceId()) |
| 54 return true; | 54 return true; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 // static | 104 // static |
| 105 void CrasAudioHandler::InitializeForTesting() { | 105 void CrasAudioHandler::InitializeForTesting() { |
| 106 CHECK(!g_cras_audio_handler); | 106 CHECK(!g_cras_audio_handler); |
| 107 CrasAudioHandler::Initialize(new AudioDevicesPrefHandlerStub()); | 107 CrasAudioHandler::Initialize(new AudioDevicesPrefHandlerStub()); |
| 108 } | 108 } |
| 109 | 109 |
| 110 // static | 110 // static |
| 111 void CrasAudioHandler::Shutdown() { | 111 void CrasAudioHandler::Shutdown() { |
| 112 CHECK(g_cras_audio_handler); | 112 CHECK(g_cras_audio_handler); |
| 113 delete g_cras_audio_handler; | 113 delete g_cras_audio_handler; |
| 114 g_cras_audio_handler = NULL; | 114 g_cras_audio_handler = nullptr; |
| 115 } | 115 } |
| 116 | 116 |
| 117 // static | 117 // static |
| 118 bool CrasAudioHandler::IsInitialized() { | 118 bool CrasAudioHandler::IsInitialized() { |
| 119 return g_cras_audio_handler != NULL; | 119 return g_cras_audio_handler != nullptr; |
| 120 } | 120 } |
| 121 | 121 |
| 122 // static | 122 // static |
| 123 CrasAudioHandler* CrasAudioHandler::Get() { | 123 CrasAudioHandler* CrasAudioHandler::Get() { |
| 124 CHECK(g_cras_audio_handler) | 124 CHECK(g_cras_audio_handler) |
| 125 << "CrasAudioHandler::Get() called before Initialize()."; | 125 << "CrasAudioHandler::Get() called before Initialize()."; |
| 126 return g_cras_audio_handler; | 126 return g_cras_audio_handler; |
| 127 } | 127 } |
| 128 | 128 |
| 129 void CrasAudioHandler::OnVideoCaptureStarted(media::VideoFacingMode facing) { | 129 void CrasAudioHandler::OnVideoCaptureStarted(media::VideoFacingMode facing) { |
| 130 // TODO(jennyz): Switch active audio device according to video facing. | 130 // Do nothing if the device doesn't have both front and rear microphones. |
| 131 if (!HasDualInternalMic()) |
| 132 return; |
| 133 |
| 134 bool camera_is_already_on = IsCameraOn(); |
| 135 switch (facing) { |
| 136 case media::MEDIA_VIDEO_FACING_USER: |
| 137 front_camera_on_ = true; |
| 138 break; |
| 139 case media::MEDIA_VIDEO_FACING_ENVIRONMENT: |
| 140 rear_camera_on_ = true; |
| 141 break; |
| 142 default: |
| 143 LOG_IF(WARNING, facing == media::NUM_MEDIA_VIDEO_FACING_MODES) |
| 144 << "On the device with dual microphone, got video capture " |
| 145 << "notification with invalid camera facing mode value"; |
| 146 return; |
| 147 } |
| 148 |
| 149 // If the camera is already on before this notification, don't change active |
| 150 // input. In the case that both cameras are turned on at the same time, we |
| 151 // won't change the active input after the first camera is turned on. We only |
| 152 // support the use case of one camera on at a time. The third party |
| 153 // developer can turn on/off both microphones with extension api if they like |
| 154 // to. |
| 155 if (camera_is_already_on) |
| 156 return; |
| 157 |
| 158 // If the current active input is an external device, keep it. |
| 159 const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_); |
| 160 if (active_input && active_input->IsExternalDevice()) |
| 161 return; |
| 162 |
| 163 // Activate the correct mic for the current active camera. |
| 164 ActivateMicForCamera(facing); |
| 131 } | 165 } |
| 132 | 166 |
| 133 void CrasAudioHandler::OnVideoCaptureStopped(media::VideoFacingMode facing) { | 167 void CrasAudioHandler::OnVideoCaptureStopped(media::VideoFacingMode facing) { |
| 134 // TODO(jennyz): Switch active audio device according to video facing. | 168 // Do nothing if the device doesn't have both front and rear microphones. |
| 169 if (!HasDualInternalMic()) |
| 170 return; |
| 171 |
| 172 switch (facing) { |
| 173 case media::MEDIA_VIDEO_FACING_USER: |
| 174 front_camera_on_ = false; |
| 175 break; |
| 176 case media::MEDIA_VIDEO_FACING_ENVIRONMENT: |
| 177 rear_camera_on_ = false; |
| 178 break; |
| 179 default: |
| 180 LOG_IF(WARNING, facing == media::NUM_MEDIA_VIDEO_FACING_MODES) |
| 181 << "On the device with dual microphone, got video capture " |
| 182 << "notification with invalid camera facing mode value"; |
| 183 return; |
| 184 } |
| 185 |
| 186 // If not all cameras are turned off, don't change active input. In the case |
| 187 // that both cameras are turned on at the same time before one of them is |
| 188 // stopped, we won't change active input until all of them are stopped. |
| 189 // We only support the use case of one camera on at a time. The third party |
| 190 // developer can turn on/off both microphones with extension api if they like |
| 191 // to. |
| 192 if (IsCameraOn()) |
| 193 return; |
| 194 |
| 195 // If the current active input is an external device, keep it. |
| 196 const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_); |
| 197 if (active_input && active_input->IsExternalDevice()) |
| 198 return; |
| 199 |
| 200 // Switch to front mic properly. |
| 201 DeviceActivateType activated_by = |
| 202 HasExternalDevice(true) ? ACTIVATE_BY_USER : ACTIVATE_BY_PRIORITY; |
| 203 SwitchToDevice(*GetDeviceByType(AUDIO_TYPE_FRONT_MIC), true, activated_by); |
| 135 } | 204 } |
| 136 | 205 |
| 137 void CrasAudioHandler::AddAudioObserver(AudioObserver* observer) { | 206 void CrasAudioHandler::AddAudioObserver(AudioObserver* observer) { |
| 138 observers_.AddObserver(observer); | 207 observers_.AddObserver(observer); |
| 139 } | 208 } |
| 140 | 209 |
| 141 void CrasAudioHandler::RemoveAudioObserver(AudioObserver* observer) { | 210 void CrasAudioHandler::RemoveAudioObserver(AudioObserver* observer) { |
| 142 observers_.RemoveObserver(observer); | 211 observers_.RemoveObserver(observer); |
| 143 } | 212 } |
| 144 | 213 |
| 145 bool CrasAudioHandler::HasKeyboardMic() { | 214 bool CrasAudioHandler::HasKeyboardMic() { |
| 146 return GetKeyboardMic() != NULL; | 215 return GetKeyboardMic() != nullptr; |
| 147 } | 216 } |
| 148 | 217 |
| 149 bool CrasAudioHandler::IsOutputMuted() { | 218 bool CrasAudioHandler::IsOutputMuted() { |
| 150 return output_mute_on_; | 219 return output_mute_on_; |
| 151 } | 220 } |
| 152 | 221 |
| 153 bool CrasAudioHandler::IsOutputMutedForDevice(uint64_t device_id) { | 222 bool CrasAudioHandler::IsOutputMutedForDevice(uint64_t device_id) { |
| 154 const AudioDevice* device = GetDeviceFromId(device_id); | 223 const AudioDevice* device = GetDeviceFromId(device_id); |
| 155 if (!device) | 224 if (!device) |
| 156 return false; | 225 return false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 uint64_t CrasAudioHandler::GetPrimaryActiveOutputNode() const { | 280 uint64_t CrasAudioHandler::GetPrimaryActiveOutputNode() const { |
| 212 return active_output_node_id_; | 281 return active_output_node_id_; |
| 213 } | 282 } |
| 214 | 283 |
| 215 uint64_t CrasAudioHandler::GetPrimaryActiveInputNode() const { | 284 uint64_t CrasAudioHandler::GetPrimaryActiveInputNode() const { |
| 216 return active_input_node_id_; | 285 return active_input_node_id_; |
| 217 } | 286 } |
| 218 | 287 |
| 219 void CrasAudioHandler::GetAudioDevices(AudioDeviceList* device_list) const { | 288 void CrasAudioHandler::GetAudioDevices(AudioDeviceList* device_list) const { |
| 220 device_list->clear(); | 289 device_list->clear(); |
| 221 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 290 for (const auto& item : audio_devices_) { |
| 222 it != audio_devices_.end(); ++it) | 291 const AudioDevice& device = item.second; |
| 223 device_list->push_back(it->second); | 292 device_list->push_back(device); |
| 293 } |
| 224 } | 294 } |
| 225 | 295 |
| 226 bool CrasAudioHandler::GetPrimaryActiveOutputDevice(AudioDevice* device) const { | 296 bool CrasAudioHandler::GetPrimaryActiveOutputDevice(AudioDevice* device) const { |
| 227 const AudioDevice* active_device = GetDeviceFromId(active_output_node_id_); | 297 const AudioDevice* active_device = GetDeviceFromId(active_output_node_id_); |
| 228 if (!active_device || !device) | 298 if (!active_device || !device) |
| 229 return false; | 299 return false; |
| 230 *device = *active_device; | 300 *device = *active_device; |
| 231 return true; | 301 return true; |
| 232 } | 302 } |
| 233 | 303 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 AddActiveNode(existing_device.id, false /* notify */); | 410 AddActiveNode(existing_device.id, false /* notify */); |
| 341 else | 411 else |
| 342 RemoveActiveNodeInternal(existing_device.id, false /* notify */); | 412 RemoveActiveNodeInternal(existing_device.id, false /* notify */); |
| 343 } | 413 } |
| 344 | 414 |
| 345 if (active_devices_changed) | 415 if (active_devices_changed) |
| 346 NotifyActiveNodeChanged(is_input); | 416 NotifyActiveNodeChanged(is_input); |
| 347 } | 417 } |
| 348 | 418 |
| 349 void CrasAudioHandler::SwapInternalSpeakerLeftRightChannel(bool swap) { | 419 void CrasAudioHandler::SwapInternalSpeakerLeftRightChannel(bool swap) { |
| 350 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 420 for (const auto& item : audio_devices_) { |
| 351 it != audio_devices_.end(); | 421 const AudioDevice& device = item.second; |
| 352 ++it) { | |
| 353 const AudioDevice& device = it->second; | |
| 354 if (!device.is_input && device.type == AUDIO_TYPE_INTERNAL_SPEAKER) { | 422 if (!device.is_input && device.type == AUDIO_TYPE_INTERNAL_SPEAKER) { |
| 355 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->SwapLeftRight( | 423 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->SwapLeftRight( |
| 356 device.id, swap); | 424 device.id, swap); |
| 357 break; | 425 break; |
| 358 } | 426 } |
| 359 } | 427 } |
| 360 } | 428 } |
| 361 | 429 |
| 362 void CrasAudioHandler::SetOutputMono(bool mono_on) { | 430 void CrasAudioHandler::SetOutputMono(bool mono_on) { |
| 363 output_mono_on_ = mono_on; | 431 output_mono_on_ = mono_on; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 380 bool CrasAudioHandler::has_alternative_input() const { | 448 bool CrasAudioHandler::has_alternative_input() const { |
| 381 return has_alternative_input_; | 449 return has_alternative_input_; |
| 382 } | 450 } |
| 383 | 451 |
| 384 bool CrasAudioHandler::has_alternative_output() const { | 452 bool CrasAudioHandler::has_alternative_output() const { |
| 385 return has_alternative_output_; | 453 return has_alternative_output_; |
| 386 } | 454 } |
| 387 | 455 |
| 388 void CrasAudioHandler::SetOutputVolumePercent(int volume_percent) { | 456 void CrasAudioHandler::SetOutputVolumePercent(int volume_percent) { |
| 389 // Set all active devices to the same volume. | 457 // Set all active devices to the same volume. |
| 390 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 458 for (const auto& item : audio_devices_) { |
| 391 it != audio_devices_.end(); | 459 const AudioDevice& device = item.second; |
| 392 it++) { | |
| 393 const AudioDevice& device = it->second; | |
| 394 if (!device.is_input && device.active) | 460 if (!device.is_input && device.active) |
| 395 SetOutputNodeVolumePercent(device.id, volume_percent); | 461 SetOutputNodeVolumePercent(device.id, volume_percent); |
| 396 } | 462 } |
| 397 } | 463 } |
| 398 | 464 |
| 399 void CrasAudioHandler::SetOutputVolumePercentWithoutNotifyingObservers( | 465 void CrasAudioHandler::SetOutputVolumePercentWithoutNotifyingObservers( |
| 400 int volume_percent, | 466 int volume_percent, |
| 401 AutomatedVolumeChangeReason reason) { | 467 AutomatedVolumeChangeReason reason) { |
| 402 automated_volume_change_reasons_.push_back(reason); | 468 automated_volume_change_reasons_.push_back(reason); |
| 403 SetOutputVolumePercent(volume_percent); | 469 SetOutputVolumePercent(volume_percent); |
| 404 } | 470 } |
| 405 | 471 |
| 406 // TODO: Rename the 'Percent' to something more meaningful. | 472 // TODO: Rename the 'Percent' to something more meaningful. |
| 407 void CrasAudioHandler::SetInputGainPercent(int gain_percent) { | 473 void CrasAudioHandler::SetInputGainPercent(int gain_percent) { |
| 408 // TODO(jennyz): Should we set all input devices' gain to the same level? | 474 // TODO(jennyz): Should we set all input devices' gain to the same level? |
| 409 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 475 for (const auto& item : audio_devices_) { |
| 410 it != audio_devices_.end(); | 476 const AudioDevice& device = item.second; |
| 411 it++) { | |
| 412 const AudioDevice& device = it->second; | |
| 413 if (device.is_input && device.active) | 477 if (device.is_input && device.active) |
| 414 SetInputNodeGainPercent(active_input_node_id_, gain_percent); | 478 SetInputNodeGainPercent(active_input_node_id_, gain_percent); |
| 415 } | 479 } |
| 416 } | 480 } |
| 417 | 481 |
| 418 void CrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) { | 482 void CrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) { |
| 419 SetOutputVolumePercent(output_volume_ + adjust_by_percent); | 483 SetOutputVolumePercent(output_volume_ + adjust_by_percent); |
| 420 } | 484 } |
| 421 | 485 |
| 422 void CrasAudioHandler::SetOutputMute(bool mute_on) { | 486 void CrasAudioHandler::SetOutputMute(bool mute_on) { |
| 423 if (!SetOutputMuteInternal(mute_on)) | 487 if (!SetOutputMuteInternal(mute_on)) |
| 424 return; | 488 return; |
| 425 | 489 |
| 426 // Save the mute state for all active output audio devices. | 490 // Save the mute state for all active output audio devices. |
| 427 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 491 for (const auto& item : audio_devices_) { |
| 428 it != audio_devices_.end(); | 492 const AudioDevice& device = item.second; |
| 429 it++) { | |
| 430 const AudioDevice& device = it->second; | |
| 431 if (!device.is_input && device.active) { | 493 if (!device.is_input && device.active) { |
| 432 audio_pref_handler_->SetMuteValue(device, output_mute_on_); | 494 audio_pref_handler_->SetMuteValue(device, output_mute_on_); |
| 433 } | 495 } |
| 434 } | 496 } |
| 435 | 497 |
| 436 for (auto& observer : observers_) | 498 for (auto& observer : observers_) |
| 437 observer.OnOutputMuteChanged(output_mute_on_, false /* system_adjust */); | 499 observer.OnOutputMuteChanged(output_mute_on_, false /* system_adjust */); |
| 438 } | 500 } |
| 439 | 501 |
| 440 void CrasAudioHandler::AdjustOutputVolumeToAudibleLevel() { | 502 void CrasAudioHandler::AdjustOutputVolumeToAudibleLevel() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 461 } else { | 523 } else { |
| 462 chromeos::DBusThreadManager::Get() | 524 chromeos::DBusThreadManager::Get() |
| 463 ->GetCrasAudioClient() | 525 ->GetCrasAudioClient() |
| 464 ->SetActiveOutputNode(active_device.id); | 526 ->SetActiveOutputNode(active_device.id); |
| 465 } | 527 } |
| 466 | 528 |
| 467 if (notify) | 529 if (notify) |
| 468 NotifyActiveNodeChanged(active_device.is_input); | 530 NotifyActiveNodeChanged(active_device.is_input); |
| 469 | 531 |
| 470 // Save active state for the nodes. | 532 // Save active state for the nodes. |
| 471 for (AudioDeviceMap::iterator it = audio_devices_.begin(); | 533 for (const auto& item : audio_devices_) { |
| 472 it != audio_devices_.end(); ++it) { | 534 const AudioDevice& device = item.second; |
| 473 const AudioDevice& device = it->second; | |
| 474 if (device.is_input != active_device.is_input) | 535 if (device.is_input != active_device.is_input) |
| 475 continue; | 536 continue; |
| 476 SaveDeviceState(device, device.active, activate_by); | 537 SaveDeviceState(device, device.active, activate_by); |
| 477 } | 538 } |
| 478 } | 539 } |
| 479 | 540 |
| 480 void CrasAudioHandler::SaveDeviceState(const AudioDevice& device, | 541 void CrasAudioHandler::SaveDeviceState(const AudioDevice& device, |
| 481 bool active, | 542 bool active, |
| 482 DeviceActivateType activate_by) { | 543 DeviceActivateType activate_by) { |
| 483 // Don't save the active state for non-simple usage device, which is invisible | 544 // Don't save the active state for non-simple usage device, which is invisible |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 if (!chromeos::DBusThreadManager::IsInitialized() || | 658 if (!chromeos::DBusThreadManager::IsInitialized() || |
| 598 !chromeos::DBusThreadManager::Get() || | 659 !chromeos::DBusThreadManager::Get() || |
| 599 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) | 660 !chromeos::DBusThreadManager::Get()->GetCrasAudioClient()) |
| 600 return; | 661 return; |
| 601 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> | 662 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> |
| 602 RemoveObserver(this); | 663 RemoveObserver(this); |
| 603 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> | 664 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> |
| 604 RemoveObserver(this); | 665 RemoveObserver(this); |
| 605 if (audio_pref_handler_.get()) | 666 if (audio_pref_handler_.get()) |
| 606 audio_pref_handler_->RemoveAudioPrefObserver(this); | 667 audio_pref_handler_->RemoveAudioPrefObserver(this); |
| 607 audio_pref_handler_ = NULL; | 668 audio_pref_handler_ = nullptr; |
| 608 } | 669 } |
| 609 | 670 |
| 610 void CrasAudioHandler::AudioClientRestarted() { | 671 void CrasAudioHandler::AudioClientRestarted() { |
| 611 // Make sure the logging is enabled in case cras server | 672 // Make sure the logging is enabled in case cras server |
| 612 // restarts after crashing. | 673 // restarts after crashing. |
| 613 LogErrors(); | 674 LogErrors(); |
| 614 InitializeAudioState(); | 675 InitializeAudioState(); |
| 615 } | 676 } |
| 616 | 677 |
| 617 void CrasAudioHandler::NodesChanged() { | 678 void CrasAudioHandler::NodesChanged() { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 | 766 |
| 706 void CrasAudioHandler::EmitLoginPromptVisibleCalled() { | 767 void CrasAudioHandler::EmitLoginPromptVisibleCalled() { |
| 707 // Enable logging after cras server is started, which will be after | 768 // Enable logging after cras server is started, which will be after |
| 708 // EmitLoginPromptVisible. | 769 // EmitLoginPromptVisible. |
| 709 LogErrors(); | 770 LogErrors(); |
| 710 } | 771 } |
| 711 | 772 |
| 712 const AudioDevice* CrasAudioHandler::GetDeviceFromId(uint64_t device_id) const { | 773 const AudioDevice* CrasAudioHandler::GetDeviceFromId(uint64_t device_id) const { |
| 713 AudioDeviceMap::const_iterator it = audio_devices_.find(device_id); | 774 AudioDeviceMap::const_iterator it = audio_devices_.find(device_id); |
| 714 if (it == audio_devices_.end()) | 775 if (it == audio_devices_.end()) |
| 715 return NULL; | 776 return nullptr; |
| 716 | 777 |
| 717 return &(it->second); | 778 return &(it->second); |
| 718 } | 779 } |
| 719 | 780 |
| 720 const AudioDevice* CrasAudioHandler::GetDeviceFromStableDeviceId( | 781 const AudioDevice* CrasAudioHandler::GetDeviceFromStableDeviceId( |
| 721 uint64_t stable_device_id) const { | 782 uint64_t stable_device_id) const { |
| 722 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 783 for (const auto& item : audio_devices_) { |
| 723 it != audio_devices_.end(); ++it) { | 784 const AudioDevice& device = item.second; |
| 724 if (it->second.stable_device_id == stable_device_id) | 785 if (device.stable_device_id == stable_device_id) |
| 725 return &(it->second); | 786 return &device; |
| 726 } | 787 } |
| 727 return NULL; | 788 return nullptr; |
| 728 } | 789 } |
| 729 | 790 |
| 730 const AudioDevice* CrasAudioHandler::GetKeyboardMic() const { | 791 const AudioDevice* CrasAudioHandler::GetKeyboardMic() const { |
| 731 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 792 for (const auto& item : audio_devices_) { |
| 732 it != audio_devices_.end(); it++) { | 793 const AudioDevice& device = item.second; |
| 733 if (it->second.is_input && it->second.type == AUDIO_TYPE_KEYBOARD_MIC) | 794 if (device.is_input && device.type == AUDIO_TYPE_KEYBOARD_MIC) |
| 734 return &(it->second); | 795 return &device; |
| 735 } | 796 } |
| 736 return NULL; | 797 return nullptr; |
| 737 } | 798 } |
| 738 | 799 |
| 739 void CrasAudioHandler::SetupAudioInputState() { | 800 void CrasAudioHandler::SetupAudioInputState() { |
| 740 // Set the initial audio state to the ones read from audio prefs. | 801 // Set the initial audio state to the ones read from audio prefs. |
| 741 const AudioDevice* device = GetDeviceFromId(active_input_node_id_); | 802 const AudioDevice* device = GetDeviceFromId(active_input_node_id_); |
| 742 if (!device) { | 803 if (!device) { |
| 743 LOG_IF(ERROR, log_errors_) | 804 LOG_IF(ERROR, log_errors_) |
| 744 << "Can't set up audio state for unknown input device id =" | 805 << "Can't set up audio state for unknown input device id =" |
| 745 << "0x" << std::hex << active_input_node_id_; | 806 << "0x" << std::hex << active_input_node_id_; |
| 746 return; | 807 return; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 // do nothing. | 994 // do nothing. |
| 934 if (new_active_device.active && | 995 if (new_active_device.active && |
| 935 new_active_device.id == current_active_node_id) { | 996 new_active_device.id == current_active_node_id) { |
| 936 return false; | 997 return false; |
| 937 } | 998 } |
| 938 | 999 |
| 939 bool found_new_active_device = false; | 1000 bool found_new_active_device = false; |
| 940 // Reset all other input or output devices' active status. The active audio | 1001 // Reset all other input or output devices' active status. The active audio |
| 941 // device from the previous user session can be remembered by cras, but not | 1002 // device from the previous user session can be remembered by cras, but not |
| 942 // in chrome. see crbug.com/273271. | 1003 // in chrome. see crbug.com/273271. |
| 943 for (AudioDeviceMap::iterator it = audio_devices_.begin(); | 1004 for (auto& item : audio_devices_) { |
| 944 it != audio_devices_.end(); ++it) { | 1005 AudioDevice& device = item.second; |
| 945 if (it->second.is_input == new_active_device.is_input && | 1006 if (device.is_input == new_active_device.is_input && |
| 946 it->second.id != new_active_device.id) { | 1007 device.id != new_active_device.id) { |
| 947 it->second.active = false; | 1008 device.active = false; |
| 948 } else if (it->second.is_input == new_active_device.is_input && | 1009 } else if (device.is_input == new_active_device.is_input && |
| 949 it->second.id == new_active_device.id) { | 1010 device.id == new_active_device.id) { |
| 950 found_new_active_device = true; | 1011 found_new_active_device = true; |
| 951 } | 1012 } |
| 952 } | 1013 } |
| 953 | 1014 |
| 954 if (!found_new_active_device) { | 1015 if (!found_new_active_device) { |
| 955 LOG(ERROR) << "Invalid new active device: " << new_active_device.ToString(); | 1016 LOG(ERROR) << "Invalid new active device: " << new_active_device.ToString(); |
| 956 return false; | 1017 return false; |
| 957 } | 1018 } |
| 958 | 1019 |
| 959 // Set the current active input/output device to the new_active_device. | 1020 // Set the current active input/output device to the new_active_device. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 975 | 1036 |
| 976 SetActiveDevice(device, notify, activate_by); | 1037 SetActiveDevice(device, notify, activate_by); |
| 977 } | 1038 } |
| 978 | 1039 |
| 979 bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes, | 1040 bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes, |
| 980 bool is_input, | 1041 bool is_input, |
| 981 AudioDevicePriorityQueue* new_discovered, | 1042 AudioDevicePriorityQueue* new_discovered, |
| 982 bool* device_removed, | 1043 bool* device_removed, |
| 983 bool* active_device_removed) { | 1044 bool* active_device_removed) { |
| 984 *device_removed = false; | 1045 *device_removed = false; |
| 985 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 1046 for (const auto& item : audio_devices_) { |
| 986 it != audio_devices_.end(); ++it) { | 1047 const AudioDevice& device = item.second; |
| 987 const AudioDevice& device = it->second; | |
| 988 if (is_input != device.is_input) | 1048 if (is_input != device.is_input) |
| 989 continue; | 1049 continue; |
| 990 if (!IsDeviceInList(device, new_nodes)) { | 1050 if (!IsDeviceInList(device, new_nodes)) { |
| 991 *device_removed = true; | 1051 *device_removed = true; |
| 992 if ((is_input && device.id == active_input_node_id_) || | 1052 if ((is_input && device.id == active_input_node_id_) || |
| 993 (!is_input && device.id == active_output_node_id_)) { | 1053 (!is_input && device.id == active_output_node_id_)) { |
| 994 *active_device_removed = true; | 1054 *active_device_removed = true; |
| 995 } | 1055 } |
| 996 } | 1056 } |
| 997 } | 1057 } |
| 998 | 1058 |
| 999 bool new_or_changed_device = false; | 1059 bool new_or_changed_device = false; |
| 1000 while (!new_discovered->empty()) | 1060 while (!new_discovered->empty()) |
| 1001 new_discovered->pop(); | 1061 new_discovered->pop(); |
| 1002 for (AudioNodeList::const_iterator it = new_nodes.begin(); | 1062 |
| 1003 it != new_nodes.end(); ++it) { | 1063 for (const AudioNode& node : new_nodes) { |
| 1004 if (is_input != it->is_input) | 1064 if (is_input != node.is_input) |
| 1005 continue; | 1065 continue; |
| 1006 // Check if the new device is not in the old device list. | 1066 // Check if the new device is not in the old device list. |
| 1007 AudioDevice device(*it); | 1067 AudioDevice device(node); |
| 1008 DeviceStatus status = CheckDeviceStatus(device); | 1068 DeviceStatus status = CheckDeviceStatus(device); |
| 1009 if (status == NEW_DEVICE) | 1069 if (status == NEW_DEVICE) |
| 1010 new_discovered->push(device); | 1070 new_discovered->push(device); |
| 1011 if (status == NEW_DEVICE || status == CHANGED_DEVICE) { | 1071 if (status == NEW_DEVICE || status == CHANGED_DEVICE) { |
| 1012 new_or_changed_device = true; | 1072 new_or_changed_device = true; |
| 1013 } | 1073 } |
| 1014 } | 1074 } |
| 1015 return new_or_changed_device || *device_removed; | 1075 return new_or_changed_device || *device_removed; |
| 1016 } | 1076 } |
| 1017 | 1077 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1040 observer.OnActiveInputNodeChanged(); | 1100 observer.OnActiveInputNodeChanged(); |
| 1041 else | 1101 else |
| 1042 for (auto& observer : observers_) | 1102 for (auto& observer : observers_) |
| 1043 observer.OnActiveOutputNodeChanged(); | 1103 observer.OnActiveOutputNodeChanged(); |
| 1044 } | 1104 } |
| 1045 | 1105 |
| 1046 bool CrasAudioHandler::GetActiveDeviceFromUserPref(bool is_input, | 1106 bool CrasAudioHandler::GetActiveDeviceFromUserPref(bool is_input, |
| 1047 AudioDevice* active_device) { | 1107 AudioDevice* active_device) { |
| 1048 bool found_active_device = false; | 1108 bool found_active_device = false; |
| 1049 bool last_active_device_activate_by_user = false; | 1109 bool last_active_device_activate_by_user = false; |
| 1050 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 1110 for (const auto& item : audio_devices_) { |
| 1051 it != audio_devices_.end(); ++it) { | 1111 const AudioDevice& device = item.second; |
| 1052 AudioDevice device = it->second; | |
| 1053 if (device.is_input != is_input || !device.is_for_simple_usage()) | 1112 if (device.is_input != is_input || !device.is_for_simple_usage()) |
| 1054 continue; | 1113 continue; |
| 1055 | 1114 |
| 1056 bool active = false; | 1115 bool active = false; |
| 1057 bool activate_by_user = false; | 1116 bool activate_by_user = false; |
| 1058 // If the device entry is not found in prefs, it is likley a new audio | 1117 // If the device entry is not found in prefs, it is likley a new audio |
| 1059 // device plugged in after the cros is powered down. We should ignore the | 1118 // device plugged in after the cros is powered down. We should ignore the |
| 1060 // previously saved active device, and select the active device by priority. | 1119 // previously saved active device, and select the active device by priority. |
| 1061 // crbug.com/622045. | 1120 // crbug.com/622045. |
| 1062 if (!audio_pref_handler_->GetDeviceActive(device, &active, | 1121 if (!audio_pref_handler_->GetDeviceActive(device, &active, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 } else { | 1235 } else { |
| 1177 // Do not active the device if its previous state is inactive. | 1236 // Do not active the device if its previous state is inactive. |
| 1178 VLOG(1) << "Hotplug device remains inactive as its previous state:" | 1237 VLOG(1) << "Hotplug device remains inactive as its previous state:" |
| 1179 << hotplug_device.ToString(); | 1238 << hotplug_device.ToString(); |
| 1180 } | 1239 } |
| 1181 } | 1240 } |
| 1182 | 1241 |
| 1183 void CrasAudioHandler::SwitchToTopPriorityDevice(bool is_input) { | 1242 void CrasAudioHandler::SwitchToTopPriorityDevice(bool is_input) { |
| 1184 AudioDevice top_device = | 1243 AudioDevice top_device = |
| 1185 is_input ? input_devices_pq_.top() : output_devices_pq_.top(); | 1244 is_input ? input_devices_pq_.top() : output_devices_pq_.top(); |
| 1186 if (top_device.is_for_simple_usage()) | 1245 if (!top_device.is_for_simple_usage()) |
| 1187 SwitchToDevice(top_device, true, ACTIVATE_BY_PRIORITY); | 1246 return; |
| 1247 |
| 1248 // For the dual camera and dual microphone case, choose microphone |
| 1249 // that is consistent to the active camera. |
| 1250 if (IsFrontOrRearMic(top_device) && HasDualInternalMic() && IsCameraOn()) { |
| 1251 ActivateInternalMicForActiveCamera(); |
| 1252 return; |
| 1253 } |
| 1254 |
| 1255 SwitchToDevice(top_device, true, ACTIVATE_BY_PRIORITY); |
| 1188 } | 1256 } |
| 1189 | 1257 |
| 1190 void CrasAudioHandler::SwitchToPreviousActiveDeviceIfAvailable(bool is_input) { | 1258 void CrasAudioHandler::SwitchToPreviousActiveDeviceIfAvailable(bool is_input) { |
| 1191 AudioDevice previous_active_device; | 1259 AudioDevice previous_active_device; |
| 1192 if (GetActiveDeviceFromUserPref(is_input, &previous_active_device)) { | 1260 if (GetActiveDeviceFromUserPref(is_input, &previous_active_device)) { |
| 1193 DCHECK(previous_active_device.is_for_simple_usage()); | 1261 DCHECK(previous_active_device.is_for_simple_usage()); |
| 1194 // Switch to previous active device stored in user prefs. | 1262 // Switch to previous active device stored in user prefs. |
| 1195 SwitchToDevice(previous_active_device, true, | 1263 SwitchToDevice(previous_active_device, true, |
| 1196 ACTIVATE_BY_RESTORE_PREVIOUS_STATE); | 1264 ACTIVATE_BY_RESTORE_PREVIOUS_STATE); |
| 1197 } else { | 1265 } else { |
| 1198 // No previous active device, switch to the top priority device. | 1266 // No previous active device, switch to the top priority device. |
| 1199 SwitchToTopPriorityDevice(is_input); | 1267 SwitchToTopPriorityDevice(is_input); |
| 1200 } | 1268 } |
| 1201 } | 1269 } |
| 1202 | 1270 |
| 1203 void CrasAudioHandler::UpdateDevicesAndSwitchActive( | 1271 void CrasAudioHandler::UpdateDevicesAndSwitchActive( |
| 1204 const AudioNodeList& nodes) { | 1272 const AudioNodeList& nodes) { |
| 1205 size_t old_output_device_size = 0; | 1273 size_t old_output_device_size = 0; |
| 1206 size_t old_input_device_size = 0; | 1274 size_t old_input_device_size = 0; |
| 1207 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); | 1275 for (const auto& item : audio_devices_) { |
| 1208 it != audio_devices_.end(); ++it) { | 1276 const AudioDevice& device = item.second; |
| 1209 if (it->second.is_input) | 1277 if (device.is_input) |
| 1210 ++old_input_device_size; | 1278 ++old_input_device_size; |
| 1211 else | 1279 else |
| 1212 ++old_output_device_size; | 1280 ++old_output_device_size; |
| 1213 } | 1281 } |
| 1214 | 1282 |
| 1215 AudioDevicePriorityQueue hotplug_output_nodes; | 1283 AudioDevicePriorityQueue hotplug_output_nodes; |
| 1216 AudioDevicePriorityQueue hotplug_input_nodes; | 1284 AudioDevicePriorityQueue hotplug_input_nodes; |
| 1217 bool has_output_removed = false; | 1285 bool has_output_removed = false; |
| 1218 bool has_input_removed = false; | 1286 bool has_input_removed = false; |
| 1219 bool active_output_removed = false; | 1287 bool active_output_removed = false; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 FROM_HERE, base::TimeDelta::FromMilliseconds( | 1484 FROM_HERE, base::TimeDelta::FromMilliseconds( |
| 1417 hdmi_rediscover_grace_period_duration_in_ms_), | 1485 hdmi_rediscover_grace_period_duration_in_ms_), |
| 1418 this, &CrasAudioHandler::UpdateAudioAfterHDMIRediscoverGracePeriod); | 1486 this, &CrasAudioHandler::UpdateAudioAfterHDMIRediscoverGracePeriod); |
| 1419 } | 1487 } |
| 1420 | 1488 |
| 1421 void CrasAudioHandler::SetHDMIRediscoverGracePeriodForTesting( | 1489 void CrasAudioHandler::SetHDMIRediscoverGracePeriodForTesting( |
| 1422 int duration_in_ms) { | 1490 int duration_in_ms) { |
| 1423 hdmi_rediscover_grace_period_duration_in_ms_ = duration_in_ms; | 1491 hdmi_rediscover_grace_period_duration_in_ms_ = duration_in_ms; |
| 1424 } | 1492 } |
| 1425 | 1493 |
| 1494 void CrasAudioHandler::ActivateMicForCamera( |
| 1495 media::VideoFacingMode camera_facing) { |
| 1496 const AudioDevice* mic = GetMicForCamera(camera_facing); |
| 1497 if (!mic || mic->active) |
| 1498 return; |
| 1499 |
| 1500 SwitchToDevice(*mic, true, ACTIVATE_BY_CAMERA); |
| 1501 } |
| 1502 |
| 1503 void CrasAudioHandler::ActivateInternalMicForActiveCamera() { |
| 1504 DCHECK(IsCameraOn()); |
| 1505 if (HasDualInternalMic()) { |
| 1506 media::VideoFacingMode facing = front_camera_on_ |
| 1507 ? media::MEDIA_VIDEO_FACING_USER |
| 1508 : media::MEDIA_VIDEO_FACING_ENVIRONMENT; |
| 1509 ActivateMicForCamera(facing); |
| 1510 } |
| 1511 } |
| 1512 |
| 1513 // For the dual microphone case, from user point of view, they only see internal |
| 1514 // microphone in UI. Chrome will make the best decision on which one to pick. |
| 1515 // If the camera is off, the front microphone should be picked as the default |
| 1516 // active microphone. Otherwise, it will switch to the microphone that |
| 1517 // matches the active camera, i.e. front microphone for front camera and |
| 1518 // rear microphone for rear camera. |
| 1519 void CrasAudioHandler::SwitchToFrontOrRearMic() { |
| 1520 DCHECK(HasDualInternalMic()); |
| 1521 if (IsCameraOn()) { |
| 1522 ActivateInternalMicForActiveCamera(); |
| 1523 } else { |
| 1524 SwitchToDevice(*GetDeviceByType(AUDIO_TYPE_FRONT_MIC), true, |
| 1525 ACTIVATE_BY_USER); |
| 1526 } |
| 1527 } |
| 1528 |
| 1529 const AudioDevice* CrasAudioHandler::GetMicForCamera( |
| 1530 media::VideoFacingMode camera_facing) { |
| 1531 switch (camera_facing) { |
| 1532 case media::MEDIA_VIDEO_FACING_USER: |
| 1533 return GetDeviceByType(AUDIO_TYPE_FRONT_MIC); |
| 1534 case media::MEDIA_VIDEO_FACING_ENVIRONMENT: |
| 1535 return GetDeviceByType(AUDIO_TYPE_REAR_MIC); |
| 1536 default: |
| 1537 NOTREACHED(); |
| 1538 } |
| 1539 return nullptr; |
| 1540 } |
| 1541 |
| 1542 const AudioDevice* CrasAudioHandler::GetDeviceByType(AudioDeviceType type) { |
| 1543 for (const auto& item : audio_devices_) { |
| 1544 const AudioDevice& device = item.second; |
| 1545 if (device.type == type) |
| 1546 return &device; |
| 1547 } |
| 1548 return nullptr; |
| 1549 } |
| 1550 |
| 1551 bool CrasAudioHandler::HasDualInternalMic() const { |
| 1552 bool has_front_mic = false; |
| 1553 bool has_rear_mic = false; |
| 1554 for (const auto& item : audio_devices_) { |
| 1555 const AudioDevice& device = item.second; |
| 1556 if (device.type == AUDIO_TYPE_FRONT_MIC) |
| 1557 has_front_mic = true; |
| 1558 else if (device.type == AUDIO_TYPE_REAR_MIC) |
| 1559 has_rear_mic = true; |
| 1560 if (has_front_mic && has_rear_mic) |
| 1561 break; |
| 1562 } |
| 1563 return has_front_mic && has_rear_mic; |
| 1564 } |
| 1565 |
| 1566 bool CrasAudioHandler::IsFrontOrRearMic(const AudioDevice& device) const { |
| 1567 return device.is_input && (device.type == AUDIO_TYPE_FRONT_MIC || |
| 1568 device.type == AUDIO_TYPE_REAR_MIC); |
| 1569 } |
| 1570 |
| 1571 bool CrasAudioHandler::IsCameraOn() const { |
| 1572 return front_camera_on_ || rear_camera_on_; |
| 1573 } |
| 1574 |
| 1575 bool CrasAudioHandler::HasExternalDevice(bool is_input) const { |
| 1576 for (const auto& item : audio_devices_) { |
| 1577 const AudioDevice& device = item.second; |
| 1578 if (is_input == device.is_input && device.IsExternalDevice()) |
| 1579 return true; |
| 1580 } |
| 1581 return false; |
| 1582 } |
| 1583 |
| 1426 } // namespace chromeos | 1584 } // namespace chromeos |
| OLD | NEW |