Added more threads to car audio HAL.

Audio HAL did not have enough threads for all the work available. Each
input and ouput devices starts a thread for interacting with the PCM
and a binder thread for comunicating. Thus the pools of thread was
running out. Added more threads to the AIDL side for audio control.

Also added names to the input devices. Set the name of the thread
according to the input/output device name for better identification.

Removed the un-needed .rc command to restart the audioserver in case of
audio HAL crash. The audioserver already has mechanism to re-start
itself in case of failure. It will also attempt to re-start the audio
HAL if the HAL does crashes.

Modified how mixer thread is terminated, it used to kill the thread.
Now the loop is attempted to stop and join from the close PCM method, if
that fails the thread is still killed.

Fixed the format of the audio policy configuration xml file so that all
lines longer than 100 characters are aligned to previous's line first
attribute.

Bug: 215747045
Test: m -j, and run emulator
Test: atest VtsAidlHalAudioControlTest
Change-Id: I18a077719cf6b0d6db2ef3d3c723bdc325da4ac4
diff --git a/emulator/audio/audio_policy_configuration.xml b/emulator/audio/audio_policy_configuration.xml
index 4e61c76..d2a2b26 100644
--- a/emulator/audio/audio_policy_configuration.xml
+++ b/emulator/audio/audio_policy_configuration.xml
@@ -26,8 +26,8 @@
         The module names are the same as in current .conf file:
                 “primary”, “A2DP”, “remote_submix”, “USB”
         Each module will contain the following sections:
-        “devicePorts”: a list of device descriptors for all input and output devices accessible via this
-        module.
+        “devicePorts”: a list of device descriptors for all input and output devices accessible via
+        this module.
         This contains both permanently attached devices and removable devices.
             "gain": constraints applied to the millibel values:
                 - maxValueMB >= minValueMB
@@ -35,8 +35,8 @@
                 - (maxValueMB - minValueMB) % stepValueMB == 0
                 - (defaultValueMB - minValueMB) % stepValueMB == 0
         “mixPorts”: listing all output and input streams exposed by the audio HAL
-        “routes”: list of possible connections between input and output devices or between stream and
-        devices.
+        “routes”: list of possible connections between input and output devices or between stream
+        and devices.
             "route": is defined by an attribute:
                 -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
                 -"sink": the sink involved in this route
@@ -60,7 +60,7 @@
                 <item>bus6_notification_out</item>
                 <item>bus7_system_sound_out</item>
                 <!-- names with _audio_zone_# are used for defined an emulator rear seat audio zone
-                    where each number # is the zone id number -->
+                     where each number # is the zone id number -->
                 <item>bus100_audio_zone_1</item>
                 <item>bus200_audio_zone_2</item>
                 <item>Built-In Mic</item>
@@ -73,7 +73,7 @@
             <defaultOutputDevice>bus0_media_out</defaultOutputDevice>
             <mixPorts>
                 <mixPort name="mixport_bus0_media_out" role="source"
-                        flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000"
                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
@@ -146,84 +146,93 @@
             </mixPorts>
             <devicePorts>
                 <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus0_media_out">
+                            address="bus0_media_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus1_navigation_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
                         address="bus1_navigation_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus2_voice_command_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus2_voice_command_out">
+                            address="bus2_voice_command_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus3_call_ring_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus3_call_ring_out">
+                            address="bus3_call_ring_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus4_call_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus4_call_out">
+                            address="bus4_call_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus5_alarm_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus5_alarm_out">
+                            address="bus5_alarm_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus6_notification_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus6_notification_out">
+                            address="bus6_notification_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus7_system_sound_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus7_system_sound_out">
+                            address="bus7_system_sound_out">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus100_audio_zone_1" role="sink" type="AUDIO_DEVICE_OUT_BUS"
-                        address="bus100_audio_zone_1">
+                            address="bus100_audio_zone_1">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="bus200_audio_zone_2" role="sink" type="AUDIO_DEVICE_OUT_BUS"
@@ -232,31 +241,35 @@
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                              minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
-                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"
+                    address="Built-In Mic" >
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
-                            channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
                 </devicePort>
-                <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+                <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC"
+                            role="source" address="Built-In Back Mic">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
-                            channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
                 </devicePort>
