audio policy: removed raw pointers.

Use only RefBase objects for the following classes:
- AudioOutputDescriptor
- AudioInputDescriptor
- HwModule
- EffectDescriptor

Create a common base class AudioPortConfig for:
AudioOutputDescriptor, AudioInputDescriptor and DeviceDescriptor

Bug: 14815883.

Change-Id: I1bd193ef1020780d8b94c13142029903615aba97
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 8c3af5b..e4ff3b1 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -223,7 +223,7 @@
             index = mAvailableOutputDevices.add(devDesc);
             if (index >= 0) {
                 mAvailableOutputDevices[index]->mId = nextUniqueId();
-                HwModule *module = getModuleForDevice(device);
+                sp<HwModule> module = getModuleForDevice(device);
                 ALOG_ASSERT(module != NULL, "setDeviceConnectionState():"
                         "could not find HW module for device %08x", device);
                 mAvailableOutputDevices[index]->mModule = module;
@@ -260,7 +260,7 @@
         // outputs must be closed after checkOutputForAllStrategies() is executed
         if (!outputs.isEmpty()) {
             for (size_t i = 0; i < outputs.size(); i++) {
-                AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
+                sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
                 // close unused outputs after device disconnection or direct outputs that have been
                 // opened by checkOutputsForDevice() to query dynamic parameters
                 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
@@ -311,7 +311,7 @@
                 ALOGW("setDeviceConnectionState() device already connected: %d", device);
                 return INVALID_OPERATION;
             }
-            HwModule *module = getModuleForDevice(device);
+            sp<HwModule> module = getModuleForDevice(device);
             if (module == NULL) {
                 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
                       device);
@@ -442,7 +442,7 @@
     checkOutputForAllStrategies();
     updateDevicesAndOutputs();
 
-    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
+    sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
 
     // force routing command to audio hardware when ending call
     // even if no device change is needed
@@ -454,7 +454,7 @@
     if (isStateInCall(state)) {
         nsecs_t sysTime = systemTime();
         for (size_t i = 0; i < mOutputs.size(); i++) {
-            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
             // mute media and sonification strategies and delay device switch by the largest
             // latency of any output where either strategy is active.
             // This avoid sending the ring tone or music tail into the earpiece or headset.
@@ -644,7 +644,7 @@
 
         if (mTestOutputs[mCurOutput] == 0) {
             ALOGV("getOutput() opening test output");
-            AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
+            sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
             outputDesc->mDevice = mTestDevice;
             outputDesc->mSamplingRate = mTestSamplingRate;
             outputDesc->mFormat = mTestFormat;
@@ -696,10 +696,10 @@
     }
 
     if (profile != 0) {
-        AudioOutputDescriptor *outputDesc = NULL;
+        sp<AudioOutputDescriptor> outputDesc = NULL;
 
         for (size_t i = 0; i < mOutputs.size(); i++) {
-            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if (!desc->isDuplicated() && (profile == desc->mProfile)) {
                 outputDesc = desc;
                 // reuse direct output if currently open and configured with same parameters
@@ -747,7 +747,6 @@
             if (output != 0) {
                 mpClientInterface->closeOutput(output);
             }
-            delete outputDesc;
             return 0;
         }
         audio_io_handle_t srcOutput = getOutputForEffect();
@@ -804,7 +803,7 @@
     audio_io_handle_t outputPrimary = 0;
 
     for (size_t i = 0; i < outputs.size(); i++) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
+        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
         if (!outputDesc->isDuplicated()) {
             int commonFlags = popcount(outputDesc->mProfile->mFlags & flags);
             if (commonFlags > maxCommonFlags) {
@@ -839,7 +838,7 @@
         return BAD_VALUE;
     }
 
-    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
 
     // increment usage count for this stream on the requested output:
     // NOTE that the usage count is the same for duplicated output and hardware output which is
@@ -854,7 +853,7 @@
         uint32_t waitMs = 0;
         bool force = false;
         for (size_t i = 0; i < mOutputs.size(); i++) {
-            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if (desc != outputDesc) {
                 // force a device change if any other output is managed by the same hw
                 // module and has a current device selection that differs from selected device.
@@ -907,7 +906,7 @@
         return BAD_VALUE;
     }
 
-    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
 
     // handle special case for sonification while in call
     if (isInCall()) {
@@ -932,7 +931,7 @@
             // one being selected for this output
             for (size_t i = 0; i < mOutputs.size(); i++) {
                 audio_io_handle_t curOutput = mOutputs.keyAt(i);
-                AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
                 if (curOutput != output &&
                         desc->isActive() &&
                         outputDesc->sharesHwModuleWith(desc) &&
@@ -965,10 +964,9 @@
 #ifdef AUDIO_POLICY_TEST
     int testIndex = testOutputIndex(output);
     if (testIndex != 0) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
         if (outputDesc->isActive()) {
             mpClientInterface->closeOutput(output);
-            delete mOutputs.valueAt(index);
             mOutputs.removeItem(output);
             mTestOutputs[testIndex] = 0;
         }
@@ -976,7 +974,7 @@
     }
 #endif //AUDIO_POLICY_TEST
 
-    AudioOutputDescriptor *desc = mOutputs.valueAt(index);
+    sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index);
     if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
         if (desc->mDirectOpenCount <= 0) {
             ALOGW("releaseOutput() invalid open count %d for output %d",
@@ -1045,7 +1043,7 @@
         return 0;
     }
 
-    AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile);
+    sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
 
     inputDesc->mInputSource = inputSource;
     inputDesc->mDevice = device;
@@ -1069,7 +1067,6 @@
         if (input != 0) {
             mpClientInterface->closeInput(input);
         }
-        delete inputDesc;
         return 0;
     }
     addInput(input, inputDesc);
@@ -1085,7 +1082,7 @@
         ALOGW("startInput() unknown input %d", input);
         return BAD_VALUE;
     }
-    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
+    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
 
 #ifdef AUDIO_POLICY_TEST
     if (mTestInput == 0)
@@ -1095,7 +1092,7 @@
         // uses AUDIO_SOURCE_HOTWORD in which case it is closed.
         audio_io_handle_t activeInput = getActiveInput();
         if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) {
-            AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
+            sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
             if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
                 ALOGW("startInput() preempting already started low-priority input %d", activeInput);
                 stopInput(activeInput);
@@ -1129,7 +1126,7 @@
         ALOGW("stopInput() unknown input %d", input);
         return BAD_VALUE;
     }
-    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
+    sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
 
     if (inputDesc->mRefCount == 0) {
         ALOGW("stopInput() input %d already stopped", input);
@@ -1156,7 +1153,6 @@
         return;
     }
     mpClientInterface->closeInput(input);
-    delete mInputs.valueAt(index);
     mInputs.removeItem(input);
     nextAudioPortGeneration();
     mpClientInterface->onAudioPortListUpdate();
@@ -1265,7 +1261,7 @@
     audio_io_handle_t outputDeepBuffer = 0;
 
     for (size_t i = 0; i < outputs.size(); i++) {
-        AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
+        sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
         ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
         if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
             outputOffloaded = outputs[i];
@@ -1327,14 +1323,14 @@
             desc->name, io, strategy, session, id);
     ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
 
-    EffectDescriptor *pDesc = new EffectDescriptor();
-    memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t));
-    pDesc->mIo = io;
-    pDesc->mStrategy = (routing_strategy)strategy;
-    pDesc->mSession = session;
-    pDesc->mEnabled = false;
+    sp<EffectDescriptor> effectDesc = new EffectDescriptor();
+    memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t));
+    effectDesc->mIo = io;
+    effectDesc->mStrategy = (routing_strategy)strategy;
+    effectDesc->mSession = session;
+    effectDesc->mEnabled = false;
 
-    mEffects.add(id, pDesc);
+    mEffects.add(id, effectDesc);
 
     return NO_ERROR;
 }
@@ -1347,21 +1343,20 @@
         return INVALID_OPERATION;
     }
 
