4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
24 #include <sys/types.h>
27 #include <mm_session_private.h>
31 #include <audio-session-manager.h>
35 #define EXPORT_API __attribute__((__visibility__("default")))
36 #define MAX_FILE_LENGTH 256
38 #define TRY_LOCK(x, x_ret) \
40 x_ret = pthread_mutex_trylock(&(x));\
42 debug_warning("Mutex trylock failed, (0x%x)",x_ret);\
47 if(pthread_mutex_lock(&(x)) != 0) {\
48 debug_error("Mutex lock error");\
53 if(pthread_mutex_unlock(&(x)) != 0) {\
54 debug_error("Mutex unlock error");\
59 if(pthread_mutex_destroy(&(x)) != 0) {\
60 debug_error("Mutex destroy error");\
65 session_callback_fn fn;
68 session_event_t event;
74 session_watch_event_t event;
75 session_watch_state_t state;
78 int g_asm_handle = -1;
79 int g_session_type = -1;
80 int g_monitor_asm_handle = -1;
81 session_monitor_t g_monitor_data;
82 session_watch_t g_watch_data;
84 pthread_mutex_t g_mutex_monitor = PTHREAD_MUTEX_INITIALIZER;
86 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);
87 ASM_cb_result_t asm_watch_callback(int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, void* cb_data);
88 static session_event_t _translate_from_event_src_to_mm_session(ASM_event_sources_t event_src);
89 static session_watch_event_t _translate_from_asm_event_to_mm_session(ASM_sound_events_t sound_event);
90 static ASM_sound_events_t _translate_from_mm_session_to_asm_event(session_watch_event_t watch_event);
91 static ASM_sound_states_t _translate_from_mm_session_to_asm_state(session_watch_state_t watch_state);
95 int mm_session_init(int sessiontype)
98 return mm_session_init_ex(sessiontype, NULL, NULL);
103 int mm_session_init_ex(int sessiontype, session_callback_fn callback, void* user_param)
106 int result = MM_ERROR_NONE;
108 bool do_not_update_session_info = false;
109 pthread_mutex_init(&g_mutex_monitor, NULL);
111 debug_log("type : %d", sessiontype);
113 if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
114 debug_error("Invalid argument %d",sessiontype);
115 return MM_ERROR_INVALID_ARGUMENT;
118 result = _mm_session_util_read_type(-1, <ype);
119 if (MM_ERROR_INVALID_HANDLE != result) {
120 if ((ltype == MM_SESSION_TYPE_MEDIA_RECORD) && sessiontype == MM_SESSION_TYPE_MEDIA) {
121 /* already set by mm-camcorder, mm-sound(pcm in), keep going */
122 do_not_update_session_info = true;
124 debug_error("Session already initialized. Please finish current session first");
125 return MM_ERROR_POLICY_DUPLICATED;
129 /* Monitor Callback */
130 if (NULL == callback) {
131 debug_warning("Null callback function");
133 if (sessiontype != MM_SESSION_TYPE_RECORD_AUDIO &&
134 sessiontype != MM_SESSION_TYPE_RECORD_VIDEO ) {
135 g_monitor_data.fn = callback;
136 g_monitor_data.data = user_param;
137 LOCK(g_mutex_monitor);
138 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)) {
139 debug_error("Can not register monitor");
140 UNLOCK(g_mutex_monitor);
141 return MM_ERROR_INVALID_HANDLE;
143 UNLOCK(g_mutex_monitor);
147 /* Register here for call session types */
148 if (sessiontype == MM_SESSION_TYPE_CALL) {
149 if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_CALL, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
150 goto REGISTER_FAILURE;
152 } else if (sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
153 if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_VIDEOCALL, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_CAMERA|ASM_RESOURCE_VIDEO_OVERLAY, &error)) {
154 goto REGISTER_FAILURE;
156 } else if (sessiontype == MM_SESSION_TYPE_VOIP) {
157 if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_VOIP, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
158 goto REGISTER_FAILURE;
161 /* Register here for advanced session types (using asm_sub_event) */
162 else if (sessiontype == MM_SESSION_TYPE_VOICE_RECOGNITION) {
163 if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_VOICE_RECOGNITION, ASM_STATE_NONE, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
164 goto REGISTER_FAILURE;
166 } else if (sessiontype == MM_SESSION_TYPE_RECORD_AUDIO) {
167 if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_MMCAMCORDER_AUDIO, ASM_STATE_NONE, NULL, NULL, ASM_RESOURCE_NONE, &error)) {
168 goto REGISTER_FAILURE;
170 } else if (sessiontype == MM_SESSION_TYPE_RECORD_VIDEO) {
171 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)) {
172 goto REGISTER_FAILURE;
176 g_session_type = sessiontype;
178 if (!do_not_update_session_info) {
179 result = _mm_session_util_write_type(-1, sessiontype);
180 if (MM_ERROR_NONE != result) {
181 debug_error("Write type failed");
182 if (sessiontype == MM_SESSION_TYPE_CALL) {
183 ASM_unregister_sound(g_asm_handle, ASM_EVENT_CALL, &error);
184 } else if (sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
185 ASM_unregister_sound(g_asm_handle, ASM_EVENT_VIDEOCALL, &error);
186 } else if (sessiontype == MM_SESSION_TYPE_VOIP) {
187 ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOIP, &error);
188 } else if (sessiontype == MM_SESSION_TYPE_VOICE_RECOGNITION) {
189 ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOICE_RECOGNITION, &error);
190 } else if (sessiontype == MM_SESSION_TYPE_RECORD_AUDIO) {
191 ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_AUDIO, &error);
192 } else if (sessiontype == MM_SESSION_TYPE_RECORD_VIDEO) {
193 ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_VIDEO, &error);
195 LOCK(g_mutex_monitor);
196 ASM_unregister_sound(g_monitor_asm_handle, ASM_EVENT_MONITOR, &error);
197 UNLOCK(g_mutex_monitor);
207 return MM_ERROR_NONE;
210 debug_error("failed to ASM_register_sound(), sessiontype(%d), error(0x%x)", sessiontype, error);
212 case ERR_ASM_POLICY_CANNOT_PLAY:
213 return MM_ERROR_POLICY_BLOCKED;
214 case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
215 return MM_ERROR_POLICY_BLOCKED_BY_CALL;
216 case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
217 return MM_ERROR_POLICY_BLOCKED_BY_ALARM;
221 return MM_ERROR_INVALID_HANDLE;
225 int mm_session_update_option(session_update_type_t update_type, int options)
228 int result = MM_ERROR_NONE;
232 debug_log("update_type: %d(0:Add, 1:Remove), options: %x", update_type, options);
234 if (update_type < 0 || update_type >= MM_SESSION_UPDATE_TYPE_NUM) {
235 debug_error("Invalid update_type value(%d)", update_type);
236 return MM_ERROR_INVALID_ARGUMENT;
239 debug_error("Invalid options value(%x)", options);
240 return MM_ERROR_INVALID_ARGUMENT;
243 result = _mm_session_util_read_information(-1, <ype, &loption);
245 debug_error("failed to _mm_session_util_read_information(), ret(%x)", result);
248 debug_log("[current] session_type: %d, session_option: %x", ltype, loption);
250 if (update_type == MM_SESSION_UPDATE_TYPE_ADD) {
252 } else if (update_type == MM_SESSION_UPDATE_TYPE_REMOVE) {
256 result = _mm_session_util_write_information(-1, ltype, loption);
258 debug_error("failed to _mm_session_util_write_information(), ret(%x)", result);
262 debug_log("[updated] session_type: %d, session_option: %x", ltype, loption);
265 return MM_ERROR_NONE;
269 int mm_session_add_watch_callback(int watchevent, int watchstate, watch_callback_fn callback, void* user_param)
271 int result = MM_ERROR_NONE;
277 result = _mm_session_util_read_type(-1, &sessiontype);
279 debug_error("failed to _mm_session_util_read_type(), result(%d), maybe session is not created", result);
282 debug_log("type : %d", sessiontype);
284 if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
285 debug_error("Invalid session type %d", sessiontype);
286 return MM_ERROR_INVALID_ARGUMENT;
289 if (watchevent < MM_SESSION_WATCH_EVENT_CALL || watchevent >= MM_SESSION_WATCH_EVENT_NUM) {
290 debug_error("Invalid watch event %d", watchevent);
291 return MM_ERROR_INVALID_ARGUMENT;
294 if (watchstate < MM_SESSION_WATCH_STATE_STOP || watchstate >= MM_SESSION_WATCH_STATE_NUM) {
295 debug_error("Invalid watch state %d", watchstate);
296 return MM_ERROR_INVALID_ARGUMENT;
299 /* Register a watch callback */
300 if (NULL == callback) {
301 debug_error("Null callback function");
303 g_watch_data.fn = callback;
304 g_watch_data.data = user_param;
305 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)) {
306 debug_error("Could not register a watcher(event:%d, state:%d), error(0x%x)", watchevent, watchstate, error);
307 return MM_ERROR_INVALID_HANDLE;
317 int mm_session_get_current_type(int *sessiontype)
319 int result = MM_ERROR_NONE;
324 if (sessiontype == NULL) {
325 debug_error("input argument is NULL\n");
326 return MM_ERROR_INVALID_ARGUMENT;
329 result = _mm_session_util_read_type(-1, <ype);
330 if (result == MM_ERROR_NONE) {
331 debug_log("Current process session type = [%d]\n", ltype);
332 *sessiontype = ltype;
334 debug_error("failed to get current process session type!!\n");
343 int mm_session_get_current_information(int *session_type, int *session_options)
345 int result = MM_ERROR_NONE;
351 if (session_type == NULL) {
352 debug_error("input argument is NULL\n");
353 return MM_ERROR_INVALID_ARGUMENT;
356 result = _mm_session_util_read_information(-1, <ype, &loption);
357 if (result == MM_ERROR_NONE) {
358 debug_log("Current process session type = [%d], options = [%x]\n", ltype, loption);
359 *session_type = ltype;
360 *session_options = loption;
362 debug_error("failed to get current process session type, option!!\n");
371 int mm_session_finish(void)
374 int result = MM_ERROR_NONE;
375 int sessiontype = MM_SESSION_TYPE_MEDIA;
376 ASM_sound_states_t state = ASM_STATE_NONE;
380 result = _mm_session_util_read_type(-1, &sessiontype);
381 if (MM_ERROR_NONE != result) {
382 debug_error("Can not read current type");
383 DESTROY(g_mutex_monitor);
387 /* Unregister call session type here */
388 if (sessiontype == MM_SESSION_TYPE_CALL) {
389 if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_CALL, &error)) {
392 } else if (sessiontype == MM_SESSION_TYPE_VIDEOCALL) {
393 if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_VIDEOCALL, &error)) {
396 } else if (sessiontype == MM_SESSION_TYPE_VOIP) {
397 if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOIP, &error)) {
401 /* Unregister advanced session type here */
402 else if (sessiontype == MM_SESSION_TYPE_VOICE_RECOGNITION) {
403 if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_VOICE_RECOGNITION, &error)) {
406 } else if (sessiontype == MM_SESSION_TYPE_RECORD_AUDIO) {
407 if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_AUDIO, &error)) {
410 } else if (sessiontype == MM_SESSION_TYPE_RECORD_VIDEO) {
411 if (!ASM_unregister_sound(g_asm_handle, ASM_EVENT_MMCAMCORDER_VIDEO, &error)) {
415 if (g_asm_handle != -1) {
420 /* Check monitor handle */
421 TRY_LOCK(g_mutex_monitor, error);
423 if(g_monitor_asm_handle != -1) {
424 if(!ASM_get_process_session_state(g_monitor_asm_handle, &state, &error)) {
425 debug_error("[%s] Can not get process status", __func__);
426 UNLOCK(g_mutex_monitor);
427 DESTROY(g_mutex_monitor);
428 return MM_ERROR_POLICY_INTERNAL;
433 case ASM_STATE_PLAYING:
434 case ASM_STATE_WAITING:
436 case ASM_STATE_PAUSE:
437 debug_error("[%s] MSL instance still alive", __func__);
438 UNLOCK(g_mutex_monitor);
439 DESTROY(g_mutex_monitor);
440 return MM_ERROR_POLICY_BLOCKED;
443 /* Unregister monitor */
444 if(!ASM_unregister_sound(g_monitor_asm_handle, ASM_EVENT_MONITOR, &error)) {
445 debug_error("ASM unregister monitor failed");
446 UNLOCK(g_mutex_monitor);
449 debug_log("ASM unregister monitor success");
450 g_monitor_asm_handle = -1;
451 g_monitor_data.fn = NULL;
452 g_monitor_data.data = NULL;
455 UNLOCK(g_mutex_monitor);
456 DESTROY(g_mutex_monitor);
459 result = _mm_session_util_delete_information(-1);
460 if(result != MM_ERROR_NONE)
465 return MM_ERROR_NONE;
468 DESTROY(g_mutex_monitor);
469 debug_error("failed to ASM_unregister_sound(), sessiontype(%d)", sessiontype);
470 return MM_ERROR_INVALID_HANDLE;
474 int mm_session_remove_watch_callback(int watchevent, int watchstate)
476 int result = MM_ERROR_NONE;
482 result = _mm_session_util_read_type(-1, &sessiontype);
484 debug_error("failed to _mm_session_util_read_type(), result(%d), maybe session is not created", result);
487 debug_log("type : %d", sessiontype);
489 if(sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
490 debug_error("Invalid session type %d", sessiontype);
491 return MM_ERROR_INVALID_ARGUMENT;
494 if(watchevent < MM_SESSION_WATCH_EVENT_CALL || watchevent >= MM_SESSION_WATCH_EVENT_NUM) {
495 debug_error("Invalid watch event %d", watchevent);
496 return MM_ERROR_INVALID_ARGUMENT;
499 if(watchstate < MM_SESSION_WATCH_STATE_STOP || watchstate >= MM_SESSION_WATCH_STATE_NUM) {
500 debug_error("Invalid watch state %d", watchstate);
501 return MM_ERROR_INVALID_ARGUMENT;
504 /* Unregister a watch callback */
505 if(!ASM_unset_watch_session (_translate_from_mm_session_to_asm_event(watchevent), _translate_from_mm_session_to_asm_state(watchstate), &error)) {
506 debug_error("Could not unregister a watcher(event:%d, state:%d), error(0x%x)", watchevent, watchstate, error);
507 return MM_ERROR_INVALID_HANDLE;
509 g_watch_data.fn = NULL;
510 g_watch_data.data = NULL;
519 int mm_session_set_subsession(mm_subsession_t subsession, mm_subsession_option_t option)
526 if (g_asm_handle == -1) {
527 debug_error ("call session is not started...\n");
528 return MM_ERROR_INVALID_HANDLE;
530 if (g_session_type == -1 || g_session_type < MM_SESSION_TYPE_CALL || g_session_type >= MM_SESSION_TYPE_NUM ) {
531 debug_error ("session type is null, or out of bound(%d)\n", g_session_type);
532 return MM_ERROR_INVALID_HANDLE;
535 if (subsession >= MM_SUBSESSION_TYPE_VOICE && subsession <= MM_SUBSESSION_TYPE_MEDIA) {
536 if (g_session_type < MM_SESSION_TYPE_CALL || g_session_type > MM_SESSION_TYPE_VOIP) {
537 debug_error ("Not support this subsession(%d) of CALL session_type(%d)\n", subsession, g_session_type);
538 return MM_ERROR_INVALID_HANDLE;
540 } else if (subsession == MM_SUBSESSION_TYPE_INIT) {
541 if (g_session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
542 g_session_type != MM_SESSION_TYPE_RECORD_AUDIO &&
543 g_session_type != MM_SESSION_TYPE_RECORD_VIDEO) {
544 debug_error ("Not support this subsession(%d) of the session_type(%d)\n", subsession, g_session_type);
545 return MM_ERROR_INVALID_HANDLE;
547 } else if (subsession == MM_SUBSESSION_TYPE_RECORD_STEREO ||
548 subsession == MM_SUBSESSION_TYPE_RECORD_MONO) {
549 if (g_session_type < MM_SESSION_TYPE_RECORD_AUDIO || g_session_type > MM_SESSION_TYPE_RECORD_VIDEO) {
550 debug_error ("Not support this subsession(%d) of the session_type(%d)\n", subsession, g_session_type);
551 return MM_ERROR_INVALID_HANDLE;
555 if(option < MM_SUBSESSION_OPTION_NONE || option >= MM_SUBSESSION_OPTION_NUM) {
556 debug_error ("option(%d) is not valid\n", option);
557 return MM_ERROR_INVALID_ARGUMENT;
560 ret = ASM_set_subsession (g_asm_handle, (ASM_sound_sub_sessions_t)subsession, option, &error);
562 debug_error("ASM_set_subsession() failed, Set subsession to [%d] failed 0x%X\n\n", subsession, error);
563 return MM_ERROR_SOUND_INTERNAL;
568 return MM_ERROR_NONE;
572 int mm_session_get_subsession(mm_subsession_t *subsession)
579 if(g_asm_handle == -1) {
580 debug_error ("call session is not started...\n");
581 return MM_ERROR_INVALID_HANDLE;
583 if(g_session_type == -1 || g_session_type < MM_SESSION_TYPE_CALL || g_session_type >= MM_SESSION_TYPE_NUM ) {
584 debug_error ("Not support this session_type(%d)\n", g_session_type);
585 return MM_ERROR_INVALID_HANDLE;
588 ret = ASM_get_subsession (g_asm_handle, (ASM_sound_sub_sessions_t*)subsession, &error);
590 debug_error("ASM_get_subsession() failed 0x%X\n\n", error);
591 return MM_ERROR_SOUND_INTERNAL;
594 debug_log("ASM_get_subsession returned [%d]\n", *subsession);
597 return MM_ERROR_NONE;
601 int mm_session_set_subevent(mm_session_sub_t subevent)
608 if(g_asm_handle == -1) {
609 debug_error ("session is not started...\n");
610 return MM_ERROR_INVALID_HANDLE;
612 if(g_session_type == -1 || g_session_type < MM_SESSION_TYPE_VOICE_RECOGNITION || g_session_type >= MM_SESSION_TYPE_NUM ) {
613 debug_error ("not support this session_type(%d)\n", g_session_type);
614 return MM_ERROR_INVALID_ARGUMENT;
617 ret = ASM_set_subevent (g_asm_handle, (ASM_sound_sub_events_t)subevent, &error);
619 debug_error("ASM_set_subevent() failed, Set subevent to [%d] failed 0x%X\n\n", subevent, error);
621 case ERR_ASM_POLICY_CANNOT_PLAY:
622 case ERR_ASM_POLICY_CANNOT_PLAY_BY_PROFILE:
623 case ERR_ASM_POLICY_CANNOT_PLAY_BY_CUSTOM:
624 return MM_ERROR_POLICY_BLOCKED;
625 case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
626 return MM_ERROR_POLICY_BLOCKED_BY_CALL;
627 case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
628 return MM_ERROR_POLICY_BLOCKED_BY_ALARM;
630 return MM_ERROR_SOUND_INTERNAL;
635 return MM_ERROR_NONE;
639 int mm_session_get_subevent(mm_session_sub_t *subevent)
645 if(g_asm_handle == -1) {
646 debug_error ("session is not started...\n");
647 return MM_ERROR_INVALID_HANDLE;
649 if(g_session_type == -1 || g_session_type < MM_SESSION_TYPE_VOICE_RECOGNITION || g_session_type >= MM_SESSION_TYPE_NUM ) {
650 debug_error ("not support this session_type(%d)\n", g_session_type);
651 return MM_ERROR_INVALID_ARGUMENT;
654 ret = ASM_get_subevent (g_asm_handle, (ASM_sound_sub_events_t*)subevent, &error);
656 debug_error("ASM_get_subevent() failed 0x%X\n\n", error);
657 return MM_ERROR_SOUND_INTERNAL;
660 debug_log("ASM_get_subevent returned [%d]\n", *subevent);
663 return MM_ERROR_NONE;
667 int mm_session_reset_resumption_info(void)
674 if(g_asm_handle == -1) {
675 debug_error ("call series or voice recognition session is not started...\n");
676 return MM_ERROR_INVALID_HANDLE;
678 if(g_session_type == -1 || g_session_type < MM_SESSION_TYPE_MEDIA || g_session_type >= MM_SESSION_TYPE_NUM ) {
679 debug_error ("not support this session_type(%d)\n", g_session_type);
680 return MM_ERROR_INVALID_ARGUMENT;
682 ret = ASM_reset_resumption_info (g_asm_handle, &error);
684 debug_error("ASM_reset_resumption_info() failed 0x%X\n\n", error);
685 return MM_ERROR_SOUND_INTERNAL;
690 return MM_ERROR_NONE;
694 int _mm_session_util_delete_information(int app_pid)
697 char filename[MAX_FILE_LENGTH];
702 mypid = (pid_t)app_pid;
704 ////// DELETE SESSION TYPE /////////
705 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
706 if(-1 == unlink(filename))
707 return MM_ERROR_FILE_NOT_FOUND;
708 ////// DELETE SESSION TYPE /////////
710 return MM_ERROR_NONE;
714 int _mm_session_util_write_type(int app_pid, int sessiontype)
718 char filename[MAX_FILE_LENGTH];
720 if(sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
721 return MM_ERROR_INVALID_ARGUMENT;
727 mypid = (pid_t)app_pid;
729 ////// WRITE SESSION TYPE /////////
730 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
731 fd = open(filename, O_WRONLY | O_CREAT, 0644 );
733 debug_error("open() failed with %d",errno);
734 return MM_ERROR_FILE_WRITE;
736 sessiontype = sessiontype << 16;
737 write(fd, &sessiontype, sizeof(int));
738 if(0 > fchmod (fd, 00777)) {
739 debug_error("fchmod failed with %d", errno);
741 debug_warning("write sessiontype(%d) to /tmp/mm_session_%d", sessiontype >> 16, mypid);
744 ////// WRITE SESSION TYPE /////////
746 return MM_ERROR_NONE;
750 int _mm_session_util_read_type(int app_pid, int *sessiontype)
754 char filename[MAX_FILE_LENGTH];
758 if(sessiontype == NULL)
759 return MM_ERROR_INVALID_ARGUMENT;
764 mypid = (pid_t)app_pid;
766 ////// READ SESSION TYPE /////////
767 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
768 fd = open(filename, O_RDONLY);
770 return MM_ERROR_INVALID_HANDLE;
772 read(fd, sessiontype, sizeof(int));
773 *sessiontype = *sessiontype >> 16;
774 debug_warning("read sessiontype(%d) from /tmp/mm_session_%d", *sessiontype, mypid);
776 ////// READ SESSION TYPE /////////
780 return MM_ERROR_NONE;
784 int _mm_session_util_write_information(int app_pid, int session_type, int flags)
788 char filename[MAX_FILE_LENGTH];
791 if(session_type < MM_SESSION_TYPE_MEDIA || session_type >= MM_SESSION_TYPE_NUM) {
792 return MM_ERROR_INVALID_ARGUMENT;
795 return MM_ERROR_INVALID_ARGUMENT;
801 mypid = (pid_t)app_pid;
804 ////// WRITE SESSION INFO /////////
805 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
806 fd = open(filename, O_WRONLY | O_CREAT, 0644 );
808 debug_error("open() failed with %d",errno);
809 return MM_ERROR_FILE_WRITE;
812 result_info = (flags) | (session_type << 16);
813 write(fd, &result_info, sizeof(int));
814 if(0 > fchmod (fd, 00777)) {
815 debug_error("fchmod failed with %d", errno);
817 debug_warning("write session information(%x) to /tmp/mm_session_%d", result_info, mypid);
820 ////// WRITE SESSION INFO /////////
822 return MM_ERROR_NONE;
826 int _mm_session_util_read_information(int app_pid, int *session_type, int *flags)
830 char filename[MAX_FILE_LENGTH];
835 if(session_type == NULL || flags == NULL) {
836 return MM_ERROR_INVALID_ARGUMENT;
842 mypid = (pid_t)app_pid;
845 ////// READ SESSION INFO /////////
846 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
847 fd = open(filename, O_RDONLY);
849 return MM_ERROR_INVALID_HANDLE;
851 read(fd, &result_info, sizeof(int));
852 *session_type = result_info >> 16;
853 *flags = result_info & 0x0000ffff;
855 debug_warning("read session_type(%d), session_option(%x) from /tmp/mm_session_%d", *session_type, *flags, mypid);
857 ////// READ SESSION INFO /////////
861 return MM_ERROR_NONE;
864 gboolean _asm_monitor_cb(gpointer *data)
866 session_monitor_t* monitor = (session_monitor_t*)data;
871 monitor->fn(monitor->msg, monitor->event, monitor->data);
879 gboolean _asm_watch_cb(gpointer *data)
881 session_watch_t* watch_h = (session_watch_t*)data;
886 watch_h->fn(watch_h->event, watch_h->state, watch_h->data);
894 static session_event_t _translate_from_event_src_to_mm_session(ASM_event_sources_t event_src)
898 case ASM_EVENT_SOURCE_CALL_START:
899 case ASM_EVENT_SOURCE_CALL_END:
900 return MM_SESSION_EVENT_CALL;
902 case ASM_EVENT_SOURCE_EARJACK_UNPLUG:
903 return MM_SESSION_EVENT_EARJACK_UNPLUG;
905 case ASM_EVENT_SOURCE_RESOURCE_CONFLICT:
906 return MM_SESSION_EVENT_RESOURCE_CONFLICT;
908 case ASM_EVENT_SOURCE_ALARM_START:
909 case ASM_EVENT_SOURCE_ALARM_END:
910 return MM_SESSION_EVENT_ALARM;
912 case ASM_EVENT_SOURCE_NOTIFY_START:
913 case ASM_EVENT_SOURCE_NOTIFY_END:
914 return MM_SESSION_EVENT_NOTIFICATION;
916 case ASM_EVENT_SOURCE_EMERGENCY_START:
917 case ASM_EVENT_SOURCE_EMERGENCY_END:
918 return MM_SESSION_EVENT_EMERGENCY;
920 case ASM_EVENT_SOURCE_MEDIA:
921 case ASM_EVENT_SOURCE_OTHER_PLAYER_APP:
923 return MM_SESSION_EVENT_MEDIA;
927 static session_watch_event_t _translate_from_asm_event_to_mm_session(ASM_sound_events_t sound_event)
932 return MM_SESSION_WATCH_EVENT_CALL;
933 case ASM_EVENT_VIDEOCALL:
934 return MM_SESSION_WATCH_EVENT_VIDEO_CALL;
935 case ASM_EVENT_ALARM:
936 return MM_SESSION_WATCH_EVENT_ALARM;
938 return MM_SESSION_WATCH_EVENT_IGNORE;
942 static ASM_sound_events_t _translate_from_mm_session_to_asm_event(session_watch_event_t watch_event)
946 case MM_SESSION_WATCH_EVENT_CALL:
947 return ASM_EVENT_CALL;
948 case MM_SESSION_WATCH_EVENT_VIDEO_CALL:
949 return ASM_EVENT_VIDEOCALL;
950 case MM_SESSION_WATCH_EVENT_ALARM:
951 return ASM_EVENT_ALARM;
953 return ASM_EVENT_NONE;
957 static ASM_sound_states_t _translate_from_mm_session_to_asm_state(session_watch_state_t watch_state)
961 case MM_SESSION_WATCH_STATE_STOP:
962 return ASM_STATE_STOP;
963 case MM_SESSION_WATCH_STATE_PLAYING:
964 return ASM_STATE_PLAYING;
966 return ASM_STATE_NONE;
971 asm_monitor_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
973 ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
974 session_monitor_t *monitor = (session_monitor_t*)cb_data;
976 debug_log("monitor callback called for handle %d, event_src %d", handle, event_src);
978 debug_log("monitor instance is null\n");
979 return ASM_CB_RES_IGNORE;
984 case ASM_COMMAND_STOP:
985 case ASM_COMMAND_PAUSE:
986 //call session_callback_fn for stop here
988 monitor->msg = MM_SESSION_MSG_STOP;
989 monitor->event = _translate_from_event_src_to_mm_session (event_src);
990 g_idle_add((GSourceFunc)_asm_monitor_cb, (gpointer)monitor);
992 cb_res = (command == ASM_COMMAND_STOP)? ASM_CB_RES_STOP : ASM_CB_RES_PAUSE;
995 case ASM_COMMAND_RESUME:
996 case ASM_COMMAND_PLAY:
997 //call session_callback_fn for resume here
999 monitor->msg = MM_SESSION_MSG_RESUME;
1000 monitor->event = _translate_from_event_src_to_mm_session (event_src);
1001 g_idle_add((GSourceFunc)_asm_monitor_cb, (gpointer)monitor);
1003 cb_res = ASM_CB_RES_IGNORE;
1013 asm_watch_callback(int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, void* cb_data)
1015 ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
1016 session_watch_t *watch_handle = (session_watch_t*)cb_data;
1018 debug_log("watch callback called for handle %d, sound_event %d, sound_state %d", handle, sound_event, sound_state);
1020 debug_log("watch_handle instance is null\n");
1021 return ASM_CB_RES_IGNORE;
1024 switch(sound_state) {
1025 case ASM_STATE_PLAYING:
1026 if(watch_handle->fn) {
1027 watch_handle->event = _translate_from_asm_event_to_mm_session(sound_event);
1028 watch_handle->state = MM_SESSION_WATCH_STATE_PLAYING;
1029 if (watch_handle->event == MM_SESSION_WATCH_EVENT_IGNORE) {
1030 cb_res = ASM_CB_RES_IGNORE;
1031 debug_error("sound_event(%d) is not valid..", sound_event);
1033 g_idle_add((GSourceFunc)_asm_watch_cb, (gpointer)watch_handle);
1037 case ASM_STATE_STOP:
1038 if(watch_handle->fn) {
1039 watch_handle->event = _translate_from_asm_event_to_mm_session(sound_event);
1040 watch_handle->state = MM_SESSION_WATCH_STATE_STOP;
1041 if (watch_handle->event == MM_SESSION_WATCH_EVENT_IGNORE) {
1042 debug_error("sound_event(%d) is not valid..", sound_event);
1043 cb_res = ASM_CB_RES_IGNORE;
1045 g_idle_add((GSourceFunc)_asm_watch_cb, (gpointer)watch_handle);
1050 debug_error("sound_state(%d) is not valid..", sound_state);
1051 cb_res = ASM_CB_RES_IGNORE;
1057 __attribute__ ((destructor))
1058 void __mmsession_finalize(void)
1064 TRY_LOCK(g_mutex_monitor, error);
1066 if(g_monitor_asm_handle != -1) {
1067 /* Unregister monitor */
1068 if(!ASM_unregister_sound(g_monitor_asm_handle, ASM_EVENT_MONITOR, &error)) {
1069 debug_error("ASM unregister monitor failed");
1071 debug_log("ASM unregister monitor success");
1072 g_monitor_asm_handle = -1;
1073 g_monitor_data.fn = NULL;
1074 g_monitor_data.data = NULL;
1077 UNLOCK(g_mutex_monitor);
1078 DESTROY(g_mutex_monitor);
1080 _mm_session_util_delete_information(-1);
1085 __attribute__ ((constructor))
1086 void __mmsession_initialize(void)