-                <devicePort tagName="Echo-Reference Mic" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
+                <devicePort tagName="Echo-Reference Mic" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source"
+                            address="Echo-Reference Mic">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
-                            channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
                 </devicePort>
                 <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"
-                        address="tuner0">
+                            address="tuner0">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="Tone Generator 0" type="AUDIO_DEVICE_IN_BUS" role="source"
@@ -265,7 +278,8 @@
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                              minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
                 <devicePort tagName="Tone Generator 1" type="AUDIO_DEVICE_IN_BUS" role="source"
@@ -274,7 +288,8 @@
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                     <gains>
                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
-                              minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
+                              minValueMB="-3200" maxValueMB="600"
+                              defaultValueMB="0" stepValueMB="100"/>
                     </gains>
                 </devicePort>
             </devicePorts>
@@ -282,15 +297,19 @@
             <routes>
                 <route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out"/>
                 <route type="mix" sink="bus1_navigation_out" sources="mixport_bus1_navigation_out"/>
-                <route type="mix" sink="bus2_voice_command_out" sources="mixport_bus2_voice_command_out"/>
+                <route type="mix" sink="bus2_voice_command_out"
+                       sources="mixport_bus2_voice_command_out"/>
                 <route type="mix" sink="bus3_call_ring_out" sources="mixport_bus3_call_ring_out"/>
                 <route type="mix" sink="bus4_call_out" sources="mixport_bus4_call_out"/>
                 <route type="mix" sink="bus5_alarm_out" sources="mixport_bus5_alarm_out"/>
-                <route type="mix" sink="bus6_notification_out" sources="mixport_bus6_notification_out"/>
-                <route type="mix" sink="bus7_system_sound_out" sources="mixport_bus7_system_sound_out"/>
+                <route type="mix" sink="bus6_notification_out"
+                       sources="mixport_bus6_notification_out"/>
+                <route type="mix" sink="bus7_system_sound_out"
+                       sources="mixport_bus7_system_sound_out"/>
                 <route type="mix" sink="bus100_audio_zone_1" sources="mixport_bus100_audio_zone_1"/>
                 <route type="mix" sink="bus200_audio_zone_2" sources="mixport_bus200_audio_zone_2"/>
-                <route type="mix" sink="primary input" sources="Built-In Mic,Built-In Back Mic,Echo-Reference Mic"/>
+                <route type="mix" sink="primary input"
+                       sources="Built-In Mic,Built-In Back Mic,Echo-Reference Mic"/>
                 <route type="mix" sink="mixport_tuner0" sources="FM Tuner"/>
                 <route type="mix" sink="mixport_input_bus_tone_zone_0" sources="Tone Generator 0"/>
                 <route type="mix" sink="mixport_input_bus_tone_zone_1" sources="Tone Generator 1"/>
diff --git a/emulator/audio/car_emulator_audio.mk b/emulator/audio/car_emulator_audio.mk
index 9ebb3b6..80e59f7 100644
--- a/emulator/audio/car_emulator_audio.mk
+++ b/emulator/audio/car_emulator_audio.mk
@@ -35,5 +35,6 @@
     frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
     device/generic/car/emulator/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     device/generic/car/emulator/audio/car_audio_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/car_audio_configuration.xml \
+    frameworks/av/media/libeffects/data/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
 
 DEVICE_PACKAGE_OVERLAYS += device/generic/car/emulator/audio/overlay
diff --git a/emulator/audio/driver/audio_hw.c b/emulator/audio/driver/audio_hw.c
index 2580756..65cbb11 100644
--- a/emulator/audio/driver/audio_hw.c
+++ b/emulator/audio/driver/audio_hw.c
@@ -88,6 +88,7 @@
 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 
 #define SIZE_OF_PARSE_BUFFER 32
+#define SIZE_OF_THREAD_NAME_BUFFER 16
 
 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state);
 
@@ -163,6 +164,11 @@
     pthread_mutex_unlock(&out->lock);
 }
 