-    EffectDescriptor *pDesc = mEffects.valueAt(index);
+    sp<EffectDescriptor> effectDesc = mEffects.valueAt(index);
 
-    setEffectEnabled(pDesc, false);
+    setEffectEnabled(effectDesc, false);
 
-    if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) {
+    if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) {
         ALOGW("unregisterEffect() memory %d too big for total %d",
-                pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
-        pDesc->mDesc.memoryUsage = mTotalEffectsMemory;
+                effectDesc->mDesc.memoryUsage, mTotalEffectsMemory);
+        effectDesc->mDesc.memoryUsage = mTotalEffectsMemory;
     }
-    mTotalEffectsMemory -= pDesc->mDesc.memoryUsage;
+    mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage;
     ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d",
-            pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
+            effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory);
 
     mEffects.removeItem(id);
-    delete pDesc;
 
     return NO_ERROR;
 }
@@ -1377,43 +1372,43 @@
     return setEffectEnabled(mEffects.valueAt(index), enabled);
 }
 
-status_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled)
+status_t AudioPolicyManager::setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled)
 {
-    if (enabled == pDesc->mEnabled) {
+    if (enabled == effectDesc->mEnabled) {
         ALOGV("setEffectEnabled(%s) effect already %s",
              enabled?"true":"false", enabled?"enabled":"disabled");
         return INVALID_OPERATION;
     }
 
     if (enabled) {
-        if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) {
+        if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) {
             ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS",
-                 pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10);
+                 effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10);
             return INVALID_OPERATION;
         }
-        mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad;
+        mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad;
         ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad);
     } else {
-        if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) {
+        if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) {
             ALOGW("setEffectEnabled(false) CPU load %d too high for total %d",
-                    pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
-            pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
+                    effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
+            effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
         }
-        mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad;
+        mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad;
         ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad);
     }
-    pDesc->mEnabled = enabled;
+    effectDesc->mEnabled = enabled;
     return NO_ERROR;
 }
 
 bool AudioPolicyManager::isNonOffloadableEffectEnabled()
 {
     for (size_t i = 0; i < mEffects.size(); i++) {
-        const EffectDescriptor * const pDesc = mEffects.valueAt(i);
-        if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) &&
-                ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
+        sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
+        if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) &&
+                ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
             ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
-                  pDesc->mDesc.name, pDesc->mSession);
+                  effectDesc->mDesc.name, effectDesc->mSession);
             return true;
         }
     }
