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>
35 #define EXPORT_API __attribute__((__visibility__("default")))
36 #define MAX_FILE_LENGTH 256
38 int g_session_type = -1;
40 struct sigaction session_int_old_action;
41 struct sigaction session_abrt_old_action;
42 struct sigaction session_segv_old_action;
43 struct sigaction session_term_old_action;
44 struct sigaction session_sys_old_action;
45 struct sigaction session_xcpu_old_action;
48 int mm_session_init(int sessiontype)
50 int result = MM_ERROR_NONE;
52 bool do_not_update_session_info = false;
55 debug_log("type : %d", sessiontype);
57 if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
58 debug_error("Invalid argument %d", sessiontype);
59 return MM_ERROR_INVALID_ARGUMENT;
62 result = _mm_session_util_read_type(-1, <ype);
63 if (MM_ERROR_INVALID_HANDLE != result) {
64 if ((ltype == MM_SESSION_TYPE_MEDIA_RECORD) && sessiontype == MM_SESSION_TYPE_MEDIA) {
65 /* already set by mm-camcorder, mm-sound(pcm in), keep going */
66 do_not_update_session_info = true;
68 debug_error("Session already initialized. Please finish current session first");
69 return MM_ERROR_POLICY_DUPLICATED;
73 g_session_type = sessiontype;
75 if (!do_not_update_session_info) {
76 result = _mm_session_util_write_type(-1, sessiontype);
77 if (MM_ERROR_NONE != result) {
78 debug_error("Write type failed");
90 int mm_session_update_option(session_update_type_t update_type, int options)
92 int result = MM_ERROR_NONE;
96 debug_log("update_type: %d(0:Add, 1:Remove), options: %x", update_type, options);
98 if (update_type < 0 || update_type >= MM_SESSION_UPDATE_TYPE_NUM) {
99 debug_error("Invalid update_type value(%d)", update_type);
100 return MM_ERROR_INVALID_ARGUMENT;
103 debug_error("Invalid options value(%x)", options);
104 return MM_ERROR_INVALID_ARGUMENT;
107 result = _mm_session_util_read_information(-1, <ype, &loption);
109 debug_error("failed to _mm_session_util_read_information(), ret(%x)", result);
112 debug_log("[current] session_type: %d, session_option: %x", ltype, loption);
114 if (update_type == MM_SESSION_UPDATE_TYPE_ADD)
116 else if (update_type == MM_SESSION_UPDATE_TYPE_REMOVE)
119 result = _mm_session_util_write_information(-1, ltype, loption);
121 debug_error("failed to _mm_session_util_write_information(), ret(%x)", result);
125 debug_log("[updated] session_type: %d, session_option: %x", ltype, loption);
128 return MM_ERROR_NONE;
132 int mm_session_get_current_type(int *sessiontype)
134 int result = MM_ERROR_NONE;
139 if (sessiontype == NULL) {
140 debug_error("input argument is NULL\n");
141 return MM_ERROR_INVALID_ARGUMENT;
144 result = _mm_session_util_read_type(-1, <ype);
145 if (result == MM_ERROR_NONE) {
146 debug_log("Current process session type = [%d]\n", ltype);
147 *sessiontype = ltype;
149 debug_error("failed to get current process session type!!\n");
158 int mm_session_get_current_information(int *session_type, int *session_options)
160 int result = MM_ERROR_NONE;
166 if (session_type == NULL) {
167 debug_error("input argument is NULL\n");
168 return MM_ERROR_INVALID_ARGUMENT;
171 result = _mm_session_util_read_information(-1, <ype, &loption);
172 if (result == MM_ERROR_NONE) {
173 debug_log("Current process session type = [%d], options = [%x]\n", ltype, loption);
174 *session_type = ltype;
175 *session_options = loption;
177 debug_error("failed to get current process session type, option!!\n");
186 int mm_session_finish(void)
188 int result = MM_ERROR_NONE;
189 int sessiontype = MM_SESSION_TYPE_MEDIA;
193 result = _mm_session_util_read_type(-1, &sessiontype);
194 if (MM_ERROR_NONE != result) {
195 debug_error("Can not read current type");
199 /* Check monitor handle */
200 result = _mm_session_util_delete_information(-1);
201 if (result != MM_ERROR_NONE)
206 return MM_ERROR_NONE;
210 int _mm_session_util_delete_information(int app_pid)
213 char filename[MAX_FILE_LENGTH];
218 mypid = (pid_t)app_pid;
220 ////// DELETE SESSION TYPE /////////
221 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
222 if (-1 == unlink(filename))
223 return MM_ERROR_FILE_NOT_FOUND;
224 ////// DELETE SESSION TYPE /////////
226 return MM_ERROR_NONE;
230 int _mm_session_util_write_type(int app_pid, int sessiontype)
234 char filename[MAX_FILE_LENGTH];
236 if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM)
237 return MM_ERROR_INVALID_ARGUMENT;
242 mypid = (pid_t)app_pid;
244 ////// WRITE SESSION TYPE /////////
245 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
246 fd = open(filename, O_WRONLY | O_CREAT, 0644);
248 debug_error("open() failed with %d", errno);
249 return MM_ERROR_FILE_WRITE;
251 sessiontype = sessiontype << 16;
252 write(fd, &sessiontype, sizeof(int));
253 if (0 > fchmod(fd, 00777))
254 debug_error("fchmod failed with %d", errno);
256 debug_warning("write sessiontype(%d) to /tmp/mm_session_%d", sessiontype >> 16, mypid);
259 ////// WRITE SESSION TYPE /////////
261 return MM_ERROR_NONE;
265 int _mm_session_util_read_type(int app_pid, int *sessiontype)
269 char filename[MAX_FILE_LENGTH];
270 int result = MM_ERROR_NONE;
274 if (sessiontype == NULL)
275 return MM_ERROR_INVALID_ARGUMENT;
280 mypid = (pid_t)app_pid;
282 ////// READ SESSION TYPE /////////
283 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
284 fd = open(filename, O_RDONLY);
286 return MM_ERROR_INVALID_HANDLE;
288 if (read(fd, sessiontype, sizeof(int)) == sizeof(int)) {
289 *sessiontype = *sessiontype >> 16;
290 debug_warning("read sessiontype(%d) from /tmp/mm_session_%d", *sessiontype, mypid);
292 debug_error("failed to read from %s, errno %d", filename, errno);
293 result = MM_ERROR_INVALID_HANDLE;
297 ////// READ SESSION TYPE /////////
305 int _mm_session_util_write_information(int app_pid, int session_type, int flags)
309 char filename[MAX_FILE_LENGTH];
312 if ((session_type != MM_SESSION_TYPE_REPLACED_BY_STREAM) &&
313 (session_type < MM_SESSION_TYPE_MEDIA || session_type >= MM_SESSION_TYPE_NUM)) {
314 return MM_ERROR_INVALID_ARGUMENT;
317 return MM_ERROR_INVALID_ARGUMENT;
322 mypid = (pid_t)app_pid;
324 ////// WRITE SESSION INFO /////////
325 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
326 fd = open(filename, O_WRONLY | O_CREAT, 0644);
328 debug_error("open() failed with %d", errno);
329 return MM_ERROR_FILE_WRITE;
332 result_info = (flags) | (session_type << 16);
333 write(fd, &result_info, sizeof(int));
334 if (0 > fchmod(fd, 00777))
335 debug_error("fchmod failed with %d", errno);
337 debug_warning("write session information(%x) to /tmp/mm_session_%d", result_info, mypid);
339 ////// WRITE SESSION INFO /////////
341 return MM_ERROR_NONE;
345 int _mm_session_util_read_information(int app_pid, int *session_type, int *flags)
349 char filename[MAX_FILE_LENGTH];
351 int result = MM_ERROR_NONE;
355 if (session_type == NULL || flags == NULL)
356 return MM_ERROR_INVALID_ARGUMENT;
361 mypid = (pid_t)app_pid;
363 ////// READ SESSION INFO /////////
364 snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
365 fd = open(filename, O_RDONLY);
367 return MM_ERROR_INVALID_HANDLE;
368 if (read(fd, &result_info, sizeof(int)) == sizeof(int)) {
369 *session_type = result_info >> 16;
370 *flags = result_info & 0x0000ffff;
371 debug_warning("read session_type(%d), session_option(%x) from /tmp/mm_session_%d", *session_type, *flags, mypid);
373 debug_error("failed to read from %s, errno %d", filename, errno);
374 result = MM_ERROR_INVALID_HANDLE;
378 ////// READ SESSION INFO /////////
385 void __session_signal_handler(int signo, siginfo_t *siginfo, void *context)
387 sigset_t old_mask, all_mask;
389 debug_warning("ENTER, signo(%d), siginfo(%p), context(%p)", signo, siginfo, context);
391 /* signal block -------------- */
392 sigfillset(&all_mask);
393 sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
395 _mm_session_util_delete_information(-1);
397 sigprocmask(SIG_SETMASK, &old_mask, NULL);
398 /* signal unblock ------------ */
402 if (session_int_old_action.sa_sigaction)
403 session_int_old_action.sa_sigaction(signo, siginfo, context);
405 sigaction(signo, &session_int_old_action, NULL);
408 if (session_abrt_old_action.sa_sigaction)
409 session_abrt_old_action.sa_sigaction(signo, siginfo, context);
411 sigaction(signo, &session_abrt_old_action, NULL);
414 if (session_segv_old_action.sa_sigaction)
415 session_segv_old_action.sa_sigaction(signo, siginfo, context);
417 sigaction(signo, &session_segv_old_action, NULL);
420 if (session_term_old_action.sa_sigaction)
421 session_term_old_action.sa_sigaction(signo, siginfo, context);
423 sigaction(signo, &session_term_old_action, NULL);
426 if (session_sys_old_action.sa_sigaction)
427 session_sys_old_action.sa_sigaction(signo, siginfo, context);
429 sigaction(signo, &session_sys_old_action, NULL);
432 if (session_xcpu_old_action.sa_sigaction)
433 session_xcpu_old_action.sa_sigaction(signo, siginfo, context);
435 sigaction(signo, &session_xcpu_old_action, NULL);
441 debug_warning("LEAVE");
446 void mm_session_dotnet_cleanup(int signo)
448 debug_warning("dotnet cleanup [%d]", signo);
449 _mm_session_util_delete_information(-1);
452 static bool _is_dotnet_app(void)
454 char *is_dotnet = NULL;
456 is_dotnet = getenv("DOTNET_APP");
457 if (is_dotnet && atoi(is_dotnet) == 1)
464 __attribute__ ((constructor))
465 void __mmsession_initialize(void)
467 struct sigaction session_action;
472 if (_is_dotnet_app()) {
473 debug_warning("no signal handler for dotnet!!");
477 session_action.sa_sigaction = __session_signal_handler;
478 session_action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
480 sigemptyset(&session_action.sa_mask);
482 sigaction(SIGINT, &session_action, &session_int_old_action);
483 sigaction(SIGABRT, &session_action, &session_abrt_old_action);
484 sigaction(SIGSEGV, &session_action, &session_segv_old_action);
485 sigaction(SIGTERM, &session_action, &session_term_old_action);
486 sigaction(SIGSYS, &session_action, &session_sys_old_action);
487 sigaction(SIGXCPU, &session_action, &session_xcpu_old_action);
492 __attribute__ ((destructor))
493 void __mmsession_finalize(void)
498 _mm_session_util_delete_information(-1);
500 if (_is_dotnet_app()) {
501 debug_warning("no signal handler for dotnet!!");
505 sigaction(SIGINT, &session_int_old_action, NULL);
506 sigaction(SIGABRT, &session_abrt_old_action, NULL);
507 sigaction(SIGSEGV, &session_segv_old_action, NULL);
508 sigaction(SIGTERM, &session_term_old_action, NULL);
509 sigaction(SIGSYS, &session_sys_old_action, NULL);
510 sigaction(SIGXCPU, &session_xcpu_old_action, NULL);