Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(666)

Side by Side Diff: chromeos/audio/cras_audio_handler.cc

Issue 2721733003: Handle the dual microphones and dual cameras cases. Activate the proper microphone when user activa… (Closed)
Patch Set: Nit: log only the invalid camera facing mode value. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/audio/cras_audio_handler.h ('k') | chromeos/audio/cras_audio_handler_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chromeos/audio/cras_audio_handler.h ('k') | chromeos/audio/cras_audio_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698