d481e3e1b32393220aeb01a08e1eca10dd5c7992
[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 <glib.h>
32 #include <pthread.h>
33
34 #define EXPORT_API __attribute__((__visibility__("default")))
35 #define MAX_FILE_LENGTH 256
36
37 int g_session_type = -1;
38
39 EXPORT_API
40 int mm_session_init(int sessiontype)
41 {
42         debug_fenter();
43         return mm_session_init_ex(sessiontype, NULL, NULL);
44         debug_fleave();
45 }
46
47 EXPORT_API
48 int mm_session_init_ex(int sessiontype, session_callback_fn callback, void* user_param)
49 {
50         int result = MM_ERROR_NONE;
51         int ltype = 0;
52         bool do_not_update_session_info = false;
53
54         debug_fenter();
55         debug_log("type : %d", sessiontype);
56
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;
60         }
61
62         result = _mm_session_util_read_type(-1, &ltype);
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;
67                 } else {
68                         debug_error("Session already initialized. Please finish current session first");
69                         return MM_ERROR_POLICY_DUPLICATED;
70                 }
71         }
72
73         /* Monitor Callback */
74         if (NULL == callback) {
75                 debug_warning("Null callback function");
76         } else {
77                 debug_warning("It was deprecated, do not use monitor callback, callback(%p), user_param(%p)", callback, user_param);
78         }
79
80         g_session_type = sessiontype;
81
82         if (!do_not_update_session_info) {
83                 result = _mm_session_util_write_type(-1, sessiontype);
84                 if (MM_ERROR_NONE != result) {
85                         debug_error("Write type failed");
86                         g_session_type = -1;
87                         return result;
88                 }
89         }
90
91         debug_fleave();
92
93         return MM_ERROR_NONE;
94 }
95
96 EXPORT_API
97 int mm_session_update_option(session_update_type_t update_type, int options)
98 {
99         int result = MM_ERROR_NONE;
100         int ltype = 0;
101         int loption = 0;
102
103         debug_log("update_type: %d(0:Add, 1:Remove), options: %x", update_type, options);
104
105         if (update_type < 0 || update_type >= MM_SESSION_UPDATE_TYPE_NUM) {
106                 debug_error("Invalid update_type value(%d)", update_type);
107                 return MM_ERROR_INVALID_ARGUMENT;
108         }
109         if (options < 0) {
110                 debug_error("Invalid options value(%x)", options);
111                 return MM_ERROR_INVALID_ARGUMENT;
112         }
113
114         result = _mm_session_util_read_information(-1, &ltype, &loption);
115         if (result) {
116                 debug_error("failed to _mm_session_util_read_information(), ret(%x)", result);
117                 return result;
118         }
119         debug_log("[current] session_type: %d, session_option: %x", ltype, loption);
120
121         if (update_type == MM_SESSION_UPDATE_TYPE_ADD) {
122                 loption |= options;
123         } else if (update_type == MM_SESSION_UPDATE_TYPE_REMOVE) {
124                 loption &= ~options;
125         }
126
127         result = _mm_session_util_write_information(-1, ltype, loption);
128         if (result) {
129                 debug_error("failed to _mm_session_util_write_information(), ret(%x)", result);
130                 return result;
131         }
132
133         debug_log("[updated] session_type: %d, session_option: %x", ltype, loption);
134
135
136         return MM_ERROR_NONE;
137 }
138
139 EXPORT_API
140 int mm_session_add_watch_callback(int watchevent, int watchstate, watch_callback_fn callback, void* user_param)
141 {
142         debug_fenter();
143
144         debug_fleave();
145
146         return MM_ERROR_NOT_SUPPORT_API;
147 }
148
149 EXPORT_API
150 int mm_session_get_current_type(int *sessiontype)
151 {
152         int result = MM_ERROR_NONE;
153         int ltype = 0;
154
155         debug_fenter();
156
157         if (sessiontype == NULL) {
158                 debug_error("input argument is NULL\n");
159                 return MM_ERROR_INVALID_ARGUMENT;
160         }
161
162         result = _mm_session_util_read_type(-1, &ltype);
163         if (result == MM_ERROR_NONE) {
164                 debug_log("Current process session type = [%d]\n", ltype);
165                 *sessiontype = ltype;
166         } else {
167                 debug_error("failed to get current process session type!!\n");
168         }
169
170         debug_fleave();
171
172         return result;
173 }
174
175 EXPORT_API
176 int mm_session_get_current_information(int *session_type, int *session_options)
177 {
178         int result = MM_ERROR_NONE;
179         int ltype = 0;
180         int loption = 0;
181
182         debug_fenter();
183
184         if (session_type == NULL) {
185                 debug_error("input argument is NULL\n");
186                 return MM_ERROR_INVALID_ARGUMENT;
187         }
188
189         result = _mm_session_util_read_information(-1, &ltype, &loption);
190         if (result == MM_ERROR_NONE) {
191                 debug_log("Current process session type = [%d], options = [%x]\n", ltype, loption);
192                 *session_type = ltype;
193                 *session_options = loption;
194         } else {
195                 debug_error("failed to get current process session type, option!!\n");
196         }
197
198         debug_fleave();
199
200         return result;
201 }
202
203 EXPORT_API
204 int mm_session_finish(void)
205 {
206         int result = MM_ERROR_NONE;
207         int sessiontype = MM_SESSION_TYPE_MEDIA;
208
209         debug_fenter();
210
211         result = _mm_session_util_read_type(-1, &sessiontype);
212         if (MM_ERROR_NONE != result) {
213                 debug_error("Can not read current type");
214                 return result;
215         }
216
217         /* Check monitor handle */
218         result = _mm_session_util_delete_information(-1);
219         if(result != MM_ERROR_NONE)
220                 return result;
221
222         debug_fleave();
223
224         return MM_ERROR_NONE;
225 }
226
227 EXPORT_API
228 int mm_session_remove_watch_callback(int watchevent, int watchstate)
229 {
230         debug_fenter();
231
232         debug_fleave();
233
234         return MM_ERROR_NOT_SUPPORT_API;
235 }
236
237 EXPORT_API
238 int mm_session_set_subsession(mm_subsession_t subsession, mm_subsession_option_t option)
239 {
240         debug_fenter();
241
242         debug_fleave();
243
244         return MM_ERROR_NOT_SUPPORT_API;
245 }
246
247 EXPORT_API
248 int mm_session_get_subsession(mm_subsession_t *subsession)
249 {
250         debug_fenter();
251
252         debug_fleave();
253
254         return MM_ERROR_NOT_SUPPORT_API;
255 }
256
257 EXPORT_API
258 int mm_session_set_subevent(mm_session_sub_t subevent)
259 {
260         debug_fenter();
261
262         debug_fleave();
263
264         return MM_ERROR_NOT_SUPPORT_API;
265 }
266
267 EXPORT_API
268 int mm_session_get_subevent(mm_session_sub_t *subevent)
269 {
270         debug_fenter();
271
272         debug_fleave();
273
274         return MM_ERROR_NOT_SUPPORT_API;
275 }
276
277 EXPORT_API
278 int mm_session_reset_resumption_info(void)
279 {
280         debug_fenter();
281
282         debug_fleave();
283
284         return MM_ERROR_NOT_SUPPORT_API;
285 }
286
287 EXPORT_API
288 int _mm_session_util_delete_information(int app_pid)
289 {
290         pid_t mypid;
291         char filename[MAX_FILE_LENGTH];
292
293         if(app_pid == -1)
294                 mypid = getpid();
295         else
296                 mypid = (pid_t)app_pid;
297
298         ////// DELETE SESSION TYPE /////////
299         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
300         if(-1 ==  unlink(filename))
301                 return MM_ERROR_FILE_NOT_FOUND;
302         ////// DELETE SESSION TYPE /////////
303
304         return MM_ERROR_NONE;
305 }
306
307 EXPORT_API
308 int _mm_session_util_write_type(int app_pid, int sessiontype)
309 {
310         pid_t mypid;
311         int fd = -1;
312         char filename[MAX_FILE_LENGTH];
313
314         if(sessiontype < MM_SESSION_TYPE_MEDIA || sessiontype >= MM_SESSION_TYPE_NUM) {
315                 return MM_ERROR_INVALID_ARGUMENT;
316         }
317
318         if(app_pid == -1)
319                 mypid = getpid();
320         else
321                 mypid = (pid_t)app_pid;
322
323         ////// WRITE SESSION TYPE /////////
324         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
325         fd = open(filename, O_WRONLY | O_CREAT, 0644 );
326         if(fd < 0) {
327                 debug_error("open() failed with %d",errno);
328                 return MM_ERROR_FILE_WRITE;
329         }
330         sessiontype = sessiontype << 16;
331         write(fd, &sessiontype, sizeof(int));
332         if(0 > fchmod (fd, 00777)) {
333                 debug_error("fchmod failed with %d", errno);
334         } else {
335                 debug_warning("write sessiontype(%d) to /tmp/mm_session_%d", sessiontype >> 16, mypid);
336         }
337         close(fd);
338         ////// WRITE SESSION TYPE /////////
339
340         return MM_ERROR_NONE;
341 }
342
343 EXPORT_API
344 int _mm_session_util_read_type(int app_pid, int *sessiontype)
345 {
346         pid_t mypid;
347         int fd = -1;
348         char filename[MAX_FILE_LENGTH];
349
350         debug_fenter();
351
352         if(sessiontype == NULL)
353                 return MM_ERROR_INVALID_ARGUMENT;
354
355         if(app_pid == -1)
356                 mypid = getpid();
357         else
358                 mypid = (pid_t)app_pid;
359
360         ////// READ SESSION TYPE /////////
361         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
362         fd = open(filename, O_RDONLY);
363         if(fd < 0) {
364                 return MM_ERROR_INVALID_HANDLE;
365         }
366         read(fd, sessiontype, sizeof(int));
367         *sessiontype = *sessiontype >> 16;
368         debug_warning("read sessiontype(%d) from /tmp/mm_session_%d", *sessiontype, mypid);
369         close(fd);
370         ////// READ SESSION TYPE /////////
371
372         debug_fleave();
373
374         return MM_ERROR_NONE;
375 }
376
377 EXPORT_API
378 int _mm_session_util_write_information(int app_pid, int session_type, int flags)
379 {
380         pid_t mypid;
381         int fd = -1;
382         char filename[MAX_FILE_LENGTH];
383         int result_info = 0;
384
385         if(session_type < MM_SESSION_TYPE_MEDIA || session_type >= MM_SESSION_TYPE_NUM) {
386                 return MM_ERROR_INVALID_ARGUMENT;
387         }
388         if(flags < 0) {
389                 return MM_ERROR_INVALID_ARGUMENT;
390         }
391
392         if(app_pid == -1) {
393                 mypid = getpid();
394         } else {
395                 mypid = (pid_t)app_pid;
396         }
397
398         ////// WRITE SESSION INFO /////////
399         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
400         fd = open(filename, O_WRONLY | O_CREAT, 0644 );
401         if(fd < 0) {
402                 debug_error("open() failed with %d",errno);
403                 return MM_ERROR_FILE_WRITE;
404         }
405
406         result_info = (flags) | (session_type << 16);
407         write(fd, &result_info, sizeof(int));
408         if(0 > fchmod (fd, 00777)) {
409                 debug_error("fchmod failed with %d", errno);
410         } else {
411                 debug_warning("write session information(%x) to /tmp/mm_session_%d", result_info, mypid);
412         }
413         close(fd);
414         ////// WRITE SESSION INFO /////////
415
416         return MM_ERROR_NONE;
417 }
418
419 EXPORT_API
420 int _mm_session_util_read_information(int app_pid, int *session_type, int *flags)
421 {
422         pid_t mypid;
423         int fd = -1;
424         char filename[MAX_FILE_LENGTH];
425         int result_info = 0;
426
427         debug_fenter();
428
429         if(session_type == NULL || flags == NULL) {
430                 return MM_ERROR_INVALID_ARGUMENT;
431         }
432
433         if(app_pid == -1) {
434                 mypid = getpid();
435         } else {
436                 mypid = (pid_t)app_pid;
437         }
438
439         ////// READ SESSION INFO /////////
440         snprintf(filename, sizeof(filename)-1, "/tmp/mm_session_%d",mypid);
441         fd = open(filename, O_RDONLY);
442         if(fd < 0) {
443                 return MM_ERROR_INVALID_HANDLE;
444         }
445         read(fd, &result_info, sizeof(int));
446         *session_type = result_info >> 16;
447         *flags = result_info & 0x0000ffff;
448
449         debug_warning("read session_type(%d), session_option(%x) from /tmp/mm_session_%d", *session_type, *flags, mypid);
450         close(fd);
451         ////// READ SESSION INFO /////////
452
453         debug_fleave();
454
455         return MM_ERROR_NONE;
456 }
457
458 __attribute__ ((destructor))
459 void __mmsession_finalize(void)
460 {
461         debug_fenter();
462
463         _mm_session_util_delete_information(-1);
464
465         debug_fleave();
466 }
467
468 __attribute__ ((constructor))
469 void __mmsession_initialize(void)
470 {
471
472 }
473