audio: Clean up missing memory free's when opening devices/streams

cherry-picked from upstream device/linaro/dragonboard project.

Signed-off-by: Alden DSouza <aldend@google.com>
Change-Id: Iae726f0818464fc09d809120cbba1eb8b109e031
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 2ed1d1c..7513456 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -57,6 +57,16 @@
                                 size_t* mic_count);
 static size_t out_get_buffer_size(const struct audio_stream* stream);
 
+static bool is_aec_input(const struct alsa_stream_in* in) {
+    /* If AEC is in the app, only configure based on ECHO_REFERENCE spec.
+     * If AEC is in the HAL, configure using the given mic stream. */
+    bool aec_input = true;
+#if !defined(AEC_HAL)
+    aec_input = (in->source == AUDIO_SOURCE_ECHO_REFERENCE);
+#endif
+    return aec_input;
+}
+
 static int get_audio_output_port(audio_devices_t devices) {
     /* Default to internal speaker */
     int port = PORT_INTERNAL_SPEAKER;
@@ -785,19 +795,17 @@
     ALOGV("adev_open_output_stream...");
 
     struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
-    struct alsa_stream_out *out;
-    struct pcm_params *params;
-    int ret = 0;
-
     int out_port = get_audio_output_port(devices);
-
-    params = pcm_params_get(CARD_OUT, out_port, PCM_OUT);
-    if (!params)
+    struct pcm_params* params = pcm_params_get(CARD_OUT, out_port, PCM_OUT);
+    if (!params) {
         return -ENOSYS;
+    }
 
-    out = (struct alsa_stream_out *)calloc(1, sizeof(struct alsa_stream_out));
-    if (!out)
+    struct alsa_stream_out* out =
+            (struct alsa_stream_out*)calloc(1, sizeof(struct alsa_stream_out));
+    if (!out) {
         return -ENOMEM;
+    }
 
     out->stream.common.get_sample_rate = out_get_sample_rate;
     out->stream.common.set_sample_rate = out_set_sample_rate;
@@ -830,7 +838,7 @@
         config->sample_rate = out->config.rate;
         config->format = audio_format_from_pcm_format(out->config.format);
         config->channel_mask = audio_channel_out_mask_from_count(CHANNEL_STEREO);
-        ret = -EINVAL;
+        goto error_1;
     }
 
     ALOGI("adev_open_output_stream selects channels=%d rate=%d format=%d, devices=%d",
@@ -845,8 +853,6 @@
     config->channel_mask = out_get_channels(&out->stream.common);
     config->sample_rate = out_get_sample_rate(&out->stream.common);
 
-    *stream_out = &out->stream;
-
     out->speaker_eq = NULL;
     if (out_port == PORT_INTERNAL_SPEAKER) {
         out_set_eq(out);
@@ -855,18 +861,20 @@
         }
     }
 
