From 653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0 Mon Sep 17 00:00:00 2001 From: jiabin Date: Wed, 17 Jan 2018 17:54:10 -0800 Subject: [PATCH] Support query active microphones information in AudioRecord. This is part of device enumeration. With the new add API, developer could get the active microphones information for each channel. Bug: 64038649 Test: Run cts and check the print log. Change-Id: Ic63d86e533a30e40697da7522a5a81f7cfcea988 --- media/libaudioclient/AudioRecord.cpp | 8 ++++ .../aidl/android/media/IAudioRecord.aidl | 6 +++ .../include/media/AudioRecord.h | 7 +++ services/audioflinger/AudioFlinger.h | 2 + services/audioflinger/RecordTracks.h | 2 + services/audioflinger/Threads.cpp | 43 +++++++++++++++++++ services/audioflinger/Threads.h | 2 + services/audioflinger/Tracks.cpp | 19 ++++++++ 8 files changed, 89 insertions(+) diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp index 3aebb8a0a4..6b3a8f02ca 100644 --- a/media/libaudioclient/AudioRecord.cpp +++ b/media/libaudioclient/AudioRecord.cpp @@ -1316,6 +1316,14 @@ void AudioRecord::onAudioDeviceUpdate(audio_io_handle_t audioIo, } } +// ------------------------------------------------------------------------- + +status_t AudioRecord::getActiveMicrophones(std::vector* activeMicrophones) +{ + AutoMutex lock(mLock); + return mAudioRecord->getActiveMicrophones(activeMicrophones).transactionError(); +} + // ========================================================================= void AudioRecord::DeathNotifier::binderDied(const wp& who __unused) diff --git a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl index 7572671383..01e0a7160f 100644 --- a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl +++ b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl @@ -16,6 +16,8 @@ package android.media; +import android.media.MicrophoneInfo; + /* Native code must specify namespace media (media::IAudioRecord) when referring to this class */ interface IAudioRecord { @@ -30,4 +32,8 @@ interface IAudioRecord { * will be processed, unless flush() is called. */ void stop(); + + /* Get a list of current active microphones. + */ + void getActiveMicrophones(out MicrophoneInfo[] activeMicrophones); } diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h index caaefce11b..a82e21eb85 100644 --- a/media/libaudioclient/include/media/AudioRecord.h +++ b/media/libaudioclient/include/media/AudioRecord.h @@ -23,8 +23,10 @@ #include #include #include +#include #include #include +#include #include "android/media/IAudioRecord.h" @@ -527,6 +529,11 @@ public: /* Get the flags */ audio_input_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; } + /* Get active microphones. A empty vector of MicrophoneInfo will be passed as a parameter, + * the data will be filled when querying the hal. + */ + status_t getActiveMicrophones(std::vector* activeMicrophones); + /* * Dumps the state of an audio record. */ diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 83caca7408..7c38bccafa 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -559,6 +559,8 @@ using effect_buffer_t = int16_t; virtual binder::Status start(int /*AudioSystem::sync_event_t*/ event, int /*audio_session_t*/ triggerSession); virtual binder::Status stop(); + virtual binder::Status getActiveMicrophones( + std::vector* activeMicrophones); private: const sp mRecordTrack; diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h index 63a3d9882d..1733ef56f4 100644 --- a/services/audioflinger/RecordTracks.h +++ b/services/audioflinger/RecordTracks.h @@ -66,6 +66,8 @@ public: void setSilenced(bool silenced) { mSilenced = silenced; } bool isSilenced() const { return mSilenced; } + status_t getActiveMicrophones(std::vector* activeMicrophones); + private: friend class AudioFlinger; // for mState diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 7bfe802947..f8fa094ce9 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -7042,6 +7042,49 @@ status_t AudioFlinger::RecordThread::setSyncEvent(const sp& event __u #endif } +status_t AudioFlinger::RecordThread::getActiveMicrophones( + std::vector* activeMicrophones) +{ + ALOGV("RecordThread::getActiveMicrophones"); + AutoMutex _l(mLock); + // Fake data + struct audio_microphone_characteristic_t characteristic; + sprintf(characteristic.device_id, "builtin_mic"); + characteristic.type = AUDIO_DEVICE_IN_BUILTIN_MIC; + sprintf(characteristic.address, ""); + characteristic.location = AUDIO_MICROPHONE_LOCATION_MAINBODY; + characteristic.group = 0; + characteristic.index_in_the_group = 0; + characteristic.sensitivity = 1.0f; + characteristic.max_spl = 100.0f; + characteristic.min_spl = 0.0f; + characteristic.directionality = AUDIO_MICROPHONE_DIRECTIONALITY_OMNI; + characteristic.num_frequency_responses = 5; + for (size_t i = 0; i < characteristic.num_frequency_responses; i++) { + characteristic.frequency_responses[0][i] = 100.0f - i; + characteristic.frequency_responses[1][i] = 100.0f + i; + } + for (size_t i = 0; i < AUDIO_CHANNEL_COUNT_MAX; i++) { + characteristic.channel_mapping[i] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED; + } + audio_microphone_channel_mapping_t channel_mappings[] = { + AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT, + AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED, + }; + for (size_t i = 0; i < mChannelCount; i++) { + characteristic.channel_mapping[i] = channel_mappings[i % 2]; + } + characteristic.geometric_location.x = 0.1f; + characteristic.geometric_location.y = 0.2f; + characteristic.geometric_location.z = 0.3f; + characteristic.orientation.x = 0.0f; + characteristic.orientation.y = 1.0f; + characteristic.orientation.z = 0.0f; + media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(characteristic); + activeMicrophones->push_back(microphoneInfo); + return NO_ERROR; +} + // destroyTrack_l() must be called with ThreadBase::mLock held void AudioFlinger::RecordThread::destroyTrack_l(const sp& track) { diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index eb29497dd9..53cb8adccb 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -1398,6 +1398,8 @@ public: // Sets the UID records silence void setRecordSilenced(uid_t uid, bool silenced); + status_t getActiveMicrophones(std::vector* activeMicrophones); + private: // Enter standby if not already in standby, and set mStandby flag void standbyIfNotAlreadyInStandby(); diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 06bbf1e395..67f27d0d33 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -1580,6 +1580,13 @@ void AudioFlinger::RecordHandle::stop_nonvirtual() { mRecordTrack->stop(); } +binder::Status AudioFlinger::RecordHandle::getActiveMicrophones( + std::vector* activeMicrophones) { + ALOGV("RecordHandle::getActiveMicrophones()"); + return binder::Status::fromStatusT( + mRecordTrack->getActiveMicrophones(activeMicrophones)); +} + // ---------------------------------------------------------------------------- // RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held @@ -1792,6 +1799,18 @@ void AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo( mServerProxy->setTimestamp(local); } +status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones( + std::vector* activeMicrophones) +{ + sp thread = mThread.promote(); + if (thread != 0) { + RecordThread *recordThread = (RecordThread *)thread.get(); + return recordThread->getActiveMicrophones(activeMicrophones); + } else { + return BAD_VALUE; + } +} + AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread, uint32_t sampleRate, audio_channel_mask_t channelMask,