Support query microphones information.

Get list of all/currently active microphones from hal.

Bug: 64038649
Test: Manual Testing and Cts test
Change-Id: Id39cae38ba040f9bc91571e713487f87c2eb67b0
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 3358e35..ec8ba1c 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -86,7 +86,7 @@
     GET_AUDIO_HW_SYNC_FOR_SESSION,
     SYSTEM_READY,
     FRAME_COUNT_HAL,
-    LIST_MICROPHONES,
+    GET_MICROPHONES,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -848,7 +848,7 @@
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        status_t status = remote()->transact(LIST_MICROPHONES, data, &reply);
+        status_t status = remote()->transact(GET_MICROPHONES, data, &reply);
         if (status != NO_ERROR ||
                 (status = (status_t)reply.readInt32()) != NO_ERROR) {
             return status;
@@ -1439,7 +1439,7 @@
             reply->writeInt64( frameCountHAL((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
-        case LIST_MICROPHONES: {
+        case GET_MICROPHONES: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             std::vector<media::MicrophoneInfo> microphones;
             status_t status = getMicrophones(&microphones);
diff --git a/media/libaudiohal/2.0/DeviceHalHidl.cpp b/media/libaudiohal/2.0/DeviceHalHidl.cpp
index 0d9c6c4..63626e3 100644
--- a/media/libaudiohal/2.0/DeviceHalHidl.cpp
+++ b/media/libaudiohal/2.0/DeviceHalHidl.cpp
@@ -346,6 +346,12 @@
     return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
 }
 
+status_t DeviceHalHidl::getMicrophones(
+        std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
+    if (mDevice == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
 status_t DeviceHalHidl::dump(int fd) {
     if (mDevice == 0) return NO_INIT;
     native_handle_t* hidlHandle = native_handle_create(1, 0);
diff --git a/media/libaudiohal/2.0/DeviceHalHidl.h b/media/libaudiohal/2.0/DeviceHalHidl.h
index 8651b51..3c1cb59 100644
--- a/media/libaudiohal/2.0/DeviceHalHidl.h
+++ b/media/libaudiohal/2.0/DeviceHalHidl.h
@@ -107,6 +107,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
   private:
diff --git a/media/libaudiohal/2.0/DeviceHalLocal.cpp b/media/libaudiohal/2.0/DeviceHalLocal.cpp
index fc098f5..ec3bf78 100644
--- a/media/libaudiohal/2.0/DeviceHalLocal.cpp
+++ b/media/libaudiohal/2.0/DeviceHalLocal.cpp
@@ -184,6 +184,11 @@
         return INVALID_OPERATION;
 }
 
+status_t DeviceHalLocal::getMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    return INVALID_OPERATION;
+}
+
 status_t DeviceHalLocal::dump(int fd) {
     return mDev->dump(mDev, fd);
 }
diff --git a/media/libaudiohal/2.0/DeviceHalLocal.h b/media/libaudiohal/2.0/DeviceHalLocal.h
index 865f296..aec201a 100644
--- a/media/libaudiohal/2.0/DeviceHalLocal.h
+++ b/media/libaudiohal/2.0/DeviceHalLocal.h
@@ -100,6 +100,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
     void closeOutputStream(struct audio_stream_out *stream_out);
diff --git a/media/libaudiohal/2.0/StreamHalHidl.cpp b/media/libaudiohal/2.0/StreamHalHidl.cpp
index 0cafa36..ed90bf4 100644
--- a/media/libaudiohal/2.0/StreamHalHidl.cpp
+++ b/media/libaudiohal/2.0/StreamHalHidl.cpp
@@ -749,4 +749,10 @@
     }
 }
 
+status_t StreamInHalHidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/2.0/StreamHalHidl.h b/media/libaudiohal/2.0/StreamHalHidl.h
index d4ab943..7568399 100644
--- a/media/libaudiohal/2.0/StreamHalHidl.h
+++ b/media/libaudiohal/2.0/StreamHalHidl.h
@@ -210,6 +210,9 @@
     // the clock time associated with that frame count.
     virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
   private:
     friend class DeviceHalHidl;
     typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
diff --git a/media/libaudiohal/2.0/StreamHalLocal.cpp b/media/libaudiohal/2.0/StreamHalLocal.cpp
index 8d61e24..bf1400e 100644
--- a/media/libaudiohal/2.0/StreamHalLocal.cpp
+++ b/media/libaudiohal/2.0/StreamHalLocal.cpp
@@ -313,4 +313,9 @@
     return mStream->get_mmap_position(mStream, position);
 }
 
+status_t StreamInHalLocal::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    return INVALID_OPERATION;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/2.0/StreamHalLocal.h b/media/libaudiohal/2.0/StreamHalLocal.h
index c7136df..ebebf4e 100644
--- a/media/libaudiohal/2.0/StreamHalLocal.h
+++ b/media/libaudiohal/2.0/StreamHalLocal.h
@@ -194,6 +194,9 @@
     // Get current read/write position in the mmap buffer
     virtual status_t getMmapPosition(struct audio_mmap_position *position);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
   private:
     audio_stream_in_t *mStream;
 
diff --git a/media/libaudiohal/4.0/Android.bp b/media/libaudiohal/4.0/Android.bp
index 3d104ab..833defa 100644
--- a/media/libaudiohal/4.0/Android.bp
+++ b/media/libaudiohal/4.0/Android.bp
@@ -26,6 +26,7 @@
     shared_libs: [
         "libaudiohal_deathhandler",
         "libaudioutils",
+        "libbinder",
         "libcutils",
         "liblog",
         "libutils",
diff --git a/media/libaudiohal/4.0/ConversionHelperHidl.cpp b/media/libaudiohal/4.0/ConversionHelperHidl.cpp
index a3cc28f..fe27504 100644
--- a/media/libaudiohal/4.0/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/4.0/ConversionHelperHidl.cpp
@@ -22,6 +22,11 @@
 
 #include "ConversionHelperHidl.h"
 
+using ::android::hardware::audio::V4_0::AudioMicrophoneChannelMapping;
+using ::android::hardware::audio::V4_0::AudioMicrophoneDirectionality;
+using ::android::hardware::audio::V4_0::AudioMicrophoneLocation;
+using ::android::hardware::audio::V4_0::DeviceAddress;
+using ::android::hardware::audio::V4_0::MicrophoneInfo;
 using ::android::hardware::audio::V4_0::Result;
 
 namespace android {
@@ -101,5 +106,132 @@
     ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
 }
 
+// TODO: Use the same implementation in the hal when it moves to a util library.
+std::string deviceAddressToHal(const DeviceAddress& address) {
+    // HAL assumes that the address is NUL-terminated.
+    char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+    memset(halAddress, 0, sizeof(halAddress));
+    audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
+    const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
+    if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
+    if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
+        (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
+                 address.address.mac[0], address.address.mac[1], address.address.mac[2],
+                 address.address.mac[3], address.address.mac[4], address.address.mac[5]);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
+                 address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
+                 address.address.alsa.device);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
+    } else {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
+    }
+    return halAddress;
+}
+
+//local conversion helpers
+
+audio_microphone_channel_mapping_t  channelMappingToHal(AudioMicrophoneChannelMapping mapping) {
+    switch (mapping) {
+        case AudioMicrophoneChannelMapping::UNUSED:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+        case AudioMicrophoneChannelMapping::DIRECT:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
+        case AudioMicrophoneChannelMapping::PROCESSED:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
+        default:
+            LOG_ALWAYS_FATAL("Unknown channelMappingToHal conversion %d", mapping);
+    }
+}
+
+audio_microphone_location_t locationToHal(AudioMicrophoneLocation location) {
+    switch (location) {
+        case AudioMicrophoneLocation::UNKNOWN:
+            return AUDIO_MICROPHONE_LOCATION_UNKNOWN;
+        case AudioMicrophoneLocation::MAINBODY:
+            return AUDIO_MICROPHONE_LOCATION_MAINBODY;
+        case AudioMicrophoneLocation::MAINBODY_MOVABLE:
+            return AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE;
+        case AudioMicrophoneLocation::PERIPHERAL:
+            return AUDIO_MICROPHONE_LOCATION_PERIPHERAL;
+        default:
+            LOG_ALWAYS_FATAL("Unknown locationToHal conversion %d", location);
+    }
+}
+audio_microphone_directionality_t directionalityToHal(AudioMicrophoneDirectionality dir) {
+    switch (dir) {
+        case AudioMicrophoneDirectionality::UNKNOWN:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
+        case AudioMicrophoneDirectionality::OMNI:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
+        case AudioMicrophoneDirectionality::BI_DIRECTIONAL:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL;
+        case AudioMicrophoneDirectionality::CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID;
+        case AudioMicrophoneDirectionality::HYPER_CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID;
+        case AudioMicrophoneDirectionality::SUPER_CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID;
+        default:
+            LOG_ALWAYS_FATAL("Unknown directionalityToHal conversion %d", dir);
+    }
+}
+
+// static
+void ConversionHelperHidl::microphoneInfoToHal(const MicrophoneInfo& src,
+                                                     audio_microphone_characteristic_t *pDst) {
+    if (pDst != NULL) {
+        snprintf(pDst->device_id, sizeof(pDst->device_id),
+                 "%s", src.deviceId.c_str());
+        pDst->device = static_cast<audio_devices_t>(src.deviceAddress.device);
+        snprintf(pDst->address, sizeof(pDst->address),
+                 "%s", deviceAddressToHal(src.deviceAddress).c_str());
+        if (src.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
+            ALOGW("microphoneInfoToStruct found %zu channelMapping elements. Max expected is %d",
+                  src.channelMapping.size(), AUDIO_CHANNEL_COUNT_MAX);
+        }
+        size_t ch;
+        for (ch = 0; ch < src.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+            pDst->channel_mapping[ch] = channelMappingToHal(src.channelMapping[ch]);
+        }
+        for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+            pDst->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+        }
+        pDst->location = locationToHal(src.location);
+        pDst->group = (audio_microphone_group_t)src.group;
+        pDst->index_in_the_group = (unsigned int)src.indexInTheGroup;
+        pDst->sensitivity = src.sensitivity;
+        pDst->max_spl = src.maxSpl;
+        pDst->min_spl = src.minSpl;
+        pDst->directionality = directionalityToHal(src.directionality);
+        pDst->num_frequency_responses = (unsigned int)src.frequencyResponse.size();
+        if (pDst->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+            ALOGW("microphoneInfoToStruct found %d frequency responses. Max expected is %d",
+                  pDst->num_frequency_responses, AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES);
+            pDst->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES;
+        }
+        for (size_t k = 0; k < pDst->num_frequency_responses; k++) {
+            pDst->frequency_responses[0][k] = src.frequencyResponse[k].frequency;
+            pDst->frequency_responses[1][k] = src.frequencyResponse[k].level;
+        }
+        pDst->geometric_location.x = src.position.x;
+        pDst->geometric_location.y = src.position.y;
+        pDst->geometric_location.z = src.position.z;
+        pDst->orientation.x = src.orientation.x;
+        pDst->orientation.y = src.orientation.y;
+        pDst->orientation.z = src.orientation.z;
+    }
+}
+
 }  // namespace V4_0
 }  // namespace android