@@ -1424,7 +1419,7 @@
 {
     nsecs_t sysTime = systemTime();
     for (size_t i = 0; i < mOutputs.size(); i++) {
-        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
+        const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
         if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
             return true;
         }
@@ -1437,7 +1432,7 @@
 {
     nsecs_t sysTime = systemTime();
     for (size_t i = 0; i < mOutputs.size(); i++) {
-        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
+        const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
         if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
                 outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
             return true;
@@ -1449,7 +1444,7 @@
 bool AudioPolicyManager::isSourceActive(audio_source_t source) const
 {
     for (size_t i = 0; i < mInputs.size(); i++) {
-        const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i);
+        const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
         if ((inputDescriptor->mInputSource == (int)source ||
                 (source == AUDIO_SOURCE_VOICE_RECOGNITION &&
                  inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD))
@@ -1674,10 +1669,10 @@
     return NO_ERROR;
 }
 
-AudioPolicyManager::AudioOutputDescriptor *AudioPolicyManager::getOutputFromId(
+sp<AudioPolicyManager::AudioOutputDescriptor> AudioPolicyManager::getOutputFromId(
                                                                     audio_port_handle_t id) const
 {
-    AudioOutputDescriptor *outputDesc = NULL;
+    sp<AudioOutputDescriptor> outputDesc = NULL;
     for (size_t i = 0; i < mOutputs.size(); i++) {
         outputDesc = mOutputs.valueAt(i);
         if (outputDesc->mId == id) {
@@ -1687,10 +1682,10 @@
     return outputDesc;
 }
 
-AudioPolicyManager::AudioInputDescriptor *AudioPolicyManager::getInputFromId(
+sp<AudioPolicyManager::AudioInputDescriptor> AudioPolicyManager::getInputFromId(
                                                                     audio_port_handle_t id) const
 {
-    AudioInputDescriptor *inputDesc = NULL;
+    sp<AudioInputDescriptor> inputDesc = NULL;
     for (size_t i = 0; i < mInputs.size(); i++) {
         inputDesc = mInputs.valueAt(i);
         if (inputDesc->mId == id) {
@@ -1700,8 +1695,11 @@
     return inputDesc;
 }
 
-AudioPolicyManager::HwModule *AudioPolicyManager::getModuleForDevice(audio_devices_t device) const
+sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleForDevice(
+                                                                    audio_devices_t device) const
 {
+    sp <HwModule> module;
+
     for (size_t i = 0; i < mHwModules.size(); i++) {
         if (mHwModules[i]->mHandle == 0) {
             continue;
@@ -1722,18 +1720,20 @@
             }
         }
     }
-    return NULL;
+    return module;
 }
 
-AudioPolicyManager::HwModule *AudioPolicyManager::getModuleFromName(const char *name) const
+sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleFromName(const char *name) const
 {
+    sp <HwModule> module;
+
     for (size_t i = 0; i < mHwModules.size(); i++)
     {
         if (strcmp(mHwModules[i]->mName, name) == 0) {
             return mHwModules[i];
         }
     }
-    return NULL;
+    return module;
 }
 
 
@@ -1783,7 +1783,7 @@
             return BAD_VALUE;
         }
         // output mix to output device connection
-        AudioOutputDescriptor *outputDesc = getOutputFromId(patch->sources[0].id);
+        sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id);
         if (outputDesc == NULL) {
             ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
             return BAD_VALUE;
@@ -1832,7 +1832,7 @@
     } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
         if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
             // input device to input mix connection
-            AudioInputDescriptor *inputDesc = getInputFromId(patch->sinks[0].id);
+            sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id);
             if (inputDesc == NULL) {
                 return BAD_VALUE;
             }
@@ -1957,7 +1957,7 @@
     struct audio_patch *patch = &patchDesc->mPatch;
     patchDesc->mUid = mUidCached;
     if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
-        AudioOutputDescriptor *outputDesc = getOutputFromId(patch->sources[0].id);
+        sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id);
         if (outputDesc == NULL) {
             ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
             return BAD_VALUE;
@@ -1970,7 +1970,7 @@
                        NULL);
     } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
         if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
-            AudioInputDescriptor *inputDesc = getInputFromId(patch->sinks[0].id);
+            sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id);
             if (inputDesc == NULL) {
                 ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
                 return BAD_VALUE;
@@ -2043,14 +2043,14 @@
     struct audio_port_config portConfig;
     if (config->type == AUDIO_PORT_TYPE_MIX) {
         if (config->role == AUDIO_PORT_ROLE_SOURCE) {
-            AudioOutputDescriptor *outputDesc = getOutputFromId(config->id);
+            sp<AudioOutputDescriptor> outputDesc = getOutputFromId(config->id);
             if (outputDesc == NULL) {
                 return BAD_VALUE;
             }
             portDesc = outputDesc->mProfile;
             outputDesc->toAudioPortConfig(&portConfig);
         } else if (config->role == AUDIO_PORT_ROLE_SINK) {
-            AudioInputDescriptor *inputDesc = getInputFromId(config->id);
+            sp<AudioInputDescriptor> inputDesc = getInputFromId(config->id);
             if (inputDesc == NULL) {
                 return BAD_VALUE;
             }
@@ -2230,7 +2230,7 @@
             audio_devices_t profileTypes = outProfile->mSupportedDevices.types();
             if ((profileTypes & outputDeviceTypes) &&
                     ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
-                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
+                sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile);
 
                 outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mDeviceType & profileTypes);
                 audio_io_handle_t output = mpClientInterface->openOutput(
@@ -2245,7 +2245,6 @@
                     ALOGW("Cannot open output stream for device %08x on hw module %s",
                           outputDesc->mDevice,
                           mHwModules[i]->mName);
-                    delete outputDesc;
                 } else {
                     for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {
                         audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType;
@@ -2282,7 +2281,7 @@
 
             audio_devices_t profileTypes = inProfile->mSupportedDevices.types();
             if (profileTypes & inputDeviceTypes) {
-                AudioInputDescriptor *inputDesc = new AudioInputDescriptor(inProfile);
+                sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile);
 
                 inputDesc->mInputSource = AUDIO_SOURCE_MIC;
                 inputDesc->mDevice = inProfile->mSupportedDevices[0]->mDeviceType;
@@ -2310,7 +2309,6 @@
                           inputDesc->mDevice,
                           mHwModules[i]->mName);
                 }
-                delete inputDesc;
             }
         }
     }
@@ -2372,17 +2370,15 @@
 #endif //AUDIO_POLICY_TEST
    for (size_t i = 0; i < mOutputs.size(); i++) {
         mpClientInterface->closeOutput(mOutputs.keyAt(i));
-        delete mOutputs.valueAt(i);
    }
    for (size_t i = 0; i < mInputs.size(); i++) {
         mpClientInterface->closeInput(mInputs.keyAt(i));
-        delete mInputs.valueAt(i);
-   }
-   for (size_t i = 0; i < mHwModules.size(); i++) {
-        delete mHwModules[i];
    }
    mAvailableOutputDevices.clear();
    mAvailableInputDevices.clear();
+   mOutputs.clear();
+   mInputs.clear();
+   mHwModules.clear();
 }
 
 status_t AudioPolicyManager::initCheck()
@@ -2486,15 +2482,14 @@
             if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
                 param.remove(String8("test_cmd_policy_reopen"));
 
-                AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
+                sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
                 mpClientInterface->closeOutput(mPrimaryOutput);
 
                 audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
 
-                delete mOutputs.valueFor(mPrimaryOutput);
                 mOutputs.removeItem(mPrimaryOutput);
 
-                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
+                sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
                 outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
                 mPrimaryOutput = mpClientInterface->openOutput(moduleHandle,
                                                 &outputDesc->mDevice,
@@ -2542,7 +2537,7 @@
 
 // ---
 
-void AudioPolicyManager::addOutput(audio_io_handle_t output, AudioOutputDescriptor *outputDesc)
+void AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc)
 {
     outputDesc->mIoHandle = output;
     outputDesc->mId = nextUniqueId();
@@ -2550,7 +2545,7 @@
     nextAudioPortGeneration();
 }
 
-void AudioPolicyManager::addInput(audio_io_handle_t input, AudioInputDescriptor *inputDesc)
+void AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc)
 {
     inputDesc->mIoHandle = input;
     inputDesc->mId = nextUniqueId();
@@ -2571,7 +2566,7 @@
                                                        SortedVector<audio_io_handle_t>& outputs,
                                                        const String8 address)
 {
-    AudioOutputDescriptor *desc;
+    sp<AudioOutputDescriptor> desc;
 
     if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
         // first list already open outputs that can be routed to this device
@@ -2714,7 +2709,7 @@
                                                                                   mPrimaryOutput);
                         if (duplicatedOutput != 0) {
                             // add duplicated output descriptor
-                            AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL);
+                            sp<AudioOutputDescriptor> dupOutputDesc = new AudioOutputDescriptor(NULL);
                             dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
                             dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
                             dupOutputDesc->mSamplingRate = desc->mSamplingRate;