-    /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */
-    ret = 0;
-
-    if (ret == 0) {
-        int aec_ret = init_aec_reference_config(ladev->aec, out);
-        if (aec_ret) {
-            ALOGE("AEC: Speaker config init failed!");
-            return -EINVAL;
-        }
+    int aec_ret = init_aec_reference_config(ladev->aec, out);
+    if (aec_ret) {
+        ALOGE("AEC: Speaker config init failed!");
+        goto error_2;
     }
 
-    return ret;
+    *stream_out = &out->stream;
+    return 0;
+
+error_2:
+    fir_release(out->speaker_eq);
+error_1:
+    free(out);
+    return -EINVAL;
 }
 
 static void adev_close_output_stream(struct audio_hw_device *dev,
@@ -983,17 +991,16 @@
     ALOGV("adev_open_input_stream...");
 
     struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
-    struct alsa_stream_in *in;
-    struct pcm_params *params;
-    int ret = 0;
 
-    params = pcm_params_get(CARD_IN, PORT_BUILTIN_MIC, PCM_IN);
-    if (!params)
+    struct pcm_params* params = pcm_params_get(CARD_IN, PORT_BUILTIN_MIC, PCM_IN);
+    if (!params) {
         return -ENOSYS;
+    }
 
-    in = (struct alsa_stream_in *)calloc(1, sizeof(struct alsa_stream_in));
-    if (!in)
+    struct alsa_stream_in* in = (struct alsa_stream_in*)calloc(1, sizeof(struct alsa_stream_in));
+    if (!in) {
         return -ENOMEM;
+    }
 
     in->stream.common.get_sample_rate = in_get_sample_rate;
     in->stream.common.set_sample_rate = in_set_sample_rate;
@@ -1026,7 +1033,10 @@
     if (in->config.rate != config->sample_rate ||
            audio_channel_count_from_in_mask(config->channel_mask) != CHANNEL_STEREO ||
                in->config.format !=  pcm_format_from_audio_format(config->format) ) {
-        ret = -EINVAL;
+        config->format = in_get_format(&in->stream.common);
+        config->channel_mask = in_get_channels(&in->stream.common);
+        config->sample_rate = in_get_sample_rate(&in->stream.common);
+        goto error_1;
     }
 
     ALOGI("adev_open_input_stream selects channels=%d rate=%d format=%d source=%d",
@@ -1038,46 +1048,37 @@
     in->source = source;
     in->devices = devices;
 
-    config->format = in_get_format(&in->stream.common);
-    config->channel_mask = in_get_channels(&in->stream.common);
-    config->sample_rate = in_get_sample_rate(&in->stream.common);
-
-    /* If AEC is in the app, only configure based on ECHO_REFERENCE spec.
-     * If AEC is in the HAL, configure using the given mic stream. */
-    bool aecInput = true;
-#if !defined(AEC_HAL)
-    aecInput = (in->source == AUDIO_SOURCE_ECHO_REFERENCE);
-#endif
-
-    if ((ret == 0) && aecInput) {
+    if (is_aec_input(in)) {
         int aec_ret = init_aec_mic_config(ladev->aec, in);
         if (aec_ret) {
             ALOGE("AEC: Mic config init failed!");
-            return -EINVAL;
+            goto error_1;
         }
     }
 
-    if (ret) {
-        free(in);
-    } else {
-        *stream_in = &in->stream;
-    }
-
 #if DEBUG_AEC
     remove("/data/local/traces/aec_ref.pcm");
     remove("/data/local/traces/aec_in.pcm");
     remove("/data/local/traces/aec_ref_timestamps.txt");
     remove("/data/local/traces/aec_in_timestamps.txt");
 #endif
-    return ret;
+
+    *stream_in = &in->stream;
+    return 0;
+
+error_1:
+    free(in);
+    return -EINVAL;
 }
 
 static void adev_close_input_stream(struct audio_hw_device *dev,
         struct audio_stream_in *stream)
 {
     ALOGV("adev_close_input_stream...");
-    struct alsa_audio_device *adev = (struct alsa_audio_device *)dev;
-    destroy_aec_mic_config(adev->aec);
+    struct alsa_stream_in* in = (struct alsa_stream_in*)stream;
+    if (is_aec_input(in)) {
+        destroy_aec_mic_config(in->dev->aec);
+    }
     free(stream);
     return;
 }
@@ -1094,6 +1095,8 @@
 
     struct alsa_audio_device *adev = (struct alsa_audio_device *)device;
     release_aec(adev->aec);
+    audio_route_free(adev->audio_route);
+    mixer_close(adev->mixer);
     free(device);
     return 0;
 }
@@ -1101,16 +1104,16 @@
 static int adev_open(const hw_module_t* module, const char* name,
         hw_device_t** device)
 {
-    struct alsa_audio_device *adev;
-
     ALOGV("adev_open: %s", name);
 
-    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
+    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
         return -EINVAL;
+    }
 
-    adev = calloc(1, sizeof(struct alsa_audio_device));
-    if (!adev)
+    struct alsa_audio_device* adev = calloc(1, sizeof(struct alsa_audio_device));
+    if (!adev) {
         return -ENOMEM;
+    }
 
     adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
     adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
@@ -1138,27 +1141,34 @@
     *device = &adev->hw_device.common;
 
     adev->mixer = mixer_open(CARD_OUT);
-
     if (!adev->mixer) {
         ALOGE("Unable to open the mixer, aborting.");
-        return -EINVAL;
+        goto error_1;
     }
 
     adev->audio_route = audio_route_init(CARD_OUT, MIXER_XML_PATH);
     if (!adev->audio_route) {
         ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
-        return -EINVAL;
+        goto error_2;
     }
 
     pthread_mutex_lock(&adev->lock);
     if (init_aec(CAPTURE_CODEC_SAMPLING_RATE, NUM_AEC_REFERENCE_CHANNELS,
                     CHANNEL_STEREO, &adev->aec)) {
         pthread_mutex_unlock(&adev->lock);
-        return -EINVAL;
+        goto error_3;
     }
     pthread_mutex_unlock(&adev->lock);
 
     return 0;
+
+error_3:
+    audio_route_free(adev->audio_route);
+error_2:
+    mixer_close(adev->mixer);
+error_1:
+    free(adev);
+    return -EINVAL;
 }
 
 static struct hw_module_methods_t hal_module_methods = {