Improved unit test code for Audioflinger.
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
index 87bb014..858e5aa 100644
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -71,9 +71,21 @@
             }
         }
     } else {
-        if (format != 0 && *format != 0) lFormat = *format;
-        if (channels != 0 && *channels != 0) lChannels = *channels;
-        if (sampleRate != 0 && *sampleRate != 0) lRate = *sampleRate;
+        if (format != 0 && *format != 0) {
+            lFormat = *format;
+        } else {
+            lFormat = AudioSystem::PCM_16_BIT;
+        }
+        if (channels != 0 && *channels != 0) {
+            lChannels = *channels;
+        } else {
+            lChannels = AudioSystem::CHANNEL_OUT_STEREO;
+        }
+        if (sampleRate != 0 && *sampleRate != 0) {
+            lRate = *sampleRate;
+        } else {
+            lRate = 44100;
+        }
         if (status) *status = NO_ERROR;
     }
     LOGV("openOutputStream(), outFinal %p", outFinal);
@@ -93,9 +105,13 @@
         LOGW("Attempt to close invalid output stream");
         return;
     }
+
+    LOGV("closeOutputStream() output %p", out);
+
     dumpOut->standby();
     if (dumpOut->finalStream() != NULL) {
         mFinalInterface->closeOutputStream(dumpOut->finalStream());
+        mFirstHwOutput = true;
     }
 
     mOutputs.remove(dumpOut);
@@ -159,7 +175,7 @@
 
     if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
         mFileName = value;
-        return NO_ERROR;
+        param.remove(String8("test_cmd_file_name"));
     }
     if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
         Mutex::Autolock _l(mLock);
@@ -176,21 +192,35 @@
 String8 AudioDumpInterface::getParameters(const String8& keys)
 {
     AudioParameter param = AudioParameter(keys);
+    AudioParameter response;
     String8 value;
 
 //    LOGV("getParameters %s", keys.string());
-
-    if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
-        return mFileName;
-    }
     if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
         Mutex::Autolock _l(mLock);
+        if (mPolicyCommands.length() != 0) {
+            response = AudioParameter(mPolicyCommands);
+            response.addInt(String8("test_cmd_policy"), 1);
+        } else {
+            response.addInt(String8("test_cmd_policy"), 0);
+        }
+        param.remove(String8("test_cmd_policy"));
 //        LOGV("test_cmd_policy command %s read", mPolicyCommands.string());
-        return mPolicyCommands;
     }
 
-    if (mFinalInterface != 0 ) return mFinalInterface->getParameters(keys);
-    return String8("");
+    if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
+        response.add(String8("test_cmd_file_name"), mFileName);
+        param.remove(String8("test_cmd_file_name"));
+    }
+
+    String8 keyValuePairs = response.toString();
+
+    if (param.size() && mFinalInterface != 0 ) {
+        keyValuePairs += ";";
+        keyValuePairs += mFinalInterface->getParameters(param.toString());
+    }
+
+    return keyValuePairs;
 }
 
 
@@ -213,6 +243,7 @@
 
 AudioStreamOutDump::~AudioStreamOutDump()
 {
+    LOGV("AudioStreamOutDump destructor");
     Close();
 }
 
@@ -283,15 +314,55 @@
 }
 status_t AudioStreamOutDump::setParameters(const String8& keyValuePairs)
 {
-    LOGV("AudioStreamOutDump::setParameters()");
-    if (mFinalStream != 0 ) return mFinalStream->setParameters(keyValuePairs);
-    return NO_ERROR;
+    LOGV("AudioStreamOutDump::setParameters %s", keyValuePairs.string());
+
+    if (mFinalStream != 0 ) {
+        return mFinalStream->setParameters(keyValuePairs);
+    }
+
+    AudioParameter param = AudioParameter(keyValuePairs);
+    String8 value;
+    int valueInt;
+    status_t status = NO_ERROR;
+
+    if (param.getInt(String8("set_id"), valueInt) == NO_ERROR) {
+        mId = valueInt;
+    }
+
+    if (param.getInt(String8("format"), valueInt) == NO_ERROR) {
+        if (mOutFile == 0) {
+            mFormat = valueInt;
+        } else {
+            status = INVALID_OPERATION;
+        }
+    }
+    if (param.getInt(String8("channels"), valueInt) == NO_ERROR) {
+        if (valueInt == AudioSystem::CHANNEL_OUT_STEREO || valueInt == AudioSystem::CHANNEL_OUT_MONO) {
+            mChannels = valueInt;
+        } else {
+            status = BAD_VALUE;
+        }
+    }
+    if (param.getInt(String8("sampling_rate"), valueInt) == NO_ERROR) {
+        if (valueInt > 0 && valueInt <= 48000) {
+            if (mOutFile == 0) {
+                mSampleRate = valueInt;
+            } else {
+                status = INVALID_OPERATION;
+            }
+        } else {
+            status = BAD_VALUE;
+        }
+    }
+    return status;
 }