@@ -2736,7 +2731,6 @@
             }
             if (output == 0) {
                 ALOGW("checkOutputsForDevice() could not open output for device %x", device);
-                delete desc;
                 profiles.removeAt(profile_index);
                 profile_index--;
             } else {
@@ -2796,7 +2790,7 @@
                                                       SortedVector<audio_io_handle_t>& inputs,
                                                       const String8 address)
 {
-    AudioInputDescriptor *desc;
+    sp<AudioInputDescriptor> desc;
     if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
         // first list already open inputs that can be routed to this device
         for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
@@ -2911,7 +2905,6 @@
 
             if (input == 0) {
                 ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
-                delete desc;
                 profiles.removeAt(profile_index);
                 profile_index--;
             } else {
@@ -2972,7 +2965,7 @@
 {
     ALOGV("closeOutput(%d)", output);
 
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
     if (outputDesc == NULL) {
         ALOGW("closeOutput() unknown output %d", output);
         return;
@@ -2980,11 +2973,11 @@
 
     // look for duplicated outputs connected to the output being removed.
     for (size_t i = 0; i < mOutputs.size(); i++) {
-        AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i);
+        sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
         if (dupOutputDesc->isDuplicated() &&
                 (dupOutputDesc->mOutput1 == outputDesc ||
                 dupOutputDesc->mOutput2 == outputDesc)) {
-            AudioOutputDescriptor *outputDesc2;
+            sp<AudioOutputDescriptor> outputDesc2;
             if (dupOutputDesc->mOutput1 == outputDesc) {
                 outputDesc2 = dupOutputDesc->mOutput2;
             } else {
@@ -3002,7 +2995,6 @@
             ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
 
             mpClientInterface->closeOutput(duplicatedOutput);
-            delete mOutputs.valueFor(duplicatedOutput);
             mOutputs.removeItem(duplicatedOutput);
         }
     }
@@ -3012,14 +3004,13 @@
     mpClientInterface->setParameters(output, param.toString());
 
     mpClientInterface->closeOutput(output);
-    delete outputDesc;
     mOutputs.removeItem(output);
     mPreviousOutputs = mOutputs;
     nextAudioPortGeneration();
 }
 
 SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
-                        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs)
+                        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs)
 {
     SortedVector<audio_io_handle_t> outputs;
 
@@ -3061,7 +3052,7 @@
               strategy, srcOutputs[0], dstOutputs[0]);
         // mute strategy while moving tracks from one output to another
         for (size_t i = 0; i < srcOutputs.size(); i++) {
-            AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]);
+            sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
             if (desc->isStrategyActive(strategy)) {
                 setStrategyMute(strategy, true, srcOutputs[i]);
                 setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
@@ -3073,17 +3064,17 @@
             audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
             SortedVector<audio_io_handle_t> moved;
             for (size_t i = 0; i < mEffects.size(); i++) {
-                EffectDescriptor *desc = mEffects.valueAt(i);
-                if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
-                        desc->mIo != fxOutput) {
-                    if (moved.indexOf(desc->mIo) < 0) {
+                sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
+                if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
+                        effectDesc->mIo != fxOutput) {
+                    if (moved.indexOf(effectDesc->mIo) < 0) {
                         ALOGV("checkOutputForStrategy() moving effect %d to output %d",
                               mEffects.keyAt(i), fxOutput);
-                        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo,
+                        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
                                                        fxOutput);
-                        moved.add(desc->mIo);
+                        moved.add(effectDesc->mIo);
                     }
-                    desc->mIo = fxOutput;
+                    effectDesc->mIo = fxOutput;
                 }
             }
         }