+static void set_shortened_thread_name(pthread_t thread, const char *name) {
+    char shortenedName[SIZE_OF_THREAD_NAME_BUFFER];
+    strncpy(shortenedName, name, SIZE_OF_THREAD_NAME_BUFFER);
+    pthread_setname_np(thread, shortenedName);
+}
 
 static struct pcm_config pcm_config_out = {
     .channels = 2,
@@ -506,6 +512,8 @@
     const size_t frame_size = audio_stream_out_frame_size(stream);
     const size_t frames =  bytes / frame_size;
 
+    set_shortened_thread_name(pthread_self(), __func__);
+
     pthread_mutex_lock(&out->lock);
 
     if (out->worker_standby) {
@@ -1003,6 +1011,8 @@
     bool mic_mute = false;
     size_t read_bytes = 0;
 
+    set_shortened_thread_name(pthread_self(), __func__);
+
     adev_get_mic_mute(&adev->device, &mic_mute);
     pthread_mutex_lock(&in->lock);
 
@@ -1184,34 +1194,35 @@
         out->worker_standby = true;
         out->worker_exit = false;
         pthread_create(&out->worker_thread, NULL, out_write_worker, out);
-    }
+        set_shortened_thread_name(out->worker_thread, address);
 
-    out->enabled_channels = BOTH_CHANNELS;
-    // For targets where output streams are closed regularly, currently ducked/muted addresses
-    // should be tracked so that the address of new streams can be checked to determine the
-    // default state
-    out->is_ducked = 0;
-    out->is_muted = 0;
-    if (address) {
-        out->bus_address = calloc(strlen(address) + 1, sizeof(char));
-        strncpy(out->bus_address, address, strlen(address));
-        hashmapPut(adev->out_bus_stream_map, out->bus_address, out);
-        /* TODO: read struct audio_gain from audio_policy_configuration */
-        out->gain_stage = (struct audio_gain) {
-            .min_value = -3200,
-            .max_value = 600,
-            .step_value = 100,
-        };
-        out->amplitude_ratio = 1.0;
-        if (property_get_bool(PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO, false)) {
-            out->enabled_channels = strstr(out->bus_address, AUDIO_ZONE_KEYWORD)
-                ? RIGHT_CHANNEL: LEFT_CHANNEL;
-            ALOGD("%s Routing %s to %s channel", __func__,
-             out->bus_address, out->enabled_channels == RIGHT_CHANNEL ? "Right" : "Left");
+        out->enabled_channels = BOTH_CHANNELS;
+        // For targets where output streams are closed regularly, currently ducked/muted addresses
+        // should be tracked so that the address of new streams can be checked to determine the
+        // default state
+        out->is_ducked = 0;
+        out->is_muted = 0;
+        if (address) {
+            out->bus_address = calloc(strlen(address) + 1, sizeof(char));
+            strncpy(out->bus_address, address, strlen(address));
+            hashmapPut(adev->out_bus_stream_map, out->bus_address, out);
+            /* TODO: read struct audio_gain from audio_policy_configuration */
+            out->gain_stage = (struct audio_gain) {
+                .min_value = -3200,
+                .max_value = 600,
+                .step_value = 100,
+            };
+            out->amplitude_ratio = 1.0;
+            if (property_get_bool(PROP_KEY_SIMULATE_MULTI_ZONE_AUDIO, false)) {
+                out->enabled_channels = strstr(out->bus_address, AUDIO_ZONE_KEYWORD)
+                    ? RIGHT_CHANNEL: LEFT_CHANNEL;
+                ALOGD("%s Routing %s to %s channel", __func__,
+                 out->bus_address, out->enabled_channels == RIGHT_CHANNEL ? "Right" : "Left");
+            }
         }
+        *stream_out = &out->stream;
+        ALOGD("%s bus: %s", __func__, out->bus_address);
     }
-    *stream_out = &out->stream;
-    ALOGD("%s bus: %s", __func__, out->bus_address);
 
 error:
     return ret;
@@ -1430,6 +1441,7 @@
         in->worker_standby = true;
         in->worker_exit = false;
         pthread_create(&in->worker_thread, NULL, in_read_worker, in);
+        set_shortened_thread_name(in->worker_thread, address ? address : "mic");
     }
 
     if (address) {
diff --git a/emulator/audio/driver/audio_vbuffer.c b/emulator/audio/driver/audio_vbuffer.c
index 79be545..8377f5c 100644
--- a/emulator/audio/driver/audio_vbuffer.c
+++ b/emulator/audio/driver/audio_vbuffer.c
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "audio_hw_generic"
+#define LOG_TAG "audio_hw_generic_caremu"
+// #define LOG_NDEBUG 0
 
 #include <errno.h>
 #include <stdlib.h>
diff --git a/emulator/audio/driver/ext_pcm.c b/emulator/audio/driver/ext_pcm.c
index df3e1f1..2b0e825 100644
--- a/emulator/audio/driver/ext_pcm.c
+++ b/emulator/audio/driver/ext_pcm.c
@@ -14,9 +14,11 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "audio_hw_generic"
+#define LOG_TAG "audio_hw_generic_caremu"
+// #define LOG_NDEBUG 0
 
 #include <errno.h>
+#include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -31,6 +33,8 @@
 
 // Sleep 10ms between each mixing, this interval value is arbitrary chosen
 #define MIXER_INTERVAL_MS 10
+#define MS_TO_US 1000
+
 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
 
@@ -70,7 +74,8 @@
 }
 
 static void *mixer_thread_loop(void *context) {
-  ALOGD("%s: __enter__", __func__);
+  pthread_setname_np(pthread_self(), "car_mixer_loop");
+  ALOGD("%s: starting mixer loop", __func__);
   struct ext_pcm *ext_pcm = (struct ext_pcm *)context;
   do {
     pthread_mutex_lock(&ext_pcm->mixer_lock);
@@ -79,14 +84,25 @@
     hashmapForEach(ext_pcm->mixer_pipeline_map, mixer_thread_mix,
         &ext_pcm->mixer_pipeline);
     if (ext_pcm->mixer_pipeline.position > 0) {
-      pcm_write(ext_pcm->pcm, (void *)ext_pcm->mixer_pipeline.buffer,
+      int ret = pcm_write(ext_pcm->pcm, (void *)ext_pcm->mixer_pipeline.buffer,
           ext_pcm->mixer_pipeline.position * sizeof(int16_t));
+      if (ret != 0) {
+        ALOGE("%s error[%d] writing data to pcm");
+      }
     }
     memset(&ext_pcm->mixer_pipeline, 0, sizeof(struct ext_mixer_pipeline));
     pthread_cond_broadcast(&ext_pcm->mixer_wake);
     pthread_mutex_unlock(&ext_pcm->mixer_lock);
-    usleep(MIXER_INTERVAL_MS * 1000);
+    pthread_mutex_lock(&ext_pcm_init_lock);
+    bool keep_running = ext_pcm->run_mixer;
+    pthread_mutex_unlock(&ext_pcm_init_lock);
+    if (!keep_running) {
+      break;
+    }
+    usleep(MIXER_INTERVAL_MS * MS_TO_US);
   } while (1);
+  ALOGD("%s: exiting mixer loop", __func__);
+  return NULL;
 }
 
 static int mixer_pipeline_write(struct ext_pcm *ext_pcm, const char *bus_address,
@@ -130,12 +146,10 @@
     pthread_create(&shared_ext_pcm->mixer_thread, (const pthread_attr_t *)NULL,
             mixer_thread_loop, shared_ext_pcm);
     shared_ext_pcm->mixer_pipeline_map = hashmapCreate(8, str_hash_fn, str_eq);
+    shared_ext_pcm->run_mixer = true;
   }
-  pthread_mutex_unlock(&ext_pcm_init_lock);
-
-  pthread_mutex_lock(&shared_ext_pcm->lock);
   shared_ext_pcm->ref_count += 1;
-  pthread_mutex_unlock(&shared_ext_pcm->lock);
+  pthread_mutex_unlock(&ext_pcm_init_lock);
 
   return shared_ext_pcm;
 }
@@ -147,27 +161,37 @@
 }
 
 int ext_pcm_close(struct ext_pcm *ext_pcm) {
+  ALOGD("%s closing pcm", __func__);
   if (ext_pcm == NULL || ext_pcm->pcm == NULL) {
     return -EINVAL;
   }
 
-  pthread_mutex_lock(&ext_pcm->lock);
-  ext_pcm->ref_count -= 1;
-  pthread_mutex_unlock(&ext_pcm->lock);
-
   pthread_mutex_lock(&ext_pcm_init_lock);
-  if (ext_pcm->ref_count <= 0) {
+  int count = ext_pcm->ref_count -= 1;
+  if (count <= 0) {
+    ext_pcm->run_mixer = false;
+    // On pcm open new shared_ext_pcm will be created
+    shared_ext_pcm = NULL;
+    pthread_mutex_unlock(&ext_pcm_init_lock);
+    void* ret_val = NULL;
+    int ret = pthread_join(ext_pcm->mixer_thread, &ret_val);
+    if (ret != 0) {
+      ALOGE("%s error[%d] when joining thread",
+        __func__, ret);
+      // Try killing if timeout failed
+      pthread_kill(ext_pcm->mixer_thread, SIGINT);
+    }
+    pthread_mutex_lock(&ext_pcm_init_lock);
     pthread_mutex_destroy(&ext_pcm->lock);
     pcm_close(ext_pcm->pcm);
     pthread_mutex_destroy(&ext_pcm->mixer_lock);
     hashmapForEach(ext_pcm->mixer_pipeline_map, mixer_free_pipeline,
         (void *)NULL);
     hashmapFree(ext_pcm->mixer_pipeline_map);
-    pthread_kill(ext_pcm->mixer_thread, SIGINT);
     free(ext_pcm);
-    shared_ext_pcm = NULL;
   }
   pthread_mutex_unlock(&ext_pcm_init_lock);
+  ALOGD("%s finished closing pcm", __func__);
   return 0;
 }
 
diff --git a/emulator/audio/driver/ext_pcm.h b/emulator/audio/driver/ext_pcm.h
index c038b86..562b874 100644
--- a/emulator/audio/driver/ext_pcm.h
+++ b/emulator/audio/driver/ext_pcm.h
@@ -34,6 +34,7 @@
   struct pcm *pcm;
   pthread_mutex_t lock;
   pthread_cond_t mixer_wake;
+  bool run_mixer;
   unsigned int ref_count;
   pthread_mutex_t mixer_lock;
   struct ext_mixer_pipeline mixer_pipeline;
diff --git a/emulator/audio/halservice/android.hardware.audio.service-caremu.rc b/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
index 768425f..76ee350 100644
--- a/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
+++ b/emulator/audio/halservice/android.hardware.audio.service-caremu.rc
@@ -7,4 +7,3 @@
     capabilities BLOCK_SUSPEND
     ioprio rt 4
     task_profiles ProcessCapacityHigh HighPerformance
-    onrestart restart audioserver
diff --git a/emulator/audio/halservice/service.cpp b/emulator/audio/halservice/service.cpp
index aafff4d..581e9af 100644
--- a/emulator/audio/halservice/service.cpp
+++ b/emulator/audio/halservice/service.cpp
@@ -47,6 +47,7 @@
 
 int main(int /* argc */, char* /* argv */ []) {
     // Setup HIDL Audio HAL
+    LOG(INFO) << "AudioControl start audio HAL.";
     configureRpcThreadpool(16, false /*callerWillJoin*/);
     android::status_t status;
     status = registerPassthroughServiceImplementation<IDevicesFactory>();
@@ -55,14 +56,17 @@
     LOG_ALWAYS_FATAL_IF(status != OK, "Error while registering audio effects service: %d", status);
 
     // Setup AudioControl HAL
-    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    ABinderProcess_setThreadPoolMaxThreadCount(16);
     std::shared_ptr<AudioControl> audioControl = ::ndk::SharedRefBase::make<AudioControl>();
 
     const std::string instance = std::string() + AudioControl::descriptor + "/default";
-    binder_status_t aidlStatus =
-            AServiceManager_addService(audioControl->asBinder().get(), instance.c_str());
+    binder_status_t aidlStatus = AServiceManager_addService(audioControl->asBinder().get(),
+            instance.c_str());
     CHECK(aidlStatus == STATUS_OK);
 
+    LOG(INFO) << "AudioControl status: status " << aidlStatus;
+
     ABinderProcess_joinThreadPool();
+    LOG(ERROR) << "ABinderProcess_joinThreadPool should never get here ";
     return EXIT_FAILURE;  // should not reach
 }