diff --git a/media/libaudiohal/4.0/ConversionHelperHidl.h b/media/libaudiohal/4.0/ConversionHelperHidl.h
index ddc8569..8823a8d 100644
--- a/media/libaudiohal/4.0/ConversionHelperHidl.h
+++ b/media/libaudiohal/4.0/ConversionHelperHidl.h
@@ -19,9 +19,11 @@
 
 #include <android/hardware/audio/4.0/types.h>
 #include <hidl/HidlSupport.h>
+#include <system/audio.h>
 #include <utils/String8.h>
 
 using ::android::hardware::audio::V4_0::ParameterValue;
+using ::android::hardware::audio::V4_0::MicrophoneInfo;
 using ::android::hardware::Return;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
@@ -34,6 +36,8 @@
     static status_t keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys);
     static status_t parametersFromHal(const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams);
     static void parametersToHal(const hidl_vec<ParameterValue>& parameters, String8 *values);
+    static void microphoneInfoToHal(const MicrophoneInfo& src,
+                                    audio_microphone_characteristic_t *pDst);
 
     ConversionHelperHidl(const char* className);
 
diff --git a/media/libaudiohal/4.0/DeviceHalHidl.cpp b/media/libaudiohal/4.0/DeviceHalHidl.cpp
index 8da1051..49c5bb5 100644
--- a/media/libaudiohal/4.0/DeviceHalHidl.cpp
+++ b/media/libaudiohal/4.0/DeviceHalHidl.cpp
@@ -359,6 +359,23 @@
     return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
 }
 