@@ -3109,7 +3100,7 @@
 audio_io_handle_t AudioPolicyManager::getA2dpOutput()
 {
     for (size_t i = 0; i < mOutputs.size(); i++) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
+        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
         if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
             return mOutputs.keyAt(i);
         }
@@ -3167,7 +3158,7 @@
 {
     audio_devices_t device = AUDIO_DEVICE_NONE;
 
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
 
     ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
     if (index >= 0) {
@@ -3213,7 +3204,7 @@
 
 audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
 {
-    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
+    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
 
     ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
     if (index >= 0) {
@@ -3247,7 +3238,7 @@
     devices = getDeviceForStrategy(strategy, true /*fromCache*/);
     SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs);
     for (size_t i = 0; i < outputs.size(); i++) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
+        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
         if (outputDesc->isStrategyActive(strategy)) {
             devices = outputDesc->device();
             break;
@@ -3514,7 +3505,7 @@
     mPreviousOutputs = mOutputs;
 }
 
-uint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc,
+uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc,
                                                        audio_devices_t prevDevice,
                                                        uint32_t delayMs)
 {
@@ -3543,7 +3534,7 @@
         }
         if (doMute) {
             for (size_t j = 0; j < mOutputs.size(); j++) {
-                AudioOutputDescriptor *desc = mOutputs.valueAt(j);
+                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
                 // skip output if it does not share any device with current output
                 if ((desc->supportedDevices() & outputDesc->supportedDevices())
                         == AUDIO_DEVICE_NONE) {
@@ -3601,7 +3592,7 @@
                                              audio_patch_handle_t *patchHandle)
 {
     ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
     AudioParameter param;
     uint32_t muteWaitMs;
 
@@ -3703,7 +3694,7 @@
                                                int delayMs,
                                                audio_patch_handle_t *patchHandle)
 {
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
     ssize_t index;
     if (patchHandle) {
         index = mAudioPatches.indexOfKey(*patchHandle);
@@ -3730,7 +3721,7 @@
 {
     status_t status = NO_ERROR;
 
-    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
+    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
     if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
         inputDesc->mDevice = device;
 
@@ -3785,7 +3776,7 @@
 status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
                                               audio_patch_handle_t *patchHandle)
 {
-    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
+    sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
     ssize_t index;
     if (patchHandle) {
         index = mAudioPatches.indexOfKey(*patchHandle);
@@ -3899,7 +3890,7 @@
 audio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs)
 {
     for (size_t i = 0; i < mInputs.size(); i++) {
-        const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i);
+        const sp<AudioInputDescriptor>  input_descriptor = mInputs.valueAt(i);
         if ((input_descriptor->mRefCount > 0)
                 && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) {
             return mInputs.keyAt(i);
@@ -4144,7 +4135,7 @@
                                             audio_devices_t device)
 {
     float volume = 1.0;
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
     StreamDescriptor &streamDesc = mStreams[stream];
 
     if (device == AUDIO_DEVICE_NONE) {
@@ -4300,7 +4291,7 @@
                                            audio_devices_t device)
 {
     StreamDescriptor &streamDesc = mStreams[stream];
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
     if (device == AUDIO_DEVICE_NONE) {
         device = outputDesc->device();
     }
@@ -4345,7 +4336,7 @@
     const routing_strategy stream_strategy = getStrategy(stream);
     if ((stream_strategy == STRATEGY_SONIFICATION) ||
             ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
+        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
         ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
                 stream, starting, outputDesc->mDevice, stateChange);
         if (outputDesc->mRefCount[stream]) {
@@ -4403,8 +4394,7 @@
 
 AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(
         const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT),
-      mChannelMask(0), mLatency(0),
+    : mId(0), mIoHandle(0), mLatency(0),
     mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0),
     mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
 {
@@ -4419,6 +4409,7 @@
         mStrategyMutedByDevice[i] = false;
     }
     if (profile != NULL) {
+        mAudioPort = profile;
         mSamplingRate = profile->mSamplingRates[0];
         mFormat = profile->mFormats[0];
         mChannelMask = profile->mChannelMasks[0];
@@ -4445,7 +4436,7 @@
 }
 
 bool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith(
-        const AudioOutputDescriptor *outputDesc)
+        const sp<AudioOutputDescriptor> outputDesc)
 {
     if (isDuplicated()) {
         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
@@ -4528,31 +4519,16 @@
                                                  struct audio_port_config *dstConfig,
                                                  const struct audio_port_config *srcConfig) const
 {
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
+                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
+    if (srcConfig != NULL) {
+        dstConfig->config_mask &= srcConfig->config_mask;
+    }
+    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+
     dstConfig->id = mId;
     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
     dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->sample_rate = mSamplingRate;
-    dstConfig->channel_mask = mChannelMask;
-    dstConfig->format = mFormat;
-    dstConfig->gain.index = -1;
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
-                            AUDIO_PORT_CONFIG_FORMAT;
-    // use supplied variable configuration parameters if any
-    if (srcConfig != NULL) {
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-            dstConfig->sample_rate = srcConfig->sample_rate;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-            dstConfig->format = srcConfig->format;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-            dstConfig->gain = srcConfig->gain;
-            dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
-        }
-    }
     dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
     dstConfig->ext.mix.handle = mIoHandle;
     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
@@ -4603,15 +4579,19 @@
 // --- AudioInputDescriptor class implementation
 
 AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0), mSamplingRate(0),
-      mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0),
+    : mId(0), mIoHandle(0),
       mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0),
       mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile)
 {
     if (profile != NULL) {
+        mAudioPort = profile;
         mSamplingRate = profile->mSamplingRates[0];
         mFormat = profile->mFormats[0];
         mChannelMask = profile->mChannelMasks[0];
+    } else {
+        mSamplingRate = 0;
+        mFormat = AUDIO_FORMAT_DEFAULT;
+        mChannelMask = 0;
     }
 }
 
@@ -4619,31 +4599,17 @@
                                                    struct audio_port_config *dstConfig,
                                                    const struct audio_port_config *srcConfig) const
 {
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
+                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
+    if (srcConfig != NULL) {
+        dstConfig->config_mask &= srcConfig->config_mask;
+    }
+
+    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+
     dstConfig->id = mId;
     dstConfig->role = AUDIO_PORT_ROLE_SINK;
     dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->sample_rate = mSamplingRate;
-    dstConfig->channel_mask = mChannelMask;
-    dstConfig->format = mFormat;
-    dstConfig->gain.index = -1;
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
-                            AUDIO_PORT_CONFIG_FORMAT;
-    // use supplied variable configuration parameters if any
-    if (srcConfig != NULL) {
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-            dstConfig->sample_rate = srcConfig->sample_rate;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-            dstConfig->format = srcConfig->format;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-            dstConfig->gain = srcConfig->gain;
-            dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
-        }
-    }
     dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
     dstConfig->ext.mix.handle = mIoHandle;
     dstConfig->ext.mix.usecase.source = mInputSource;
@@ -5214,10 +5180,63 @@
     write(fd, result.string(), result.size());
 }
 
+// --- AudioPortConfig class implementation
+
+AudioPolicyManager::AudioPortConfig::AudioPortConfig()
+{
+    mSamplingRate = 0;
+    mChannelMask = AUDIO_CHANNEL_NONE;
+    mFormat = AUDIO_FORMAT_INVALID;
+    mGain.index = -1;
+}
+
+void AudioPolicyManager::AudioPortConfig::toAudioPortConfig(
+                                                    struct audio_port_config *dstConfig,
+                                                    const struct audio_port_config *srcConfig) const
+{
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+        dstConfig->sample_rate = mSamplingRate;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) {
+            dstConfig->sample_rate = srcConfig->sample_rate;
+        }
+    } else {
+        dstConfig->sample_rate = 0;
+    }
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+        dstConfig->channel_mask = mChannelMask;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) {
+            dstConfig->channel_mask = srcConfig->channel_mask;
+        }
+    } else {
+        dstConfig->channel_mask = AUDIO_CHANNEL_NONE;
+    }
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+        dstConfig->format = mFormat;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) {
+            dstConfig->format = srcConfig->format;
+        }
+    } else {
+        dstConfig->format = AUDIO_FORMAT_INVALID;
+    }
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
+        dstConfig->gain = mGain;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) {
+            dstConfig->gain = srcConfig->gain;
+        }
+    } else {
+        dstConfig->gain.index = -1;
+    }
+    if (dstConfig->gain.index != -1) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
+    } else {
+        dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
+    }
+}
+
 // --- IOProfile class implementation
 
 AudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role,
