Remove useless macros in configure.ac regarding libmm-log
[platform/core/multimedia/libmm-session.git] / mm_session.c
1 /*
2  * libmm-session
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <mm_session_private.h>
28 #include <mm_error.h>
29 #include <mm_debug.h>
30 #include <errno.h>
31 #include <pthread.h>
32 #include <signal.h>
33
34 #define EXPORT_API __attribute__((__visibility__("default")))
35 #define MAX_FILE_LENGTH 256
36
37 int g_session_type = -1;
38
39 struct sigaction session_int_old_action;
40 struct sigaction session_abrt_old_action;
41 struct sigaction session_segv_old_action;
42 struct sigaction session_term_old_action;
43 struct sigaction session_sys_old_action;
44 struct sigaction session_xcpu_old_action;
45
46 EXPORT_API
47 int mm_session_init(int sessiontype)
48 {
49         int result = MM_ERROR_NONE;
50         int ltype = 0;
51         bool do_not_update_session_info = false;
52
53         debug_fenter();
54         debug_log("type : %d", sessiontype);
55
56         if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
57                 debug_error("Invalid argument %d", sessiontype);
58                 return MM_ERROR_INVALID_ARGUMENT;
59         }
60
61         result = _mm_session_util_read_type(-1, &ltype);
62         if (MM_ERROR_INVALID_HANDLE != result) {
63                 if ((ltype == MM_SESSION_TYPE_MEDIA_RECORD) && sessiontype == MM_SESSION_TYPE_MEDIA) {
64                         /* already set by mm-camcorder, mm-sound(pcm in), keep going */
65                         do_not_update_session_info = true;
66                 } else {
67                         debug_error("Session already initialized. Please finish current session first");
68                         return MM_ERROR_POLICY_DUPLICATED;
69                 }
70         }
71
72         g_session_type = sessiontype;
73
74         if (!do_not_update_session_info) {
75                 result = _mm_session_util_write_type(-1, sessiontype);
76                 if (MM_ERROR_NONE != result) {
77                         debug_error("Write type failed");
78                         g_session_type = -1;
79                         return result;
80                 }
81         }
82
83         debug_fleave();
84
85         return MM_ERROR_NONE;
86 }
87
88 EXPORT_API
89 int mm_session_update_option(session_update_type_t update_type, int options)
90 {
91         int result = MM_ERROR_NONE;
92         int ltype = 0;
93         int loption = 0;
94
95         debug_log("update_type: %d(0:Add, 1:Remove), options: %x", update_type, options);
96
97         if (update_type < 0 || update_type >= MM_SESSION_UPDATE_TYPE_NUM) {
98                 debug_error("Invalid update_type value(%d)", update_type);
99                 return MM_ERROR_INVALID_ARGUMENT;
100         }
101         if (options < 0) {
102                 debug_error("Invalid options value(%x)", options);
103                 return MM_ERROR_INVALID_ARGUMENT;
104         }
105
106         result = _mm_session_util_read_information(-1, &ltype, &loption);
107         if (result) {
108                 debug_error("failed to _mm_session_util_read_information(), ret(%x)", result);
109                 return result;
110         }
111         debug_log("[current] session_type: %d, session_option: %x", ltype, loption);
112
113         if (update_type == MM_SESSION_UPDATE_TYPE_ADD)
114                 loption |= options;
115         else if (update_type == MM_SESSION_UPDATE_TYPE_REMOVE)
116                 loption &= ~options;
117
118         result = _mm_session_util_write_information(-1, ltype, loption);
119         if (result) {
120                 debug_error("failed to _mm_session_util_write_information(), ret(%x)", result);
121                 return result;
122         }
123
124         debug_log("[updated] session_type: %d, session_option: %x", ltype, loption);
125
126
127         return MM_ERROR_NONE;
128 }
129
130 EXPORT_API
131 int mm_session_get_current_type(int *sessiontype)
132 {
133         int result = MM_ERROR_NONE;
134         int ltype = 0;
135
136         debug_fenter();
137
138         if (sessiontype == NULL) {
139                 debug_error("input argument is NULL\n");
140                 return MM_ERROR_INVALID_ARGUMENT;
141         }
142
143         result = _mm_session_util_read_type(-1, &ltype);
144         if (result == MM_ERROR_NONE) {
145                 debug_log("Current process session type = [%d]\n", ltype);
146                 *sessiontype = ltype;
147         } else {
148                 debug_error("failed to get current process session type!!\n");
149         }
150
151         debug_fleave();
152
153         return result;
154 }
155
156 EXPORT_API
157 int mm_session_get_current_information(int *session_type, int *session_options)
158 {
159         int result = MM_ERROR_NONE;
160         int ltype = 0;
161         int loption = 0;
162
163         debug_fenter();
164
165         if (session_type == NULL) {
166                 debug_error("input argument is NULL\n");
167                 return MM_ERROR_INVALID_ARGUMENT;
168         }
169
170         result = _mm_session_util_read_information(-1, &ltype, &loption);
171         if (result == MM_ERROR_NONE) {
172                 debug_log("Current process session type = [%d], options = [%x]\n", ltype, loption);
173                 *session_type = ltype;
174                 *session_options = loption;
175         } else {
176                 debug_error("failed to get current process session type, option!!\n");
177         }
178
179         debug_fleave();
180
181         return result;
182 }
183
184 EXPORT_API
185 int mm_session_finish(void)
186 {
187         int result = MM_ERROR_NONE;
188         int sessiontype = MM_SESSION_TYPE_MEDIA;
189
190         debug_fenter();
191
192         result = _mm_session_util_read_type(-1, &sessiontype);
193         if (MM_ERROR_NONE != result) {
194                 debug_error("Can not read current type");
195                 return result;
196         }
197
198         /* Check monitor handle */
199         result = _mm_session_util_delete_information(-1);
200         if (result != MM_ERROR_NONE)
201                 return result;
202
203         debug_fleave();
204
205         return MM_ERROR_NONE;
206 }
207
208 EXPORT_API
209 int _mm_session_util_delete_information(int app_pid)
210 {
211         pid_t mypid;
212         char filename[MAX_FILE_LENGTH];
213
214         if (app_pid == -1)
215                 mypid = getpid();
216         else
217                 mypid = (pid_t)app_pid;
218
219         ////// DELETE SESSION TYPE /////////
220         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
221         if (-1 ==  unlink(filename))
222                 return MM_ERROR_FILE_NOT_FOUND;
223         ////// DELETE SESSION TYPE /////////
224
225         return MM_ERROR_NONE;
226 }
227
228 EXPORT_API
229 int _mm_session_util_write_type(int app_pid, int sessiontype)
230 {
231         pid_t mypid;
232         int fd = -1;
233         char filename[MAX_FILE_LENGTH];
234
235         if (sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM)
236                 return MM_ERROR_INVALID_ARGUMENT;
237
238         if (app_pid == -1)
239                 mypid = getpid();
240         else
241                 mypid = (pid_t)app_pid;
242
243         ////// WRITE SESSION TYPE /////////
244         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
245         fd = open(filename, O_WRONLY | O_CREAT, 0644);
246         if (fd < 0) {
247                 debug_error("open() failed with %d", errno);
248                 return MM_ERROR_FILE_WRITE;
249         }
250         sessiontype = sessiontype << 16;
251         write(fd, &sessiontype, sizeof(int));
252         if (0 > fchmod(fd, 00777))
253                 debug_error("fchmod failed with %d", errno);
254         else
255                 debug_warning("write sessiontype(%d) to /tmp/mm_session_%d", sessiontype >> 16, mypid);
256
257         close(fd);
258         ////// WRITE SESSION TYPE /////////
259
260         return MM_ERROR_NONE;
261 }
262
263 EXPORT_API
264 int _mm_session_util_read_type(int app_pid, int *sessiontype)
265 {
266         pid_t mypid;
267         int fd = -1;
268         char filename[MAX_FILE_LENGTH];
269
270         debug_fenter();
271
272         if (sessiontype == NULL)
273                 return MM_ERROR_INVALID_ARGUMENT;
274
275         if (app_pid == -1)
276                 mypid = getpid();
277         else
278                 mypid = (pid_t)app_pid;
279
280         ////// READ SESSION TYPE /////////
281         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
282         fd = open(filename, O_RDONLY);
283         if (fd < 0)
284                 return MM_ERROR_INVALID_HANDLE;
285
286         read(fd, sessiontype, sizeof(int));
287         *sessiontype = *sessiontype >> 16;
288         debug_warning("read sessiontype(%d) from /tmp/mm_session_%d", *sessiontype, mypid);
289         close(fd);
290         ////// READ SESSION TYPE /////////
291
292         debug_fleave();
293
294         return MM_ERROR_NONE;
295 }
296
297 EXPORT_API
298 int _mm_session_util_write_information(int app_pid, int session_type, int flags)
299 {
300         pid_t mypid;
301         int fd = -1;
302         char filename[MAX_FILE_LENGTH];
303         int result_info = 0;
304
305         if ((session_type != MM_SESSION_TYPE_REPLACED_BY_STREAM) &&
306             (session_type < MM_SESSION_TYPE_MEDIA || session_type >= MM_SESSION_TYPE_NUM)) {
307                 return MM_ERROR_INVALID_ARGUMENT;
308         }
309         if (flags < 0)
310                 return MM_ERROR_INVALID_ARGUMENT;
311
312         if (app_pid == -1)
313                 mypid = getpid();
314         else
315                 mypid = (pid_t)app_pid;
316
317         ////// WRITE SESSION INFO /////////
318         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
319         fd = open(filename, O_WRONLY | O_CREAT, 0644);
320         if (fd < 0) {
321                 debug_error("open() failed with %d", errno);
322                 return MM_ERROR_FILE_WRITE;
323         }
324
325         result_info = (flags) | (session_type << 16);
326         write(fd, &result_info, sizeof(int));
327         if (0 > fchmod(fd, 00777))
328                 debug_error("fchmod failed with %d", errno);
329         else
330                 debug_warning("write session information(%x) to /tmp/mm_session_%d", result_info, mypid);
331         close(fd);
332         ////// WRITE SESSION INFO /////////
333
334         return MM_ERROR_NONE;
335 }
336
337 EXPORT_API
338 int _mm_session_util_read_information(int app_pid, int *session_type, int *flags)
339 {
340         pid_t mypid;
341         int fd = -1;
342         char filename[MAX_FILE_LENGTH];
343         int result_info = 0;
344
345         debug_fenter();
346
347         if (session_type == NULL || flags == NULL)
348                 return MM_ERROR_INVALID_ARGUMENT;
349
350         if (app_pid == -1)
351                 mypid = getpid();
352         else
353                 mypid = (pid_t)app_pid;
354
355         ////// READ SESSION INFO /////////
356         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d", mypid);
357         fd = open(filename, O_RDONLY);
358         if (fd < 0)
359                 return MM_ERROR_INVALID_HANDLE;
360         read(fd, &result_info, sizeof(int));
361         *session_type = result_info >> 16;
362         *flags = result_info & 0x0000ffff;
363
364         debug_warning("read session_type(%d), session_option(%x) from /tmp/mm_session_%d", *session_type, *flags, mypid);
365         close(fd);
366         ////// READ SESSION INFO /////////
367
368         debug_fleave();
369
370         return MM_ERROR_NONE;
371 }
372
373 void __session_signal_handler(int signo, siginfo_t *siginfo, void *context)
374 {
375         char filename[MAX_FILE_LENGTH];
376         char str_error[256];
377
378         debug_warning("ENTER, sig.num(%d)", signo);
379
380         /* signal block -------------- */
381         sigset_t old_mask, all_mask;
382         sigfillset(&all_mask);
383         sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
384
385         snprintf(filename, sizeof(filename) - 1, "/tmp/mm_session_%d", getpid());
386         if (!remove(filename)) {
387                 debug_log(" remove %s success\n", filename);
388         } else {
389                 strerror_r(errno, str_error, sizeof(str_error));
390                 debug_error(" remove %s failed with %s\n", filename, str_error);
391         }
392
393         sigprocmask(SIG_SETMASK, &old_mask, NULL);
394         /* signal unblock ------------ */
395
396         switch (signo) {
397         case SIGINT:
398                 if (session_int_old_action.sa_sigaction)
399                         session_int_old_action.sa_sigaction(signo, siginfo, context);
400                 else
401                         sigaction(signo, &session_int_old_action, NULL);
402                 break;
403         case SIGABRT:
404                 if (session_abrt_old_action.sa_sigaction)
405                         session_abrt_old_action.sa_sigaction(signo, siginfo, context);
406                 else
407                         sigaction(signo, &session_abrt_old_action, NULL);
408                 break;
409         case SIGSEGV:
410                 if (session_segv_old_action.sa_sigaction)
411                         session_segv_old_action.sa_sigaction(signo, siginfo, context);
412                 else
413                         sigaction(signo, &session_segv_old_action, NULL);
414                 break;
415         case SIGTERM:
416                 if (session_term_old_action.sa_sigaction)
417                         session_term_old_action.sa_sigaction(signo, siginfo, context);
418                 else
419                         sigaction(signo, &session_term_old_action, NULL);
420                 break;
421         case SIGSYS:
422                 if (session_sys_old_action.sa_sigaction)
423                         session_sys_old_action.sa_sigaction(signo, siginfo, context);
424                 else
425                         sigaction(signo, &session_sys_old_action, NULL);
426                 break;
427         case SIGXCPU:
428                 if (session_xcpu_old_action.sa_sigaction)
429                         session_xcpu_old_action.sa_sigaction(signo, siginfo, context);
430                 else
431                         sigaction(signo, &session_xcpu_old_action, NULL);
432                 break;
433         default:
434                 break;
435         }
436
437         debug_warning("LEAVE");
438 }
439
440 __attribute__ ((constructor))
441 void __mmsession_initialize(void)
442 {
443         struct sigaction session_action;
444         session_action.sa_sigaction = __session_signal_handler;
445         session_action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
446
447         debug_fenter();
448
449         sigemptyset(&session_action.sa_mask);
450
451         sigaction(SIGINT, &session_action, &session_int_old_action);
452         sigaction(SIGABRT, &session_action, &session_abrt_old_action);
453         sigaction(SIGSEGV, &session_action, &session_segv_old_action);
454         sigaction(SIGTERM, &session_action, &session_term_old_action);
455         sigaction(SIGSYS, &session_action, &session_sys_old_action);
456         sigaction(SIGXCPU, &session_action, &session_xcpu_old_action);
457
458         debug_fleave();
459 }
460
461 __attribute__ ((destructor))
462 void __mmsession_finalize(void)
463 {
464
465         debug_fenter();
466
467         _mm_session_util_delete_information(-1);
468
469         sigaction(SIGINT, &session_int_old_action, NULL);
470         sigaction(SIGABRT, &session_abrt_old_action, NULL);
471         sigaction(SIGSEGV, &session_segv_old_action, NULL);
472         sigaction(SIGTERM, &session_term_old_action, NULL);
473         sigaction(SIGSYS, &session_sys_old_action, NULL);
474         sigaction(SIGXCPU, &session_xcpu_old_action, NULL);
475
476         debug_fleave();
477 }
478