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

Unified 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: Fix test issue. Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: chromeos/audio/cras_audio_handler.cc
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc
index 444eab643cbb4ab81cc8aef0975e9c0b7199c49c..2fd99768ccf5a96de4c9afc29253f4f180319850 100644
--- a/chromeos/audio/cras_audio_handler.cc
+++ b/chromeos/audio/cras_audio_handler.cc
@@ -41,7 +41,7 @@ const std::vector<double> kStereoToMono = {0.5, 0.5, 0.5, 0.5};
// Mixer matrix, [1, 0; 0, 1]
const std::vector<double> kStereoToStereo = {1, 0, 0, 1};
-static CrasAudioHandler* g_cras_audio_handler = NULL;
+static CrasAudioHandler* g_cras_audio_handler = nullptr;
bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) {
return a.stable_device_id == b.stable_device_id && a.is_input == b.is_input &&
@@ -111,12 +111,12 @@ void CrasAudioHandler::InitializeForTesting() {
void CrasAudioHandler::Shutdown() {
CHECK(g_cras_audio_handler);
delete g_cras_audio_handler;
- g_cras_audio_handler = NULL;
+ g_cras_audio_handler = nullptr;
}
// static
bool CrasAudioHandler::IsInitialized() {
- return g_cras_audio_handler != NULL;
+ return g_cras_audio_handler != nullptr;
}
// static
@@ -127,11 +127,54 @@ CrasAudioHandler* CrasAudioHandler::Get() {
}
void CrasAudioHandler::OnVideoCaptureStarted(media::VideoFacingMode facing) {
- // TODO(jennyz): Switch active audio device according to video facing.
+ // Do nothing if the device doesn't have both front and rear microphones.
+ if (!HasDualInternalMic())
+ return;
+ switch (facing) {
+ case media::MEDIA_VIDEO_FACING_USER:
+ front_camera_on_ = true;
+ break;
+ case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
+ rear_camera_on_ = true;
+ break;
+ default:
+ NOTREACHED();
shenghao 2017/03/01 11:25:55 I am not 100% sure but I think it's possible to re
jennyz 2017/03/02 17:31:40 I need to know in which scenario it will pass MEDI
shenghao 2017/03/03 03:45:21 Since external camera has MEDIA_VIDEO_FACING_NONE,
jennyz 2017/03/03 19:35:15 Done.
+ }
+
+ // If the current active input is an external device, keep it.
+ const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_);
+ if (active_input && active_input->IsExternalDevice())
+ return;
+
+ // Activate the correct mic for the current active camera.
+ ActivateMicForCamera(facing);
}
void CrasAudioHandler::OnVideoCaptureStopped(media::VideoFacingMode facing) {
- // TODO(jennyz): Switch active audio device according to video facing.
+ // Do nothing if the device doesn't have both front and rear microphones.
+ if (!HasDualInternalMic())
+ return;
+
+ switch (facing) {
+ case media::MEDIA_VIDEO_FACING_USER:
+ front_camera_on_ = false;
+ break;
+ case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
+ rear_camera_on_ = false;
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ // If the current active input is an external device, keep it.
+ const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_);
+ if (active_input && active_input->IsExternalDevice())
+ return;
+
+ // Switch to front mic properly.
shenghao 2017/03/01 11:25:55 Why is it "front mic"? Do you mean "correct mic"?
jennyz 2017/03/02 17:31:41 In R58, chrome code will only handle the dual came
+ DeviceActivateType activate_by =
shenghao 2017/03/01 11:25:55 s/activate_by/activated_by/
jennyz 2017/03/02 17:31:41 Done.
+ HasExternalDevice(true) ? ACTIVATE_BY_USER : ACTIVATE_BY_PRIORITY;
+ SwitchToDevice(*GetDeviceByType(AUDIO_TYPE_FRONT_MIC), true, activate_by);
shenghao 2017/03/01 11:25:55 Why do we also switch to AUDIO_TYPE_FRONT_MIC? Is
shenghao 2017/03/01 11:27:54 typo: also => always
jennyz 2017/03/02 17:31:40 Acknowledged.
jennyz 2017/03/02 17:31:41 See comments above.
}
void CrasAudioHandler::AddAudioObserver(AudioObserver* observer) {
@@ -143,7 +186,7 @@ void CrasAudioHandler::RemoveAudioObserver(AudioObserver* observer) {
}
bool CrasAudioHandler::HasKeyboardMic() {
- return GetKeyboardMic() != NULL;
+ return GetKeyboardMic() != nullptr;
}
bool CrasAudioHandler::IsOutputMuted() {
@@ -604,7 +647,7 @@ CrasAudioHandler::~CrasAudioHandler() {
RemoveObserver(this);
if (audio_pref_handler_.get())
audio_pref_handler_->RemoveAudioPrefObserver(this);
- audio_pref_handler_ = NULL;
+ audio_pref_handler_ = nullptr;
}
void CrasAudioHandler::AudioClientRestarted() {
@@ -712,7 +755,7 @@ void CrasAudioHandler::EmitLoginPromptVisibleCalled() {
const AudioDevice* CrasAudioHandler::GetDeviceFromId(uint64_t device_id) const {
AudioDeviceMap::const_iterator it = audio_devices_.find(device_id);
if (it == audio_devices_.end())
- return NULL;
+ return nullptr;
return &(it->second);
}
@@ -724,7 +767,7 @@ const AudioDevice* CrasAudioHandler::GetDeviceFromStableDeviceId(
if (it->second.stable_device_id == stable_device_id)
return &(it->second);
}
- return NULL;
+ return nullptr;
}
const AudioDevice* CrasAudioHandler::GetKeyboardMic() const {
@@ -733,7 +776,7 @@ const AudioDevice* CrasAudioHandler::GetKeyboardMic() const {
if (it->second.is_input && it->second.type == AUDIO_TYPE_KEYBOARD_MIC)
return &(it->second);
}
- return NULL;
+ return nullptr;
}
void CrasAudioHandler::SetupAudioInputState() {
@@ -1183,8 +1226,20 @@ void CrasAudioHandler::HandleHotPlugDevice(
void CrasAudioHandler::SwitchToTopPriorityDevice(bool is_input) {
AudioDevice top_device =
is_input ? input_devices_pq_.top() : output_devices_pq_.top();
- if (top_device.is_for_simple_usage())
- SwitchToDevice(top_device, true, ACTIVATE_BY_PRIORITY);
+ if (!top_device.is_for_simple_usage())
+ return;
+
+ // For the dual camera and dual microphone case, choose microphone
+ // that is consistent to the active camera.
+ if (IsFrontOrRearMic(top_device) && HasDualInternalMic() && IsCameraOn()) {
shenghao 2017/03/01 11:25:55 I think you can write: if (IsFrontOrRearMic(top_d
jennyz 2017/03/02 17:31:40 The above code is not equivalent to the original l
+ media::VideoFacingMode facing = front_camera_on_
+ ? media::MEDIA_VIDEO_FACING_USER
+ : media::MEDIA_VIDEO_FACING_ENVIRONMENT;
+ ActivateMicForCamera(facing);
+ return;
+ }
+
+ SwitchToDevice(top_device, true, ACTIVATE_BY_PRIORITY);
}
void CrasAudioHandler::SwitchToPreviousActiveDeviceIfAvailable(bool is_input) {
@@ -1423,4 +1478,94 @@ void CrasAudioHandler::SetHDMIRediscoverGracePeriodForTesting(
hdmi_rediscover_grace_period_duration_in_ms_ = duration_in_ms;
}
+void CrasAudioHandler::ActivateMicForCamera(
+ media::VideoFacingMode camera_facing) {
+ const AudioDevice* mic = GetMicForCamera(camera_facing);
+ if (!mic || mic->active)
+ return;
+
+ SwitchToDevice(*mic, true, ACTIVATE_BY_CAMERA);
+}
+
+void CrasAudioHandler::ActivateInternalMicForActiveCamera() {
+ if (HasDualInternalMic() && IsCameraOn()) {
+ media::VideoFacingMode facing = front_camera_on_
+ ? media::MEDIA_VIDEO_FACING_USER
+ : media::MEDIA_VIDEO_FACING_ENVIRONMENT;
+ ActivateMicForCamera(facing);
+ }
+}
+
+// For the dual microphone case, from user point of view, they only see internal
+// microphone in UI. Chrome will make the best decision on which one to pick.
+// If the camera is off, the front microphone should be picked as the default
+// active microphone. Otherwise, it will switch to the microphone that
+// matches the active camera, i.e. front microphone for front camera and
+// reaa microphone for rear camera.
shenghao 2017/03/01 11:25:55 s/reaa/rear/
jennyz 2017/03/02 17:31:41 Done.
+void CrasAudioHandler::SwitchToFrontOrRearMic() {
+ DCHECK(HasDualInternalMic());
+ if (IsCameraOn()) {
shenghao 2017/03/01 11:25:55 Why do we need to check IsCameraOn() twice here an
jennyz 2017/03/02 17:31:40 Removed IsCameraOn() from 1491.
+ ActivateInternalMicForActiveCamera();
+ } else {
+ SwitchToDevice(*GetDeviceByType(AUDIO_TYPE_FRONT_MIC), true,
+ ACTIVATE_BY_USER);
+ }
+}
+
+const AudioDevice* CrasAudioHandler::GetMicForCamera(
+ media::VideoFacingMode camera_facing) {
+ switch (camera_facing) {
+ case media::MEDIA_VIDEO_FACING_USER:
+ return GetDeviceByType(AUDIO_TYPE_FRONT_MIC);
+ case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
+ return GetDeviceByType(AUDIO_TYPE_REAR_MIC);
+ break;
shenghao 2017/03/01 11:25:55 You don't need "break" here because of the return
jennyz 2017/03/02 17:31:40 Done.
+ default:
+ NOTREACHED();
shenghao 2017/03/01 11:25:55 Same as line 141
jennyz 2017/03/02 17:31:41 This code path is not reachable, the code path to
+ }
+ return nullptr;
+}
+
+const AudioDevice* CrasAudioHandler::GetDeviceByType(AudioDeviceType type) {
+ for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
shenghao 2017/03/01 11:25:55 For all the "AudioDeviceMap::const_iterator", can
jennyz 2017/03/02 17:31:40 Done.
+ it != audio_devices_.end(); ++it) {
+ if (it->second.type == type)
+ return &(it->second);
+ }
+ return nullptr;
+}
+
+bool CrasAudioHandler::HasDualInternalMic() const {
+ bool has_front_mic = false;
+ bool has_rear_mic = false;
+ for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
+ it != audio_devices_.end(); ++it) {
+ if (it->second.type == AUDIO_TYPE_FRONT_MIC)
+ has_front_mic = true;
+ else if (it->second.type == AUDIO_TYPE_REAR_MIC)
+ has_rear_mic = true;
+ if (has_front_mic && has_rear_mic)
+ break;
+ }
+ return has_front_mic && has_rear_mic;
+}
+
+bool CrasAudioHandler::IsFrontOrRearMic(const AudioDevice& device) const {
+ return device.is_input && (device.type == AUDIO_TYPE_FRONT_MIC ||
+ device.type == AUDIO_TYPE_REAR_MIC);
+}
+
+bool CrasAudioHandler::IsCameraOn() const {
+ return front_camera_on_ || rear_camera_on_;
+}
+
+bool CrasAudioHandler::HasExternalDevice(bool is_input) const {
shenghao 2017/03/01 11:25:55 It seems that this method is only called in one pl
jennyz 2017/03/02 17:31:40 I would rather keep it just in case it could be us
+ for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
+ it != audio_devices_.end(); ++it) {
+ if (is_input == it->second.is_input && it->second.IsExternalDevice())
+ return true;
+ }
+ return false;
+}
+
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698