-                                         HwModule *module)
+                                         const sp<HwModule>& module)
     : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module), mFlags((audio_output_flags_t)0)
 {
 }
@@ -5322,6 +5341,18 @@
 
 // --- DeviceDescriptor implementation
 
+
+AudioPolicyManager::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),
+                     mDeviceType(type), mAddress(""),
+                     mChannelMask(AUDIO_CHANNEL_NONE), mId(0)
+{
+    mAudioPort = this;
+}
+
 bool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
 {
     // Devices are considered equal if they:
@@ -5486,23 +5517,17 @@
                                                     struct audio_port_config *dstConfig,
                                                     const struct audio_port_config *srcConfig) const
 {
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN;
+    if (srcConfig != NULL) {
+        dstConfig->config_mask &= srcConfig->config_mask;
+    }
+
+    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+
     dstConfig->id = mId;
     dstConfig->role = audio_is_output_device(mDeviceType) ?
                         AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
     dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
-    dstConfig->channel_mask = mChannelMask;
-    dstConfig->gain.index = -1;
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK;
-    // use supplied variable configuration parameters if any
-    if (srcConfig != NULL) {
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-            dstConfig->gain = srcConfig->gain;
-            dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
-        }
-    }
     dstConfig->ext.device.type = mDeviceType;
     dstConfig->ext.device.hw_module = mModule->mHandle;
     strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
@@ -5598,7 +5623,7 @@
 {
     status_t status = NAME_NOT_FOUND;
     cnode *node;
-    HwModule *module = new HwModule(root->name);
+    sp<HwModule> module = new HwModule(root->name);
 
     node = config_find(root, DEVICES_TAG);
     if (node != NULL) {
@@ -5640,8 +5665,6 @@
 
     if (status == NO_ERROR) {
         mHwModules.add(module);
-    } else {
-        delete module;
     }
 }
 
@@ -5660,7 +5683,7 @@
     }
 }
 