+
 String8 AudioStreamOutDump::getParameters(const String8& keys)
 {
-    String8 result = String8("");
-    if (mFinalStream != 0 ) result = mFinalStream->getParameters(keys);
-    return result;
+    if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
+
+    AudioParameter param = AudioParameter(keys);
+    return param.toString();
 }
 
 status_t AudioStreamOutDump::dump(int fd, const Vector<String16>& args)
@@ -426,9 +497,10 @@
 
 String8 AudioStreamInDump::getParameters(const String8& keys)
 {
-    String8 result = String8("");
-    if (mFinalStream != 0 ) result = mFinalStream->getParameters(keys);
-    return result;
+    if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
+
+    AudioParameter param = AudioParameter(keys);
+    return param.toString();
 }
 
 status_t AudioStreamInDump::dump(int fd, const Vector<String16>& args)
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index 4de4a16..1136ce1 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -57,6 +57,7 @@
     AudioStreamOut*     finalStream() { return mFinalStream; }
     uint32_t            device() { return mDevice; }
 
+    int                 getId()  { return mId; }
 private:
     AudioDumpInterface *mInterface;
     int                  mId;
diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.cpp b/libs/audioflinger/AudioPolicyManagerGeneric.cpp
index 6b17b872..6323859 100644
--- a/libs/audioflinger/AudioPolicyManagerGeneric.cpp
+++ b/libs/audioflinger/AudioPolicyManagerGeneric.cpp
@@ -197,8 +197,8 @@
 
 #ifdef AUDIO_POLICY_TEST
     if (mCurOutput != 0) {
-        LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelcount %d, mDirectOutput %d",
-                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannelcount, mDirectOutput);
+        LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d",
+                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
 
         if (mTestOutputs[mCurOutput] == 0) {
             LOGV("getOutput() opening test output");
@@ -206,7 +206,7 @@
             outputDesc->mDevice = mTestDevice;
             outputDesc->mSamplingRate = mTestSamplingRate;
             outputDesc->mFormat = mTestFormat;
-            outputDesc->mChannels = (mTestChannelcount == 1) ? AudioSystem::CHANNEL_OUT_MONO : AudioSystem::CHANNEL_OUT_STEREO;
+            outputDesc->mChannels = mTestChannels;
             outputDesc->mLatency = mTestLatencyMs;
             outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
             outputDesc->mRefCount[stream] = 0;
@@ -216,7 +216,12 @@
                                             &outputDesc->mChannels,
                                             &outputDesc->mLatency,
                                             outputDesc->mFlags);
-            mOutputs.add(mTestOutputs[mCurOutput], outputDesc);
+            if (mTestOutputs[mCurOutput]) {
+                AudioParameter outputCmd = AudioParameter();
+                outputCmd.addInt(String8("set_id"),mCurOutput);
+                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
+                mOutputs.add(mTestOutputs[mCurOutput], outputDesc);
+            }
         }
         return mTestOutputs[mCurOutput];
     }
@@ -495,10 +500,14 @@
     }
 
 #ifdef AUDIO_POLICY_TEST
+    AudioParameter outputCmd = AudioParameter();
+    outputCmd.addInt(String8("set_id"), 0);
+    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
+
     mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
     mTestSamplingRate = 44100;
     mTestFormat = AudioSystem::PCM_16_BIT;
-    mTestChannelcount = 2;
+    mTestChannels =  AudioSystem::CHANNEL_OUT_STEREO;
     mTestLatencyMs = 0;
     mCurOutput = 0;
     mDirectOutput = false;
