Revise code
[platform/core/multimedia/libmm-sound.git] / server / mm_sound_mgr_codec.c
index 433fa94..c604cf3 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include <pthread.h>
+#include <unistd.h>
+#include <errno.h>
 
-#include <mm_source.h>
 #include <mm_error.h>
 #include <mm_types.h>
 #include <mm_debug.h>
 #include <mm_ipc.h>
 #include <mm_session.h>
 
+#include <glib.h>
+
 #include "include/mm_sound_mgr_common.h"
 #include "include/mm_sound_mgr_codec.h"
 #include "include/mm_sound_mgr_ipc.h"
 #include "../include/mm_sound_common.h"
 #include "../include/mm_sound_focus.h"
 
-#define _ENABLE_KEYTONE        /* Temporal test code */
+#define SHUTDOWN_TIMEOUT_SEC 10
+#define STATUS_IDLE 0
+#define STATUS_SOUND 3
+#define SOUND_SLOT_START 0
+#define FOCUS_INTEGRATION
 
 typedef struct {
        int (*callback)(int, void *, void *, int);      /* msg_type(pid) client callback & client data info */
@@ -55,10 +62,13 @@ typedef struct {
        int status;
        int session_type;
        int session_options;
+#ifdef FOCUS_INTEGRATION
        int focus_handle;
        int focus_wcb_id;
        unsigned int subs_id;
        mm_sound_focus_type_e current_focus_type;
+#endif
+       bool stop_by_user;
 
        bool enable_session;
  } __mmsound_mgr_codec_handle_t;
@@ -67,120 +77,191 @@ static MMSoundPluginType *g_codec_plugins = NULL;
 static __mmsound_mgr_codec_handle_t g_slots[MANAGER_HANDLE_MAX];
 static mmsound_codec_interface_t g_plugins[MM_SOUND_SUPPORTED_CODEC_NUM];
 static pthread_mutex_t g_slot_mutex;
-static pthread_mutex_t codec_wave_mutex;
-static int _MMSoundMgrCodecStopCallback(int param);
-static int _MMSoundMgrCodecGetEmptySlot(int *slotid);
+GSourceFunc g_shutdown_cb;
+guint g_timer_id = 0;
+
+#define SLOT_LOCK() do { pthread_mutex_lock(&g_slot_mutex); /* debug_msg("After Slot_mutex LOCK\n"); */ } while (0)
+#define SLOT_UNLOCK() do { pthread_mutex_unlock(&g_slot_mutex); /* debug_msg("After Slot_mutex UNLOCK\n"); */ } while (0)
+
 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
+static int _MMSoundMgrCodecStopCallback(int param);
 
-#define STATUS_IDLE 0
-#define STATUS_SOUND 3
 
-#define SOUND_SLOT_START 0
+#ifdef FOCUS_INTEGRATION
 
-void sound_codec_focus_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, const char *reason_for_change, const char *additional_info, void *user_data)
+static void _handle_focus_event(int slotid, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, bool is_watch)
 {
-
-       int slotid = (int)user_data;
        int result = MM_ERROR_NONE;
 
-       debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
-
-       if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
-               debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
+       if (g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
+               debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
                return;
        }
+
        if (focus_state == FOCUS_IS_RELEASED) {
-               g_slots[slotid].current_focus_type = FOCUS_FOR_BOTH&(~focus_type);
-               debug_warning ("focus is released -> stop playing");
-               result = MMSoundMgrCodecStop(slotid);
-               if (result != MM_ERROR_NONE) {
-                       debug_log("result error %d\n", result);
-               }
+               if (!is_watch)
+                       g_slots[slotid].current_focus_type = FOCUS_FOR_BOTH & (~focus_type);
+               debug_warning("focus is released -> stop playing");
 
+               result = MMSoundMgrCodecStop(slotid);
+               if (result != MM_ERROR_NONE)
+                       debug_error("result error 0x%X", result);
        }
-       return;
 }
 
-void sound_codec_focus_watch_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, const char *reason_for_change, const char* additional_info, void *user_data)
+static void _sound_codec_focus_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state,
+                                                                               const char *reason_for_change, int option, const char *ext_info, void *user_data)
 {
-       int slotid = (int)user_data;
-       int result = MM_ERROR_NONE;
+       debug_warning("focus callback called -> focus_state(%d), reason_for_change(%s)",
+                       focus_state, reason_for_change ? reason_for_change : "N/A");
 
-       debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
+       _handle_focus_event((int)user_data, focus_type, focus_state, false);
+}
 
-       if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
-               debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
-               return;
-       }
-       if (focus_state == FOCUS_IS_ACQUIRED) {
-               debug_warning ("focus is released -> stop playing");
-               result = MMSoundMgrCodecStop(slotid);
-               if (result != MM_ERROR_NONE) {
-                       debug_log("result error %d\n", result);
-               }
+static void _sound_codec_focus_watch_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state,
+                                                                                       const char *reason_for_change, const char *ext_info, void *user_data)
+{
+       debug_warning("focus watch callback called -> focus_state(%d), reason_for_change(%s)",
+                               focus_state, reason_for_change ? reason_for_change : "N/A");
 
-       }
-       return;
+       _handle_focus_event((int)user_data, focus_type, focus_state, true);
 }
 