-void AudioPolicyManager::loadGlobalConfig(cnode *root, HwModule *module)
+void AudioPolicyManager::loadGlobalConfig(cnode *root, const sp<HwModule>& module)
 {
     cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
     if (node == NULL) {
@@ -5726,9 +5749,10 @@
 
 void AudioPolicyManager::defaultAudioPolicyConfig(void)
 {
-    HwModule *module;
+    sp<HwModule> module;
     sp<IOProfile> profile;
-    sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_IN_BUILTIN_MIC);
+    sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""),
+                                                                   AUDIO_DEVICE_IN_BUILTIN_MIC);
     mAvailableOutputDevices.add(mDefaultOutputDevice);
     mAvailableInputDevices.add(defaultInputDevice);
 
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index e012d63..db0da24 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -203,11 +203,11 @@
             struct audio_gain mGain;
         };
 
-        class AudioPort: public RefBase
+        class AudioPort: public virtual RefBase
         {
         public:
             AudioPort(const String8& name, audio_port_type_t type,
-                      audio_port_role_t role, HwModule *module) :
+                      audio_port_role_t role, const sp<HwModule>& module) :
                 mName(name), mType(type), mRole(role), mModule(module) {}
             virtual ~AudioPort() {}
 
@@ -234,9 +234,25 @@
             Vector <audio_channel_mask_t> mChannelMasks; // supported channel masks
             Vector <audio_format_t> mFormats; // supported audio formats
             Vector < sp<AudioGain> > mGains; // gain controllers
-            HwModule *mModule;                 // audio HW module exposing this I/O stream
+            sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
         };
 
+        class AudioPortConfig: public virtual RefBase
+        {
+        public:
+            AudioPortConfig();
+            virtual ~AudioPortConfig() {}
+
+            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
+                                   const struct audio_port_config *srcConfig = NULL) const = 0;
+            sp<AudioPort> mAudioPort;
+            uint32_t mSamplingRate;
+            audio_format_t mFormat;
+            audio_channel_mask_t mChannelMask;
+            struct audio_gain_config mGain;
+        };
+
+
         class AudioPatch: public RefBase
         {
         public:
@@ -250,29 +266,15 @@
             audio_patch_handle_t mAfPatchHandle;
         };
 
-        class DeviceDescriptor: public AudioPort
+        class DeviceDescriptor: public AudioPort, public AudioPortConfig
         {
         public:
-            DeviceDescriptor(const String8& name, audio_devices_t type, String8 address,
-                             audio_channel_mask_t channelMask) :
-                                 AudioPort(name, AUDIO_PORT_TYPE_DEVICE,
-                                           audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
-                                                                          AUDIO_PORT_ROLE_SOURCE,
-                                         NULL),
-                                 mDeviceType(type), mAddress(address),
-                                 mChannelMask(channelMask), mId(0) {}
+            DeviceDescriptor(const String8& name, audio_devices_t type);
 
-            DeviceDescriptor(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),
-                                mDeviceType(type), mAddress(""),
-                                mChannelMask(0), mId(0) {}
             virtual ~DeviceDescriptor() {}
 
             bool equals(const sp<DeviceDescriptor>& other) const;
-            void toAudioPortConfig(struct audio_port_config *dstConfig,
+            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                                    const struct audio_port_config *srcConfig = NULL) const;
 
             virtual void toAudioPort(struct audio_port *port) const;
@@ -317,7 +319,7 @@
         class IOProfile : public AudioPort
         {
         public:
-            IOProfile(const String8& name, audio_port_role_t role, HwModule *module);
+            IOProfile(const String8& name, audio_port_role_t role, const sp<HwModule>& module);
             virtual ~IOProfile();
 
             bool isCompatibleProfile(audio_devices_t device,
@@ -335,7 +337,7 @@
                                                 // direct output...). For outputs only.
         };
 
-        class HwModule {
+        class HwModule : public RefBase{
         public:
                     HwModule(const char *name);
                     ~HwModule();
@@ -373,7 +375,7 @@
 
         // descriptor for audio outputs. Used to maintain current configuration of each opened audio output
         // and keep track of the usage of this output by each audio stream type.
-        class AudioOutputDescriptor
+        class AudioOutputDescriptor: public AudioPortConfig
         {
         public:
             AudioOutputDescriptor(const sp<IOProfile>& profile);
@@ -386,7 +388,7 @@
             bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
             audio_devices_t supportedDevices();
             uint32_t latency();
-            bool sharesHwModuleWith(const AudioOutputDescriptor *outputDesc);
+            bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
             bool isActive(uint32_t inPastMs = 0) const;
             bool isStreamActive(audio_stream_type_t stream,
                                 uint32_t inPastMs = 0,
@@ -395,23 +397,20 @@
                              uint32_t inPastMs = 0,
                              nsecs_t sysTime = 0) const;
 
-            void toAudioPortConfig(struct audio_port_config *dstConfig,
+            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                                    const struct audio_port_config *srcConfig = NULL) const;
             void toAudioPort(struct audio_port *port) const;
 
             audio_port_handle_t mId;
             audio_io_handle_t mIoHandle;              // output handle
-            uint32_t mSamplingRate;             //
-            audio_format_t mFormat;             //
-            audio_channel_mask_t mChannelMask;     // output configuration
             uint32_t mLatency;                  //
             audio_output_flags_t mFlags;   //
             audio_devices_t mDevice;                   // current device this output is routed to
             audio_patch_handle_t mPatchHandle;
             uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
             nsecs_t mStopTime[AUDIO_STREAM_CNT];
-            AudioOutputDescriptor *mOutput1;    // used by duplicated outputs: first output
-            AudioOutputDescriptor *mOutput2;    // used by duplicated outputs: second output
+            sp<AudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
+            sp<AudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
             float mCurVolume[AUDIO_STREAM_CNT];   // current stream volume
             int mMuteCount[AUDIO_STREAM_CNT];     // mute request counter
             const sp<IOProfile> mProfile;          // I/O profile this output derives from
@@ -422,7 +421,7 @@
 
         // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
         // and keep track of the usage of this input.
-        class AudioInputDescriptor
+        class AudioInputDescriptor: public AudioPortConfig
         {
         public:
             AudioInputDescriptor(const sp<IOProfile>& profile);
@@ -431,16 +430,13 @@
 
             audio_port_handle_t mId;
             audio_io_handle_t mIoHandle;              // input handle
-            uint32_t mSamplingRate;                     //
-            audio_format_t mFormat;                     // input configuration
-            audio_channel_mask_t mChannelMask;             //
             audio_devices_t mDevice;                    // current device this input is routed to
             audio_patch_handle_t mPatchHandle;
             uint32_t mRefCount;                         // number of AudioRecord clients using this output
             audio_source_t mInputSource;                // input source selected by application (mediarecorder.h)
             const sp<IOProfile> mProfile;                  // I/O profile this output derives from
 
-            void toAudioPortConfig(struct audio_port_config *dstConfig,
+            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                                    const struct audio_port_config *srcConfig = NULL) const;
             void toAudioPort(struct audio_port *port) const;
         };
@@ -463,7 +459,7 @@
         };
 
         // stream descriptor used for volume control
-        class EffectDescriptor
+        class EffectDescriptor : public RefBase
         {
         public:
 
@@ -476,8 +472,8 @@
             bool mEnabled;              // enabled state: CPU load being used or not
         };
 
-        void addOutput(audio_io_handle_t output, AudioOutputDescriptor *outputDesc);
-        void addInput(audio_io_handle_t input, AudioInputDescriptor *inputDesc);
+        void addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc);
+        void addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc);
 
         // return the strategy corresponding to a given stream type
         static routing_strategy getStrategy(audio_stream_type_t stream);
@@ -618,7 +614,7 @@
         int testOutputIndex(audio_io_handle_t output);
 #endif //AUDIO_POLICY_TEST
 
-        status_t setEffectEnabled(EffectDescriptor *pDesc, bool enabled);
+        status_t setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled);
 
         // returns the category the device belongs to with regard to volume curve management
         static device_category getDeviceCategory(audio_devices_t device);
@@ -627,7 +623,7 @@
         static audio_devices_t getDeviceForVolume(audio_devices_t device);
 
         SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device,
-                        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs);
+                        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs);
         bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
                                            SortedVector<audio_io_handle_t>& outputs2);
 
