Pass through availability of audio mic for input devices.

Bug: 15374820
Change-Id: Id2ca6da10165e3a887ebfbb18f663a3bf316ac79
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 3135692..4d54d56 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -1279,6 +1279,11 @@
         return -1;
     }
 
+    // Determine whether the device has a mic.
+    if (deviceHasMicLocked(device)) {
+        device->classes |= INPUT_DEVICE_CLASS_MIC;
+    }
+
     // Determine whether the device is external or internal.
     if (isExternalDeviceLocked(device)) {
         device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
@@ -1415,6 +1420,16 @@
     return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH;
 }
 
+bool EventHub::deviceHasMicLocked(Device* device) {
+    if (device->configuration) {
+        bool value;
+        if (device->configuration->tryGetProperty(String8("audio.mic"), value)) {
+            return value;
+        }
+    }
+    return false;
+}
+
 int32_t EventHub::getNextControllerNumberLocked(Device* device) {
     if (mControllerNumbers.isFull()) {
         ALOGI("Maximum number of controllers reached, assigning controller number 0 to device %s",
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
index 20179ae..d08f60e 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -131,6 +131,9 @@
     /* The input device has a vibrator (supports FF_RUMBLE). */
     INPUT_DEVICE_CLASS_VIBRATOR      = 0x00000200,
 
+    /* The input device has a microphone. */
+    INPUT_DEVICE_CLASS_MIC           = 0x00000400,
+
     /* The input device is virtual (not a real device, not part of UI configuration). */
     INPUT_DEVICE_CLASS_VIRTUAL       = 0x40000000,
 
@@ -394,6 +397,7 @@
     status_t loadKeyMapLocked(Device* device);
 
     bool isExternalDeviceLocked(Device* device);
+    bool deviceHasMicLocked(Device* device);
 
     int32_t getNextControllerNumberLocked(Device* device);
     void releaseControllerNumberLocked(Device* device);
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index ccf8ced..b39f367 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -417,6 +417,11 @@
         device->setExternal(true);
     }
 
+    // Devices with mics.
+    if (classes & INPUT_DEVICE_CLASS_MIC) {
+        device->setMic(true);
+    }
+
     // Switch-like devices.
     if (classes & INPUT_DEVICE_CLASS_SWITCH) {
         device->addMapper(new SwitchInputMapper(device));
@@ -858,7 +863,7 @@
         int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
         mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
         mIdentifier(identifier), mClasses(classes),
-        mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
+        mSources(0), mIsExternal(false), mHasMic(false), mDropUntilNextSync(false) {
 }
 
 InputDevice::~InputDevice() {
@@ -877,6 +882,7 @@
             deviceInfo.getDisplayName().string());
     dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
     dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
+    dump.appendFormat(INDENT2 "HasMic:     %s\n", toString(mHasMic));
     dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
     dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
 
@@ -1008,8 +1014,7 @@
 
 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
     outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
-            mIsExternal);
-
+            mIsExternal, mHasMic);
     size_t numMappers = mMappers.size();
     for (size_t i = 0; i < numMappers; i++) {
         InputMapper* mapper = mMappers[i];
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 34f20af..7a514e0 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -555,6 +555,9 @@
     inline bool isExternal() { return mIsExternal; }
     inline void setExternal(bool external) { mIsExternal = external; }
 
+    inline void setMic(bool hasMic) { mHasMic = hasMic; }
+    inline bool hasMic() const { return mHasMic; }
+
     inline bool isIgnored() { return mMappers.isEmpty(); }
 
     void dump(String8& dump);
@@ -618,6 +621,7 @@
 
     uint32_t mSources;
     bool mIsExternal;
+    bool mHasMic;
     bool mDropUntilNextSync;
 
     typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);