-void sound_codec_device_connected_callback(MMSoundDevice_t device, bool is_connected, void *user_data)
+static void _sound_codec_device_connected_callback(MMSoundDevice_t device, bool is_connected, void *user_data)
 {
        int slotid = (int)user_data;
        int result = MM_ERROR_NONE;
        mm_sound_device_type_e type;
 
-       debug_warning ("device_connected_callback called");
+       debug_warning ("device_connected_callback called : handle[%p], connected[%d], slotid[%d]", device, is_connected, slotid);
 
        if (mm_sound_get_device_type (device, &type) != MM_ERROR_NONE) {
                debug_error("getting device type failed");
+               return;
+       }
+
+       switch (type) {
+               case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
+               case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
+               case MM_SOUND_DEVICE_TYPE_HDMI:
+               case MM_SOUND_DEVICE_TYPE_MIRRORING:
+               case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
+                       if (!is_connected) {
+                               debug_warning("sound device unplugged");
+                               result = MMSoundMgrCodecStop(slotid);
+                               if (result != MM_ERROR_NONE)
+                                       debug_error("MMSoundMgrCodecStop error %d\n", result);
+
+                               result = mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id);
+                               if (result != MM_ERROR_NONE)
+                                       debug_error("mm_sound_remove_device_connected_callback error %d\n", result);
+                       }
+                       break;
+
+               default:
+                       break;
+       }
+}
+#endif
+
+/* FIXME : critical section for g_timer_id? */
+static void _mm_sound_mgr_codec_shutdown_timer_start()
+{
+       if (g_timer_id > 0) {
+               debug_error("Already active timer [%d] exists", g_timer_id);
+               return;
+       }
+
+       if (g_shutdown_cb) {
+               g_timer_id = g_timeout_add_seconds(SHUTDOWN_TIMEOUT_SEC, g_shutdown_cb, NULL);
+               debug_error("TIMER : new timer [%d]", g_timer_id);
        } else {
-               switch (type) {
-                       case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
-                       case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
-                       case MM_SOUND_DEVICE_TYPE_HDMI:
-                       case MM_SOUND_DEVICE_TYPE_MIRRORING:
-                       case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
-                               if (!is_connected) {
-                                       debug_warning("sound device unplugged");
-                                       result = MMSoundMgrCodecStop(slotid);
-                                       if (result != MM_ERROR_NONE) {
-                                               debug_error("MMSoundMgrCodecStop error %d\n", result);
-                                       }
-                                       result = mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id);
-                                       if (result != MM_ERROR_NONE) {
-                                               debug_error("mm_sound_remove_device_connected_callback error %d\n", result);
-                                       }
-                               }
-                               break;
-                       default:
-                               break;
-               }
+               debug_warning("No Timer started due to invalid shutdown callback");
        }
 }
 
-int MMSoundMgrCodecInit(const char *targetdir)
+static void _mm_sound_mgr_codec_shutdown_timer_stop()
 {
-       int loop = 0;
-       int count = 0;
+       if (g_timer_id > 0) {
+               debug_error("TIMER : remove timer id [%d]", g_timer_id);
+               g_source_remove(g_timer_id);
+               g_timer_id = 0;
+       } else {
+               debug_log("No Timer to stop...");
+       }
+}
 