@@ -635,7 +631,7 @@
         // if muting, wait for the audio in pcm buffer to be drained before proceeding
         // if unmuting, unmute only after the specified delay
         // Returns the number of ms waited
-        uint32_t  checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc,
+        uint32_t  checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc,
                                             audio_devices_t prevDevice,
                                             uint32_t delayMs);
 
@@ -659,10 +655,10 @@
                                const sp<AudioPatch>& patch);
         status_t removeAudioPatch(audio_patch_handle_t handle);
 
-        AudioOutputDescriptor *getOutputFromId(audio_port_handle_t id) const;
-        AudioInputDescriptor *getInputFromId(audio_port_handle_t id) const;
-        HwModule *getModuleForDevice(audio_devices_t device) const;
-        HwModule *getModuleFromName(const char *name) const;
+        sp<AudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;
+        sp<AudioInputDescriptor> getInputFromId(audio_port_handle_t id) const;
+        sp<HwModule> getModuleForDevice(audio_devices_t device) const;
+        sp<HwModule> getModuleFromName(const char *name) const;
         //
         // Audio policy configuration file parsing (audio_policy.conf)
         //
@@ -677,7 +673,7 @@
         static audio_devices_t parseDeviceNames(char *name);
         void loadHwModule(cnode *root);
         void loadHwModules(cnode *root);
-        void loadGlobalConfig(cnode *root, HwModule *module);
+        void loadGlobalConfig(cnode *root, const sp<HwModule>& module);
         status_t loadAudioPolicyConfig(const char *path);
         void defaultAudioPolicyConfig(void);
 
@@ -686,11 +682,11 @@
         AudioPolicyClientInterface *mpClientInterface;  // audio policy client interface
         audio_io_handle_t mPrimaryOutput;              // primary output handle
         // list of descriptors for outputs currently opened
-        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs;
+        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > mOutputs;
         // copy of mOutputs before setDeviceConnectionState() opens new outputs
         // reset to mOutputs when updateDevicesAndOutputs() is called.
-        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mPreviousOutputs;
-        DefaultKeyedVector<audio_io_handle_t, AudioInputDescriptor *> mInputs;     // list of input descriptors
+        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > mPreviousOutputs;
+        DefaultKeyedVector<audio_io_handle_t, sp<AudioInputDescriptor> > mInputs;     // list of input descriptors
         DeviceVector  mAvailableOutputDevices; // all available output devices
         DeviceVector  mAvailableInputDevices;  // all available input devices
         int mPhoneState;                                                    // current phone state
@@ -707,13 +703,13 @@
         static const uint32_t MAX_EFFECTS_MEMORY = 512;
         uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
         uint32_t mTotalEffectsMemory;  // current memory used by effects
-        KeyedVector<int, EffectDescriptor *> mEffects;  // list of registered audio effects
+        KeyedVector<int, sp<EffectDescriptor> > mEffects;  // list of registered audio effects
         bool    mA2dpSuspended;  // true if A2DP output is suspended
         sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
         bool mSpeakerDrcEnabled;// true on devices that use DRC on the DEVICE_CATEGORY_SPEAKER path
                                 // to boost soft sounds, used to adjust volume curves accordingly
 
-        Vector <HwModule *> mHwModules;
+        Vector < sp<HwModule> > mHwModules;
         volatile int32_t mNextUniqueId;
         volatile int32_t mAudioPortGeneration;