+status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
+    if (mDevice == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mDevice->getMicrophones(
+            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
+        retval = r;
+        for (size_t k = 0; k < micArrayHal.size(); k++) {
+            audio_microphone_characteristic_t dst;
+            //convert
+            microphoneInfoToHal(micArrayHal[k], &dst);
+            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
+            microphonesInfo->push_back(microphone);
+        }
+    });
+    return processReturn("getMicrophones", ret, retval);
+}
+
 status_t DeviceHalHidl::dump(int fd) {
     if (mDevice == 0) return NO_INIT;
     native_handle_t* hidlHandle = native_handle_create(1, 0);
diff --git a/media/libaudiohal/4.0/DeviceHalHidl.h b/media/libaudiohal/4.0/DeviceHalHidl.h
index f460add..0bd2175 100644
--- a/media/libaudiohal/4.0/DeviceHalHidl.h
+++ b/media/libaudiohal/4.0/DeviceHalHidl.h
@@ -108,6 +108,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
   private:
diff --git a/media/libaudiohal/4.0/DeviceHalLocal.cpp b/media/libaudiohal/4.0/DeviceHalLocal.cpp
index e64eee1..a245dd9 100644
--- a/media/libaudiohal/4.0/DeviceHalLocal.cpp
+++ b/media/libaudiohal/4.0/DeviceHalLocal.cpp
@@ -185,6 +185,18 @@
         return INVALID_OPERATION;
 }
 
