Fix memory leak when filtering commands in insertCommand_l()
When AudioPolicyService::AudioCommandThread::insertCommand_l filters
a command from the queue, the AudioCommand* is removed from the
vector mAudioCommands by calling mAudioCommands.removeAt(). This will
destroy the pointer and compact the vector, but not delete the
AudioCommand object.
This patch adds code to delete a filtered out AudioCommand and its
data object mParam. However, mParam was void* and deleting a void
pointer is undefined behavior according to the C++
standard. Therefore, the data classes are modified to inherit
from an abstract base class with a virtual destructor.
The deletion of non-filtered commands in
AudioPolicyService::AudioCommandThread::threadLoop() was already
correct, as each case casts mParam to the proper type before
deleting.
This also fixes AOSP issue 36370.
Change-Id: I2b63838aff3608132aa496f964a929f78c4b6267
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index ae053a9..a38160f 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -197,6 +197,8 @@
void insertCommand_l(AudioCommand *command, int delayMs = 0);
private:
+ class AudioCommandData;
+
// descriptor for requested tone playback event
class AudioCommand {
@@ -211,41 +213,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;
};