rebase code with tizen 2.3 25/38225/1 tizen_3.0.2015.q2_common tizen_3.0.m1_mobile tizen_3.0.m1_tv accepted/tizen/common/20150506.091342 accepted/tizen/mobile/20150511.004103 accepted/tizen/tv/20150506.233452 accepted/tizen/wearable/20150506.234514 submit/tizen/20150429.013912 submit/tizen_common/20150505.090000 submit/tizen_common/20151015.190624 submit/tizen_common/20151019.135620 tizen_3.0.m1_mobile_release tizen_3.0.m1_tv_release tizen_3.0.m2.a1_mobile_release tizen_3.0.m2.a1_tv_release
authorSeungbae Shin <seungbae.shin@samsung.com>
Wed, 15 Apr 2015 04:32:47 +0000 (13:32 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Wed, 15 Apr 2015 04:33:06 +0000 (13:33 +0900)
Change-Id: I524fc7afd6bfefeff20bd902040367df5e03a38e

mm-session.pc.in
mm_session.c
mm_session.h
mm_session_private.h

index 7c28b7b..c2245a2 100644 (file)
@@ -8,4 +8,4 @@ Description : Multimedia Session Library
 Requires : audio-session-mgr mm-common
 Version : @VERSION@
 Libs : -L${libdir} -lmmfsession
-Cflags : -I${includedir}/mmf
\ No newline at end of file
+Cflags : -I${includedir}/mmf
index dac8b2f..7e94308 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * libmm-session
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@
  *
  */
 
-
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -69,13 +68,28 @@ typedef struct {
        session_event_t event;
 }session_monitor_t;
 
-int g_call_asm_handle = -1;
+typedef struct {
+       watch_callback_fn fn;
+       void* data;
+       session_watch_event_t event;
+       session_watch_state_t state;
+}session_watch_t;
+
+int g_asm_handle = -1;
+int g_session_type = -1;
 int g_monitor_asm_handle = -1;
 session_monitor_t g_monitor_data;
+session_watch_t g_watch_data;
 
 pthread_mutex_t g_mutex_monitor = PTHREAD_MUTEX_INITIALIZER;
 
 ASM_cb_result_t asm_monitor_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data);
+ASM_cb_result_t asm_watch_callback(int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, void* cb_data);
+static session_event_t _translate_from_event_src_to_mm_session(ASM_event_sources_t event_src);
+static session_watch_event_t _translate_from_asm_event_to_mm_session(ASM_sound_events_t sound_event);
+static ASM_sound_events_t _translate_from_mm_session_to_asm_event(session_watch_event_t watch_event);
+static ASM_sound_states_t _translate_from_mm_session_to_asm_state(session_watch_state_t watch_state);
+
 
 EXPORT_API
 int mm_session_init(int sessiontype)