+status_t DeviceHalLocal::getMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
+    if (mDev->get_microphones == NULL) return INVALID_OPERATION;
+    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
+    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
+    status_t status = mDev->get_microphones(mDev, &mic_array[0], &actual_mics);
+    for (size_t i = 0; i < actual_mics; i++) {
+        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
+        microphones->push_back(microphoneInfo);
+    }
+    return status;
+}
+
 status_t DeviceHalLocal::dump(int fd) {
     return mDev->dump(mDev, fd);
 }
diff --git a/media/libaudiohal/4.0/DeviceHalLocal.h b/media/libaudiohal/4.0/DeviceHalLocal.h
index daafdc7..08341a4 100644
--- a/media/libaudiohal/4.0/DeviceHalLocal.h
+++ b/media/libaudiohal/4.0/DeviceHalLocal.h
@@ -101,6 +101,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
     void closeOutputStream(struct audio_stream_out *stream_out);
diff --git a/media/libaudiohal/4.0/StreamHalHidl.cpp b/media/libaudiohal/4.0/StreamHalHidl.cpp
index de16e98..47db08e 100644
--- a/media/libaudiohal/4.0/StreamHalHidl.cpp
+++ b/media/libaudiohal/4.0/StreamHalHidl.cpp
@@ -33,6 +33,7 @@
 using ::android::hardware::audio::V4_0::AudioDrain;
 using ::android::hardware::audio::V4_0::IStreamOutCallback;
 using ::android::hardware::audio::V4_0::MessageQueueFlagBits;
+using ::android::hardware::audio::V4_0::MicrophoneInfo;
 using ::android::hardware::audio::V4_0::MmapBufferInfo;
 using ::android::hardware::audio::V4_0::MmapPosition;
 using ::android::hardware::audio::V4_0::ParameterValue;
@@ -754,5 +755,24 @@
     }
 }
 
+
+status_t StreamInHalHidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphonesInfo) {
+    if (!mStream) return NO_INIT;
+    Result retval;
+    Return<void> ret = mStream->getActiveMicrophones(
+            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
+        retval = r;
+        for (size_t k = 0; k < micArrayHal.size(); k++) {
+            audio_microphone_characteristic_t dst;
+            // convert
+            microphoneInfoToHal(micArrayHal[k], &dst);
+            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
+            microphonesInfo->push_back(microphone);
+        }
+    });
+    return processReturn("getActiveMicrophones", ret, retval);
+}
+
 } // namespace V4_0
 } // namespace android
diff --git a/media/libaudiohal/4.0/StreamHalHidl.h b/media/libaudiohal/4.0/StreamHalHidl.h
index 8d4dc8c..dd6eb74 100644
--- a/media/libaudiohal/4.0/StreamHalHidl.h
+++ b/media/libaudiohal/4.0/StreamHalHidl.h
@@ -211,6 +211,9 @@
     // the clock time associated with that frame count.
     virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
   private:
     friend class DeviceHalHidl;
     typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
diff --git a/media/libaudiohal/4.0/StreamHalLocal.cpp b/media/libaudiohal/4.0/StreamHalLocal.cpp
index 592a931..b00027e 100644
--- a/media/libaudiohal/4.0/StreamHalLocal.cpp
+++ b/media/libaudiohal/4.0/StreamHalLocal.cpp
@@ -315,5 +315,17 @@
     return mStream->get_mmap_position(mStream, position);
 }
 
