Merge "audio policy: fix unique audio port ID."
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 7536a37..18bcfdb 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -34,12 +34,11 @@
 public:
     AudioInputDescriptor(const sp<IOProfile>& profile);
     void setIoHandle(audio_io_handle_t ioHandle);
-
+    audio_port_handle_t getId() const;
     audio_module_handle_t getModuleHandle() const;
 
     status_t    dump(int fd);
 
-    audio_port_handle_t           mId;
     audio_io_handle_t             mIoHandle;       // input handle
     audio_devices_t               mDevice;         // current device this input is routed to
     AudioMix                      *mPolicyMix;     // non NULL when used by a dynamic policy
@@ -57,6 +56,9 @@
             const struct audio_port_config *srcConfig = NULL) const;
     virtual sp<AudioPort> getAudioPort() const { return mProfile; }
     void toAudioPort(struct audio_port *port) const;
+
+private:
+    audio_port_handle_t           mId;
 };
 
 class AudioInputCollection :
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index c3f584e..cc2a3bd 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -40,7 +40,7 @@
 
     audio_devices_t device() const;
     void changeRefCount(audio_stream_type_t stream, int delta);
-
+    audio_port_handle_t getId() const;
     void setIoHandle(audio_io_handle_t ioHandle);
     bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
     audio_devices_t supportedDevices();
@@ -58,7 +58,6 @@
 
     audio_module_handle_t getModuleHandle() const;
 
-    audio_port_handle_t mId;
     audio_io_handle_t mIoHandle;              // output handle
     uint32_t mLatency;                  //
     audio_output_flags_t mFlags;   //
@@ -75,6 +74,9 @@
     bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
                                         // device selection. See checkDeviceMuteStrategies()
     uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
+
+private:
+    audio_port_handle_t mId;
 };
 
 class AudioOutputCollection :
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 16eac50..dea1b8a 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -32,13 +32,11 @@
 {
 public:
     AudioPort(const String8& name, audio_port_type_t type,
-              audio_port_role_t role, const sp<HwModule>& module);
+              audio_port_role_t role);
     virtual ~AudioPort() {}
 
-    audio_port_handle_t getHandle() { return mId; }
-
-    void attach(const sp<HwModule>& module);
-    bool isAttached() { return mId != 0; }
+    virtual void attach(const sp<HwModule>& module);
+    bool isAttached() { return mModule != 0; }
 
     static audio_port_handle_t getNextUniqueId();
 
@@ -76,6 +74,8 @@
     static int compareFormats(audio_format_t format1, audio_format_t format2);
 
     audio_module_handle_t getModuleHandle() const;
+    uint32_t getModuleVersion() const;
+    const char *getModuleName() const;
 
     void dump(int fd, int spaces) const;
     void log(const char* indent) const;
@@ -95,13 +95,6 @@
     uint32_t mFlags; // attribute flags (e.g primary output,
                      // direct output...).
 
-
-protected:
-    //TODO - clarify the role of mId in this case, both an "attached" indicator
-    // and a unique ID for identifying a port to the (upcoming) selection API,
-    // and its relationship to the mId in AudioOutputDescriptor and AudioInputDescriptor.
-    audio_port_handle_t mId;
-
 private:
     static volatile int32_t mNextUniqueId;
 };
diff --git a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
index 14a7d36..f8c4d08 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
@@ -39,11 +39,12 @@
 };
 
 #define STRING_TO_ENUM(string) { #string, string }
+#define NAME_TO_ENUM(name, value) { name, value }
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 #endif
 
-const StringToEnum sDeviceNameToEnumTable[] = {
+const StringToEnum sDeviceTypeToEnumTable[] = {
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE),
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER),
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER_SAFE),
@@ -94,6 +95,57 @@
     STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
 };
 