-       debug_enter("\n");
+static int _mm_sound_mgr_codec_slot_get_empty(int *slot)
+{
+       int slotid = 0;
+       int err = MM_ERROR_NONE;
 
-       memset (g_slots, 0, sizeof(g_slots));
+       SLOT_LOCK();
 
-       if(pthread_mutex_init(&g_slot_mutex, NULL)) {
-               debug_error("pthread_mutex_init failed\n");
-               return MM_ERROR_SOUND_INTERNAL;
+       for (slotid = SOUND_SLOT_START; slotid < MANAGER_HANDLE_MAX ; slotid++) {
+               if (g_slots[slotid].status == STATUS_IDLE) {
+                       g_slots[slotid].status = STATUS_SOUND;
+                       break;
+               }
+       }
+
+       if (slotid < MANAGER_HANDLE_MAX) {
+               debug_msg("New handle allocated (codec slot ID : [%d])\n", slotid);
+               *slot = slotid;
+
+               _mm_sound_mgr_codec_shutdown_timer_stop();
+
+       } else {
+               debug_warning("Handle is full handle : [%d]\n", slotid);
+               *slot = -1;
+               /* Temporal code for reset */
+               while (slotid--) {
+                       g_slots[slotid].status = STATUS_IDLE;
+               }
+               err = MM_ERROR_SOUND_INTERNAL;
        }
 
-       if(pthread_mutex_init(&codec_wave_mutex, NULL)) {
+       SLOT_UNLOCK();
+
+       return err;
+}
+
+static gboolean _mm_sound_mgr_codec_slot_is_empty()
+{
+       int slotid = 0;
+
+       for (slotid = SOUND_SLOT_START; slotid < MANAGER_HANDLE_MAX ; slotid++) {
+               if (g_slots[slotid].status == STATUS_SOUND)
+                       break;
+       }
+
+       return (slotid == MANAGER_HANDLE_MAX) ? TRUE : FALSE;
+}
+
+static void _mm_sound_mgr_codec_slot_clear(int slotid)
+{
+       memset(&g_slots[slotid], 0, sizeof(__mmsound_mgr_codec_handle_t));
+       g_slots[slotid].status = STATUS_IDLE;
+
+       debug_error("SlotID [%d] cleared", slotid);
+}
+
+int MMSoundMgrCodecInit(const char *targetdir, GSourceFunc _shutdown_cb)
+{
+       int loop = 0;
+       int slotid = 0;
+
+       debug_enter();
+
+       memset(g_slots, 0, sizeof(g_slots));
+
+       if (pthread_mutex_init(&g_slot_mutex, NULL)) {
                debug_error("pthread_mutex_init failed\n");
                return MM_ERROR_SOUND_INTERNAL;
        }
 
-       for (count = 0; count < MANAGER_HANDLE_MAX; count++) {
-               g_slots[count].status = STATUS_IDLE;
-               g_slots[count].plughandle = 0;
-       }
+       for (slotid = 0; slotid < MANAGER_HANDLE_MAX; slotid++)
+               _mm_sound_mgr_codec_slot_clear(slotid);
 
        if (g_codec_plugins) {
                debug_warning("Please Check Init twice\n");
@@ -194,56 +275,78 @@ int MMSoundMgrCodecInit(const char *targetdir)
                }
        }
 
-       debug_leave("\n");
+       if (_shutdown_cb)
+               g_shutdown_cb = _shutdown_cb;
+       else
+               debug_warning("shutdown callback is NULL");
+
+       debug_leave();
        return MM_ERROR_NONE;
 }
 
 int MMSoundMgrCodecFini(void)
 {
-       debug_enter("\n");
+       debug_enter();
 
        memset(g_plugins, 0, sizeof(mmsound_codec_interface_t) * MM_SOUND_SUPPORTED_CODEC_NUM);
        MMSoundPluginRelease(g_codec_plugins);
        g_codec_plugins = NULL;
        pthread_mutex_destroy(&g_slot_mutex);
-       pthread_mutex_destroy(&codec_wave_mutex);
-       debug_leave("\n");
+
+       debug_leave();
        return MM_ERROR_NONE;
 }
 
+static int _MMSoundMgrCodecFindCodecPluginID(enum MMSoundSupportedCodec codec_to_find)
+{
+       int plugin_id = 0;
+       int *codec_type;
+
+       for (plugin_id = 0; plugin_id < MM_SOUND_SUPPORTED_CODEC_NUM; plugin_id++) {
+               if (g_plugins[plugin_id].GetSupportTypes) {
+                       codec_type = g_plugins[plugin_id].GetSupportTypes();
+                       if (codec_type[0] == codec_to_find)
+                               return plugin_id;
+               }
+       }
+
+       return -1;
+}
 
 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
        int err = MM_ERROR_NONE;
+
+#ifdef FOCUS_INTEGRATION
        int need_focus_unregister = 0;
+#endif
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
-
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
-               /* Find codec */
-               if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
-                       break;
+       plugin_id = _MMSoundMgrCodecFindCodecPluginID(MM_SOUND_SUPPORTED_CODEC_WAVE);
+       if (plugin_id == -1) {
+               debug_error("Could not find proper codec plugin!!!");
+               err = MM_ERROR_SOUND_INTERNAL;
+               goto cleanup;
        }
 
-       /*The count num means codec type WAV, MP3 */
-       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
-
-       if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
-               debug_error("unsupported file type %d\n", count);
-               err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
+       err = g_plugins[plugin_id].Parse(param->pfilename, &info);
+       if (err != MM_ERROR_NONE) {
+               debug_error("Could not parse file [%s] by plugin[%d]\n", param->pfilename, plugin_id);
                goto cleanup;
        }
 
+       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, plugin_id);
+
 #ifdef DEBUG_DETAIL
        debug_msg("Get New handle\n");
 #endif
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
        if (err != MM_ERROR_NONE || *slotid < 0) {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
@@ -253,20 +356,15 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
        codec_param.volume_config = param->volume_config;
        codec_param.repeat_count = param->repeat_count;
        codec_param.volume = param->volume;
-       codec_param.source = param->source;
-       codec_param.priority = param->priority;
+       codec_param.pfilename = param->pfilename;
        codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
        codec_param.param = *slotid;
        codec_param.pid = (int)param->param;
-       codec_param.handle_route = param->handle_route;
-       codec_param.codec_wave_mutex = &codec_wave_mutex;
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
+       SLOT_LOCK();
 
+#ifdef FOCUS_INTEGRATION
        /*
         * Register FOCUS here
         */
@@ -279,28 +377,33 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
 
                unsigned int subs_id = 0;
 
-               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, (mm_sound_device_connected_cb)sound_codec_device_connected_callback, (void*) *slotid, &subs_id);
+               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG,
+                                                                                                       (mm_sound_device_connected_cb)_sound_codec_device_connected_callback,
+                                                                                                       (void*) *slotid, &subs_id);
                if (err) {
                        debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
-                       pthread_mutex_unlock(&g_slot_mutex);
+                       SLOT_UNLOCK();
                        return MM_ERROR_POLICY_INTERNAL;
                }
                g_slots[*slotid].subs_id = subs_id;
 