@@ -91,136 +105,318 @@ int mm_session_init_ex(int sessiontype, session_callback_fn callback, void* user
        int error = 0;
        int result = MM_ERROR_NONE;
        int ltype = 0;
+       bool do_not_update_session_info = false;
        pthread_mutex_init(&g_mutex_monitor, NULL);
        debug_fenter();
        debug_log("type : %d", sessiontype);
 
-       if(sessiontype < MM_SESSION_TYPE_SHARE || sessiontype >= MM_SESSION_PRIVATE_TYPE_NUM) {
+       if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
                debug_error("Invalid argument %d",sessiontype);
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
        result = _mm_session_util_read_type(-1, &ltype);
-       if(MM_ERROR_INVALID_HANDLE != result) {
-               debug_error("Session already initialized. Please finish current session first");
-               return MM_ERROR_POLICY_DUPLICATED;
+       if (MM_ERROR_INVALID_HANDLE != result) {
+               if ((ltype == MM_SESSION_TYPE_MEDIA_RECORD) && sessiontype == MM_SESSION_TYPE_MEDIA) {
+                       /* already set by mm-camcorder, mm-sound(pcm in), keep going */
+                       do_not_update_session_info = true;
+               } else {
+                       debug_error("Session already initialized. Please finish current session first");
+                       return MM_ERROR_POLICY_DUPLICATED;
+               }
        }
 
        /* Monitor Callback */
-       if(NULL == callback) {
+       if (NULL == callback) {
                debug_warning("Null callback function");
        } else {
-               g_monitor_data.fn = callback;
-               g_monitor_data.data = user_param;
-               LOCK(g_mutex_monitor);
-               if(!ASM_register_sound(-1, &g_monitor_asm_handle, ASM_EVENT_MONITOR, ASM_STATE_NONE, asm_monitor_callback, (void*)&g_monitor_data, ASM_RESOURCE_NONE, &error)) {
-                       debug_error("Can not register monitor");
+               if (sessiontype != MM_SESSION_TYPE_RECORD_AUDIO &&
+                       sessiontype != MM_SESSION_TYPE_RECORD_VIDEO ) {
+                       g_monitor_data.fn = callback;
+                       g_monitor_data.data = user_param;
+                       LOCK(g_mutex_monitor);
+                       if(!ASM_register_sound(-1, &g_monitor_asm_handle, ASM_EVENT_MONITOR, ASM_STATE_NONE, asm_monitor_callback, (void*)&g_monitor_data, ASM_RESOURCE_NONE, &error)) {
+                               debug_error("Can not register monitor");
+                               UNLOCK(g_mutex_monitor);
+                               return MM_ERROR_INVALID_HANDLE;
+                       }
                        UNLOCK(g_mutex_monitor);
-                       return MM_ERROR_INVALID_HANDLE;
                }
-               UNLOCK(g_mutex_monitor);
        }
 
        /* Register here for call session types */
-       if(sessiontype == MM_SESSION_TYPE_CALL) {
-               if(!ASM_register_sound(-1, &g_call_asm_handle, ASM_EVENT_CALL, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
-                       debug_error("Can not register sound");
-                       return MM_ERROR_INVALID_HANDLE;
+       if (sessiontype == MM_SESSION_TYPE_CALL) {
+               if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_CALL, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
+                       goto REGISTER_FAILURE;
                }
-       } else if(sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
-               if(!ASM_register_sound(-1, &g_call_asm_handle, ASM_EVENT_VIDEOCALL, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_CAMERA|ASM_RESOURCE_VIDEO_OVERLAY, &error)) {
-                       debug_error("Can not register sound");
-                       return MM_ERROR_INVALID_HANDLE;
+       } else if (sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
+               if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_VIDEOCALL, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_CAMERA|ASM_RESOURCE_VIDEO_OVERLAY, &error)) {
+                       goto REGISTER_FAILURE;
                }
-       } else if(sessiontype == MM_SESSION_TYPE_RICH_CALL) {
-               if(!ASM_register_sound(-1, &g_call_asm_handle, ASM_EVENT_RICH_CALL, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
-                       debug_error("Can not register sound");
-                       return MM_ERROR_INVALID_HANDLE;
+       } else if (sessiontype == MM_SESSION_TYPE_VOIP) {
+               if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_VOIP, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
+                       goto REGISTER_FAILURE;
+               }
+       }
+       /* Register here for advanced session types (using asm_sub_event) */
+         else if (sessiontype == MM_SESSION_TYPE_VOICE_RECOGNITION) {
+               if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_VOICE_RECOGNITION, ASM_STATE_NONE, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
+                       goto REGISTER_FAILURE;
+               }
+       } else if (sessiontype == MM_SESSION_TYPE_RECORD_AUDIO) {
+               if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_MMCAMCORDER_AUDIO, ASM_STATE_NONE, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
+                       goto REGISTER_FAILURE;
+               }
+       } else if (sessiontype == MM_SESSION_TYPE_RECORD_VIDEO) {
+               if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_MMCAMCORDER_VIDEO, ASM_STATE_NONE, NULL, NULL, ASM_RESOURCE_CAMERA|ASM_RESOURCE_VIDEO_OVERLAY|ASM_RESOURCE_HW_ENCODER, &error)) {
+                       goto REGISTER_FAILURE;
                }
        }
 
-       result = _mm_session_util_write_type(-1, sessiontype);
-       if(MM_ERROR_NONE != result) {
-               debug_error("Write type failed");
-               if(sessiontype == MM_SESSION_TYPE_CALL) {
-                       ASM_unregister_sound(g_call_asm_handle, ASM_EVENT_CALL, &error);
-               } else if(sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
-                       ASM_unregister_sound(g_call_asm_handle, ASM_EVENT_VIDEOCALL, &error);
-               } else if(sessiontype == MM_SESSION_TYPE_RICH_CALL) {
-                       ASM_unregister_sound(g_call_asm_handle, ASM_EVENT_RICH_CALL, &error);
-               } else {
-                       LOCK(g_mutex_monitor);
-                       ASM_unregister_sound(g_monitor_asm_handle, ASM_EVENT_MONITOR, &error);
-                       UNLOCK(g_mutex_monitor);
+       g_session_type = sessiontype;
+
+       if (!do_not_update_session_info) {
+               result = _mm_session_util_write_type(-1, sessiontype);
+               if (MM_ERROR_NONE != result) {
+                       debug_error("Write type failed");
+                       if (sessiontype == MM_SESSION_TYPE_CALL) {
+                               ASM_unregister_sound(g_asm_handle, ASM_EVENT_CALL, &error);
+                       } else if (sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
+                               ASM_unregister_sound(g_asm_handle, ASM_EVENT_VIDEOCALL, &error);
+                       } else if (sessiontype == MM_SESSION_TYPE_VOIP) {
+                               ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOIP, &error);
+                       } else if (sessiontype == MM_SESSION_TYPE_VOICE_RECOGNITION) {
+                               ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOICE_RECOGNITION, &error);
+                       } else if (sessiontype == MM_SESSION_TYPE_RECORD_AUDIO) {
+                               ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_AUDIO, &error);
+                       } else if (sessiontype == MM_SESSION_TYPE_RECORD_VIDEO) {
+                               ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_VIDEO, &error);
+                       } else {
+                               LOCK(g_mutex_monitor);
+                               ASM_unregister_sound(g_monitor_asm_handle, ASM_EVENT_MONITOR, &error);
+                               UNLOCK(g_mutex_monitor);
+                       }
+                       g_asm_handle = -1;
+                       g_session_type = -1;
+                       return result;
                }
-               return result;
        }
 
        debug_fleave();
 
        return MM_ERROR_NONE;
+
+REGISTER_FAILURE:
+       debug_error("failed to ASM_register_sound(), sessiontype(%d), error(0x%x)", sessiontype, error);
+       switch (error) {
+       case ERR_ASM_POLICY_CANNOT_PLAY:
+               return MM_ERROR_POLICY_BLOCKED;
+       case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
+               return MM_ERROR_POLICY_BLOCKED_BY_CALL;
+       case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
+               return MM_ERROR_POLICY_BLOCKED_BY_ALARM;
+       default:
+               break;
+       }
+       return MM_ERROR_INVALID_HANDLE;
+}
+
+EXPORT_API
+int mm_session_update_option(session_update_type_t update_type, int options)
+{
+       int error = 0;
+       int result = MM_ERROR_NONE;
+       int ltype = 0;
+       int loption = 0;
+
+       debug_log("update_type: %d(0:Add, 1:Remove), options: %x", update_type, options);
+
+       if (update_type < 0 || update_type >= MM_SESSION_UPDATE_TYPE_NUM) {
+               debug_error("Invalid update_type value(%d)", update_type);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       if (options < 0) {
+               debug_error("Invalid options value(%x)", options);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       result = _mm_session_util_read_information(-1, &ltype, &loption);
+       if (result) {
+               debug_error("failed to _mm_session_util_read_information(), ret(%x)", result);
+               return result;
+       }
+       debug_log("[current] session_type: %d, session_option: %x", ltype, loption);
+
+       if (update_type == MM_SESSION_UPDATE_TYPE_ADD) {
+               loption |= options;
+       } else if (update_type == MM_SESSION_UPDATE_TYPE_REMOVE) {
+               loption &= ~options;
+       }
+
+       result = _mm_session_util_write_information(-1, ltype, loption);
+       if (result) {
+               debug_error("failed to _mm_session_util_write_information(), ret(%x)", result);
+               return result;
+       }
+
+       debug_log("[updated] session_type: %d, session_option: %x", ltype, loption);
+
+
+       return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int mm_session_add_watch_callback(int watchevent, int watchstate, watch_callback_fn callback, void* user_param)
+{
+       int result = MM_ERROR_NONE;
+       int error = 0;
+       int sessiontype = 0;
+
+       debug_fenter();
+
+       result = _mm_session_util_read_type(-1, &sessiontype);
+       if (result) {
+               debug_error("failed to _mm_session_util_read_type(), result(%d), maybe session is not created", result);
+               return result;
+       }
+       debug_log("type : %d", sessiontype);
+
+       if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
+               debug_error("Invalid session type %d", sessiontype);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (watchevent < MM_SESSION_WATCH_EVENT_CALL || watchevent >= MM_SESSION_WATCH_EVENT_NUM) {
+               debug_error("Invalid watch event %d", watchevent);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (watchstate < MM_SESSION_WATCH_STATE_STOP || watchstate >= MM_SESSION_WATCH_STATE_NUM) {
+               debug_error("Invalid watch state %d", watchstate);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       /* Register a watch callback */
+       if (NULL == callback) {
+               debug_error("Null callback function");
+       } else {
+               g_watch_data.fn = callback;
+               g_watch_data.data = user_param;
+               if (!ASM_set_watch_session (-1, _translate_from_mm_session_to_asm_event(watchevent), _translate_from_mm_session_to_asm_state(watchstate), asm_watch_callback, (void*)&g_watch_data, &error)) {
+                       debug_error("Could not register a watcher(event:%d, state:%d), error(0x%x)", watchevent, watchstate, error);
+                       return MM_ERROR_INVALID_HANDLE;
+               }
+       }
+
+       debug_fleave();
+
+       return result;
 }
 
 EXPORT_API
-int mm_session_get_current_type (int *sessiontype)
+int mm_session_get_current_type(int *sessiontype)
 {
        int result = MM_ERROR_NONE;
        int ltype = 0;
 
+       debug_fenter();
+
        if (sessiontype == NULL) {
                debug_error("input argument is NULL\n");
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
        result = _mm_session_util_read_type(-1, &ltype);
-       if(result == MM_ERROR_NONE) {
+       if (result == MM_ERROR_NONE) {
                debug_log("Current process session type = [%d]\n", ltype);
                *sessiontype = ltype;
        } else {
                debug_error("failed to get current process session type!!\n");
        }
 
+       debug_fleave();
+
        return result;
 }
 
 EXPORT_API
-int mm_session_finish()
+int mm_session_get_current_information(int *session_type, int *session_options)
+{
+       int result = MM_ERROR_NONE;
+       int ltype = 0;
+       int loption = 0;
+
+       debug_fenter();
+
+       if (session_type == NULL) {
+               debug_error("input argument is NULL\n");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       result = _mm_session_util_read_information(-1, &ltype, &loption);
+       if (result == MM_ERROR_NONE) {
+               debug_log("Current process session type = [%d], options = [%x]\n", ltype, loption);
+               *session_type = ltype;
+               *session_options = loption;
+       } else {
+               debug_error("failed to get current process session type, option!!\n");
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+EXPORT_API
+int mm_session_finish(void)
 {
        int error = 0;
        int result = MM_ERROR_NONE;
-       int sessiontype = MM_SESSION_TYPE_SHARE;
+       int sessiontype = MM_SESSION_TYPE_MEDIA;
        ASM_sound_states_t state = ASM_STATE_NONE;
 
        debug_fenter();
 
        result = _mm_session_util_read_type(-1, &sessiontype);
-       if(MM_ERROR_NONE != result) {
+       if (MM_ERROR_NONE != result) {
                debug_error("Can not read current type");
                DESTROY(g_mutex_monitor);
                return result;
        }
 
-       /* Unregister call session here */
-       if(sessiontype == MM_SESSION_TYPE_CALL) {
-               if(!ASM_unregister_sound(g_call_asm_handle, ASM_EVENT_CALL, &error)) {
-                       debug_error("\"CALL\" ASM unregister failed");
+       /* Unregister call session type here */
+       if (sessiontype == MM_SESSION_TYPE_CALL) {
+               if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_CALL, &error)) {
                        goto INVALID_HANDLE;
                }
-               g_call_asm_handle = -1;
-       } else if(sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
-               if(!ASM_unregister_sound(g_call_asm_handle, ASM_EVENT_VIDEOCALL, &error)) {
-                       debug_error("\"VIDEOCALL\" ASM unregister failed");
+       } else if (sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
+               if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_VIDEOCALL, &error)) {
                        goto INVALID_HANDLE;
                }
-               g_call_asm_handle = -1;
-       } else if(sessiontype == MM_SESSION_TYPE_RICH_CALL) {
-               if(!ASM_unregister_sound(g_call_asm_handle, ASM_EVENT_RICH_CALL, &error)) {
-                       debug_error("\"RICH-CALL\" ASM unregister failed");
+       } else if (sessiontype == MM_SESSION_TYPE_VOIP) {
+               if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOIP, &error)) {
+                       goto INVALID_HANDLE;
+               }
+       }
+       /* Unregister advanced session type here */
+       else if (sessiontype == MM_SESSION_TYPE_VOICE_RECOGNITION) {
+               if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOICE_RECOGNITION, &error)) {
                        goto INVALID_HANDLE;
                }
-               g_call_asm_handle = -1;
+       } else if (sessiontype == MM_SESSION_TYPE_RECORD_AUDIO) {
+               if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_AUDIO, &error)) {
+                       goto INVALID_HANDLE;
+               }
+       } else if (sessiontype == MM_SESSION_TYPE_RECORD_VIDEO) {
+               if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_VIDEO, &error)) {
+                       goto INVALID_HANDLE;
+               }
+       }
+       if (g_asm_handle != -1) {
+               g_asm_handle = -1;
        }
 
+
        /* Check monitor handle */
        TRY_LOCK(g_mutex_monitor, error);
        if (!error) {
@@ -232,14 +428,12 @@ int mm_session_finish()
                                return MM_ERROR_POLICY_INTERNAL;
                        } else {
                                switch(state) {
-                               case ASM_STATE_IGNORE:
                                case ASM_STATE_NONE:
                                        break;
                                case ASM_STATE_PLAYING:
                                case ASM_STATE_WAITING:
                                case ASM_STATE_STOP:
                                case ASM_STATE_PAUSE:
-                               case ASM_STATE_PAUSE_BY_APP:
                                        debug_error("[%s] MSL instance still alive", __func__);
                                        UNLOCK(g_mutex_monitor);
                                        DESTROY(g_mutex_monitor);
@@ -254,13 +448,15 @@ int mm_session_finish()
                        } else {
                                debug_log("ASM unregister monitor success");
                                g_monitor_asm_handle = -1;
+                               g_monitor_data.fn = NULL;
+                               g_monitor_data.data = NULL;
                        }
                }
                UNLOCK(g_mutex_monitor);
                DESTROY(g_mutex_monitor);
        }
 
-       result = _mm_session_util_delete_type(-1);
+       result = _mm_session_util_delete_information(-1);
        if(result != MM_ERROR_NONE)
                return result;
 
@@ -270,24 +466,102 @@ int mm_session_finish()
 
 INVALID_HANDLE:
        DESTROY(g_mutex_monitor);
+       debug_error("failed to ASM_unregister_sound(), sessiontype(%d)", sessiontype);
        return MM_ERROR_INVALID_HANDLE;
 }
 
 EXPORT_API
-int mm_session_set_subsession (mm_subsession_t subsession)
+int mm_session_remove_watch_callback(int watchevent, int watchstate)
 {
-       int error = 0;
        int result = MM_ERROR_NONE;
+       int error = 0;
+       int sessiontype = 0;
 
        debug_fenter();
 
-       if(g_call_asm_handle == -1) {
+       result = _mm_session_util_read_type(-1, &sessiontype);
+       if(result) {
+               debug_error("failed to _mm_session_util_read_type(), result(%d), maybe session is not created", result);
+               return result;
+       }
+       debug_log("type : %d", sessiontype);
+
+       if(sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
+               debug_error("Invalid session type %d", sessiontype);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if(watchevent < MM_SESSION_WATCH_EVENT_CALL || watchevent >= MM_SESSION_WATCH_EVENT_NUM) {
+               debug_error("Invalid watch event %d", watchevent);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if(watchstate < MM_SESSION_WATCH_STATE_STOP || watchstate >= MM_SESSION_WATCH_STATE_NUM) {
+               debug_error("Invalid watch state %d", watchstate);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       /* Unregister a watch callback */
+       if(!ASM_unset_watch_session (_translate_from_mm_session_to_asm_event(watchevent), _translate_from_mm_session_to_asm_state(watchstate), &error)) {
+               debug_error("Could not unregister a watcher(event:%d, state:%d), error(0x%x)", watchevent, watchstate, error);
+               return MM_ERROR_INVALID_HANDLE;
+       } else {
+               g_watch_data.fn = NULL;
+               g_watch_data.data = NULL;
+       }
+
+       debug_fleave();
+
+       return result;
+}
+
+EXPORT_API
+int mm_session_set_subsession(mm_subsession_t subsession, mm_subsession_option_t option)
+{
+       int error = 0;
+       int ret = 0;
+
+       debug_fenter();
+
+       if (g_asm_handle == -1) {
                debug_error ("call session is not started...\n");
                return MM_ERROR_INVALID_HANDLE;
        }
+       if (g_session_type == -1 || g_session_type < MM_SESSION_TYPE_CALL || g_session_type >= MM_SESSION_TYPE_NUM ) {
+               debug_error ("session type is null, or out of bound(%d)\n", g_session_type);
+               return MM_ERROR_INVALID_HANDLE;
+       }
 
-       /* FIXME : Error handling */
-       ASM_set_subsession (g_call_asm_handle, subsession, &error, NULL);
+       if (subsession >= MM_SUBSESSION_TYPE_VOICE && subsession <= MM_SUBSESSION_TYPE_MEDIA) {
+               if (g_session_type < MM_SESSION_TYPE_CALL || g_session_type > MM_SESSION_TYPE_VOIP) {
+                       debug_error ("Not support this subsession(%d) of CALL session_type(%d)\n", subsession, g_session_type);
+                       return MM_ERROR_INVALID_HANDLE;
+               }
+       } else if (subsession == MM_SUBSESSION_TYPE_INIT) {
+               if (g_session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
+                       g_session_type != MM_SESSION_TYPE_RECORD_AUDIO &&
+                       g_session_type != MM_SESSION_TYPE_RECORD_VIDEO) {
+                       debug_error ("Not support this subsession(%d) of the session_type(%d)\n", subsession, g_session_type);
+                       return MM_ERROR_INVALID_HANDLE;
+               }
+       } else if (subsession == MM_SUBSESSION_TYPE_RECORD_STEREO ||
+                               subsession == MM_SUBSESSION_TYPE_RECORD_MONO) {
+               if (g_session_type < MM_SESSION_TYPE_RECORD_AUDIO || g_session_type > MM_SESSION_TYPE_RECORD_VIDEO) {
+                       debug_error ("Not support this subsession(%d) of the session_type(%d)\n", subsession, g_session_type);
+                       return MM_ERROR_INVALID_HANDLE;
+               }
+       }
+
+       if(option < MM_SUBSESSION_OPTION_NONE || option >= MM_SUBSESSION_OPTION_NUM) {
+               debug_error ("option(%d) is not valid\n", option);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       ret = ASM_set_subsession (g_asm_handle, (ASM_sound_sub_sessions_t)subsession, option, &error);
+       if (!ret) {
+               debug_error("ASM_set_subsession() failed, Set subsession to [%d] failed 0x%X\n\n", subsession, error);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
 
        debug_fleave();
 
@@ -295,18 +569,27 @@ int mm_session_set_subsession (mm_subsession_t subsession)
 }
 
 EXPORT_API
-int mm_session_get_subsession (mm_subsession_t *subsession)
+int mm_session_get_subsession(mm_subsession_t *subsession)
 {
        int error = 0;
-       int result = MM_ERROR_NONE;
+       int ret = 0;
+
        debug_fenter();
 
-       if(g_call_asm_handle == -1) {
+       if(g_asm_handle == -1) {
                debug_error ("call session is not started...\n");
                return MM_ERROR_INVALID_HANDLE;
        }
+       if(g_session_type == -1 || g_session_type < MM_SESSION_TYPE_CALL || g_session_type >= MM_SESSION_TYPE_NUM ) {
+               debug_error ("Not support this session_type(%d)\n", g_session_type);
+               return MM_ERROR_INVALID_HANDLE;
+       }
 
-       ASM_get_subsession (g_call_asm_handle, subsession, &error, NULL);
+       ret = ASM_get_subsession (g_asm_handle, (ASM_sound_sub_sessions_t*)subsession, &error);
+       if (!ret) {
+               debug_error("ASM_get_subsession() failed 0x%X\n\n", error);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
 
        debug_log("ASM_get_subsession returned [%d]\n", *subsession);
        debug_fleave();
@@ -315,7 +598,100 @@ int mm_session_get_subsession (mm_subsession_t *subsession)
 }
 
 EXPORT_API
-int _mm_session_util_delete_type(int app_pid)
+int mm_session_set_subevent(mm_session_sub_t subevent)
+{
+       int error = 0;
+       int ret = 0;
+
+       debug_fenter();
+
+       if(g_asm_handle == -1) {
+               debug_error ("session is not started...\n");
+               return MM_ERROR_INVALID_HANDLE;
+       }
+       if(g_session_type == -1 ||  g_session_type < MM_SESSION_TYPE_VOICE_RECOGNITION || g_session_type >= MM_SESSION_TYPE_NUM ) {
+               debug_error ("not support this session_type(%d)\n", g_session_type);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       ret = ASM_set_subevent (g_asm_handle, (ASM_sound_sub_events_t)subevent, &error);
+       if (!ret) {
+               debug_error("ASM_set_subevent() failed, Set subevent to [%d] failed 0x%X\n\n", subevent, error);
+               switch (error) {
+               case ERR_ASM_POLICY_CANNOT_PLAY:
+               case ERR_ASM_POLICY_CANNOT_PLAY_BY_PROFILE:
+               case ERR_ASM_POLICY_CANNOT_PLAY_BY_CUSTOM:
+                       return MM_ERROR_POLICY_BLOCKED;
+               case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
+                       return MM_ERROR_POLICY_BLOCKED_BY_CALL;
+               case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
+                       return MM_ERROR_POLICY_BLOCKED_BY_ALARM;
+               }
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int mm_session_get_subevent(mm_session_sub_t *subevent)
+{
+       int error = 0;
+       int ret = 0;
+       debug_fenter();
+
+       if(g_asm_handle == -1) {
+               debug_error ("session is not started...\n");
+               return MM_ERROR_INVALID_HANDLE;
+       }
+       if(g_session_type == -1 ||  g_session_type < MM_SESSION_TYPE_VOICE_RECOGNITION || g_session_type >= MM_SESSION_TYPE_NUM ) {
+               debug_error ("not support this session_type(%d)\n", g_session_type);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       ret = ASM_get_subevent (g_asm_handle, (ASM_sound_sub_events_t*)subevent, &error);
+       if (!ret) {
+               debug_error("ASM_get_subevent() failed 0x%X\n\n", error);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       debug_log("ASM_get_subevent returned [%d]\n", *subevent);
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int mm_session_reset_resumption_info(void)
+{
+       int error = 0;
+       int ret = 0;
+
+       debug_fenter();
+
+       if(g_asm_handle == -1) {
+               debug_error ("call series or voice recognition session is not started...\n");
+               return MM_ERROR_INVALID_HANDLE;
+       }
+       if(g_session_type == -1 || g_session_type < MM_SESSION_TYPE_MEDIA || g_session_type >= MM_SESSION_TYPE_NUM ) {
+               debug_error ("not support this session_type(%d)\n", g_session_type);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       ret = ASM_reset_resumption_info (g_asm_handle, &error);
+       if (!ret) {
+               debug_error("ASM_reset_resumption_info() failed 0x%X\n\n", error);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       debug_leave();
+
+       return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_session_util_delete_information(int app_pid)
 {
        pid_t mypid;
        char filename[MAX_FILE_LENGTH];
@@ -341,7 +717,7 @@ int _mm_session_util_write_type(int app_pid, int sessiontype)
        int fd = -1;
        char filename[MAX_FILE_LENGTH];
 
-       if(sessiontype < MM_SESSION_TYPE_SHARE || sessiontype >= MM_SESSION_PRIVATE_TYPE_NUM) {
+       if(sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
@@ -357,9 +733,12 @@ int _mm_session_util_write_type(int app_pid, int sessiontype)
                debug_error("open() failed with %d",errno);
                return MM_ERROR_FILE_WRITE;
        }
+       sessiontype = sessiontype << 16;
        write(fd, &sessiontype, sizeof(int));
        if(0 > fchmod (fd, 00777)) {
-               debug_log("fchmod failed with %d", errno);
+               debug_error("fchmod failed with %d", errno);
+       } else {
+               debug_warning("write sessiontype(%d) to /tmp/mm_session_%d", sessiontype >> 16, mypid);
        }
        close(fd);
        ////// WRITE SESSION TYPE /////////
@@ -374,6 +753,8 @@ int _mm_session_util_read_type(int app_pid, int *sessiontype)
        int fd = -1;
        char filename[MAX_FILE_LENGTH];
 
+       debug_fenter();
+
        if(sessiontype == NULL)
                return MM_ERROR_INVALID_ARGUMENT;
 
@@ -389,30 +770,133 @@ int _mm_session_util_read_type(int app_pid, int *sessiontype)
                return MM_ERROR_INVALID_HANDLE;
        }
        read(fd, sessiontype, sizeof(int));
+       *sessiontype = *sessiontype >> 16;
+       debug_warning("read sessiontype(%d) from /tmp/mm_session_%d", *sessiontype, mypid);
        close(fd);
        ////// READ SESSION TYPE /////////
 
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_session_util_write_information(int app_pid, int session_type, int flags)
+{
+       pid_t mypid;
+       int fd = -1;
+       char filename[MAX_FILE_LENGTH];
+       int result_info = 0;
+
+       if(session_type < MM_SESSION_TYPE_MEDIA || session_type >= MM_SESSION_TYPE_NUM) {
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       if(flags < 0) {
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if(app_pid == -1) {
+               mypid = getpid();
+       } else {
+               mypid = (pid_t)app_pid;
+       }
+
+       ////// WRITE SESSION INFO /////////
+       snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
+       fd = open(filename, O_WRONLY | O_CREAT, 0644 );
+       if(fd < 0) {
+               debug_error("open() failed with %d",errno);
+               return MM_ERROR_FILE_WRITE;
+       }
+
+       result_info = (flags) | (session_type << 16);
+       write(fd, &result_info, sizeof(int));
+       if(0 > fchmod (fd, 00777)) {
+               debug_error("fchmod failed with %d", errno);
+       } else {
+               debug_warning("write session information(%x) to /tmp/mm_session_%d", result_info, mypid);
+       }
+       close(fd);
+       ////// WRITE SESSION INFO /////////
+
+       return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_session_util_read_information(int app_pid, int *session_type, int *flags)
+{
+       pid_t mypid;
+       int fd = -1;
+       char filename[MAX_FILE_LENGTH];
+       int result_info = 0;
+
+       debug_fenter();
+
+       if(session_type == NULL || flags == NULL) {
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if(app_pid == -1) {
+               mypid = getpid();
+       } else {
+               mypid = (pid_t)app_pid;
+       }
+
+       ////// READ SESSION INFO /////////
+       snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
+       fd = open(filename, O_RDONLY);
+       if(fd < 0) {
+               return MM_ERROR_INVALID_HANDLE;
+       }
+       read(fd, &result_info, sizeof(int));
+       *session_type = result_info >> 16;
+       *flags = result_info & 0x0000ffff;
+
+       debug_warning("read session_type(%d), session_option(%x) from /tmp/mm_session_%d", *session_type, *flags, mypid);
+       close(fd);
+       ////// READ SESSION INFO /////////
+
+       debug_fleave();
+
        return MM_ERROR_NONE;
 }
 
 gboolean _asm_monitor_cb(gpointer *data)
 {
        session_monitor_t* monitor = (session_monitor_t*)data;
+       debug_fenter();
+
        if (monitor) {
                if (monitor->fn) {
-                       debug_log("calling _asm_monitor_cb()");
                        monitor->fn(monitor->msg, monitor->event, monitor->data);
                }
        }
+       debug_fleave();
 
        return FALSE;
 }
 
-static session_event_t _translate_from_asm_to_mm_session (ASM_event_sources_t event_src)
+gboolean _asm_watch_cb(gpointer *data)
+{
+       session_watch_t* watch_h = (session_watch_t*)data;
+       debug_fenter();
+
+       if (watch_h) {
+               if (watch_h->fn) {
+                       watch_h->fn(watch_h->event, watch_h->state, watch_h->data);
+               }
+       }
+       debug_fleave();
+
+       return FALSE;
+}
+
+static session_event_t _translate_from_event_src_to_mm_session(ASM_event_sources_t event_src)
 {
        switch (event_src)
        {
        case ASM_EVENT_SOURCE_CALL_START:
+       case ASM_EVENT_SOURCE_CALL_END:
                return MM_SESSION_EVENT_CALL;
 
        case ASM_EVENT_SOURCE_EARJACK_UNPLUG:
@@ -425,19 +909,64 @@ static session_event_t _translate_from_asm_to_mm_session (ASM_event_sources_t ev
        case ASM_EVENT_SOURCE_ALARM_END:
                return MM_SESSION_EVENT_ALARM;
 
+       case ASM_EVENT_SOURCE_NOTIFY_START:
+       case ASM_EVENT_SOURCE_NOTIFY_END:
+               return MM_SESSION_EVENT_NOTIFICATION;
+
        case ASM_EVENT_SOURCE_EMERGENCY_START:
        case ASM_EVENT_SOURCE_EMERGENCY_END:
                return MM_SESSION_EVENT_EMERGENCY;
 
-       case ASM_EVENT_SOURCE_RESUMABLE_MEDIA:
-               return MM_SESSION_EVENT_RESUMABLE_MEDIA;
-
        case ASM_EVENT_SOURCE_MEDIA:
+       case ASM_EVENT_SOURCE_OTHER_PLAYER_APP:
        default:
                return MM_SESSION_EVENT_MEDIA;
        }
 }
 
+static session_watch_event_t _translate_from_asm_event_to_mm_session(ASM_sound_events_t sound_event)
+{
+       switch (sound_event)
+       {
+       case ASM_EVENT_CALL:
+               return MM_SESSION_WATCH_EVENT_CALL;
+       case ASM_EVENT_VIDEOCALL:
+               return MM_SESSION_WATCH_EVENT_VIDEO_CALL;
+       case ASM_EVENT_ALARM:
+               return MM_SESSION_WATCH_EVENT_ALARM;
+       default:
+               return MM_SESSION_WATCH_EVENT_IGNORE;
+       }
+}
+
+static ASM_sound_events_t _translate_from_mm_session_to_asm_event(session_watch_event_t watch_event)
+{
+       switch (watch_event)
+       {
+       case MM_SESSION_WATCH_EVENT_CALL:
+               return ASM_EVENT_CALL;
+       case MM_SESSION_WATCH_EVENT_VIDEO_CALL:
+               return ASM_EVENT_VIDEOCALL;
+       case MM_SESSION_WATCH_EVENT_ALARM:
+               return ASM_EVENT_ALARM;
+       default:
+               return ASM_EVENT_NONE;
+       }
+}
+
+static ASM_sound_states_t _translate_from_mm_session_to_asm_state(session_watch_state_t watch_state)
+{
+       switch (watch_state)
+       {
+       case MM_SESSION_WATCH_STATE_STOP:
+               return ASM_STATE_STOP;
+       case MM_SESSION_WATCH_STATE_PLAYING:
+               return ASM_STATE_PLAYING;
+       default:
+               return ASM_STATE_NONE;
+       }
+}
+
 ASM_cb_result_t
 asm_monitor_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
 {
@@ -457,7 +986,7 @@ asm_monitor_callback(int handle, ASM_event_sources_t event_src, ASM_sound_comman
                //call session_callback_fn for stop here
                if(monitor->fn) {
                        monitor->msg = MM_SESSION_MSG_STOP;
-                       monitor->event = _translate_from_asm_to_mm_session (event_src);
+                       monitor->event = _translate_from_event_src_to_mm_session (event_src);
                        g_idle_add((GSourceFunc)_asm_monitor_cb, (gpointer)monitor);
                }
                cb_res = (command == ASM_COMMAND_STOP)? ASM_CB_RES_STOP : ASM_CB_RES_PAUSE;
@@ -468,7 +997,7 @@ asm_monitor_callback(int handle, ASM_event_sources_t event_src, ASM_sound_comman
                //call session_callback_fn for resume here
                if(monitor->fn) {
                        monitor->msg = MM_SESSION_MSG_RESUME;
-                       monitor->event = _translate_from_asm_to_mm_session (event_src);
+                       monitor->event = _translate_from_event_src_to_mm_session (event_src);
                        g_idle_add((GSourceFunc)_asm_monitor_cb, (gpointer)monitor);
                }
                cb_res = ASM_CB_RES_IGNORE;
@@ -480,6 +1009,51 @@ asm_monitor_callback(int handle, ASM_event_sources_t event_src, ASM_sound_comman
        return cb_res;
 }
 
+ASM_cb_result_t
+asm_watch_callback(int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, void* cb_data)
+{
+       ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
+       session_watch_t *watch_handle = (session_watch_t*)cb_data;
+
+       debug_log("watch callback called for handle %d, sound_event %d, sound_state %d", handle, sound_event, sound_state);
+       if(!watch_handle) {
+               debug_log("watch_handle instance is null\n");
+               return ASM_CB_RES_IGNORE;
+       }
+
+       switch(sound_state) {
+       case ASM_STATE_PLAYING:
+               if(watch_handle->fn) {
+                       watch_handle->event = _translate_from_asm_event_to_mm_session(sound_event);
+                       watch_handle->state = MM_SESSION_WATCH_STATE_PLAYING;
+                       if (watch_handle->event == MM_SESSION_WATCH_EVENT_IGNORE) {
+                               cb_res = ASM_CB_RES_IGNORE;
+                               debug_error("sound_event(%d) is not valid..", sound_event);
+                       } else {
+                               g_idle_add((GSourceFunc)_asm_watch_cb, (gpointer)watch_handle);
+                       }
+               }
+               break;
+       case ASM_STATE_STOP:
+               if(watch_handle->fn) {
+                       watch_handle->event = _translate_from_asm_event_to_mm_session(sound_event);
+                       watch_handle->state = MM_SESSION_WATCH_STATE_STOP;
+                       if (watch_handle->event == MM_SESSION_WATCH_EVENT_IGNORE) {
+                               debug_error("sound_event(%d) is not valid..", sound_event);
+                               cb_res = ASM_CB_RES_IGNORE;
+                       } else {
+                               g_idle_add((GSourceFunc)_asm_watch_cb, (gpointer)watch_handle);
+                       }
+               }
+               break;
+       default:
+               debug_error("sound_state(%d) is not valid..", sound_state);
+               cb_res = ASM_CB_RES_IGNORE;
+               break;
+       }
+       return cb_res;
+}
+
 __attribute__ ((destructor))
 void __mmsession_finalize(void)
 {
@@ -496,12 +1070,14 @@ void __mmsession_finalize(void)
                        } else {
                                debug_log("ASM unregister monitor success");
                                g_monitor_asm_handle = -1;
+                               g_monitor_data.fn = NULL;
+                               g_monitor_data.data = NULL;
                        }
                }
                UNLOCK(g_mutex_monitor);
                DESTROY(g_mutex_monitor);
        }
-       _mm_session_util_delete_type(-1);
+       _mm_session_util_delete_information(-1);
 
        debug_fleave();
 }
index 7e38301..c38a709 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * libmm-session
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@
 #ifndef        _MM_SESSION_H_
 #define        _MM_SESSION_H_
 
+#include <audio-session-manager-types.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -45,12 +47,37 @@ extern "C" {
   * This enumeration defines application's session types.
   */
 enum MMSessionType {
-       MM_SESSION_TYPE_SHARE = 0,      /**< Share type : this type shares it's session with other share type application */
-       MM_SESSION_TYPE_EXCLUSIVE,      /**< Exclusive type : this type make previous session stop. And it does not allow other share type session start */
-       MM_SESSION_TYPE_NUM,
+       MM_SESSION_TYPE_MEDIA = 0,
+       MM_SESSION_TYPE_MEDIA_RECORD,
+       MM_SESSION_TYPE_ALARM,
+       MM_SESSION_TYPE_NOTIFY,
+       MM_SESSION_TYPE_EMERGENCY,
+       MM_SESSION_TYPE_CALL,
+       MM_SESSION_TYPE_VIDEOCALL,
+       MM_SESSION_TYPE_VOIP,
+       MM_SESSION_TYPE_VOICE_RECOGNITION,
+       MM_SESSION_TYPE_RECORD_AUDIO,
+       MM_SESSION_TYPE_RECORD_VIDEO,
+       MM_SESSION_TYPE_NUM
 };
 
 /**
+  * This enumeration defines behavior of update.
+  */
+typedef enum {
+       MM_SESSION_UPDATE_TYPE_ADD,
+       MM_SESSION_UPDATE_TYPE_REMOVE,
+       MM_SESSION_UPDATE_TYPE_NUM
+}session_update_type_t;
+
+/**
+  * This define is for session options
+  */
+#define MM_SESSION_OPTION_PAUSE_OTHERS                      ASM_SESSION_OPTION_PAUSE_OTHERS
+#define MM_SESSION_OPTION_UNINTERRUPTIBLE                   ASM_SESSION_OPTION_UNINTERRUPTIBLE
+#define MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED  ASM_SESSION_OPTION_RESUME_BY_MEDIA_PAUSED
+
+/**
   * This enumeration defines session callback message type.
   */
 typedef enum {
@@ -68,10 +95,25 @@ typedef enum {
        MM_SESSION_EVENT_EARJACK_UNPLUG,
        MM_SESSION_EVENT_RESOURCE_CONFLICT,
        MM_SESSION_EVENT_EMERGENCY,
-       MM_SESSION_EVENT_RESUMABLE_MEDIA,
+       MM_SESSION_EVENT_NOTIFICATION,
 }session_event_t;
 
+typedef enum {
+       MM_SESSION_WATCH_EVENT_IGNORE = -1,
+       MM_SESSION_WATCH_EVENT_CALL = 0,
+       MM_SESSION_WATCH_EVENT_VIDEO_CALL,
+       MM_SESSION_WATCH_EVENT_ALARM,
+       MM_SESSION_WATCH_EVENT_NUM
+}session_watch_event_t;
+
+typedef enum {
+       MM_SESSION_WATCH_STATE_STOP = 0,
+       MM_SESSION_WATCH_STATE_PLAYING,
+       MM_SESSION_WATCH_STATE_NUM
+}session_watch_state_t;
+
 typedef void (*session_callback_fn) (session_msg_t msg, session_event_t event, void *user_param);
+typedef void (*watch_callback_fn) (session_watch_event_t event, session_watch_state_t state, void *user_param);
 
 /**
  * This function defines application's Multimedia Session policy
@@ -95,7 +137,7 @@ static int _create(void *data)
        int ret = 0;
 
        // Initialize Multimedia Session Type
-       ret = mm_session_init(MM_SESSION_TYPE_SHARE);
+       ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
        if(ret < 0)
        {
                printf("Can not initialize session \n");
@@ -183,7 +225,7 @@ static int _create(void *data)
        int ret = 0;
 
        // Initialize Multimedia Session Type with callback
-       ret = mm_session_init_ex(MM_SESSION_TYPE_SHARE, session_cb, (void*)ad);
+       ret = mm_session_init_ex(MM_SESSION_TYPE_MEDIA, session_cb, (void*)ad);
        if(ret < 0)
        {
                printf("Can not initialize session \n");
@@ -246,7 +288,7 @@ static int _create(void *data)
        int ret = 0;
 
        // Initialize Multimedia Session Type
-       ret = mm_session_init(MM_SESSION_TYPE_SHARE);
+       ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
        if(ret < 0)
        {
                printf("Can not initialize session \n");
@@ -293,8 +335,66 @@ int mm_session_finish(void);
  * @see                mm_session_init
  * @since
  */
-int mm_session_get_current_type (int *sessiontype);
+int mm_session_get_current_type(int *sessiontype);
 
+/**
+ * This function get current application's Multimedia Session information
+ *
+ * @param      session_type    [out] Current Multimedia Session type
+ * @param      session_options [out] Current Multimedia Session options
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @see
+ * @since
+ */
+int mm_session_get_current_information(int *session_type, int *session_options);
+
+/**
+ * This function update application's Multimedia Session options
+ *
+ * @param      update_type     [in] add or remove options
+ * @param      session_options [in] Multimedia Session options to be updated
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @see
+ * @since
+ */
+int mm_session_update_option(session_update_type_t update_type, int options);
+
+/**
+ * This function add a watch callback
+ *
+ * @param      watchevent      [in]    The session type to be watched
+ * @param      watchstate      [in]    The session state of the session type of first argument to be watched
+ * @param      callback        [in]    The callback which will be called when the watched session state was activated
+ * @param      user_param      [in]    The user param passed from the callback registration function
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @see
+ * @since
+ */
+int mm_session_add_watch_callback(int watchevent, int watchstate, watch_callback_fn callback, void* user_param);
+
+/**
+ * This function removes a watch callback corresponding with two arguments
+ *
+ * @param      watchevent      [in]    The session type to be removed
+ * @param      watchstate      [in]    The session state to be removed
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @see
+ * @since
+ */
+int mm_session_remove_watch_callback(int watchevent, int watchstate);
+
+/**
+ * This function initialize resumption of other ASM handles which were paused by this session
+ * It can be used only when call series or voice recognition session is set
+ *
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ */
+int mm_session_reset_resumption_info(void);
 
 /**
        @}
index 506f451..4cbe223 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * libmm-session
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,39 +36,42 @@ extern "C" {
 
 #include <mm_session.h>
 
-/**
-  * This enumeration defines session types for internal usage.
-  */
-enum MMSessionTypePrivate{
-       MM_SESSION_TYPE_ALARM = 2,
-       MM_SESSION_TYPE_EMERGENCY,
-       MM_SESSION_TYPE_NOTIFY,
-       MM_SESSION_TYPE_CALL,
-       MM_SESSION_TYPE_VIDEOCALL,
-       MM_SESSION_TYPE_RICH_CALL,
-       MM_SESSION_PRIVATE_TYPE_NUM
-};
-
 typedef enum {
        MM_SUBSESSION_TYPE_VOICE = 0,
        MM_SUBSESSION_TYPE_RINGTONE,
-       MM_SUBSESSION_TYPE_MEDIA
+       MM_SUBSESSION_TYPE_MEDIA,
+       MM_SUBSESSION_TYPE_INIT,
+       MM_SUBSESSION_TYPE_VR_NORMAL,
+       MM_SUBSESSION_TYPE_VR_DRIVE,
+       MM_SUBSESSION_TYPE_RECORD_STEREO,
+       MM_SUBSESSION_TYPE_RECORD_MONO,
+       MM_SUBSESSION_TYPE_NUM
 } mm_subsession_t;
 
+typedef enum {
+       MM_SUBSESSION_OPTION_NONE = 0,
+       MM_SUBSESSION_OPTION_NUM
+       /* NOTE : Do not exceed 15, because of using mm_subsession_option_priv_t type with it internally */
+} mm_subsession_option_t;
+
+typedef enum {
+       MM_SESSION_SUB_TYPE_NONE = 0,
+       MM_SESSION_SUB_TYPE_SHARE,
+       MM_SESSION_SUB_TYPE_EXCLUSIVE
+} mm_session_sub_t;
+
+
 /**
- * This function delete session type information to system
+ * This function delete session information to system
  *
  * @param      app_pid [in] Application pid (if -1, use caller process)
  * @return     This function returns MM_ERROR_NONE on success, or negative value
  *                     with error code.
  * @remark     This function is only for internal implementation do not use this at application
- *                     Session type is unique for each application.
- *                     if application want to change session type, Finish session first and Init again
- * @see                _mm_session_util_write_type _mm_session_util_read_type
+ * @see                _mm_session_util_write_type _mm_session_util_read_type _mm_session_util_write_information _mm_session_util_read_information
  * @since
  */
-int _mm_session_util_delete_type(int app_pid);
-
+int _mm_session_util_delete_information(int app_pid);
 
 
 /**
@@ -82,7 +85,7 @@ int _mm_session_util_delete_type(int app_pid);
  * @remark     This function is only for internal implementation do not use this at application
  *                     Session type is unique for each application.
  *                     if application want to change session type, Finish session first and Init again
- * @see                _mm_session_util_delete_type _mm_session_util_read_type
+ * @see                _mm_session_util_delete_information _mm_session_util_read_type
  * @since
  */
 int _mm_session_util_write_type(int app_pid, int sessiontype);
@@ -98,15 +101,49 @@ int _mm_session_util_write_type(int app_pid, int sessiontype);
  *                     with error code.
  * @remark     Session type is unique for each application.
  *                     if application want to change session type, Finish session first and Init again
- * @see                _mm_session_util_write_type _mm_session_util_delete_type
+ * @see                _mm_session_util_write_type _mm_session_util_delete_information
  * @since
  */
 int _mm_session_util_read_type(int app_pid, int *sessiontype);
 
+
+/**
+ * This function write session information to system
+ *
+ * @param      app_pid [in] Application pid (if -1, use caller process)
+ * @param      session_type    [in] Multimedia Session type
+ * @param      flags   [in] Multimedia Session options
+ *
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @remark     This function is only for internal implementation do not use this at application
+ *                     Session type and Session option are unique for each application.
+ * @see                _mm_session_util_delete_information _mm_session_util_read_information
+ * @since
+ */
+int _mm_session_util_write_information(int app_pid, int session_type, int flags);
+
+
+/**
+ * This function read session information from system
+ *
+ * @param      app_pid [in] Application pid (if -1, use caller process)
+ * @param      sessiontype     [out] Multimedia Session type
+ * @param      flags   [out] Multimedia Session options
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @remark     Session type is unique for each application.
+ * @see                _mm_session_util_write_information _mm_session_util_delete_information
+ * @since
+ */
+int _mm_session_util_read_information(int app_pid, int *session_type, int *flags);
+
+
 /**
  * This function set sub-session type
  *
  * @param      subsession [in] subsession type
+ * @param      option  [in] option of subsession type
  *
  * @return     This function returns MM_ERROR_NONE on success, or negative value
  *                     with error code.
@@ -115,7 +152,7 @@ int _mm_session_util_read_type(int app_pid, int *sessiontype);
  * @see                mm_session_get_subsession
  * @since
  */
-int mm_session_set_subsession (mm_subsession_t subsession);
+int mm_session_set_subsession (mm_subsession_t subsession, mm_subsession_option_t option);
 
 /**
  * This function get current sub-session type
@@ -131,6 +168,34 @@ int mm_session_set_subsession (mm_subsession_t subsession);
  */
 int mm_session_get_subsession (mm_subsession_t *subsession);
 
+/**
+ * This function set sub-event type
+ *
+ * @param      subevent [in] subevent type
+ *
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @remark     This function is only for internal implementation do not use this at application
+ *                     Session type is unique for each application.
+ * @see                mm_session_get_subevent
+ * @since
+ */
+int mm_session_set_subevent (mm_session_sub_t subevent);
+
+/**
+ * This function get current sub-event type
+ *
+ * @param      subevent [out] subevent type
+ *
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ * @remark     This function is only for internal implementation do not use this at application
+ *                     Session type is unique for each application.
+ * @see                mm_session_set_subsevnt
+ * @since
+ */
+int mm_session_get_subevent (mm_session_sub_t *subevent);
+
 #ifdef __cplusplus
 }
 #endif