Added support for TTY

Change-Id: I60e8ae30da4c3879bdd6a272dd65f6add4d1f520
diff --git a/libaudio/AudioHardware.cpp b/libaudio/AudioHardware.cpp
index b6ec8ab..99c38fa 100644
--- a/libaudio/AudioHardware.cpp
+++ b/libaudio/AudioHardware.cpp
@@ -88,6 +88,7 @@
     mInCallAudioMode(false),
     mInputSource(AUDIO_SOURCE_DEFAULT),
     mBluetoothNrec(true),
+    mTTYMode(TTY_MODE_OFF),
     mSecRilLibHandle(NULL),
     mRilClient(0),
     mActivatedCP(false),
@@ -465,6 +466,11 @@
     String8 key;
     const char BT_NREC_KEY[] = "bt_headset_nrec";
     const char BT_NREC_VALUE_ON[] = "on";
+    const char TTY_MODE_KEY[] = "tty_mode";
+    const char TTY_MODE_VALUE_OFF[] = "tty_off";
+    const char TTY_MODE_VALUE_VCO[] = "tty_vco";
+    const char TTY_MODE_VALUE_HCO[] = "tty_hco";
+    const char TTY_MODE_VALUE_FULL[] = "tty_full";
 
     key = String8(BT_NREC_KEY);
     if (param.get(key, value) == NO_ERROR) {
@@ -475,8 +481,34 @@
             LOGD("Turning noise reduction and echo cancellation off for BT "
                  "headset");
         }
+        param.remove(String8(BT_NREC_KEY));
     }
 
+    key = String8(TTY_MODE_KEY);
+    if (param.get(key, value) == NO_ERROR) {
+        int ttyMode;
+        if (value == TTY_MODE_VALUE_OFF) {
+            ttyMode = TTY_MODE_OFF;
+        } else if (value == TTY_MODE_VALUE_VCO) {
+            ttyMode = TTY_MODE_VCO;
+        } else if (value == TTY_MODE_VALUE_HCO) {
+            ttyMode = TTY_MODE_HCO;
+        } else if (value == TTY_MODE_VALUE_FULL) {
+            ttyMode = TTY_MODE_FULL;
+        } else {
+            return BAD_VALUE;
+        }
+
+        if (ttyMode != mTTYMode) {
+            LOGV("new tty mode %d", ttyMode);
+            mTTYMode = ttyMode;
+            if (mOutput != 0 && mMode == AudioSystem::MODE_IN_CALL) {
+                setIncallPath_l(mOutput->device());
+            }
+        }
+        param.remove(String8(TTY_MODE_KEY));
+     }
+
     return NO_ERROR;
 }
 
@@ -681,12 +713,10 @@
                     LOGD("### incall mode headphone route");
                     path = SOUND_AUDIO_PATH_HEADPHONE;
                     break;
-
                 case AudioSystem::DEVICE_OUT_WIRED_HEADSET :
                     LOGD("### incall mode headset route");
                     path = SOUND_AUDIO_PATH_HEADSET;
                     break;
-
                 default:
                     LOGW("### incall mode Error!! route = [%d]", device);
                     path = SOUND_AUDIO_PATH_HANDSET;
@@ -829,9 +859,22 @@
     case AudioSystem::DEVICE_OUT_SPEAKER:
         return "SPK";
     case AudioSystem::DEVICE_OUT_WIRED_HEADPHONE:
-        return "HP_NO_MIC";
     case AudioSystem::DEVICE_OUT_WIRED_HEADSET:
-        return "HP";
+        switch (mTTYMode) {
+        case TTY_MODE_VCO:
+            return "TTY_VCO";
+        case TTY_MODE_HCO:
+            return "TTY_HCO";
+        case TTY_MODE_FULL:
+            return "TTY_FULL";
+        case TTY_MODE_OFF:
+        default:
+            if (device == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
+                return "HP_NO_MIC";
+            } else {
+                return "HP";
+            }
+        }
     case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO:
     case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
     case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
diff --git a/libaudio/AudioHardware.h b/libaudio/AudioHardware.h
index 37a9a6e..a23e6c9 100644
--- a/libaudio/AudioHardware.h
+++ b/libaudio/AudioHardware.h
@@ -137,6 +137,13 @@
 
 private:
 
+    enum tty_modes {
+        TTY_MODE_OFF,
+        TTY_MODE_VCO,
+        TTY_MODE_HCO,
+        TTY_MODE_FULL
+    };
+
     bool            mInit;
     bool            mMicMute;
     sp <AudioStreamOutALSA>                 mOutput;
@@ -150,6 +157,8 @@
 
     audio_source    mInputSource;
     bool            mBluetoothNrec;
+    int             mTTYMode;
+
     void*           mSecRilLibHandle;
     HRilClient      mRilClient;
     bool            mActivatedCP;