+const StringToEnum sDeviceNameToEnumTable[] = {
+    NAME_TO_ENUM("Earpiece", AUDIO_DEVICE_OUT_EARPIECE),
+    NAME_TO_ENUM("Speaker", AUDIO_DEVICE_OUT_SPEAKER),
+    NAME_TO_ENUM("Speaker Protected", AUDIO_DEVICE_OUT_SPEAKER_SAFE),
+    NAME_TO_ENUM("Wired Headset", AUDIO_DEVICE_OUT_WIRED_HEADSET),
+    NAME_TO_ENUM("Wired Headphones", AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
+    NAME_TO_ENUM("BT SCO", AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
+    NAME_TO_ENUM("BT SCO Headset", AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
+    NAME_TO_ENUM("BT SCO Car Kit", AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
+    NAME_TO_ENUM("", AUDIO_DEVICE_OUT_ALL_SCO),
+    NAME_TO_ENUM("BT A2DP Out", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
+    NAME_TO_ENUM("BT A2DP Headphones", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
+    NAME_TO_ENUM("BT A2DP Speaker", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
+    NAME_TO_ENUM("", AUDIO_DEVICE_OUT_ALL_A2DP),
+    NAME_TO_ENUM("HDMI Out", AUDIO_DEVICE_OUT_AUX_DIGITAL),
+    NAME_TO_ENUM("HDMI Out", AUDIO_DEVICE_OUT_HDMI),
+    NAME_TO_ENUM("Analog Dock Out", AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
+    NAME_TO_ENUM("Digital Dock Out", AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
+    NAME_TO_ENUM("USB Host Out", AUDIO_DEVICE_OUT_USB_ACCESSORY),
+    NAME_TO_ENUM("USB Device Out", AUDIO_DEVICE_OUT_USB_DEVICE),
+    NAME_TO_ENUM("", AUDIO_DEVICE_OUT_ALL_USB),
+    NAME_TO_ENUM("Reroute Submix Out", AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
+    NAME_TO_ENUM("Telephony Tx", AUDIO_DEVICE_OUT_TELEPHONY_TX),
+    NAME_TO_ENUM("Line Out", AUDIO_DEVICE_OUT_LINE),
+    NAME_TO_ENUM("HDMI ARC Out", AUDIO_DEVICE_OUT_HDMI_ARC),
+    NAME_TO_ENUM("S/PDIF Out", AUDIO_DEVICE_OUT_SPDIF),
+    NAME_TO_ENUM("FM transceiver Out", AUDIO_DEVICE_OUT_FM),
+    NAME_TO_ENUM("Aux Line Out", AUDIO_DEVICE_OUT_AUX_LINE),
+    NAME_TO_ENUM("Ambient Mic", AUDIO_DEVICE_IN_AMBIENT),
+    NAME_TO_ENUM("Built-In Mic", AUDIO_DEVICE_IN_BUILTIN_MIC),
+    NAME_TO_ENUM("BT SCO Headset Mic", AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
+    NAME_TO_ENUM("", AUDIO_DEVICE_IN_ALL_SCO),
+    NAME_TO_ENUM("Wired Headset Mic", AUDIO_DEVICE_IN_WIRED_HEADSET),
+    NAME_TO_ENUM("HDMI In", AUDIO_DEVICE_IN_AUX_DIGITAL),
+    NAME_TO_ENUM("HDMI In", AUDIO_DEVICE_IN_HDMI),
+    NAME_TO_ENUM("Telephony Rx", AUDIO_DEVICE_IN_TELEPHONY_RX),
+    NAME_TO_ENUM("Telephony Rx", AUDIO_DEVICE_IN_VOICE_CALL),
+    NAME_TO_ENUM("Built-In Back Mic", AUDIO_DEVICE_IN_BACK_MIC),
+    NAME_TO_ENUM("Reroute Submix In", AUDIO_DEVICE_IN_REMOTE_SUBMIX),
+    NAME_TO_ENUM("Analog Dock In", AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
+    NAME_TO_ENUM("Digital Dock In", AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
+    NAME_TO_ENUM("USB Host In", AUDIO_DEVICE_IN_USB_ACCESSORY),
+    NAME_TO_ENUM("USB Device In", AUDIO_DEVICE_IN_USB_DEVICE),
+    NAME_TO_ENUM("FM Tuner In", AUDIO_DEVICE_IN_FM_TUNER),
+    NAME_TO_ENUM("TV Tuner In", AUDIO_DEVICE_IN_TV_TUNER),
+    NAME_TO_ENUM("Line In", AUDIO_DEVICE_IN_LINE),
+    NAME_TO_ENUM("S/PDIF In", AUDIO_DEVICE_IN_SPDIF),
+    NAME_TO_ENUM("BT A2DP In", AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
+    NAME_TO_ENUM("Loopback In", AUDIO_DEVICE_IN_LOOPBACK),
+};
+
 const StringToEnum sOutputFlagNameToEnumTable[] = {
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index d6daacd..aa37eec 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -41,20 +41,22 @@
             const struct audio_port_config *srcConfig = NULL) const;
 
     // AudioPort
+    virtual void attach(const sp<HwModule>& module);
     virtual void loadGains(cnode *root);
     virtual void toAudioPort(struct audio_port *port) const;
 
+    audio_port_handle_t getId() const;
     audio_devices_t type() const { return mDeviceType; }
     status_t dump(int fd, int spaces, int index) const;
     void log() const;
 
     String8 mAddress;
-    audio_port_handle_t mId;
 
     static String8  emptyNameStr;
 
 private:
-    audio_devices_t mDeviceType;
+    audio_devices_t     mDeviceType;
+    audio_port_handle_t mId;
 
 friend class DeviceVector;
 };
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 095e759..022257e 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -33,7 +33,7 @@
 class IOProfile : public AudioPort
 {
 public:
-    IOProfile(const String8& name, audio_port_role_t role, const sp<HwModule>& module);
+    IOProfile(const String8& name, audio_port_role_t role);
     virtual ~IOProfile();
 
     // This method is used for both output and input.
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index fa66728..937160b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -27,9 +27,9 @@
 namespace android {
 
 AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0),
+    : mIoHandle(0),
       mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0),
-      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false)
+      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false), mId(0)
 {
     if (profile != NULL) {
         mSamplingRate = profile->pickSamplingRate();
@@ -49,9 +49,17 @@
 
 audio_module_handle_t AudioInputDescriptor::getModuleHandle() const
 {
+    if (mProfile == 0) {
+        return 0;
+    }
     return mProfile->getModuleHandle();
 }
 
+audio_port_handle_t AudioInputDescriptor::getId() const
+{
+    return mId;
+}
+
 void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
                                              const struct audio_port_config *srcConfig) const
 {
@@ -68,7 +76,7 @@
     dstConfig->id = mId;
     dstConfig->role = AUDIO_PORT_ROLE_SINK;
     dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
+    dstConfig->ext.mix.hw_module = getModuleHandle();
     dstConfig->ext.mix.handle = mIoHandle;
     dstConfig->ext.mix.usecase.source = mInputSource;
 }
@@ -80,7 +88,7 @@
     mProfile->toAudioPort(port);
     port->id = mId;
     toAudioPortConfig(&port->active_config);
-    port->ext.mix.hw_module = mProfile->mModule->mHandle;
+    port->ext.mix.hw_module = getModuleHandle();
     port->ext.mix.handle = mIoHandle;
     port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
 }
@@ -91,7 +99,7 @@
     char buffer[SIZE];
     String8 result;
 
-    snprintf(buffer, SIZE, " ID: %d\n", mId);
+    snprintf(buffer, SIZE, " ID: %d\n", getId());
     result.append(buffer);
     snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
     result.append(buffer);
@@ -130,7 +138,7 @@
     sp<AudioInputDescriptor> inputDesc = NULL;
     for (size_t i = 0; i < size(); i++) {
         inputDesc = valueAt(i);
-        if (inputDesc->mId == id) {
+        if (inputDesc->getId() == id) {
             break;
         }
     }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 7207a71..8de8cd8 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -30,10 +30,11 @@
 namespace android {
 
 AudioOutputDescriptor::AudioOutputDescriptor(const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0), mLatency(0),
+    : mIoHandle(0), mLatency(0),
     mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
     mPatchHandle(0),
-    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
+    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0),
+    mId(0)
 {
     // clear usage count for all stream types
     for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
@@ -58,9 +59,17 @@
 
 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
 {
+    if (mProfile == 0) {
+        return 0;
+    }
     return mProfile->getModuleHandle();
 }
 
+audio_port_handle_t AudioOutputDescriptor::getId() const
+{
+    return mId;
+}
+
 audio_devices_t AudioOutputDescriptor::device() const
 {
     if (isDuplicated()) {
@@ -93,7 +102,7 @@
     } else if (outputDesc->isDuplicated()){
         return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
     } else {
-        return (mProfile->mModule == outputDesc->mProfile->mModule);
+        return (getModuleHandle() == outputDesc->getModuleHandle());
     }
 }
 
@@ -176,7 +185,7 @@
     dstConfig->id = mId;
     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
     dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
+    dstConfig->ext.mix.hw_module = getModuleHandle();
     dstConfig->ext.mix.handle = mIoHandle;
     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
 }
@@ -188,7 +197,7 @@
     mProfile->toAudioPort(port);
     port->id = mId;
     toAudioPortConfig(&port->active_config);
-    port->ext.mix.hw_module = mProfile->mModule->mHandle;
+    port->ext.mix.hw_module = getModuleHandle();
     port->ext.mix.handle = mIoHandle;
     port->ext.mix.latency_class =
             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
@@ -200,7 +209,7 @@
     char buffer[SIZE];
     String8 result;
 
-    snprintf(buffer, SIZE, " ID: %d\n", mId);
+    snprintf(buffer, SIZE, " ID: %d\n", getId());
     result.append(buffer);
     snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
     result.append(buffer);
@@ -289,7 +298,7 @@
     sp<AudioOutputDescriptor> outputDesc = NULL;
     for (size_t i = 0; i < size(); i++) {
         outputDesc = valueAt(i);
-        if (outputDesc->mId == id) {
+        if (outputDesc->getId() == id) {
             break;
         }
     }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index 3a317fa..a06d867 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -54,8 +54,8 @@
     for (size_t i = 0; i < mPatch.num_sources; i++) {
         if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) {
             snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
-                     mPatch.sources[i].id, ConfigParsingUtils::enumToString(sDeviceNameToEnumTable,
-                                                        ARRAY_SIZE(sDeviceNameToEnumTable),
+                     mPatch.sources[i].id, ConfigParsingUtils::enumToString(sDeviceTypeToEnumTable,
+                                                        ARRAY_SIZE(sDeviceTypeToEnumTable),
                                                         mPatch.sources[i].ext.device.type));
         } else {
             snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
@@ -68,8 +68,8 @@
     for (size_t i = 0; i < mPatch.num_sinks; i++) {
         if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) {
             snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
-                     mPatch.sinks[i].id, ConfigParsingUtils::enumToString(sDeviceNameToEnumTable,
-                                                        ARRAY_SIZE(sDeviceNameToEnumTable),
+                     mPatch.sinks[i].id, ConfigParsingUtils::enumToString(sDeviceTypeToEnumTable,
+                                                        ARRAY_SIZE(sDeviceTypeToEnumTable),
                                                         mPatch.sinks[i].ext.device.type));
         } else {
             snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 2bbcc05..e8191dd 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -31,8 +31,8 @@
 // --- AudioPort class implementation
 
 AudioPort::AudioPort(const String8& name, audio_port_type_t type,
-                     audio_port_role_t role, const sp<HwModule>& module) :
-    mName(name), mType(type), mRole(role), mModule(module), mFlags(0), mId(0)
+                     audio_port_role_t role) :
+    mName(name), mType(type), mRole(role), mFlags(0)
 {
     mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
                     ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
@@ -40,7 +40,6 @@
 
 void AudioPort::attach(const sp<HwModule>& module)
 {
-    mId = getNextUniqueId();
     mModule = module;
 }
 
@@ -51,9 +50,28 @@
 
 audio_module_handle_t AudioPort::getModuleHandle() const
 {
+    if (mModule == 0) {
+        return 0;
+    }
     return mModule->mHandle;
 }
 
+uint32_t AudioPort::getModuleVersion() const
+{
+    if (mModule == 0) {
+        return 0;
+    }
+    return mModule->mHalVersion;
+}
+
+const char *AudioPort::getModuleName() const
+{
+    if (mModule == 0) {
+        return "";
+    }
+    return mModule->mName;
+}
+
 void AudioPort::toAudioPort(struct audio_port *port) const
 {
     port->role = mRole;
@@ -629,7 +647,7 @@
     char buffer[SIZE];
     String8 result;
 
-    if (mName.size() != 0) {
+    if (mName.length() != 0) {
         snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
         result.append(buffer);
     }
@@ -687,7 +705,6 @@
     if (mGains.size() != 0) {
         snprintf(buffer, SIZE, "%*s- gains:\n", spaces, "");
         write(fd, buffer, strlen(buffer) + 1);
-        result.append(buffer);
         for (size_t i = 0; i < mGains.size(); i++) {
             mGains[i]->dump(fd, spaces + 2, i);
         }
diff --git a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
index fe5bc5f..9ab1d61 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
@@ -113,8 +113,8 @@
     char *devName = strtok(name, "|");
     while (devName != NULL) {
         if (strlen(devName) != 0) {
-            device |= stringToEnum(sDeviceNameToEnumTable,
-                                 ARRAY_SIZE(sDeviceNameToEnumTable),
+            device |= stringToEnum(sDeviceTypeToEnumTable,
+                                 ARRAY_SIZE(sDeviceTypeToEnumTable),
                                  devName);
          }
         devName = strtok(NULL, "|");
@@ -224,8 +224,8 @@
                   availableOutputDevices.types());
         } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
             audio_devices_t device = (audio_devices_t)stringToEnum(
-                    sDeviceNameToEnumTable,
-                    ARRAY_SIZE(sDeviceNameToEnumTable),
+                    sDeviceTypeToEnumTable,
+                    ARRAY_SIZE(sDeviceTypeToEnumTable),
                     (char *)node->value);
             if (device != AUDIO_DEVICE_NONE) {
                 defaultOutputDevice = new DeviceDescriptor(String8("default-output"), device);
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 9249d47..9573583 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -29,13 +29,23 @@
 DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) :
     AudioPort(name, AUDIO_PORT_TYPE_DEVICE,
               audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
-                                             AUDIO_PORT_ROLE_SOURCE,
-              NULL),
-    mAddress(""), mDeviceType(type)
+                                             AUDIO_PORT_ROLE_SOURCE),
+    mAddress(""), mDeviceType(type), mId(0)
 {
 
 }
 
+audio_port_handle_t DeviceDescriptor::getId() const
+{
+    return mId;
+}
+
+void DeviceDescriptor::attach(const sp<HwModule>& module)
+{
+    AudioPort::attach(module);
+    mId = getNextUniqueId();
+}
+
 bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
 {
     // Devices are considered equal if they:
@@ -139,11 +149,14 @@
     char *devName = strtok(name, "|");
     while (devName != NULL) {
         if (strlen(devName) != 0) {
-            audio_devices_t type = ConfigParsingUtils::stringToEnum(sDeviceNameToEnumTable,
-                                 ARRAY_SIZE(sDeviceNameToEnumTable),
+            audio_devices_t type = ConfigParsingUtils::stringToEnum(sDeviceTypeToEnumTable,
+                                 ARRAY_SIZE(sDeviceTypeToEnumTable),
                                  devName);
             if (type != AUDIO_DEVICE_NONE) {
-                sp<DeviceDescriptor> dev = new DeviceDescriptor(String8(name), type);
+                devName = (char *)ConfigParsingUtils::enumToString(sDeviceNameToEnumTable,
+                                                           ARRAY_SIZE(sDeviceNameToEnumTable),
+                                                           type);
+                sp<DeviceDescriptor> dev = new DeviceDescriptor(String8(devName), type);
                 if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX ||
                         type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
                     dev->mAddress = String8("0");
@@ -183,7 +196,7 @@
 {
     sp<DeviceDescriptor> device;
     for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->getHandle() == id) {
+        if (itemAt(i)->getId() == id) {
             device = itemAt(i);
             break;
         }
@@ -303,8 +316,8 @@
         result.append(buffer);
     }
     snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "",
-            ConfigParsingUtils::enumToString(sDeviceNameToEnumTable,
-                    ARRAY_SIZE(sDeviceNameToEnumTable),
+            ConfigParsingUtils::enumToString(sDeviceTypeToEnumTable,
+                    ARRAY_SIZE(sDeviceTypeToEnumTable),
                     mDeviceType));
     result.append(buffer);
     if (mAddress.size() != 0) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 0097d69..e955447 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -48,7 +48,7 @@
 {
     cnode *node = root->first_child;
 
-    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this);
+    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK);
 
     while (node) {
         if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
@@ -83,6 +83,7 @@
         ALOGV("loadInput() adding input Supported Devices %04x",
               profile->mSupportedDevices.types());
 
+        profile->attach(this);
         mInputProfiles.add(profile);
         return NO_ERROR;
     } else {
@@ -94,7 +95,7 @@
 {
     cnode *node = root->first_child;
 
-    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this);
+    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE);
 
     while (node) {
         if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
@@ -128,7 +129,7 @@
 
         ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
               profile->mSupportedDevices.types(), profile->mFlags);
-
+        profile->attach(this);
         mOutputProfiles.add(profile);
         return NO_ERROR;
     } else {
@@ -154,7 +155,6 @@
         return BAD_VALUE;
     }
     sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type);
-    deviceDesc->mModule = this;
 
     node = root->first_child;
     while (node) {
@@ -183,7 +183,7 @@
 status_t HwModule::addOutputProfile(String8 name, const audio_config_t *config,
                                                   audio_devices_t device, String8 address)
 {
-    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SOURCE, this);
+    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SOURCE);
 
     profile->mSamplingRates.add(config->sample_rate);
     profile->mChannelMasks.add(config->channel_mask);
@@ -193,6 +193,7 @@
     devDesc->mAddress = address;
     profile->mSupportedDevices.add(devDesc);
 
+    profile->attach(this);
     mOutputProfiles.add(profile);
 
     return NO_ERROR;
@@ -213,7 +214,7 @@
 status_t HwModule::addInputProfile(String8 name, const audio_config_t *config,
                                                   audio_devices_t device, String8 address)
 {
-    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SINK, this);
+    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SINK);
 
     profile->mSamplingRates.add(config->sample_rate);
     profile->mChannelMasks.add(config->channel_mask);
@@ -225,6 +226,7 @@
 
     ALOGV("addInputProfile() name %s rate %d mask 0x08", name.string(), config->sample_rate, config->channel_mask);
 
+    profile->attach(this);
     mInputProfiles.add(profile);
 
     return NO_ERROR;
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index 376dd22..de6539c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -23,9 +23,8 @@
 
 namespace android {
 
-IOProfile::IOProfile(const String8& name, audio_port_role_t role,
-                                         const sp<HwModule>& module)
-    : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module)
+IOProfile::IOProfile(const String8& name, audio_port_role_t role)
+    : AudioPort(name, AUDIO_PORT_TYPE_MIX, role)
 {
 }
 
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 1fd3341..417eebc 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -358,7 +358,7 @@
             if (((availableInputDevices.types() &
                     AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
                     (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
-                         (primaryOutput->getAudioPort()->mModule->mHalVersion <
+                         (primaryOutput->getAudioPort()->getModuleVersion() <
                              AUDIO_DEVICE_API_VERSION_3_0))) {
                 availableOutputDevicesType = availPrimaryOutputDevices;
             }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 804a64b..a7d9fd5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -681,7 +681,7 @@
     sp<DeviceDescriptor> deviceDesc;
 
     for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
-        if (mAvailableOutputDevices[i]->getHandle() == selectedDeviceId) {
+        if (mAvailableOutputDevices[i]->getId() == selectedDeviceId) {
             deviceDesc = mAvailableOutputDevices[i];
             break;
         }
@@ -818,7 +818,7 @@
         if (offloadInfo != NULL) {
             config.offload_info = *offloadInfo;
         }
-        status = mpClientInterface->openOutput(profile->mModule->mHandle,
+        status = mpClientInterface->openOutput(profile->getModuleHandle(),
                                                &output,
                                                &config,
                                                &outputDesc->mDevice,
@@ -1286,8 +1286,8 @@
         }
     }
 
-    if (profile->mModule->mHandle == 0) {
-        ALOGE("getInputForAttr(): HW module %s not opened", profile->mModule->mName);
+    if (profile->getModuleHandle() == 0) {
+        ALOGE("getInputForAttr(): HW module %s not opened", profile->getModuleName());
         return NO_INIT;
     }
 
@@ -1296,7 +1296,7 @@
     config.channel_mask = channelMask;
     config.format = format;
 
-    status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
+    status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
                                                    input,
                                                    &config,
                                                    &device,
@@ -2184,7 +2184,7 @@
                 }
                 sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
 
-                if (srcDeviceDesc->mModule != sinkDeviceDesc->mModule) {
+                if (srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) {
                     // only one sink supported when connected devices across HW modules
                     if (patch->num_sinks > 1) {
                         return INVALID_OPERATION;
@@ -2503,7 +2503,7 @@
             config.channel_mask = outputDesc->mChannelMask;
             config.format = outputDesc->mFormat;
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle,
+            status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
                                                             &output,
                                                             &config,
                                                             &outputDesc->mDevice,
@@ -2579,7 +2579,7 @@
             config.channel_mask = inputDesc->mChannelMask;
             config.format = inputDesc->mFormat;
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-            status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle,
+            status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
                                                            &input,
                                                            &config,
                                                            &inputDesc->mDevice,
@@ -2784,7 +2784,7 @@
                 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
                 mpClientInterface->closeOutput(mPrimaryOutput);
 
-                audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
+                audio_module_handle_t moduleHandle = outputDesc->getModuleHandle();
 
                 removeOutput(mPrimaryOutput);
                 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
@@ -2958,7 +2958,7 @@
             config.offload_info.channel_mask = desc->mChannelMask;
             config.offload_info.format = desc->mFormat;
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status_t status = mpClientInterface->openOutput(profile->mModule->mHandle,
+            status_t status = mpClientInterface->openOutput(profile->getModuleHandle(),
                                                             &output,
                                                             &config,
                                                             &desc->mDevice,
@@ -3028,7 +3028,7 @@
                     config.offload_info.sample_rate = config.sample_rate;
                     config.offload_info.channel_mask = config.channel_mask;
                     config.offload_info.format = config.format;
-                    status = mpClientInterface->openOutput(profile->mModule->mHandle,
+                    status = mpClientInterface->openOutput(profile->getModuleHandle(),
                                                            &output,
                                                            &config,
                                                            &desc->mDevice,
@@ -3233,7 +3233,7 @@
             config.channel_mask = desc->mChannelMask;
             config.format = desc->mFormat;
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-            status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
+            status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
                                                            &input,
                                                            &config,
                                                            &desc->mDevice,
@@ -4518,7 +4518,8 @@
 
     module = new HwModule("primary");
 
-    profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE, module);
+    profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE);
+    profile->attach(module);
     profile->mSamplingRates.add(44100);
     profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
     profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
@@ -4526,7 +4527,8 @@
     profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
     module->mOutputProfiles.add(profile);
 
-    profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK, module);
+    profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK);
+    profile->attach(module);
     profile->mSamplingRates.add(8000);
     profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
     profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);