am 71171988: am f655acf1: am 8fb04d47: Merge "Fix memory leak when filtering commands in insertCommand_l()"

* commit '711719885d7563068579abf347c366cf6bc906f5':
  Fix memory leak when filtering commands in insertCommand_l()
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp
index 4a708a0..918c25c 100644
--- a/services/audiopolicy/AudioPolicyService.cpp
+++ b/services/audiopolicy/AudioPolicyService.cpp
@@ -270,6 +270,10 @@
     if (!mAudioCommands.isEmpty()) {
         release_wake_lock(mName.string());
     }
+    for (size_t k=0; k < mAudioCommands.size(); k++) {
+        delete mAudioCommands[k]->mParam;
+        delete mAudioCommands[k];
+    }
     mAudioCommands.clear();
     delete mpToneGenerator;
 }
@@ -441,7 +445,7 @@
     ToneData *data = new ToneData();
     data->mType = type;
     data->mStream = stream;
-    command->mParam = (void *)data;
+    command->mParam = data;
     Mutex::Autolock _l(mLock);
     insertCommand_l(command);
     ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
@@ -542,7 +546,7 @@
     data->mIO = output;
     data->mStream = stream;
     data->mSession = session;
-    command->mParam = (void *)data;
+    command->mParam = data;
     Mutex::Autolock _l(mLock);
     insertCommand_l(command);
     ALOGV("AudioCommandThread() adding stop output %d", output);
@@ -555,7 +559,7 @@
     command->mCommand = RELEASE_OUTPUT;
     ReleaseOutputData *data = new ReleaseOutputData();
     data->mIO = output;
-    command->mParam = (void *)data;
+    command->mParam = data;
     Mutex::Autolock _l(mLock);
     insertCommand_l(command);
     ALOGV("AudioCommandThread() adding release output %d", output);
@@ -644,6 +648,10 @@
         for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
             if (mAudioCommands[k] == removedCommands[j]) {
                 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
+                // for commands that are not filtered,
+                // command->mParam is deleted in threadLoop
+                delete mAudioCommands[k]->mParam;
+                delete mAudioCommands[k];
                 mAudioCommands.removeAt(k);
                 break;
             }
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index cdc90d0..28e3a4b 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -198,6 +198,8 @@
                     void        insertCommand_l(AudioCommand *command, int delayMs = 0);
 
     private:
+        class AudioCommandData;
+
         // descriptor for requested tone playback event
         class AudioCommand {
 
@@ -212,41 +214,48 @@
             Condition mCond; // condition for status return
             status_t mStatus; // command status
             bool mWaitStatus; // true if caller is waiting for status
-            void *mParam;     // command parameter (ToneData, VolumeData, ParametersData)
+            AudioCommandData *mParam;     // command specific parameter data
         };
 
-        class ToneData {
+        class AudioCommandData {
+        public:
+            virtual ~AudioCommandData() {}
+        protected:
+            AudioCommandData() {}
+        };
+
+        class ToneData : public AudioCommandData {
         public:
             ToneGenerator::tone_type mType; // tone type (START_TONE only)
             audio_stream_type_t mStream;    // stream type (START_TONE only)
         };
 
-        class VolumeData {
+        class VolumeData : public AudioCommandData {
         public:
             audio_stream_type_t mStream;
             float mVolume;
             audio_io_handle_t mIO;
         };
 
-        class ParametersData {
+        class ParametersData : public AudioCommandData {
         public:
             audio_io_handle_t mIO;
             String8 mKeyValuePairs;
         };
 
-        class VoiceVolumeData {
+        class VoiceVolumeData : public AudioCommandData {
         public:
             float mVolume;
         };
 
-        class StopOutputData {
+        class StopOutputData : public AudioCommandData {
         public:
             audio_io_handle_t mIO;
             audio_stream_type_t mStream;
             int mSession;
         };
 
-        class ReleaseOutputData {
+        class ReleaseOutputData : public AudioCommandData {
         public:
             audio_io_handle_t mIO;
         };