+status_t StreamInHalLocal::getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
+    if (mStream->get_active_microphones == NULL) return INVALID_OPERATION;
+    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
+    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
+    status_t status = mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics);
+    for (size_t i = 0; i < actual_mics; i++) {
+        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
+        microphones->push_back(microphoneInfo);
+    }
+    return status;
+}
+
 } // namespace V4_0
 } // namespace android
diff --git a/media/libaudiohal/4.0/StreamHalLocal.h b/media/libaudiohal/4.0/StreamHalLocal.h
index 076bc4c..a6009e0 100644
--- a/media/libaudiohal/4.0/StreamHalLocal.h
+++ b/media/libaudiohal/4.0/StreamHalLocal.h
@@ -195,6 +195,9 @@
     // Get current read/write position in the mmap buffer
     virtual status_t getMmapPosition(struct audio_mmap_position *position);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
   private:
     audio_stream_in_t *mStream;
 
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index caf01be..7de8eb3 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
 #define ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
 
+#include <media/MicrophoneInfo.h>
 #include <system/audio.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
@@ -105,6 +106,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+
     virtual status_t dump(int fd) = 0;
 
   protected:
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index 7419c34..e0ffe33 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -18,6 +18,7 @@
 #define ANDROID_HARDWARE_STREAM_HAL_INTERFACE_H
 
 #include <media/audiohal/EffectHalInterface.h>
+#include <media/MicrophoneInfo.h>
 #include <system/audio.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
@@ -161,6 +162,9 @@
     // the clock time associated with that frame count.
     virtual status_t getCapturePosition(int64_t *frames, int64_t *time) = 0;
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+
   protected:
     virtual ~StreamInHalInterface() {}
 };
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ea06b6c..32ed0bb 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1962,39 +1962,10 @@
 
 status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
 {
-    // Fake data
-    size_t fakeNum = 2;
-    audio_devices_t fakeTypes[] = { AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BACK_MIC };
-    for (size_t i = 0; i < fakeNum; i++) {
-        struct audio_microphone_characteristic_t characteristics;
-        sprintf(characteristics.device_id, "microphone:%zu", i);
-        characteristics.device = fakeTypes[i];
-        sprintf(characteristics.address, "");
-        characteristics.location = AUDIO_MICROPHONE_LOCATION_MAINBODY;
-        characteristics.group = 0;
-        characteristics.index_in_the_group = i;
-        characteristics.sensitivity = 1.0f;
-        characteristics.max_spl = 100.0f;
-        characteristics.min_spl = 0.0f;
-        characteristics.directionality = AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
-        characteristics.num_frequency_responses = 5 - i;
-        for (size_t j = 0; j < characteristics.num_frequency_responses; j++) {
-            characteristics.frequency_responses[0][j] = 100.0f - j;
-            characteristics.frequency_responses[1][j] = 100.0f + j;
-        }
-        for (size_t j = 0; j < AUDIO_CHANNEL_COUNT_MAX; j++) {
-            characteristics.channel_mapping[j] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
-        }
-        characteristics.geometric_location.x = 0.1f;
-        characteristics.geometric_location.y = 0.2f;
-        characteristics.geometric_location.z = 0.3f;
-        characteristics.orientation.x = 0.0f;
-        characteristics.orientation.y = 1.0f;
-        characteristics.orientation.z = 0.0f;
-        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(characteristics);
-        microphones->push_back(microphoneInfo);
-    }
-    return NO_ERROR;
+    AutoMutex lock(mHardwareLock);
+    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
+    status_t status = dev->getMicrophones(microphones);
+    return status;
 }
 
 // setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 62e9fe7..875b55f 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7129,42 +7129,8 @@
 {
     ALOGV("RecordThread::getActiveMicrophones");
     AutoMutex _l(mLock);
-    // Fake data
-    struct audio_microphone_characteristic_t characteristic;
-    sprintf(characteristic.device_id, "builtin_mic");
-    characteristic.device = 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;
+    status_t status = mInput->stream->getActiveMicrophones(activeMicrophones);
+    return status;
 }
 
 // destroyTrack_l() must be called with ThreadBase::mLock held
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 73d92ac..126da1e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3777,6 +3777,16 @@
         ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
         status = NO_INIT;
     }
+    // If microphones address is empty, set it according to device type
+    for (size_t i = 0; i  < mAvailableInputDevices.size(); i++) {
+        if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
+            if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
+                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+            } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
+                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
+            }
+        }
+    }
 
     if (mPrimaryOutput == 0) {
         ALOGE("Failed to open primary output");