@@ -537,15 +546,23 @@
     LOGV("entering threadLoop()");
     while (!exitPending())
     {
+        String8 command;
+        int valueInt;
+        String8 value;
+
         Mutex::Autolock _l(mLock);
         mWaitWorkCV.waitRelative(mLock, milliseconds(50));
-        String8 command;
+
         command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
-        if (command != "") {
+        AudioParameter param = AudioParameter(command);
+
+        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
+            valueInt != 0) {
             LOGV("Test command %s received", command.string());
-            AudioParameter param = AudioParameter(command);
-            int valueInt;
-            String8 value;
+            String8 target;
+            if (param.get(String8("target"), target) != NO_ERROR) {
+                target = "Manager";
+            }
             if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
                 param.remove(String8("test_cmd_policy_output"));
                 mCurOutput = valueInt;
@@ -565,28 +582,84 @@
 
             if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
                 param.remove(String8("test_cmd_policy_format"));
+                int format = AudioSystem::INVALID_FORMAT;
                 if (value == "PCM 16 bits") {
-                    mTestFormat = AudioSystem::PCM_16_BIT;
+                    format = AudioSystem::PCM_16_BIT;
                 } else if (value == "PCM 8 bits") {
-                    mTestFormat = AudioSystem::PCM_8_BIT;
+                    format = AudioSystem::PCM_8_BIT;
                 } else if (value == "Compressed MP3") {
-                    mTestFormat = AudioSystem::MP3;
+                    format = AudioSystem::MP3;
+                }
+                if (format != AudioSystem::INVALID_FORMAT) {
+                    if (target == "Manager") {
+                        mTestFormat = format;
+                    } else if (mTestOutputs[mCurOutput] != 0) {
+                        AudioParameter outputParam = AudioParameter();
+                        outputParam.addInt(String8("format"), format);
+                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
+                    }
                 }
             }
             if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
                 param.remove(String8("test_cmd_policy_channels"));
+                int channels = 0;
+
                 if (value == "Channels Stereo") {
-                    mTestChannelcount = 2;
+                    channels =  AudioSystem::CHANNEL_OUT_STEREO;
                 } else if (value == "Channels Mono") {
-                    mTestChannelcount = 1;
+                    channels =  AudioSystem::CHANNEL_OUT_MONO;
+                }
+                if (channels != 0) {
+                    if (target == "Manager") {
+                        mTestChannels = channels;
+                    } else if (mTestOutputs[mCurOutput] != 0) {
+                        AudioParameter outputParam = AudioParameter();
+                        outputParam.addInt(String8("channels"), channels);
+                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
+                    }
                 }
             }
             if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
                 param.remove(String8("test_cmd_policy_sampleRate"));
                 if (valueInt >= 0 && valueInt <= 96000) {
-                    mTestSamplingRate = valueInt;
+                    int samplingRate = valueInt;
+                    if (target == "Manager") {
+                        mTestSamplingRate = samplingRate;
+                    } else if (mTestOutputs[mCurOutput] != 0) {
+                        AudioParameter outputParam = AudioParameter();
+                        outputParam.addInt(String8("sampling_rate"), samplingRate);
+                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
+                    }
                 }
             }
+
+            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_reopen"));
+
+                mpClientInterface->closeOutput(mHardwareOutput);
+                delete mOutputs.valueFor(mHardwareOutput);
+                mOutputs.removeItem(mHardwareOutput);
+
+                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
+                outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
+                mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
+                                                &outputDesc->mSamplingRate,
+                                                &outputDesc->mFormat,
+                                                &outputDesc->mChannels,
+                                                &outputDesc->mLatency,
+                                                outputDesc->mFlags);
+                if (mHardwareOutput == 0) {
+                    LOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
+                            outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
+                } else {
+                    AudioParameter outputCmd = AudioParameter();
+                    outputCmd.addInt(String8("set_id"), 0);
+                    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
+                    mOutputs.add(mHardwareOutput, outputDesc);
+                }
+            }
+
+
             mpClientInterface->setParameters(0, String8("test_cmd_policy="));
         }
     }
diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.h b/libs/audioflinger/AudioPolicyManagerGeneric.h
index ddcb306..d904520 100644
--- a/libs/audioflinger/AudioPolicyManagerGeneric.h
+++ b/libs/audioflinger/AudioPolicyManagerGeneric.h
@@ -180,7 +180,7 @@
         uint32_t        mTestDevice;
         uint32_t        mTestSamplingRate;
         uint32_t        mTestFormat;
-        uint32_t        mTestChannelcount;
+        uint32_t        mTestChannels;
         uint32_t        mTestLatencyMs;
 #endif //AUDIO_POLICY_TEST