-               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        debug_warning("session option is PAUSE_OTHERS -> acquire focus");
                        err = mm_sound_focus_get_id((int *)(&param->focus_handle));
-                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
+                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", _sound_codec_focus_callback, (void*)*slotid);
                        if (err) {
                                debug_error("mm_sound_register_focus_for_session failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
                        if (err) {
                                debug_error("mm_sound_acquire_focus failed [0x%x]", err);
                                err = mm_sound_unregister_focus(param->focus_handle);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
@@ -309,23 +412,27 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
                        debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
                } else {
                        debug_warning("need to set focus watch callback");
-                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(&param->focus_wcb_id));
+                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, _sound_codec_focus_watch_callback,
+                                                                                                                               (void*)*slotid, (int *)(&param->focus_wcb_id));
                        if (err) {
                                debug_error("mm_sound_set_focus_watch_callback_for_session failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                }
        }
        //
+#endif
 
        /* Codec id WAV or MP3 */
-       g_slots[*slotid].pluginid = count;
+       g_slots[*slotid].pluginid = plugin_id;
        g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
        g_slots[*slotid].session_type = param->session_type;
        g_slots[*slotid].session_options = param->session_options;
+#ifdef FOCUS_INTEGRATION
        g_slots[*slotid].focus_handle = param->focus_handle;
        g_slots[*slotid].focus_wcb_id = param->focus_wcb_id;
+#endif
        g_slots[*slotid].enable_session = true;
        g_slots[*slotid].pid = (int)param->param;
 
@@ -337,11 +444,12 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
        if (err != MM_ERROR_NONE) {
                debug_error("Plugin create fail : 0x%08X\n", err);
                g_slots[*slotid].status = STATUS_IDLE;
-               pthread_mutex_unlock(&g_slot_mutex);
-               debug_warning("After Slot_mutex UNLOCK\n");
+               SLOT_UNLOCK();
+#ifdef FOCUS_INTEGRATION
                if (param->focus_handle) {
                        need_focus_unregister = 1;
                }
+#endif
                goto cleanup;
        }
 
@@ -349,27 +457,33 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
        if (err != MM_ERROR_NONE) {
                debug_error("Fail to play : 0x%08X\n", err);
                g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
+#ifdef FOCUS_INTEGRATION
                if (param->focus_handle) {
                        need_focus_unregister = 1;
                }
+#endif
        }
 
-       pthread_mutex_unlock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex UNLOCK\n");
-#endif
+       SLOT_UNLOCK();
 
 cleanup:
-       if(param->session_type != MM_SESSION_TYPE_CALL &&
+       if (_mm_sound_mgr_codec_slot_is_empty())
+               _mm_sound_mgr_codec_shutdown_timer_start();
+
+#ifdef FOCUS_INTEGRATION
+       if (param->session_type != MM_SESSION_TYPE_CALL &&
                param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
                param->session_type != MM_SESSION_TYPE_VOIP &&
                param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
                param->enable_session &&
                need_focus_unregister == 1) {
 
-               if (param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
-                       if(mm_sound_unregister_focus(param->focus_handle) || err) {
+                       if (mm_sound_unregister_focus(param->focus_handle) || err) {
                                debug_error("focus cleaning up failed[0x%x]", err);
                                return MM_ERROR_POLICY_INTERNAL;
                        }
@@ -381,9 +495,11 @@ cleanup:
                        }
                }
        }
+#endif
+
 
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;
@@ -391,31 +507,28 @@ cleanup:
 
 int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
        int err = MM_ERROR_NONE;
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
-
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
-               /* Find codec */
-               if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
-                       break;
+       plugin_id = _MMSoundMgrCodecFindCodecPluginID(MM_SOUND_SUPPORTED_CODEC_WAVE);
+       if (plugin_id == -1) {
+               debug_error("Could not find proper codec plugin!!!");
+               err = MM_ERROR_SOUND_INTERNAL;
+               goto cleanup;
        }
 
-       /*The count num means codec type WAV, MP3 */
-       debug_msg("Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->repeat_count, param->volume, count);
-
-       if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
-               debug_error("unsupported file type %d\n", count);
-               err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
+       err = g_plugins[plugin_id].Parse(param->pfilename, &info);
+       if (err != MM_ERROR_NONE) {
+               debug_error("Could not parse file [%s] by plugin[%d]\n", param->pfilename, plugin_id);
                goto cleanup;
        }
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
        if (err != MM_ERROR_NONE || *slotid < 0) {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
@@ -424,33 +537,26 @@ int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param
        codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
        codec_param.repeat_count = param->repeat_count;
        codec_param.volume = param->volume;
-       codec_param.source = param->source;
-       codec_param.priority = param->priority;
+       codec_param.pfilename = param->pfilename;
        codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
        codec_param.param = *slotid;
        codec_param.pid = (int)param->param;
-       codec_param.handle_route = param->handle_route;
-       codec_param.codec_wave_mutex = &codec_wave_mutex;
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
+       SLOT_LOCK();
 
        /* Codec id WAV or MP3 */
-       g_slots[*slotid].pluginid = count;
+       g_slots[*slotid].pluginid = plugin_id;
        g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
 
        debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
 
        err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
-       debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
+       debug_msg("Created audio handle : [%p]\n", g_slots[*slotid].plughandle);
        if (err != MM_ERROR_NONE) {
                debug_error("Plugin create fail : 0x%08X\n", err);
                g_slots[*slotid].status = STATUS_IDLE;
-               pthread_mutex_unlock(&g_slot_mutex);
-               debug_warning("After Slot_mutex UNLOCK\n");
+               SLOT_UNLOCK();
                goto cleanup;
        }
 
@@ -460,15 +566,14 @@ int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param
                g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
        }
 
-       pthread_mutex_unlock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex UNLOCK\n");
-#endif
+       SLOT_UNLOCK();
 
 cleanup:
+       if (_mm_sound_mgr_codec_slot_is_empty())
+               _mm_sound_mgr_codec_shutdown_timer_start();
 
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;
@@ -478,30 +583,32 @@ cleanup:
 #define DTMF_PLUGIN_COUNT 2
 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        int *codec_type;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
        int err = MM_ERROR_NONE;
+#ifdef FOCUS_INTEGRATION
        int need_focus_unregister = 0;
+#endif
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
 
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
+       for (plugin_id = 0; g_plugins[plugin_id].GetSupportTypes; plugin_id++) {
                /* Find codec */
-               codec_type = g_plugins[count].GetSupportTypes();
-               if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
+               codec_type = g_plugins[plugin_id].GetSupportTypes();
+               if (codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
                        break;
        }
 
        /*The count num means codec type DTMF */
-       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
+       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, plugin_id);
 
-       if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
-               debug_error("unsupported file type %d\n", count);
-               printf("unsupported file type %d\n", count);
+       if (g_plugins[plugin_id].GetSupportTypes == NULL) {     /* Codec not found */
+               debug_error("unsupported file type %d\n", plugin_id);
+               printf("unsupported file type %d\n", plugin_id);
                err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
                goto cleanup;
        }
@@ -510,15 +617,13 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
        debug_msg("Get New handle\n");
 #endif
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
-       if(err != MM_ERROR_NONE || *slotid < 0)
-       {
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
+       if (err != MM_ERROR_NONE || *slotid < 0) {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
        }
 
        codec_param.tone = param->tone;
-       codec_param.priority = 0;
        codec_param.volume_config = param->volume_config;
        codec_param.repeat_count = param->repeat_count;
        codec_param.volume = param->volume;
@@ -527,12 +632,9 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
        codec_param.pid = (int)param->param;
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
+       SLOT_LOCK();
 
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
-
+#ifdef FOCUS_INTEGRATION
        //
        /*
         * Register FOCUS here
@@ -546,28 +648,33 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
 
                unsigned int subs_id = 0;
 
-               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, (mm_sound_device_connected_cb)sound_codec_device_connected_callback, (void*) *slotid, &subs_id);
+               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG,
+                                                                                                       (mm_sound_device_connected_cb)_sound_codec_device_connected_callback,
+                                                                                                       (void*) *slotid, &subs_id);
                if (err) {
                        debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
-                       pthread_mutex_unlock(&g_slot_mutex);
+                       SLOT_UNLOCK();
                        return MM_ERROR_POLICY_INTERNAL;
                }
                g_slots[*slotid].subs_id = subs_id;
 
-               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        debug_warning("session option is PAUSE_OTHERS -> acquire focus");
                        err = mm_sound_focus_get_id((int *)(&param->focus_handle));
-                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
+                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", _sound_codec_focus_callback, (void*)*slotid);
                        if (err) {
                                debug_error("mm_sound_register_focus failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
                        if (err) {
                                debug_error("mm_sound_acquire_focus failed [0x%x]", err);
                                err = mm_sound_unregister_focus(param->focus_handle);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
@@ -576,21 +683,25 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
                        debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
                } else {
                        debug_warning("need to set focus watch callback");
-                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(&param->focus_wcb_id));
+                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, _sound_codec_focus_watch_callback,
+                                                                                                                               (void*)*slotid, (int *)(&param->focus_wcb_id));
                        if (err) {
                                debug_error("mm_sound_set_focus_watch_callback failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                }
        }
+#endif
 
-       g_slots[*slotid].pluginid = count;
+       g_slots[*slotid].pluginid = plugin_id;
        g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
        g_slots[*slotid].session_type = param->session_type;
        g_slots[*slotid].session_options = param->session_options;
+#ifdef FOCUS_INTEGRATION
        g_slots[*slotid].focus_handle= param->focus_handle;
        g_slots[*slotid].focus_wcb_id= param->focus_wcb_id;
+#endif
        g_slots[*slotid].enable_session = param->enable_session;
        g_slots[*slotid].pid = (int)param->param;
 
@@ -603,9 +714,10 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
        if (err != MM_ERROR_NONE) {
                debug_error("Plugin create fail : 0x%08X\n", err);
                g_slots[*slotid].status = STATUS_IDLE;
-               pthread_mutex_unlock(&g_slot_mutex);
-               debug_warning("After Slot_mutex UNLOCK\n");
+               SLOT_UNLOCK();
+#ifdef FOCUS_INTEGRATION
                need_focus_unregister = 1;
+#endif
                goto cleanup;
        }
 
@@ -613,17 +725,16 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
        if (err != MM_ERROR_NONE) {
                debug_error("Fail to play : 0x%08X\n", err);
                g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
+#ifdef FOCUS_INTEGRATION
                need_focus_unregister = 1;
+#endif
        }
 
-       pthread_mutex_unlock(&g_slot_mutex);
-
+       SLOT_UNLOCK();
        debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex UNLOCK\n")
-#endif
 
 cleanup:
+#ifdef FOCUS_INTEGRATION
        if (param->session_type != MM_SESSION_TYPE_CALL &&
                param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
                param->session_type != MM_SESSION_TYPE_VOIP &&
@@ -631,9 +742,12 @@ cleanup:
                param->enable_session &&
                need_focus_unregister == 1) {
 
-               if (param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
-                       if(mm_sound_unregister_focus(param->focus_handle) || err) {
+                       if (mm_sound_unregister_focus(param->focus_handle) || err) {
                                debug_error("focus cleaning up failed[0x%x]", err);
                                return MM_ERROR_POLICY_INTERNAL;
                        }
@@ -645,9 +759,10 @@ cleanup:
                        }
                }
        }
+#endif
 
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;
@@ -655,29 +770,29 @@ cleanup:
 
 int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        int *codec_type;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
        int err = MM_ERROR_NONE;
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
 
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
+       for (plugin_id = 0; g_plugins[plugin_id].GetSupportTypes; plugin_id++) {
                /* Find codec */
-               codec_type = g_plugins[count].GetSupportTypes();
-               if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
+               codec_type = g_plugins[plugin_id].GetSupportTypes();
+               if (codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
                        break;
        }
 
        /*The count num means codec type DTMF */
-       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
+       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, plugin_id);
 
-       if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
-               debug_error("unsupported file type %d\n", count);
-               printf("unsupported file type %d\n", count);
+       if (g_plugins[plugin_id].GetSupportTypes == NULL) { /* Codec not found */
+               debug_error("unsupported file type %d\n", plugin_id);
+               printf("unsupported file type %d\n", plugin_id);
                err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
                goto cleanup;
        }
@@ -686,15 +801,14 @@ int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_p
        debug_msg("Get New handle\n");
 #endif
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
-       if(err != MM_ERROR_NONE || *slotid < 0)
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
+       if (err != MM_ERROR_NONE || *slotid < 0)
        {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
        }
 
        codec_param.tone = param->tone;
-       codec_param.priority = 0;
        codec_param.repeat_count = param->repeat_count;
        codec_param.volume = param->volume;
        codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
@@ -703,48 +817,40 @@ int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_p
        codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
+       SLOT_LOCK();
 
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
-               g_slots[*slotid].pluginid = count;
-               g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
-               g_slots[*slotid].enable_session = param->enable_session;
+       g_slots[*slotid].pluginid = plugin_id;
+       g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
+       g_slots[*slotid].enable_session = param->enable_session;
 
 #ifdef DEBUG_DETAIL
-               debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
+       debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
 #endif
 
-               err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
-               debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
-               if (err != MM_ERROR_NONE) {
-                       debug_error("Plugin create fail : 0x%08X\n", err);
-                       g_slots[*slotid].status = STATUS_IDLE;
-                       pthread_mutex_unlock(&g_slot_mutex);
-                       debug_warning("After Slot_mutex UNLOCK\n");
-                       goto cleanup;
-               }
-
-               err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
-               if (err != MM_ERROR_NONE) {
-                       debug_error("Fail to play : 0x%08X\n", err);
-                       g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
-               }
+       err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
+       debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
+       if (err != MM_ERROR_NONE) {
+               debug_error("Plugin create fail : 0x%08X\n", err);
+               g_slots[*slotid].status = STATUS_IDLE;
+               SLOT_UNLOCK();
+               goto cleanup;
+       }
 
-               pthread_mutex_unlock(&g_slot_mutex);
+       err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
+       if (err != MM_ERROR_NONE) {
+               debug_error("Fail to play : 0x%08X\n", err);
+               g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
+       }
 
-               debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
-#ifdef DEBUG_DETAIL
-               debug_msg("After Slot_mutex UNLOCK\n");
-#endif
+       SLOT_UNLOCK();
+       debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
 
-       cleanup:
+cleanup:
 #ifdef DEBUG_DETAIL
-               debug_leave("\n");
+       debug_leave();
 #endif
 
-               return err;
+       return err;
 
 }
 
@@ -758,10 +864,7 @@ int MMSoundMgrCodecStop(const int slotid)
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       pthread_mutex_lock (&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
+       SLOT_LOCK();
        if (g_slots[slotid].status == STATUS_IDLE) {
                err = MM_ERROR_SOUND_INVALID_STATE;
                debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid);
@@ -771,21 +874,20 @@ int MMSoundMgrCodecStop(const int slotid)
        debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
 #endif
 
+       g_slots[slotid].stop_by_user = true;
+
        err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
        if (err != MM_ERROR_NONE) {
                debug_error("Fail to STOP Code : 0x%08X\n", err);
        }
-       debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
+
 cleanup:
-       pthread_mutex_unlock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex UNLOCK\n");
-#endif
+       SLOT_UNLOCK();
        debug_leave("(err : 0x%08X)\n", err);
 
        return err;
 }
-
+#ifdef FOCUS_INTEGRATION
 int MMSoundMgrCodecClearFocus(int pid)
 {
        int err = MM_ERROR_NONE;
@@ -793,22 +895,25 @@ int MMSoundMgrCodecClearFocus(int pid)
 
        debug_enter("(pid : [%d])\n", pid);
 
-       pthread_mutex_lock (&g_slot_mutex);
+       SLOT_LOCK();
 
        for (slotid = 0 ; slotid < MANAGER_HANDLE_MAX ; slotid++) {
                if (g_slots[slotid].pid == pid) {
                        if (g_slots[slotid].focus_handle || g_slots[slotid].focus_wcb_id) {
-                               if(g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
+                               if (g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
                                        g_slots[slotid].session_type != MM_SESSION_TYPE_VIDEOCALL &&
                                        g_slots[slotid].session_type != MM_SESSION_TYPE_VOIP &&
                                        g_slots[slotid].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
                                        g_slots[slotid].enable_session ) {
-                                       if ((g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || g_slots[slotid].session_type == MM_SESSION_TYPE_ALARM || g_slots[slotid].session_type == MM_SESSION_TYPE_NOTIFY || g_slots[slotid].session_type == MM_SESSION_TYPE_EMERGENCY) {
+                                       if ((g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                                               g_slots[slotid].session_type == MM_SESSION_TYPE_ALARM ||
+                                               g_slots[slotid].session_type == MM_SESSION_TYPE_NOTIFY ||
+                                               g_slots[slotid].session_type == MM_SESSION_TYPE_EMERGENCY) {
                                                err = mm_sound_release_focus(g_slots[slotid].focus_handle, FOCUS_FOR_BOTH, NULL);
                                                if (err) {
                                                        debug_error("mm_sound_release_focus failed [0x%x]", err);
                                                }
-                                               if(mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
+                                               if (mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
                                                        debug_error("Focus clean up failed [0x%x]", err);
                                                        err = MM_ERROR_POLICY_INTERNAL;
                                                        goto cleanup;
@@ -822,7 +927,7 @@ int MMSoundMgrCodecClearFocus(int pid)
                                                }
                                        }
                                }
-                               if(mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id) != MM_ERROR_NONE)
+                               if (mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id) != MM_ERROR_NONE)
                                        debug_error("mm_sound_remove_device_connected_callback() failed");
                                g_slots[slotid].focus_handle = 0;
                                g_slots[slotid].focus_wcb_id = 0;
@@ -832,12 +937,12 @@ int MMSoundMgrCodecClearFocus(int pid)
        }
 
 cleanup:
-       pthread_mutex_unlock(&g_slot_mutex);
+       SLOT_UNLOCK();
        debug_leave("(err : 0x%08X)\n", err);
 
        return err;
 }
-
+#endif
 
 static int _MMSoundMgrCodecStopCallback(int param)
 {
@@ -850,124 +955,94 @@ static int _MMSoundMgrCodecStopCallback(int param)
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       pthread_mutex_lock(&g_slot_mutex);
-       debug_msg("[CODEC MGR] Slot_mutex lock done\n");
+       if (g_slots[param].stop_by_user == false) {
+               SLOT_LOCK();
+       }
 
+#ifdef FOCUS_INTEGRATION
        /*
         * Unregister FOCUS here
         */
        debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
 
        if (g_slots[param].focus_handle || g_slots[param].focus_wcb_id) {
-               if(g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
+               if (g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
                        g_slots[param].session_type != MM_SESSION_TYPE_VIDEOCALL &&
                        g_slots[param].session_type != MM_SESSION_TYPE_VOIP &&
                        g_slots[param].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
                        g_slots[param].enable_session ) {
-                       if ((g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || g_slots[param].session_type == MM_SESSION_TYPE_ALARM || g_slots[param].session_type == MM_SESSION_TYPE_NOTIFY || g_slots[param].session_type == MM_SESSION_TYPE_EMERGENCY) {
-                               if(g_slots[param].current_focus_type != FOCUS_NONE) {
+                       if ((g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                               g_slots[param].session_type == MM_SESSION_TYPE_ALARM ||
+                               g_slots[param].session_type == MM_SESSION_TYPE_NOTIFY ||
+                               g_slots[param].session_type == MM_SESSION_TYPE_EMERGENCY) {
+                               if (g_slots[param].current_focus_type != FOCUS_NONE) {
                                        err = mm_sound_release_focus(g_slots[param].focus_handle, g_slots[param].current_focus_type, NULL);
                                        if (err) {
                                                debug_error("mm_sound_release_focus failed [0x%x]", err);
                                        }
                                }
-                               if(mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
+                               if (mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
                                        debug_error("Focus clean up failed [0x%x]", err);
-                                       pthread_mutex_unlock(&g_slot_mutex);
-                                       return MM_ERROR_POLICY_INTERNAL;
+                                       err = MM_ERROR_POLICY_INTERNAL;
+                                       goto finish;
                                }
                        } else if (~(g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
                                err = mm_sound_unset_focus_watch_callback(g_slots[param].focus_wcb_id);
                                if (err) {
                                        debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
-                                       pthread_mutex_unlock(&g_slot_mutex);
-                                       return MM_ERROR_POLICY_INTERNAL;
+                                       err = MM_ERROR_POLICY_INTERNAL;
+                                       goto finish;
                                }
                        }
                }
-               if(mm_sound_remove_device_connected_callback(g_slots[param].subs_id) != MM_ERROR_NONE)
+               if (mm_sound_remove_device_connected_callback(g_slots[param].subs_id) != MM_ERROR_NONE)
                        debug_error("mm_sound_remove_device_connected_callback() failed");
        }
+#endif
 
-       __mm_sound_mgr_ipc_notify_play_file_end(param);
+       if (g_slots[param].stop_by_user == false) {
+               __mm_sound_mgr_ipc_notify_play_file_end(param);
+               debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
+       }
 
-       debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
        debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle);
        err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle);
-       if (err < 0 ) {
+       if (err < 0)
                debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err);
-       }
-       memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t));
-       g_slots[param].status = STATUS_IDLE;
-       pthread_mutex_unlock(&g_slot_mutex);
-       debug_msg("[CODEC MGR] Slot_mutex done\n");
 
-       return err;
-}
+       _mm_sound_mgr_codec_slot_clear(param);
+       if (_mm_sound_mgr_codec_slot_is_empty())
+               _mm_sound_mgr_codec_shutdown_timer_start();
 
-static int _MMSoundMgrCodecGetEmptySlot(int *slot)
-{
-       int count = 0;
-       int err = MM_ERROR_NONE;
-
-#ifdef DEBUG_DETAIL
-       debug_enter("\n");
-#endif
-       debug_msg("Codec slot ID : [%d]\n", *slot);
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
-
-       for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
-               if (g_slots[count].status == STATUS_IDLE) {
-                       g_slots[count].status = STATUS_SOUND;
-                       break;
-               }
-       }
-       pthread_mutex_unlock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex UNLOCK\n");
-#endif
-
-       if (count < MANAGER_HANDLE_MAX) {
-               debug_msg("New handle allocated (codec slot ID : [%d])\n", count);
-               *slot = count;
-               err =  MM_ERROR_NONE;
-       } else {
-               debug_warning("Handle is full handle : [%d]\n", count);
-               *slot = -1;
-               /* Temporal code for reset */
-               while(count--) {
-                       g_slots[count].status = STATUS_IDLE;
-               }
-               err =  MM_ERROR_SOUND_INTERNAL;
+finish:
+       if (g_slots[param].stop_by_user == false) {
+               SLOT_UNLOCK();
        }
 
-#ifdef DEBUG_DETAIL
-       debug_leave("\n");
-#endif
+       debug_fleave();
 
        return err;
 }
 
+
+
 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
 {
        int err = MM_ERROR_NONE;
-       int count = 0;
+       int plugin_id = 0;
        void *getinterface = NULL;
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
 
        /* find emptry slot */
-       for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
-               if (g_plugins[count].GetSupportTypes == NULL)
+       for (plugin_id = 0; plugin_id < MM_SOUND_SUPPORTED_CODEC_NUM; plugin_id++) {
+               if (g_plugins[plugin_id].GetSupportTypes == NULL)
                        break;
        }
 
-       if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
+       if (plugin_id == MM_SOUND_SUPPORTED_CODEC_NUM) {
                debug_critical("The plugin support type is not valid\n");
                return MM_ERROR_COMMON_OUT_OF_RANGE;
        }
@@ -977,22 +1052,22 @@ static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
                debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
                goto cleanup;
        }
-       debug_msg("interface[%p] empty_slot[%d]\n", getinterface, count);
+       debug_msg("interface[%p] empty_slot[%d]\n", getinterface, plugin_id);
 
-       err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
+       err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[plugin_id]);
        if (err != MM_ERROR_NONE) {
                debug_error("Get interface fail : %x\n", err);
 
 cleanup:
                /* If error occur, clean interface */
-               memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t));
+               memset(&g_plugins[plugin_id], 0, sizeof(mmsound_codec_interface_t));
        } else {
-               if (g_plugins[count].SetThreadPool)
-                       g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);
+               if (g_plugins[plugin_id].SetThreadPool)
+                       g_plugins[plugin_id].SetThreadPool(MMSoundThreadPoolRun);
        }
 
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;